Skip to content

Instantly share code, notes, and snippets.

@jasper502
Last active January 15, 2024 06:00
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jasper502/4b2f1b8b6f21a26c64a5 to your computer and use it in GitHub Desktop.
Save jasper502/4b2f1b8b6f21a26c64a5 to your computer and use it in GitHub Desktop.
Active Admin, Devise and Pundit
# /config/initializers/active_admin.rb
ActiveAdmin.setup do |config|
# == User Authentication
#
# Active Admin will automatically call an authentication
# method in a before filter of all controller actions to
# ensure that there is a currently logged in admin user.
#
# This setting changes the method which Active Admin calls
# within the application controller.
config.authentication_method = :authenticate_admin_user!
# config.authentication_method = false
# == User Authorization
#
# Active Admin will automatically call an authorization
# method in a before filter of all controller actions to
# ensure that there is a user with proper rights. You can use
# CanCanAdapter or make your own. Please refer to documentation.
# config.authorization_adapter = ActiveAdmin::CanCanAdapter
# In case you prefer Pundit over other solutions you can here pass
# the name of default policy class. This policy will be used in every
# case when Pundit is unable to find suitable policy.
#config.pundit_default_policy = "FlagPolicy"
config.authorization_adapter = ActiveAdmin::PunditAdapter
#config.authorization_adapter = ActiveAdminAuthorization
#config.pundit_default_policy = "ApplicationPolicy"
config.current_user_method = :current_admin_user
config.logout_link_path = :destroy_admin_user_session_path
config.batch_actions = true
config.localize_format = :long
# I added this allow an active admin login without logging in to the main app
ActiveAdmin::BaseController.class_eval do
skip_before_filter :authenticate_user!
end
end
# config/initializers/active_admin_extensions.rb:
ActiveAdmin::BaseController.send(:include, ActiveAdmin::SkipPolicyScoping)
# /controller/application_controller.rb
class ApplicationController < ActionController::Base
include Pundit
rescue_from Pundit::NotAuthorizedError, with: :permission_denied
protect_from_forgery with: :exception
before_action :authenticate_user!
after_action :verify_authorized, except: [:landing, :dashboard], unless: :devise_controller?
after_action :verify_policy_scoped, only: [:index]
#after_action :verify_policy_scoped, only: [:index] if controller_path.split('/').first != "admin"
#edited to make clearer
end
# /admin/dashboard.rb
ActiveAdmin.register_page "Dashboard" do
def index
authorize :dashboards, :index?
end
menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") }
content title: proc{ I18n.t("active_admin.dashboard") } do
div class: "blank_slate_container", id: "dashboard_default_message" do
span class: "blank_slate" do
span I18n.t("active_admin.dashboard_welcome.welcome")
small I18n.t("active_admin.dashboard_welcome.call_to_action")
end
end
# Here is an example of a simple dashboard with columns and panels.
#
# columns do
# column do
# panel "Recent Posts" do
# ul do
# Post.recent(5).map do |post|
# li link_to(post.title, admin_post_path(post))
# end
# end
# end
# end
# column do
# panel "Info" do
# para "Welcome to ActiveAdmin."
# end
# end
# end
end # content
end
# /confirg/initializers/devise.rb
# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
Devise.setup do |config|
require 'devise/orm/active_record'
config.case_insensitive_keys = [:email]
config.strip_whitespace_keys = [:email]
config.skip_session_storage = [:http_auth]
config.stretches = Rails.env.test? ? 1 : 10
config.reconfirmable = true
config.expire_all_remember_me_on_sign_out = true
config.password_length = 8..72
config.reset_password_within = 6.hours
## Added this so when you log out from the User you don't logout the AdminUser too
config.sign_out_all_scopes = false
config.sign_out_via = :delete
end
# /lib/active_admin/pundit_adapter.rb
# in lib/active_admin/
require 'pundit'
# https://github.com/gregbell/active_admin/blob/master/lib/active_admin/authorization_adapter.rb
module ActiveAdmin
# References
#
# Default Authorization permissions for Active Admin
#
# module Authorization
# READ = :read
# CREATE = :create
# UPDATE = :update
# DESTROY = :destroy
# end
class PunditAdapter < AuthorizationAdapter
def authorized?(action, subject = nil)
true
#
#action = if subject.is_a? Class
# :index?
#else
# override_action_name action
#end
#Pundit.policy(user, subject).public_send action
end
def scope_collection(collection, action = Auth::READ)
Pundit.policy_scope(user, collection)
end
def override_action_name(action)
case action
# https://github.com/elabs/pundit/blob/master/lib/generators/pundit/install/templates/application_policy.rb
when :read
:show?
when :create
:create?
when :update
:update?
when :destroy?
:destroy?
else
"#{ action }?"
end
end
end
end
# lib/active_admin/skip_policy_scoping.rb:
module ActiveAdmin
module SkipPolicyScoping
extend ActiveSupport::Concern
included do
before_filter :skip_policy_scoping
before_filter :skip_auth, if: 'controller_path == "admin/dashboard"'
end
private
def skip_policy_scoping
skip_policy_scope
end
def skip_auth
skip_authorization
end
end
end
# /admin/user.rb
ActiveAdmin.register User do
before_filter :only => [:index] do
authorize collection
end
before_filter :except => [:index] do
authorize resource
end
# See permitted parameters documentation:
# https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters
#
# permit_params :list, :of, :attributes, :on, :model
#
# or
#
# permit_params do
# permitted = [:permitted, :attributes]
# permitted << :other if resource.something?
# permitted
# end
end
# /policies/active_admin/user_policy.rb
module ActiveAdmin
class UserPolicy < ApplicationPolicy
class Scope < Struct.new(:user, :scope)
# class Scope < Struct.new(:enrollment, :scope)
def resolve
scope
end
end
def home?
true
end
def index?
true
end
def show?
true
end
def new?
true
end
def create?
true
end
def update?
true
end
def destroy?
true
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment