-
-
Save kivanio/b11f398fb75c606a6c97 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
class Ability | |
include CanCan::Ability | |
attr_reader :current_user | |
def initialize(user) | |
alias_action :create, :update, :destroy, :to => :write | |
@current_user = user || User.new | |
public_send(current_user.role) | |
end | |
def guest | |
end | |
def user | |
end | |
def manager | |
can :read, ActiveAdmin::Page, name: 'Dashboard' | |
can [:read, :update], User, User.where(id: current_user.id) do |user| | |
user.id == current_user.id | |
end | |
end | |
def publisher | |
can :read, ActiveAdmin::Page, name: 'Dashboard' | |
can [ | |
:create, | |
:read, | |
:update | |
], User, User.accessibles_for(current_user) do |user| | |
user.accessible_for? current_user | |
end | |
can :destroy, User, User.where.not(id: current_user.id) do |user| | |
user.id != current_user.id | |
end | |
end | |
def developer | |
can :read, ActiveAdmin::Page, name: 'Dashboard' | |
can :manage, User | |
cannot :destroy, User | |
can :destroy, User, User.where.not(id: current_user.id) do |user| | |
user.id != current_user.id | |
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
ActiveAdmin.register User do | |
permit_params do | |
[:email].tap do |allowed_params| | |
if params[:user] && current_user.has_access_for?(params[:user][:role]) | |
allowed_params << :role | |
end | |
if [:new, :create].include?(params[:action].try(:to_sym)) | |
allowed_params << :password | |
allowed_params << :password_confirmation | |
else | |
if params[:user] && params[:user][:password].present? | |
allowed_params << :password | |
allowed_params << :password_confirmation | |
end | |
end | |
end | |
end | |
config.filters = false | |
# XXX: Very important, disable batch actions because they don't check cancan | |
# permissions. It probably can be worked around, check the following | |
# links: | |
# http://www.activeadmin.info/docs/9-batch-actions.html | |
# https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities-with-Blocks | |
# https://github.com/CanCanCommunity/cancancan/wiki/Fetching-Records | |
config.batch_actions = false | |
index download_links: false do | |
column :email do |user| | |
link_to user.email, admin_user_path(user) | |
end | |
column :role do |user| | |
I18n.t(user.role, scope: 'authorization.roles') | |
end | |
column :current_sign_in_at | |
column :sign_in_count | |
actions | |
end | |
form do |f| | |
f.inputs I18n.t('admin.resources.user.details') do | |
f.input :email | |
if user.accessible_for?(current_user) && current_user.id != user.id | |
f.input :role, as: :select, | |
collection: User.i18n_roles, | |
include_blank: false | |
end | |
f.input :password | |
f.input :password_confirmation | |
end | |
f.actions | |
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 < ActiveRecord::Base | |
# Include default devise modules. Others available are: | |
# :confirmable, :lockable, :timeoutable and :omniauthable | |
devise :database_authenticatable, | |
:recoverable, :rememberable, :trackable, :validatable, :lockable | |
ROLES = %i(guest user manager publisher developer).freeze | |
ROLES_ACCESSIBILITY = HashWithIndifferentAccess.new({ | |
guest: [].freeze, | |
user: [].freeze, | |
manager: %i(guest user manager).freeze, | |
publisher: %i(guest user manager publisher).freeze, | |
developer: %i(guest user manager publisher developer).freeze | |
}).freeze | |
enum role: ROLES | |
validates :email, presence: true, uniqueness: true, email: true | |
validates :password, presence: true, if: -> { new_record? } | |
validates :password_confirmation, presence: true, if: -> { new_record? } | |
def has_access_for?(other_role) | |
ROLES_ACCESSIBILITY[role].include?(other_role.try(:to_sym)) | |
end | |
def accessible_for?(user) | |
ROLES_ACCESSIBILITY[user.role].include?(role.try(:to_sym)) | |
end | |
class << self | |
extend Memoist | |
def roles_accessiblity_values(role) | |
ROLES_ACCESSIBILITY[role].map { |accessible_role| roles[accessible_role] } | |
end | |
memoize :roles_accessiblity_values | |
def i18n_roles | |
User.roles.keys.inject({}) do |result, role| | |
# XXX: Must use string for enum values | |
result[I18n.t(role, scope: 'authorization.roles')] = role | |
result | |
end | |
end | |
memoize :i18n_roles | |
def accessibles_for(user) | |
where(role: roles_accessiblity_values(user.role)) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment