Skip to content

Instantly share code, notes, and snippets.

@dhoss
Last active August 29, 2015 14:15
Show Gist options
  • Save dhoss/486294369b2015d37a39 to your computer and use it in GitHub Desktop.
Save dhoss/486294369b2015d37a39 to your computer and use it in GitHub Desktop.
# Scenario:
# We run a youtube production company and we make videos for paying members.
# Paying members can likewise access paid for premium content, and guests can access free content.
# Pretty straight forward.
#
# Next Scenario:
# We decide, one day, to open source all of our content. All videos, text posts, tutorials, etc
# are now available to *all* users.
#
# What's the most optimal way to be able to ship such a feature, with all tests passing.
#
# Well, an AuthorizationObject isn't the worst way to go.
# Here's an example of how we might use one here.
#
# Example controller
class SessionsController < Devise::SessionsController
before_filter :set_auth_object
# Login example.
# Do normal login, then goto route based on access level.
def new
super
redirect_to super_secret_admin_url if @user_authorizer.admin?
redirect_to content_url if @user_authorizer.has_access_to_content?
redirect_to guest_url if @user_authorizer.has_no_permissions?
end
private
# Create our auth object to ask it questions about the users permissions.
def set_auth_object
if user_signed_in?
@user_authorizer = Authorizer.new(current_user)
else
@user_authorizer = Authorizer.new(:guest)
end
end
end
# Here's how an example implementation of that auth object might look.
class Authorizer
def initialize user
@user = user
end
def admin?
@user.admin
end
# Here we are choosing rudimentary booleans just as an example.
def has_access_to_content?
# Examples ideas on random ways a user could have access
if @user.admin || @user.has_purchased
true
elsif Receipt.find_by(cardholder_name: @user.name)
true
else
false
end
end
end
# But.. now we want to open it all up. All users can access all content.
# Well, an easy way to do that now would be to just subclass the main auth object
# implement all the methods, return true, and profit.
class VoidAuthorizer < Authorizer
def has_access_to_content?
true
end
end
# Then, we change API where we implemented it, and that's basically it.
VoidAuthorizer.new
# Such is the beauty of auth objects.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment