Created
August 18, 2014 02:11
-
-
Save Fire-Dragon-DoL/6767b281dc5494d4cab9 to your computer and use it in GitHub Desktop.
ActiveAdmin 1.0.0.pre user management page, simple setup with proper user handling for a website backoffice through CanCan, Devise and StrongParameters for Rails 4
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
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 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
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 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
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