diff --git a/dor-services.gemspec b/dor-services.gemspec index 26493b79..76f8a902 100644 --- a/dor-services.gemspec +++ b/dor-services.gemspec @@ -7,8 +7,8 @@ Gem::Specification.new do |s| s.name = 'dor-services' s.version = Dor::VERSION s.platform = Gem::Platform::RUBY - s.authors = ['Michael Klein', 'Willy Mene', 'Chris Fitzpatrick', 'Richard Anderson', 'Renzo Sanchez-Silva', 'Joseph Atzberger', 'Johnathan Martin'] - s.email = ['mbklein@stanford.edu'] + s.authors = ['Michael Klein', 'Willy Mene', 'Chris Fitzpatrick', 'Richard Anderson', 'Renzo Sanchez-Silva', 'Joseph Atzberger', 'Johnathan Martin', 'Darren Weber'] + s.email = ['dlss-developers@lists.stanford.edu'] s.summary = 'Ruby implmentation of DOR services used by the SULAIR Digital Library' s.description = 'Contains classes to register objects and initialize workflows' s.licenses = ['ALv2', 'Stanford University'] diff --git a/lib/dor-services.rb b/lib/dor-services.rb index 8651c2cf..d2b21eaf 100644 --- a/lib/dor-services.rb +++ b/lib/dor-services.rb @@ -107,6 +107,7 @@ def root autoload :Publishable, 'dor/models/publishable' autoload :Shelvable, 'dor/models/shelvable' autoload :Embargoable, 'dor/models/embargoable' + autoload :Permissable, 'dor/models/permissable' autoload :Preservable, 'dor/models/preservable' autoload :Assembleable, 'dor/models/assembleable' autoload :Upgradable, 'dor/models/upgradable' diff --git a/lib/dor/models/admin_policy_object.rb b/lib/dor/models/admin_policy_object.rb index ab41b6e0..8200b0cf 100644 --- a/lib/dor/models/admin_policy_object.rb +++ b/lib/dor/models/admin_policy_object.rb @@ -4,6 +4,7 @@ class AdminPolicyObject < ::ActiveFedora::Base include Governable include Editable include Describable + include Permissable include Processable include Versionable diff --git a/lib/dor/models/collection.rb b/lib/dor/models/collection.rb index 5c1875f5..a2c3d18b 100644 --- a/lib/dor/models/collection.rb +++ b/lib/dor/models/collection.rb @@ -4,6 +4,7 @@ class Collection < ::ActiveFedora::Base include Processable include Governable include Describable + include Permissable include Publishable include Versionable include Releaseable diff --git a/lib/dor/models/governable.rb b/lib/dor/models/governable.rb index 1d8abb3f..7cafaddb 100644 --- a/lib/dor/models/governable.rb +++ b/lib/dor/models/governable.rb @@ -27,7 +27,7 @@ def default_workflow_lane end def reset_to_apo_default - rightsMetadata.content = admin_policy_object.rightsMetadata.ng_xml + rightsMetadata.content = admin_policy_object.rightsMetadata.ng_xml.to_s end def set_read_rights(rights) @@ -52,14 +52,15 @@ def remove_collection(collection_or_druid) when Dor::Collection collection_or_druid end - collections.delete(collection) sets.delete(collection) end + # set the rights metadata datastream to the content of the APO's default object rights def reapplyAdminPolicyObjectDefaults rightsMetadata.content = admin_policy_object.datastreams['defaultObjectRights'].content end + def rights return nil unless self.respond_to? :rightsMetadata return nil if rightsMetadata.nil? @@ -75,56 +76,5 @@ def rights 'None' end end - def groups_which_manage_item - ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor'] - end - def groups_which_manage_desc_metadata - ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-apo-metadata'] - end - def groups_which_manage_system_metadata - ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor'] - end - def groups_which_manage_content - ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor'] - end - def groups_which_manage_rights - ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor'] - end - def groups_which_manage_embargo - ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor'] - end - def groups_which_view_content - ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-viewer', 'sdr-viewer'] - end - def groups_which_view_metadata - ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-viewer', 'sdr-viewer'] - end - def intersect(arr1, arr2) - (arr1 & arr2).length > 0 - end - def can_manage_item?(roles) - intersect roles, groups_which_manage_item - end - def can_manage_desc_metadata?(roles) - intersect roles, groups_which_manage_desc_metadata - end - def can_manage_system_metadata?(roles) - intersect roles, groups_which_manage_system_metadata - end - def can_manage_content?(roles) - intersect roles, groups_which_manage_content - end - def can_manage_rights?(roles) - intersect roles, groups_which_manage_rights - end - def can_manage_embargo?(roles) - intersect roles, groups_which_manage_embargo - end - def can_view_content?(roles) - intersect roles, groups_which_view_content - end - def can_view_metadata?(roles) - intersect roles, groups_which_view_metadata - end end end diff --git a/lib/dor/models/permissable.rb b/lib/dor/models/permissable.rb new file mode 100644 index 00000000..6c125dae --- /dev/null +++ b/lib/dor/models/permissable.rb @@ -0,0 +1,160 @@ +module Dor + module Permissable + extend ActiveSupport::Concern + + # General documentation about roles and permissions is on SUL Consul at + # https://consul.stanford.edu/display/chimera/Repository+Roles+and+Permissions + # All these constants are frozen arrays so the methods that use them can + # easily add them to return arrays. + SDR_ADMINS = %w(sdr-administrator).freeze + SDR_MANAGERS = %w(sdr-manager).freeze + SDR_VIEWERS = %w(sdr-viewer).freeze + + APO_MANAGERS = %w(dor-apo-manager).freeze + APO_DEPOSITORS = %w(dor-apo-depositor).freeze + APO_METADATA = %w(dor-apo-metadata).freeze + APO_VIEWERS = %w(dor-apo-viewer).freeze + + # A complete set of known roles. This can be used by clients to + # inspect all the possible roles available. + KNOWN_ROLES = ( + SDR_ADMINS + SDR_MANAGERS + SDR_VIEWERS + + APO_MANAGERS + APO_DEPOSITORS + APO_METADATA + APO_VIEWERS + ).freeze + + # --- + # APO permissions + + def can_create_apo?(roles) + intersect roles, roles_which_create_apo + end + + def can_manage_apo?(roles) + intersect roles, roles_which_manage_apo + end + + def can_manage_collections?(roles) + intersect roles, roles_which_manage_collections + end + + def can_manage_roles?(roles) + intersect roles, roles_which_manage_roles + end + + def can_manage_sets?(roles) + intersect roles, roles_which_manage_sets + end + + def can_release_objects?(roles) + intersect roles, roles_which_release_objects + end + + # --- + # Item permissions + + def can_manage_item?(roles) + intersect roles, roles_which_manage_item + end + + def can_register_item?(roles) + intersect roles, roles_which_register_item + end + + def can_manage_desc_metadata?(roles) + intersect roles, roles_which_manage_desc_md + end + + def can_manage_system_metadata?(roles) + intersect roles, roles_which_manage_sys_md + end + + def can_manage_contents?(roles) + intersect roles, roles_which_manage_contents + end + + def can_manage_rights?(roles) + intersect roles, roles_which_manage_rights + end + + def can_manage_workflows?(roles) + intersect roles, roles_which_manage_workflows + end + + def can_manage_embargo?(roles) + intersect roles, roles_which_manage_embargo + end + + # --- + # Common viewing permissions + + def can_view_content?(roles) + intersect roles, roles_which_view_content + end + + def can_view_metadata?(roles) + intersect roles, roles_which_view_metadata + end + + private + + # --- + # APO roles + + def roles_which_create_apo + SDR_ADMINS + SDR_MANAGERS + end + + def roles_which_manage_apo + SDR_ADMINS + SDR_MANAGERS + APO_MANAGERS + end + + # When more granular roles are defined for APOs, these aliases + # could be redefined as stand-alone methods. + alias roles_which_manage_roles roles_which_manage_apo + alias roles_which_manage_collections roles_which_manage_apo + alias roles_which_manage_sets roles_which_manage_apo + + def roles_which_release_objects + SDR_ADMINS + SDR_MANAGERS + APO_MANAGERS + APO_DEPOSITORS + end + + # --- + # Item roles + + def roles_which_manage_item + # exclude SDR_MANAGERS + SDR_ADMINS + APO_MANAGERS + APO_DEPOSITORS + end + + def roles_which_manage_desc_md + SDR_ADMINS + APO_MANAGERS + APO_DEPOSITORS + APO_METADATA + end + + # When more granular management roles are defined, these aliases + # should be redefined as stand-alone methods. + alias roles_which_register_item roles_which_manage_item + alias roles_which_manage_sys_md roles_which_manage_item + alias roles_which_manage_contents roles_which_manage_item + alias roles_which_manage_rights roles_which_manage_item + alias roles_which_manage_workflows roles_which_manage_item + alias roles_which_manage_embargo roles_which_manage_item + + # --- + # Viewer roles (apply to both APO and Item) + + # All roles can view metadata + def roles_which_view_metadata + KNOWN_ROLES + end + + # Only SDR_MANAGERS cannot view content + def roles_which_view_content + SDR_ADMINS + SDR_VIEWERS + + APO_MANAGERS + APO_DEPOSITORS + APO_METADATA + APO_VIEWERS + end + + def intersect(arr1, arr2) + (arr1 & arr2).length > 0 + end + end +end diff --git a/lib/dor/models/publishable.rb b/lib/dor/models/publishable.rb index b917fe23..10c8925e 100644 --- a/lib/dor/models/publishable.rb +++ b/lib/dor/models/publishable.rb @@ -7,6 +7,7 @@ module Publishable include Governable include Describable include Itemizable + include Permissable include Rightsable def public_relationships diff --git a/lib/dor/models/set.rb b/lib/dor/models/set.rb index ce4ceefd..d566b02b 100644 --- a/lib/dor/models/set.rb +++ b/lib/dor/models/set.rb @@ -4,6 +4,7 @@ class Set < ::ActiveFedora::Base include Processable include Governable include Describable + include Permissable include Publishable include Versionable diff --git a/lib/dor/models/workflow_object.rb b/lib/dor/models/workflow_object.rb index dac3d1fa..6411ed18 100644 --- a/lib/dor/models/workflow_object.rb +++ b/lib/dor/models/workflow_object.rb @@ -4,6 +4,7 @@ module Dor class WorkflowObject < ::ActiveFedora::Base include Identifiable include Governable + include Permissable @@xml_cache = {} @@repo_cache = {} diff --git a/spec/dor/governable_spec.rb b/spec/dor/governable_spec.rb index e8d69887..3a579b19 100644 --- a/spec/dor/governable_spec.rb +++ b/spec/dor/governable_spec.rb @@ -11,6 +11,12 @@ class GovernableItem < ActiveFedora::Base before(:each) { stub_config } after(:each) { unstub_config } + before :each do + @item = instantiate_fixture('druid:oo201oo0001', Dor::AdminPolicyObject) + # @item.stub(:new_record? => false) + allow(Dor::Collection).to receive(:find).with('druid:oo201oo0002').and_return(mock_collection) + end + let(:mock_collection) { coll = Dor::Collection.new allow(coll).to receive(:new?).and_return false @@ -20,21 +26,34 @@ class GovernableItem < ActiveFedora::Base coll } - before :each do - @item = instantiate_fixture('druid:oo201oo0001', Dor::AdminPolicyObject) - # @item.stub(:new_record? => false) - allow(Dor::Collection).to receive(:find).with('druid:oo201oo0002').and_return(mock_collection) - end - describe 'set_read_rights error handling' do - it 'should raise an exception if the rights option doesnt match the accepted values' do + it 'should raise an exception if the rights option does not match the accepted values' do expect{@item.set_read_rights('"druid:oo201oo0001"', 'Something')}.to raise_error(ArgumentError) end - it 'should raise an exception if the rights option doesnt match the accepted values' do + it 'should raise an exception if the rights option does not match the accepted values' do expect{@item.set_read_rights('mambo')}.to raise_error(ArgumentError) end end + describe 'rights' do + it 'returns "Stanford" for the "stanford" rights' do + @item.set_read_rights('stanford') + expect(@item.rights).to eq('Stanford') + end + it 'returns "World" for the "world" rights' do + @item.set_read_rights('world') + expect(@item.rights).to eq('World') + end + it 'returns "Dark" for the "dark" rights' do + @item.set_read_rights('dark') + expect(@item.rights).to eq('Dark') + end + it 'returns "None" for the "none" rights' do + @item.set_read_rights('none') + expect(@item.rights).to eq('None') + end + end + describe 'set_read_rights' do it 'should set rights to dark (double none), removing the discovery rights' do @item.set_read_rights('dark') @@ -123,59 +142,6 @@ class GovernableItem < ActiveFedora::Base XML end - end - - describe 'to_solr' do - it 'should include a rights facet' do - allow(@item).to receive(:milestones).and_return({}) - @item.set_read_rights('world') - solr_doc = @item.to_solr - expect(solr_doc).to match a_hash_including('rights_ssim' => ['World'], :id => @item.pid) - end - it 'should shouldnt error if there is nothing in the datastream' do - allow(@item).to receive(:milestones).and_return({}) - allow(@item).to receive(:rightsMetadata).and_return(ActiveFedora::OmDatastream.new) - solr_doc = @item.to_solr - expect(solr_doc).not_to include('rights_facet') - end - end - - describe 'add_collection' do - it 'should add a collection' do - @item.add_collection('druid:oo201oo0002') - rels_ext_ds = @item.datastreams['RELS-EXT'] - xml = Nokogiri::XML(rels_ext_ds.to_rels_ext.to_s) - expect(xml).to be_equivalent_to <<-XML - - - - - - - - - - XML - end - end - - describe 'remove_collection' do - it 'should delete a collection' do - @item.add_collection('druid:oo201oo0002') - rels_ext_ds = @item.datastreams['RELS-EXT'] - @item.remove_collection('druid:oo201oo0002') - rels_ext_ds.serialize! - xml = Nokogiri::XML(rels_ext_ds.content.to_s) - expect(xml).to be_equivalent_to <<-XML - - - - - - - - XML - end it 'should change the read permissions value from stanford to ' do expect(@item.datastreams['rightsMetadata'].ng_xml).to be_equivalent_to <<-XML @@ -226,6 +192,91 @@ class GovernableItem < ActiveFedora::Base end end + describe 'reset_to_apo_default' do + it 'should set rights to APO rights' do + apo = instantiate_fixture('druid:fg890hi1234', Dor::AdminPolicyObject) + apo_rights = apo.rightsMetadata.ng_xml + allow(@item).to receive(:admin_policy_object).and_return(apo) + @item.set_read_rights('dark') + expect(@item.rightsMetadata.ng_xml).not_to be_equivalent_to apo_rights + @item.reset_to_apo_default + expect(@item.rightsMetadata.ng_xml).to be_equivalent_to apo_rights + end + end + + describe 'to_solr' do + it 'should include a rights facet' do + allow(@item).to receive(:milestones).and_return({}) + @item.set_read_rights('world') + solr_doc = @item.to_solr + expect(solr_doc).to match a_hash_including('rights_ssim' => ['World'], :id => @item.pid) + end + it 'should not error if there is nothing in the datastream' do + allow(@item).to receive(:milestones).and_return({}) + allow(@item).to receive(:rightsMetadata).and_return(ActiveFedora::OmDatastream.new) + solr_doc = @item.to_solr + expect(solr_doc).not_to include('rights_facet') + end + end + + describe 'add_collection' do + def check_collection + rels_ext_ds = @item.datastreams['RELS-EXT'] + xml = Nokogiri::XML(rels_ext_ds.to_rels_ext.to_s) + expect(xml).to be_equivalent_to <<-XML + + + + + + + + + + XML + end + it 'should find and add a collection' do + expect(Dor::Collection).to receive(:find).once + @item.add_collection('druid:oo201oo0002') + check_collection + end + it 'should add a collection' do + expect(Dor::Collection).not_to receive(:find) + @item.add_collection(mock_collection) + check_collection + end + end + + describe 'remove_collection' do + def check_collection(rels_ext_ds) + rels_ext_ds.serialize! + xml = Nokogiri::XML(rels_ext_ds.content.to_s) + expect(xml).to be_equivalent_to <<-XML + + + + + + + + XML + end + it 'should find and delete a collection' do + expect(Dor::Collection).to receive(:find).twice + @item.add_collection('druid:oo201oo0002') + rels_ext_ds = @item.datastreams['RELS-EXT'] + @item.remove_collection('druid:oo201oo0002') + check_collection(rels_ext_ds) + end + it 'should delete a collection' do + expect(Dor::Collection).not_to receive(:find) + @item.add_collection(mock_collection) + rels_ext_ds = @item.datastreams['RELS-EXT'] + @item.remove_collection(mock_collection) + check_collection(rels_ext_ds) + end + end + describe 'initiate_apo_workflow' do it 'calls Processable.initialize_workflow without creating a datastream when the object is new' do i = GovernableItem.new @@ -282,83 +333,7 @@ class GovernableItem < ActiveFedora::Base i.initiate_apo_workflow('accessionWF') end end - describe 'can_manage_item?' do - it 'should match a group that has rights' do - expect(@item.can_manage_item?(['dor-administrator'])).to be_truthy - end - it 'should match a group that has rights' do - expect(@item.can_manage_item?(['sdr-administrator'])).to be_truthy - end - it 'shouldnt match a group that doesnt have rights' do - expect(@item.can_manage_item?(['dor-apo-metadata'])).to be_falsey - end - end - describe 'can_manage_desc_metadata?' do - it 'should match a group that has rights' do - expect(@item.can_manage_desc_metadata?(['dor-apo-metadata'])).to be_truthy - end - it 'shouldnt match a group that doesnt have rights' do - expect(@item.can_manage_desc_metadata?(['dor-viewer'])).to be_falsey - end - it 'shouldnt match a group that doesnt have rights' do - expect(@item.can_manage_desc_metadata?(['sdr-viewer'])).to be_falsey - end - end - describe 'can_manage_content?' do - it 'should match a group that has rights' do - expect(@item.can_manage_content?(['dor-administrator'])).to be_truthy - end - it 'should match a group that has rights' do - expect(@item.can_manage_content?(['sdr-administrator'])).to be_truthy - end - it 'shouldnt match a group that doesnt have rights' do - expect(@item.can_manage_content?(['dor-apo-metadata'])).to be_falsey - end - end - describe 'can_manage_rights?' do - it 'should match a group that has rights' do - expect(@item.can_manage_rights?(['dor-administrator'])).to be_truthy - end - it 'should match a group that has rights' do - expect(@item.can_manage_rights?(['sdr-administrator'])).to be_truthy - end - it 'shouldnt match a group that doesnt have rights' do - expect(@item.can_manage_rights?(['dor-apo-metadata'])).to be_falsey - end - end - describe 'can_manage_embargo?' do - it 'should match a group that has rights' do - expect(@item.can_manage_embargo?(['dor-administrator'])).to be_truthy - end - it 'should match a group that has rights' do - expect(@item.can_manage_embargo?(['sdr-administrator'])).to be_truthy - end - it 'shouldnt match a group that doesnt have rights' do - expect(@item.can_manage_embargo?(['dor-apo-metadata'])).to be_falsey - end - end - describe 'can_view_content?' do - it 'should match a group that has rights' do - expect(@item.can_view_content?(['dor-viewer'])).to be_truthy - end - it 'should match a group that has rights' do - expect(@item.can_view_content?(['sdr-viewer'])).to be_truthy - end - it 'shouldnt match a group that doesnt have rights' do - expect(@item.can_view_content?(['dor-people'])).to be_falsey - end - end - describe 'can_view_metadata?' do - it 'should match a group that has rights' do - expect(@item.can_view_metadata?(['dor-viewer'])).to be_truthy - end - it 'should match a group that has rights' do - expect(@item.can_view_metadata?(['sdr-viewer'])).to be_truthy - end - it 'shouldnt match a group that doesnt have rights' do - expect(@item.can_view_metadata?(['dor-people'])).to be_falsey - end - end + describe 'reapplyAdminPolicyObjectDefaults' do it 'should update rightsMetadata from the APO defaultObjectRights' do expect(@item.rightsMetadata.ng_xml.search('//rightsMetadata/access[@type=\'read\']/machine/group').length).to eq(1) diff --git a/spec/dor/permissable_spec.rb b/spec/dor/permissable_spec.rb new file mode 100644 index 00000000..354d16ea --- /dev/null +++ b/spec/dor/permissable_spec.rb @@ -0,0 +1,307 @@ +require 'spec_helper' + +describe Dor::Permissable do + + let(:sdr_administrator) { 'sdr-administrator' } + let(:sdr_manager) { 'sdr-manager' } + let(:sdr_viewer) { 'sdr-viewer' } + + let(:apo_manager) { 'dor-apo-manager' } + let(:apo_depositor) { 'dor-apo-depositor' } + let(:apo_metadata) { 'dor-apo-metadata' } + let(:apo_viewer) { 'dor-apo-viewer' } + + let(:druid) { 'fg890hi1234' } + let(:apo) { instantiate_fixture(druid, Dor::AdminPolicyObject) } + + before :each do + stub_config + end + + after :each do + unstub_config + end + + describe 'KNOWN_ROLES' do + it 'includes all known roles' do + expect(Dor::Permissable::KNOWN_ROLES).to include(sdr_administrator) + expect(Dor::Permissable::KNOWN_ROLES).to include(sdr_manager) + expect(Dor::Permissable::KNOWN_ROLES).to include(sdr_viewer) + expect(Dor::Permissable::KNOWN_ROLES).to include(apo_manager) + expect(Dor::Permissable::KNOWN_ROLES).to include(apo_depositor) + expect(Dor::Permissable::KNOWN_ROLES).to include(apo_metadata) + expect(Dor::Permissable::KNOWN_ROLES).to include(apo_viewer) + end + end + + # ---- + # Shared examples to allow/forbid all known roles + + shared_examples 'allows sdr-administrator' do + it 'allows sdr-administrator' do + expect(apo.send(method, [sdr_administrator])).to be true + end + end + shared_examples 'forbids sdr-administrator' do + it 'forbids sdr-administrator' do + expect(apo.send(method, [sdr_administrator])).to be false + end + end + + shared_examples 'allows sdr-manager' do + it 'allows sdr-manager' do + expect(apo.send(method, [sdr_manager])).to be true + end + end + shared_examples 'forbids sdr-manager' do + it 'forbids sdr-manager' do + expect(apo.send(method, [sdr_manager])).to be false + end + end + + shared_examples 'allows sdr-viewer' do + it 'allows sdr-viewer' do + expect(apo.send(method, [sdr_viewer])).to be true + end + end + shared_examples 'forbids sdr-viewer' do + it 'forbids sdr-viewer' do + expect(apo.send(method, [sdr_viewer])).to be false + end + end + + shared_examples 'allows dor-apo-manager' do + it 'allows dor-apo-manager' do + expect(apo.send(method, [apo_manager])).to be true + end + end + shared_examples 'forbids dor-apo-manager' do + it 'forbids dor-apo-manager' do + expect(apo.send(method, [apo_manager])).to be false + end + end + + shared_examples 'allows dor-apo-depositor' do + it 'allows dor-apo-depositor' do + expect(apo.send(method, [apo_depositor])).to be true + end + end + shared_examples 'forbids dor-apo-depositor' do + it 'forbids dor-apo-depositor' do + expect(apo.send(method, [apo_depositor])).to be false + end + end + + shared_examples 'allows dor-apo-metadata' do + it 'allows dor-apo-metadata' do + expect(apo.send(method, [apo_metadata])).to be true + end + end + shared_examples 'forbids dor-apo-metadata' do + it 'forbids dor-apo-metadata' do + expect(apo.send(method, [apo_metadata])).to be false + end + end + + shared_examples 'allows dor-apo-viewer' do + it 'allows dor-apo-viewer' do + expect(apo.send(method, [apo_viewer])).to be true + end + end + shared_examples 'forbids dor-apo-viewer' do + it 'forbids dor-apo-viewer' do + expect(apo.send(method, [apo_viewer])).to be false + end + end + + shared_examples 'forbids deprecated roles' do + it 'forbids dor-administrator' do + expect(apo.send(method, ['dor-administrator'])).to be false + end + it 'forbids dor-viewer' do + expect(apo.send(method, ['dor-viewer'])).to be false + end + end + + shared_examples 'it only allows APO managers' do + # allows + it_behaves_like 'allows sdr-administrator' + it_behaves_like 'allows sdr-manager' + it_behaves_like 'allows dor-apo-manager' + # forbids + it_behaves_like 'forbids sdr-viewer' + it_behaves_like 'forbids dor-apo-depositor' + it_behaves_like 'forbids dor-apo-metadata' + it_behaves_like 'forbids dor-apo-viewer' + it_behaves_like 'forbids deprecated roles' + end + + shared_examples 'only allows ITEM managers' do + # allows + it_behaves_like 'allows sdr-administrator' + it_behaves_like 'allows dor-apo-manager' + it_behaves_like 'allows dor-apo-depositor' + # forbids + it_behaves_like 'forbids sdr-manager' + it_behaves_like 'forbids sdr-viewer' + it_behaves_like 'forbids dor-apo-metadata' + it_behaves_like 'forbids dor-apo-viewer' + it_behaves_like 'forbids deprecated roles' + end + + context 'with a Dor::AdminPolicyObject' do + # --- + # APO roles + + describe 'can_create_apo?' do + let(:method) { :can_create_apo? } + it_behaves_like 'allows sdr-administrator' + it_behaves_like 'allows sdr-manager' + # forbids + it_behaves_like 'forbids sdr-viewer' + it_behaves_like 'forbids dor-apo-manager' + it_behaves_like 'forbids dor-apo-depositor' + it_behaves_like 'forbids dor-apo-metadata' + it_behaves_like 'forbids dor-apo-viewer' + it_behaves_like 'forbids deprecated roles' + end + + describe 'can_manage_apo?' do + let(:method) { :can_manage_apo? } + it_behaves_like 'it only allows APO managers' + end + + describe 'can_manage_roles?' do + let(:method) { :can_manage_roles? } + it_behaves_like 'it only allows APO managers' + end + + describe 'can_manage_collections?' do + let(:method) { :can_manage_collections? } + it_behaves_like 'it only allows APO managers' + end + + describe 'can_manage_sets?' do + let(:method) { :can_manage_sets? } + it_behaves_like 'it only allows APO managers' + end + + describe 'can_release_objects?' do + let(:method) { :can_release_objects? } + it_behaves_like 'allows sdr-administrator' + it_behaves_like 'allows sdr-manager' + it_behaves_like 'allows dor-apo-manager' + it_behaves_like 'allows dor-apo-depositor' + # forbids + it_behaves_like 'forbids sdr-viewer' + it_behaves_like 'forbids dor-apo-metadata' + it_behaves_like 'forbids dor-apo-viewer' + it_behaves_like 'forbids deprecated roles' + end + + # --- + # Item roles + + describe 'can_manage_item?' do + let(:method) { :can_manage_item? } + it_behaves_like 'only allows ITEM managers' + end + describe 'can_register_item?' do + let(:method) { :can_register_item? } + it_behaves_like 'only allows ITEM managers' + end + describe 'can_manage_contents?' do + let(:method) { :can_manage_contents? } + it_behaves_like 'only allows ITEM managers' + end + describe 'can_manage_rights?' do + let(:method) { :can_manage_rights? } + it_behaves_like 'only allows ITEM managers' + end + describe 'can_manage_workflows?' do + let(:method) { :can_manage_workflows? } + it_behaves_like 'only allows ITEM managers' + end + describe 'can_manage_embargo?' do + let(:method) { :can_manage_embargo? } + it_behaves_like 'only allows ITEM managers' + end + describe 'can_manage_system_metadata?' do + let(:method) { :can_manage_system_metadata? } + it_behaves_like 'only allows ITEM managers' + end + describe 'can_manage_desc_metadata?' do + # differs from others by allowing dor-apo-metadata + let(:method) { :can_manage_desc_metadata? } + it_behaves_like 'allows sdr-administrator' + it_behaves_like 'allows dor-apo-manager' + it_behaves_like 'allows dor-apo-depositor' + it_behaves_like 'allows dor-apo-metadata' # diff from others + # forbids + it_behaves_like 'forbids sdr-manager' + it_behaves_like 'forbids sdr-viewer' + it_behaves_like 'forbids dor-apo-viewer' + it_behaves_like 'forbids deprecated roles' + end + + describe 'can_view_content?' do + let(:method) { :can_view_content? } + # allows + it_behaves_like 'allows sdr-administrator' + it_behaves_like 'allows sdr-viewer' + it_behaves_like 'allows dor-apo-depositor' + it_behaves_like 'allows dor-apo-manager' + it_behaves_like 'allows dor-apo-metadata' + it_behaves_like 'allows dor-apo-viewer' + # forbids + it_behaves_like 'forbids sdr-manager' + it_behaves_like 'forbids deprecated roles' + end + describe 'can_view_metadata?' do + let(:method) { :can_view_metadata? } + # allows every role + it_behaves_like 'allows sdr-administrator' + it_behaves_like 'allows sdr-manager' + it_behaves_like 'allows sdr-viewer' + it_behaves_like 'allows dor-apo-depositor' + it_behaves_like 'allows dor-apo-manager' + it_behaves_like 'allows dor-apo-metadata' + it_behaves_like 'allows dor-apo-viewer' + # forbids + it_behaves_like 'forbids deprecated roles' + end + end + + # ---- + # alias_methods + + describe 'aliases' do + it 'return :roles_which_manage_apo' do + aliases = [ + :roles_which_manage_roles, + :roles_which_manage_collections, + :roles_which_manage_sets + ] + aliases.each do |a| + # Use Object.send to access private methods + expect(apo.send(a)).to eq apo.send(:roles_which_manage_apo) + end + end + it 'return :roles_which_manage_item' do + aliases = [ + :roles_which_register_item, + :roles_which_manage_sys_md, + :roles_which_manage_contents, + :roles_which_manage_rights, + :roles_which_manage_workflows, + :roles_which_manage_embargo + ] + aliases.each do |a| + # Use Object.send to access private methods + expect(apo.send(a)).to eq apo.send(:roles_which_manage_item) + end + end + end +end + +