Created
August 28, 2014 16:46
-
-
Save willscripted/ba8a004941b2f22a4347 to your computer and use it in GitHub Desktop.
Fine-grained permissions
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
| ## e.g. Usage | |
| def V1::UserController < V1::BaseController | |
| ## In controller | |
| def show | |
| render :json => reject_unpermitted(user, V1::UserPresenter.new(user)) | |
| end | |
| def update | |
| user = User.find(params[:id]) | |
| if user.update_attributes(updatable_params(user)) | |
| render :status => 200, :json => V1::UserPresenter.new(user) | |
| else | |
| render :status => :unprocessable_entity, :json => { :errors => user.errors } | |
| end | |
| end | |
| def index | |
| render :json => User.all.map {|u| reject_unpermitted(u, V1::UserPresenter.new(u))} | |
| end | |
| private | |
| def updateable_params(user) | |
| # Determine what fields the user with `current_ability` can update | |
| updatable = V1::UserPermissions.new(user, current_ability).on_update | |
| # Remove anything they can't update | |
| p = params.clone | |
| p.slice!(updatable) | |
| p | |
| end | |
| def reject_unpermitted(user, json) | |
| # Determine showable fields | |
| # e.g. [:is_admin, :username, :password] | |
| showable = V1::UserPermissions.new(user, current_ability).on_show | |
| # Remove unpermitted fields from json | |
| json.slice!(showable) | |
| json | |
| 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
| # Takes a target object and current ability, and | |
| # spits out arrays of permitted keys. Arrays can then | |
| # be used to slice! params or json | |
| class V1::UserPermissions | |
| def initialize(user, current_ability) | |
| @user = user | |
| @ability = current_ability | |
| end | |
| # Returns an array of attribute symbols that @current_user can update on @user | |
| def on_update | |
| fields = [:username, :email, :password] | |
| fields.push(:is_admin) if @ability.can?(:manage, @user) | |
| fields | |
| end | |
| # Returns an array of attribute symbols that can be shown to a user with @ability | |
| def on_show | |
| fields = User.attribute_names | |
| fields -= [:is_admin] | |
| fields | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment