user policies
This commit is contained in:
parent
12c7e9e77c
commit
ead9564fe8
@ -2,14 +2,16 @@
|
||||
module Admin
|
||||
class UserController < AdminController
|
||||
def index
|
||||
@users = User.order(:name)
|
||||
@users = policy_scope User.order(:name)
|
||||
end
|
||||
|
||||
def new
|
||||
@user = User.new
|
||||
authorize @user
|
||||
end
|
||||
|
||||
def create
|
||||
authorize User
|
||||
default_passwd = SecureRandom.urlsafe_base64(12)
|
||||
@user = User.create({ password: default_passwd }.merge(user_params.to_h))
|
||||
|
||||
@ -24,14 +26,17 @@ module Admin
|
||||
|
||||
def view
|
||||
@user = User.find(params[:user_id])
|
||||
authorize @user
|
||||
end
|
||||
|
||||
def edit
|
||||
@user = User.find(params[:user_id])
|
||||
authorize @user
|
||||
end
|
||||
|
||||
def update
|
||||
@user = User.find(params[:user_id])
|
||||
authorize @user
|
||||
|
||||
if @user.update_attributes(user_params)
|
||||
redirect_to admin_user_path(@user.to_i),
|
||||
|
@ -4,8 +4,12 @@ class AdminController < ApplicationController
|
||||
layout 'admin'
|
||||
before_action :authorize_user
|
||||
|
||||
# TODO: after_action :verify_authorized, except: :index
|
||||
# TODO: after_action :verify_policy_scoped, only: :index
|
||||
|
||||
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
|
||||
|
||||
# TODO: move to DashboardController#index
|
||||
def dashboard
|
||||
authorize :admin, :dashboard?
|
||||
@quizzes = Quiz.includes(:questions).all
|
||||
@ -25,6 +29,6 @@ class AdminController < ApplicationController
|
||||
|
||||
def user_not_authorized
|
||||
flash[:error] = "You are not authorized to perform this action."
|
||||
redirect_to(request.referer || root_path)
|
||||
redirect_to(request.referer || admin_login_path)
|
||||
end
|
||||
end
|
||||
|
@ -15,6 +15,12 @@ class User < ApplicationRecord
|
||||
save
|
||||
end
|
||||
|
||||
# TODO: move to mixin: UserRoles
|
||||
# define remaining helpers
|
||||
def admin?
|
||||
role == 'admin'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def gen_reset_token
|
||||
|
60
app/policies/application_policy.rb
Normal file
60
app/policies/application_policy.rb
Normal file
@ -0,0 +1,60 @@
|
||||
# frozen_string_literal: true
|
||||
class ApplicationPolicy
|
||||
attr_reader :user, :record
|
||||
|
||||
def initialize(user, record)
|
||||
raise Pundit::NotAuthorizedError, "Must be logged in." unless user
|
||||
@user = user
|
||||
@record = record
|
||||
end
|
||||
|
||||
def index?
|
||||
false
|
||||
end
|
||||
|
||||
def show?
|
||||
scope.where(id: record.id).exists?
|
||||
end
|
||||
|
||||
def view?
|
||||
show?
|
||||
end
|
||||
|
||||
def create?
|
||||
false
|
||||
end
|
||||
|
||||
def new?
|
||||
create?
|
||||
end
|
||||
|
||||
def update?
|
||||
false
|
||||
end
|
||||
|
||||
def edit?
|
||||
update?
|
||||
end
|
||||
|
||||
def destroy?
|
||||
false
|
||||
end
|
||||
|
||||
def scope
|
||||
Pundit.policy_scope!(user, record.class)
|
||||
end
|
||||
|
||||
class Scope
|
||||
attr_reader :user, :scope
|
||||
|
||||
def initialize(user, scope)
|
||||
@user = user
|
||||
@scope = scope
|
||||
end
|
||||
|
||||
def resolve
|
||||
# This is a closed system.
|
||||
raise Pundit::NotAuthorizedError, "No access to resource."
|
||||
end
|
||||
end
|
||||
end
|
21
app/policies/user_policy.rb
Normal file
21
app/policies/user_policy.rb
Normal file
@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
class UserPolicy < ApplicationPolicy
|
||||
def view?
|
||||
user.admin? && show?
|
||||
end
|
||||
|
||||
def create?
|
||||
user.admin?
|
||||
end
|
||||
|
||||
def update?
|
||||
user.admin?
|
||||
end
|
||||
|
||||
class Scope < Scope
|
||||
def resolve
|
||||
return scope if user.admin?
|
||||
raise Pundit::NotAuthorizedError, "No access to resource."
|
||||
end
|
||||
end
|
||||
end
|
30
test/policies/application_policy_test.rb
Normal file
30
test/policies/application_policy_test.rb
Normal file
@ -0,0 +1,30 @@
|
||||
# frozen_string_literal: true
|
||||
require 'test_helper'
|
||||
|
||||
class ApplicationPolicyTest < PolicyAssertions::Test
|
||||
# Verify default policies are most restrictive
|
||||
|
||||
test 'should require a user' do
|
||||
assert_raise Pundit::NotAuthorizedError do
|
||||
ApplicationPolicy.new(nil, User.new)
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not allow collections' do
|
||||
assert_raise Pundit::NotAuthorizedError do
|
||||
ApplicationPolicy::Scope.new(users(:admin), User).resolve
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not permit by default' do
|
||||
admin = users(:admin)
|
||||
refute ApplicationPolicy.new(admin, User.new).view?
|
||||
refute ApplicationPolicy.new(admin, User.new).show?
|
||||
refute ApplicationPolicy.new(admin, nil).index?
|
||||
refute ApplicationPolicy.new(admin, nil).create?
|
||||
refute ApplicationPolicy.new(admin, nil).new?
|
||||
refute ApplicationPolicy.new(admin, nil).update?
|
||||
refute ApplicationPolicy.new(admin, nil).edit?
|
||||
refute ApplicationPolicy.new(admin, nil).destroy?
|
||||
end
|
||||
end
|
31
test/policies/user_policy_test.rb
Normal file
31
test/policies/user_policy_test.rb
Normal file
@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
require 'test_helper'
|
||||
|
||||
class UserPolicyTest < PolicyAssertions::Test
|
||||
test 'should allow admin to scope' do
|
||||
scope = UserPolicy::Scope.new(users(:admin), User).resolve
|
||||
assert_equal User.count, scope.count
|
||||
end
|
||||
|
||||
test 'should not allow non_admin' do
|
||||
assert_raise Pundit::NotAuthorizedError do
|
||||
UserPolicy::Scope.new(users(:manager), User).resolve
|
||||
end
|
||||
end
|
||||
|
||||
test 'should require current_user' do
|
||||
assert_raise Pundit::NotAuthorizedError do
|
||||
UserPolicy.new(nil, User.first).view?
|
||||
end
|
||||
end
|
||||
|
||||
def test_view
|
||||
refute_permit users(:manager), User.first
|
||||
assert_permit users(:admin), User.first
|
||||
end
|
||||
|
||||
def test_create_and_update
|
||||
refute_permit users(:manager), User
|
||||
assert_permit users(:admin), User
|
||||
end
|
||||
end
|
@ -7,6 +7,7 @@ SimpleCov.start 'rails' do
|
||||
add_group 'Models', %w(app/models app/validators)
|
||||
add_group 'Services & Workers', %w(app/workers app/services)
|
||||
add_group "Jobs", 'app/jobs'
|
||||
add_group "Policies", 'app/policies'
|
||||
end
|
||||
|
||||
require File.expand_path('../../config/environment', __FILE__)
|
||||
|
Loading…
Reference in New Issue
Block a user