Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎁 Add admin dashboard data repair jobs menu #939

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions app/controllers/admin/roles_service_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

module Admin
class RolesServiceController < ApplicationController
layout 'hyrax/dashboard'

def index
authorize! :update, RolesService
add_breadcrumb t(:'hyrax.controls.home'), root_path
add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path
add_breadcrumb t(:'hyrax.admin.sidebar.roles_service_jobs'), main_app.admin_roles_service_jobs_path
end

# post "admin/roles_service/:job_name_key
def update_roles
authorize! :update, RolesService
job = RolesService.valid_jobs.fetch(params[:job_name_key])

job.perform_later

respond_to do |wants|
wants.html { redirect_to main_app.admin_roles_service_jobs_path, notice: "#{job} has been submitted." }
wants.json { render json: { notice: "#{job} has been submitted." }, status: :ok }
end
end
end
end
1 change: 1 addition & 0 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def admin_permissions

super
can [:manage], [Site, Role, User]
can [:update], RolesService

can [:read, :update], Account do |account|
account == Site.account
Expand Down
199 changes: 116 additions & 83 deletions app/services/roles_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,95 +101,19 @@ def create_default_hyrax_groups_with_roles!
# creating a Hyrax::PermissionTemplateAccess record (combined with Ability#user_groups)
# means all Collections will show up in Blacklight / Solr queries.
def create_collection_accesses!
Collection.find_each do |c|
pt = Hyrax::PermissionTemplate.find_or_create_by!(source_id: c.id)
original_access_grants_count = pt.access_grants.count

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::MANAGE,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: Ability.admin_group_name
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::MANAGE,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'collection_manager'
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::VIEW,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'collection_editor'
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::VIEW,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'collection_reader'
)

c.reset_access_controls! if pt.access_grants.count != original_access_grants_count
end
CreateCollectionAccessesJob.perform_now
end

# Creating a Hyrax::PermissionTemplateAccess record (combined with Ability#user_groups)
# will allow Works in all AdminSets to show up in Blacklight / Solr queries.
def create_admin_set_accesses!
AdminSet.find_each do |as|
pt = Hyrax::PermissionTemplate.find_or_create_by!(source_id: as.id)
original_access_grants_count = pt.access_grants.count

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::MANAGE,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: Ability.admin_group_name
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::DEPOSIT,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'work_depositor'
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::DEPOSIT,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'work_editor'
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::VIEW,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'work_editor'
)

as.reset_access_controls! if pt.access_grants.count != original_access_grants_count
end
CreateAdminSetAccessesJob.perform_now
end

# Because some of the collection roles have access to every Collection within a tenant, create a
# Hyrax::CollectionTypeParticipant record for them on every Hyrax::CollectionType (except the AdminSet)
def create_collection_type_participants!
Hyrax::CollectionType.find_each do |ct|
next if ct.admin_set?

# The :collection_manager role will automatically get a Hyrax::PermissionTemplateAccess
# record when a Collection is created, giving them manage access to that Collection.
ct.collection_type_participants.find_or_create_by!(
access: Hyrax::CollectionTypeParticipant::MANAGE_ACCESS,
agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE,
agent_id: 'collection_manager'
)

# The :collection_editor role will automatically get a Hyrax::PermissionTemplateAccess
# record when a Collection is created, giving them create access to that Collection.
ct.collection_type_participants.find_or_create_by!(
access: Hyrax::CollectionTypeParticipant::CREATE_ACCESS,
agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE,
agent_id: 'collection_editor'
)
end
CreateCollectionTypeParticipantsJob.perform_now
end

# Because the collection roles are used to explicitly grant Collection creation permissions,
Expand Down Expand Up @@ -227,10 +151,7 @@ def create_admin_group_memberships!
#
# NOTE: All AdminSets must have a permission template or this will fail. Run #create_admin_set_accesses first.
def grant_workflow_roles_for_all_admin_sets!
AdminSet.find_each do |admin_set|
Hyrax::Workflow::PermissionGrantor
.grant_default_workflow_roles!(permission_template: admin_set.permission_template)
end
GrantWorkflowRolesForAllAdminSetsJob.perform_now
end

# This method is inspired by the devise_guests:delete_old_guest_users rake task in the devise-guests gem:
Expand Down Expand Up @@ -301,4 +222,116 @@ def seed_qa_users!
end
end
end

class GrantWorkflowRolesForAllAdminSetsJob < Hyrax::ApplicationJob
def perform
AdminSet.find_each do |admin_set|
Hyrax::Workflow::PermissionGrantor
.grant_default_workflow_roles!(permission_template: admin_set.permission_template)
end
end
end

class CreateCollectionAccessesJob < Hyrax::ApplicationJob
def perform
Collection.find_each do |c|
pt = Hyrax::PermissionTemplate.find_or_create_by!(source_id: c.id)
original_access_grants_count = pt.access_grants.count

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::MANAGE,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: Ability.admin_group_name
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::MANAGE,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'collection_manager'
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::VIEW,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'collection_editor'
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::VIEW,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'collection_reader'
)

c.reset_access_controls! if pt.access_grants.count != original_access_grants_count
end
end
end

class CreateAdminSetAccessesJob < Hyrax::ApplicationJob
def perform
AdminSet.find_each do |as|
pt = Hyrax::PermissionTemplate.find_or_create_by!(source_id: as.id)
original_access_grants_count = pt.access_grants.count

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::MANAGE,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: Ability.admin_group_name
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::DEPOSIT,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'work_depositor'
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::DEPOSIT,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'work_editor'
)

pt.access_grants.find_or_create_by!(
access: Hyrax::PermissionTemplateAccess::VIEW,
agent_type: Hyrax::PermissionTemplateAccess::GROUP,
agent_id: 'work_editor'
)

as.reset_access_controls! if pt.access_grants.count != original_access_grants_count
end
end
end

class CreateCollectionTypeParticipantsJob < Hyrax::ApplicationJob
def perform
Hyrax::CollectionType.find_each do |ct|
next if ct.admin_set?

# The :collection_manager role will automatically get a Hyrax::PermissionTemplateAccess
# record when a Collection is created, giving them manage access to that Collection.
ct.collection_type_participants.find_or_create_by!(
access: Hyrax::CollectionTypeParticipant::MANAGE_ACCESS,
agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE,
agent_id: 'collection_manager'
)

# The :collection_editor role will automatically get a Hyrax::PermissionTemplateAccess
# record when a Collection is created, giving them create access to that Collection.
ct.collection_type_participants.find_or_create_by!(
access: Hyrax::CollectionTypeParticipant::CREATE_ACCESS,
agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE,
agent_id: 'collection_editor'
)
end
end
end

def self.valid_jobs
ActiveSupport::HashWithIndifferentAccess.new(
create_collection_accesses: CreateCollectionAccessesJob,
create_admin_set_accesses: CreateAdminSetAccessesJob,
create_collection_type_participants: CreateCollectionTypeParticipantsJob,
grant_workflow_roles_for_all_admin_sets: GrantWorkflowRolesForAllAdminSetsJob
)
end
end
21 changes: 21 additions & 0 deletions app/views/admin/roles_service/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<% content_for :page_title, construct_page_title(t('hyrax.admin.roles_service_jobs.header'), t('hyku.admin.title')) %>
<% provide :page_header do %>
<h1><span class="fa fa-wrench" aria-hidden="true"></span>
<%= t('hyrax.admin.roles_service_jobs.header') %></h1>
<% end %>

<div class='panel panel-default'>
<div class='panel-body'>
<div class='table-responsive'>
<table class='table table-striped datatable'>
<tbody>
<% RolesService.valid_jobs.each do |key, klass| %>
<tr>
<td><%= button_to t("hyrax.admin.roles_service_jobs.jobs.#{key}.label"), main_app.admin_update_roles_path(job_name_key: key), method: :post, class: 'btn btn-danger' %></td>
<td><%= t("hyrax.admin.roles_service_jobs.jobs.#{key}.description") %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
5 changes: 5 additions & 0 deletions app/views/hyrax/dashboard/sidebar/_configuration.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,9 @@
<% end # end of configuration block %>
<%= render 'hyrax/dashboard/sidebar/menu_partials', menu: menu, section: :configuration %>
<% end %>
<% if can?(:update, RolesService) %>
<%= menu.nav_link(main_app.admin_roles_service_jobs_path) do %>
<span class="fa fa-users" aria-hidden="true"></span> <span class="sidebar-action-text"><%= t('hyrax.admin.sidebar.roles_service_jobs') %></span>
<% end %>
<% end %>
<% end %>
23 changes: 23 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,35 @@ en:
favicon: Favicon
fonts: "Fonts"
themes: "Themes"
roles_service_jobs:
header: Data Repair Jobs
jobs:
create_admin_set_accesses:
label: Create Admin Set Accesses
description: "Creating a Hyrax::PermissionTemplateAccess record (combined with Ability#user_groups)
will allow Works in all AdminSets to show up in Blacklight / Solr queries."
create_collection_accesses:
label: Create Collection Accesses
description: "Because each collection role has some level of access to every Collection within a tenant,
creating a Hyrax::PermissionTemplateAccess record (combined with Ability#user_groups)
means all Collections will show up in Blacklight / Solr queries."
create_collection_type_participants:
label: Create Collection Type Participants
description: "Because some of the collection roles have access to every Collection within a tenant, create a
Hyrax::CollectionTypeParticipant record for them on every Hyrax::CollectionType (except the AdminSet)"
grant_workflow_roles_for_all_admin_sets:
label: Admin Set Workflow Roles
description: "Permissions to deposit Works are controlled by Workflow Roles on individual AdminSets.
In order for Hyrax::Group and User records who have either the 'Work Editor' or 'Work Depositor' Role
to have the correct permissions for Works, we grant them Workflow Roles for all AdminSets.
NOTE: All AdminSets must have a permission template or this will fail. Run 'Create Admin Set Accesses' first."
sidebar:
accounts: Accounts
activity_summary: Activity Summary
labels: Labels
manage_groups: Manage Groups
system_status: System Status
roles_service_jobs: Data Repair
users:
activate:
confirmation: Are you sure you want to activate the user "%{user}"?
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@
resources :users, only: %i[index create destroy], param: :user_id, controller: 'group_users'
resources :roles, only: %i[index create destroy], param: :role_id, controller: 'group_roles'
end
post "roles_service/:job_name_key", to: "roles_service#update_roles", as: :update_roles
get "roles_service", to: "roles_service#index", as: :roles_service_jobs
end

# OVERRIDE here to add featured collection routes
Expand Down
40 changes: 40 additions & 0 deletions spec/controllers/admin/roles_service_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

RSpec.describe Admin::RolesServiceController, type: :controller do
context 'as an anonymous user' do
describe 'GET #index' do
subject { get :index }

it { is_expected.to redirect_to new_user_session_path }
end
end

context 'as an admin user' do
before { sign_in create(:admin) }

describe 'GET #index' do
subject { get :index }

it { is_expected.to render_template('layouts/hyrax/dashboard') }
it { is_expected.to render_template('admin/roles_service/index') }
end
end

context 'as an admin user' do
before { sign_in create(:admin) }

describe 'GET #index' do
subject { get :index }

it { is_expected.to render_template('layouts/hyrax/dashboard') }
it { is_expected.to render_template('admin/roles_service/index') }
end

describe 'POST #update_roles' do
it 'submits a job when it receives a valid job name' do
expect(RolesService::CreateCollectionAccessesJob).to receive(:perform_later)
post :update_roles, params: { job_name_key: :create_collection_accesses }
end
end
end
end
13 changes: 13 additions & 0 deletions spec/routing/admin/roles_service_routing_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

RSpec.describe Admin::RolesServiceController, type: :routing do
describe "routing" do
it "routes to #index" do
expect(get: "/admin/roles_service").to route_to("admin/roles_service#index")
end

it "routes to #update_roles via POST" do
expect(post: "/admin/roles_service/create_collection_accesses").to route_to("admin/roles_service#update_roles", job_name_key: 'create_collection_accesses')
end
end
end
Loading