diff --git a/app/services/hyrax/collections/permissions_service.rb b/app/services/hyrax/collections/permissions_service.rb index 40e73a25d5..b50db30b68 100644 --- a/app/services/hyrax/collections/permissions_service.rb +++ b/app/services/hyrax/collections/permissions_service.rb @@ -1,13 +1,82 @@ module Hyrax module Collections class PermissionsService + # @api private + # + # IDs of collections, including admin sets, a user can access based on participant roles. + # + # @param user [User] user + # @param access [Array] one or more types of access (e.g. Hyrax::PermissionTemplateAccess::MANAGE, Hyrax::PermissionTemplateAccess::DEPOSIT, Hyrax::PermissionTemplateAccess::VIEW) + # @return [Array] IDs of collections for which the user has specified roles + def self.collection_ids_for_user(user:, access:) # rubocop:disable Metrics/MethodLength + if user.ability.admin? + PermissionTemplate.all.where(source_type: 'collection').pluck('DISTINCT source_id') + else + PermissionTemplateAccess.joins(:permission_template) + .where(agent_type: 'user', + agent_id: user.user_key, + access: access) + .or( + PermissionTemplateAccess.joins(:permission_template) + .where(agent_type: 'group', + agent_id: user.groups, + access: access) + ).pluck('DISTINCT source_id') + end + end + private_class_method :collection_ids_for_user + + # @api public + # + # IDs of collections, including admin sets, for which the user is assigned view access + # + # @param user [User] + # @return [Array] a list of collection ids for which the user is assigned view access + def self.collection_ids_with_view_access(user:) + return [] unless user + collection_ids_for_user(user: user, access: [Hyrax::PermissionTemplateAccess::VIEW]) + end + + # @api public + # + # IDs of collections, including admin sets, for which the user is assigned manage access + # + # @param user [User] + # @return [Array] a list of collection ids for which the user is assigned manage access + def self.collection_ids_with_manage_access(user:) + return [] unless user + collection_ids_for_user(user: user, access: [Hyrax::PermissionTemplateAccess::MANAGE]) + end + + # @api public + # + # IDs of collections, including admin sets, for which the user is assigned deposit access + # + # @param user [User] + # @return [Array] a list of collection ids for which the user is assigned deposit access + def self.collection_ids_with_deposit_access(user:) + return [] unless user + collection_ids_for_user(user: user, access: [Hyrax::PermissionTemplateAccess::DEPOSIT]) + end + + # @api public + # + # IDs of collections, including admin sets, into which the user can deposit + # + # @param user [User] the user that wants to deposit + # @return [Array] a list of collection ids for collections in which the user can deposit + def self.collection_ids_for_deposit(user:) + return [] unless user + collection_ids_for_user(user: user, access: [Hyrax::PermissionTemplateAccess::MANAGE, Hyrax::PermissionTemplateAccess::DEPOSIT]) + end + # @api public # # Determine if the given user has permissions to deposit into the given collection # # @param user [User] the user that wants to deposit # @param collection [Hyrax::Collection] the collection we are checking permissions on - # @return [Boolean] true if the user has permission to depoisit into the collection + # @return [Boolean] true if the user has permission to deposit into the collection def self.can_deposit_in_collection(user:, collection:) return false unless user && collection template = Hyrax::PermissionTemplate.find_by!(source_id: collection.id) diff --git a/spec/services/hyrax/collections/permissions_service_spec.rb b/spec/services/hyrax/collections/permissions_service_spec.rb index 48498498e6..9b455783fe 100644 --- a/spec/services/hyrax/collections/permissions_service_spec.rb +++ b/spec/services/hyrax/collections/permissions_service_spec.rb @@ -126,4 +126,56 @@ expect(subject).to be false end end + + context "access helper method" do + let(:user) { create(:user) } + let(:col_vu) { create(:collection, with_permission_template: true) } + let(:col_vg) { create(:collection, with_permission_template: true) } + let(:col_mu) { create(:collection, with_permission_template: true) } + let(:col_mg) { create(:collection, with_permission_template: true) } + let(:col_du) { create(:collection, with_permission_template: true) } + let(:col_dg) { create(:collection, with_permission_template: true) } + + before do + collection_access(col_vu.permission_template, 'user', user.user_key, :view) + collection_access(col_vg.permission_template, 'group', 'view_group', :view) + collection_access(col_mu.permission_template, 'user', user.user_key, :manage) + collection_access(col_mg.permission_template, 'group', 'manage_group', :manage) + collection_access(col_du.permission_template, 'user', user.user_key, :deposit) + collection_access(col_dg.permission_template, 'group', 'deposit_group', :deposit) + allow(user).to receive(:groups).and_return(['view_group', 'deposit_group', 'manage_group']) + end + + describe '.collection_ids_with_view_access' do + it 'returns ids for view user and group' do + expect(described_class.collection_ids_with_view_access(user: user)).to match_array [col_vu.id, col_vg.id] + end + end + + describe '.collection_ids_with_manage_access' do + it 'returns ids for manage user and group' do + expect(described_class.collection_ids_with_manage_access(user: user)).to match_array [col_mu.id, col_mg.id] + end + end + + describe '.collection_ids_with_deposit_access' do + it 'returns ids for deposit user and group' do + expect(described_class.collection_ids_with_deposit_access(user: user)).to match_array [col_du.id, col_dg.id] + end + end + + describe '.collection_ids_for_deposit' do + it 'returns ids for deposit user and group and manage user and group' do + expect(described_class.collection_ids_for_deposit(user: user)).to match_array [col_du.id, col_dg.id, col_mu.id, col_mg.id] + end + end + end + + def collection_access(permission_template, agent_type, agent_id, access) + create(:permission_template_access, + access, + permission_template: permission_template, + agent_type: agent_type, + agent_id: agent_id) + end end