Reputation: 15107
I am writing a system where every user can manage other users' permissions.
I have a business requirement where a logged_in_user can't demote someone higher than them in rankings. My positions are the following:
STAFF < MANAGER < ORGANIZATION_ADMIN
I am trying to display the permission buttons for the users and have the following (ugly) method that gets the job done, but feels like awful code.
# Iterate through all users and allow for their permissions to be modified
other_users.each do |other_user|
buttons_to_show = get_buttons_to_show(logged_in_user, other_user)
if buttons_to_show.include?(ORGANIZATION_ADMIN)
puts "Make other_user #{ORGANIZATION_ADMIN}" # Will be a button on UI
if buttons_to_show.include?(MANAGER)
puts "Make other_user #{MANAGER}" # Will be a button on UI
if buttons_to_show.include?(STAFF)
puts "Make other_user #{STAFF}" # Will be a button on UI
end
def get_buttons_to_show(current_user, other_user)
buttons_to_show = []
if (current_user.at_least_staff? && other_user.role != MANAGER && other_user.role != ORGANIZATION_ADMIN) ||
(current_user.at_least_manager? && other_user.role != ORGANIZATION_ADMIN) ||
(current_user.at_least_organization_admin?)
buttons_to_show << STAFF
end
if (current_user.at_least_manager? && other_user.role != ORGANIZATION_ADMIN) ||
(current_user.at_least_organization_admin?)
buttons_to_show << MANAGER
end
if current_user.at_least_organization_admin?
buttons_to_show << ORGANIZATION_ADMIN
end
buttons_to_show
end
Upvotes: 0
Views: 38
Reputation: 15107
I decided to use Pundit and move all of those methods into my policies. Works like a charm and is much cleaner.
Upvotes: 0
Reputation: 2912
Have you looked at using something like https://github.com/CanCanCommunity/cancancan ?
I used it recently and you end up adding some code to the models like this:
if user.has_role? :uam_officer
can :create, Segment
cannot :approve, User
cannot :reject, User
end
and then in views for instance:
<% if can?(:create, Segment) %>
<%= link_to 'New', new_management_segment_path, { :class=>"btn btn-primary" } %>
<% end %>
it helps keep the authorization logic packaged neatly.
Upvotes: 1