Created
August 27, 2013 13:57
-
-
Save cpuguy83/6353857 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
This is cherry-picked from an internal application that I built... | |
Basically, a User is assigned a set of Permissions, inheritted from their group and also directly assigned to the user object (which in my code gets merged, but is simplified here). | |
Permissions are a set of permissions storing a few things (allowed actions, authorization scope, etc), including the list of attrs the user is allowed to modify. | |
When the controller action is called it is getting filtered through the policy for that controller (which inherits from ApplicationPolicy) which determines if the user is allowed to perform that action, on that resource(s), and which fields the user is allowed to modify (in an array). | |
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
class ApplicationController < ActionController::Base | |
#... stuff | |
private | |
def resource_params | |
if params[:action] == 'new' | |
[] | |
elsif current_user.admin? | |
params.require(resource_instance_name).permit! | |
else | |
params.require(resource_instance_name).permit( *policy_attributes(resource_class) ) | |
end | |
end | |
def policy_attributes(user, scope) | |
policy = PolicyFinder.new(scope).permitted_attributes | |
policy.new(user, scope).resolve if policy | |
end | |
end |
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
class ApplicationPolicy | |
# My authorization logic for controller actions goes here | |
# ... | |
class PermittedAttributes < Struct.new(:user, :scope) | |
def resolve | |
if user.admin? | |
scope.available_attrs | |
else | |
user.materialized_accessible_attrs(scope) | |
end | |
end | |
end | |
end |
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
class User | |
has_many :permissions | |
#... user stuff | |
def materialized_accessible_attrs(klass) | |
# ... | |
# I have some additional logic where a user is in a group, | |
# and attrs can be defined at the group level and the user level | |
# Skipping that here | |
permissions.where(model_class: klass.to_s).pluck(&:accessible_attrs) | |
end | |
# Checks accessible_attrs to see if user can write to it | |
def has_write_permission_to_field?(klass, field) | |
if materialized_accessible_attrs(klass).include? field | |
true | |
else | |
false | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment