Created
October 27, 2016 10:49
-
-
Save dux/7b95fd273699b7cb29cb767d6483e7b8 to your computer and use it in GitHub Desktop.
few simple policy objects
This file contains hidden or 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
class DefaultPolicy < Policy | |
def before(action) | |
# return true for admins | |
admin? | |
end | |
def admin? | |
@user.try(:is_admin?) || false | |
end | |
def my? | |
return false unless @user | |
@user.id == @model.created_by | |
end | |
end |
This file contains hidden or 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
class ModelPolicy < DefaultPolicy | |
class << self | |
# ModelPolicy.can?(:write, @user) check UserPolicy.can?(:write, @user) if UserPolicy exists | |
# if not, it will fallback to ModelPolicy | |
def policy_class(model) | |
return self if self != ModelPolicy | |
"#{model.class}Policy".constantize rescue ModelPolicy | |
end | |
end | |
### | |
def read? | |
true | |
end | |
def create? | |
!!@user | |
end | |
def update? | |
my? | |
end | |
def delete? | |
my? | |
end | |
end |
This file contains hidden or 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
# current user actions | |
# alias for current_user.can?(...) but works with guests | |
# --- | |
# Policy.can?(:login?) -> ApplicationPolicy.can?(:login?) | |
# Policy.can?(:create, @product) -> ModelPolicy.can? ... | |
# Policy.can?(:update, @product) -> ProductPolicy.can? ... | |
# check if some other user can do action | |
# @user.can?(:update, @product) | |
# base caller | |
# Policy.check?(@user, action, model, &block) | |
# UserPolicy.can?(:update, @user) -> can current user update @user | |
# UserPolicy.can?(:update, @rental) -> can current user update @rental | |
# UserPolicy.check?(@user, :update, @rental) -> can @user update @rental | |
# call without block | |
# begin | |
# ApplicationPolicy.can?(:login) | |
# rescue | |
# raise UnauthorizedError, 'Err test_can: no access' | |
# end | |
# block will capture error message and be triggered only if error is present | |
# ApplicationPolicy.can?(:login) { |msg| http_error 401, "Err: #{msg}".red; return 'no access' } | |
class Policy | |
class << self | |
# assumes @user User.current | |
def can?(action, argument=nil, &block) | |
check?(User.current, action, argument, &block) | |
end | |
# default action | |
def check?(user, action, argument=nil, &block) | |
policy_class(argument).new(user, action, argument).call(&block) | |
end | |
# you can provide some other class for a given argument | |
def policy_class(argument=nil) | |
self | |
end | |
end | |
### | |
def initialize(user, action, argument=nil) | |
action = action.to_s.sub('?','') + '?' | |
action = action.to_sym | |
raise NoMethodError, %[Policy check "#{action}" not found in #{self.class}] unless respond_to?(action) | |
@user = user | |
@action = action | |
@model = @argument = argument | |
end | |
def call(&block) | |
return true if before(@action) | |
return true if send(@action) | |
raise UnauthorizedError, "access disabled in policy" | |
rescue UnauthorizedError | |
error = $!.message | |
error += "- #{self.class}.#{@action}" if Lux.dev? | |
raise UnauthorizedError, error unless block | |
block.call(error) | |
false | |
end | |
### | |
def before(action) | |
false | |
end | |
def error(message) | |
raise UnauthorizedError, message | |
end | |
end |
This file contains hidden or 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
class UserPolicy < ModelPolicy | |
def create? | |
false | |
end | |
def read? | |
my? | |
end | |
def update? | |
my? | |
end | |
def delete? | |
false | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment