Last active
August 29, 2015 14:15
-
-
Save dhoss/486294369b2015d37a39 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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