Authorization in Rails 4 app that has external data source -
i building app uses salesforce backend data storage. means have no models in database other user. can't use traditional authorization solutions rails because require me access rails models.
the app i'm building requires permissions surrounding user. user has 2 states: user:unactivated user:activated
i triggering change in users' states salesforce.
i have views need protected based on state of user. i'm not sure if scalable way handle simple state column in user model , have <%= current_user.state == "activated" %> in views or if there better solution?
thank you
a new feature of active record, enum, introduced in rails 4.1, simplest way implement requirement. can implement basic form of role-based authorization, single role "activated" has 2 states.
create migration:
$ rails generate migration addroletousers role:integer
the migration this:
class addroletousers < activerecord::migration def change add_column :users, :role, :integer end end
add code user model implement enum:
class user < activerecord::base enum role: [:activated, :unactivated] after_initialize :set_default_role, :if => :new_record? def set_default_role self.role ||= :unactivated end end
you define names of roles, , if necessary, can change names needed (the integer values stored each user record remain unchanged). active record restrict assignment of attribute collection of predefined values, don’t have add code restrict names of roles defined set. best of all, enums come set of convenience methods allow directly query role without code. enum attribute named role, values activated, , unactivated, can use these methods:
user.roles # => {"activated"=>0, "unactivated"=>1} # list roles user.activated! # make user activated user.activated? # => true # query if user activated user.role # => "activated" # find out user’s role @users = user.activated # obtain array of users activated user.role = 'foo' # argumenterror: 'foo' not valid, can’t set invalid roles
you can use conditionals in controller:
class userscontroller < applicationcontroller def index unless current_user.activated? redirect_to :back, :alert => "access denied." end @users = user.all end end
or use in view:
<% if current_user.activated? %> <li><%= link_to 'special reports', some_path %></li> <% end %>
in general, if access control adds lot of code controller, you're well-advised use cancancan or pundit, because can move complex authorization logic central location segregated controllers ("skinny controllers"). however, if needs simple describe, role-based authorization in controller optimal.
i've written rails pundit tutorial compares both approaches , provides greater detail on simple role-based authorization role-based authorization pundit.
Comments
Post a Comment