hyrax 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +5 -5
  3. data/.dassie/Gemfile +1 -1
  4. data/.dassie/app/controllers/catalog_controller.rb +6 -0
  5. data/Dockerfile +2 -3
  6. data/app/actors/hyrax/actors/base_actor.rb +1 -1
  7. data/app/actors/hyrax/actors/collections_membership_actor.rb +3 -3
  8. data/app/actors/hyrax/actors/file_set_actor.rb +2 -0
  9. data/app/assets/stylesheets/hyrax/_styles.scss +5 -0
  10. data/app/controllers/concerns/hyrax/collections_controller_behavior.rb +13 -5
  11. data/app/controllers/concerns/hyrax/controller.rb +13 -2
  12. data/app/controllers/hyrax/admin/admin_sets_controller.rb +2 -19
  13. data/app/controllers/hyrax/admin/permission_template_accesses_controller.rb +5 -2
  14. data/app/controllers/hyrax/collections_controller.rb +3 -1
  15. data/app/controllers/hyrax/dashboard/collection_members_controller.rb +12 -9
  16. data/app/controllers/hyrax/dashboard/collections_controller.rb +92 -28
  17. data/app/controllers/hyrax/dashboard/nest_collections_controller.rb +75 -39
  18. data/app/controllers/hyrax/my_controller.rb +4 -4
  19. data/app/controllers/hyrax/workflow_actions_controller.rb +8 -5
  20. data/app/forms/hyrax/forms/administrative_set_form.rb +62 -0
  21. data/app/forms/hyrax/forms/collection_form.rb +2 -2
  22. data/app/forms/hyrax/forms/dashboard/nest_collection_form.rb +14 -4
  23. data/app/forms/hyrax/forms/pcdm_collection_form.rb +64 -0
  24. data/app/forms/hyrax/forms/resource_form.rb +15 -10
  25. data/app/forms/hyrax/forms/workflow_action_form.rb +4 -0
  26. data/app/helpers/hyrax/hyrax_helper_behavior.rb +9 -0
  27. data/app/indexers/hyrax/administrative_set_indexer.rb +6 -6
  28. data/app/indexers/hyrax/pcdm_collection_indexer.rb +2 -0
  29. data/app/models/admin_set.rb +16 -5
  30. data/app/models/concerns/hyrax/ability/admin_set_ability.rb +31 -7
  31. data/app/models/concerns/hyrax/ability/collection_ability.rb +35 -20
  32. data/app/models/concerns/hyrax/ability/collection_type_ability.rb +1 -1
  33. data/app/models/concerns/hyrax/ability.rb +2 -2
  34. data/app/models/concerns/hyrax/solr_document_behavior.rb +2 -2
  35. data/app/models/hyrax/administrative_set.rb +7 -1
  36. data/app/models/hyrax/permission.rb +1 -1
  37. data/app/models/hyrax/permission_template.rb +19 -5
  38. data/app/models/hyrax/work.rb +1 -0
  39. data/app/models/hyrax/workflow_action_info.rb +16 -0
  40. data/app/models/sipity/comment.rb +17 -0
  41. data/app/models/sipity.rb +11 -2
  42. data/app/presenters/hyrax/admin_set_presenter.rb +8 -3
  43. data/app/presenters/hyrax/collection_presenter.rb +3 -3
  44. data/app/presenters/hyrax/work_show_presenter.rb +2 -1
  45. data/app/search_builders/hyrax/abstract_type_relation.rb +4 -2
  46. data/app/search_builders/hyrax/dashboard/collections_search_builder.rb +1 -1
  47. data/app/search_builders/hyrax/exposed_models_relation.rb +1 -1
  48. data/app/search_builders/hyrax/filter_by_type.rb +1 -2
  49. data/app/search_builders/hyrax/my/collections_search_builder.rb +1 -1
  50. data/app/services/hyrax/admin_set_create_service.rb +136 -54
  51. data/app/services/hyrax/collection_types/permissions_service.rb +1 -1
  52. data/app/services/hyrax/collections/collection_member_service.rb +12 -2
  53. data/app/services/hyrax/collections/permissions_create_service.rb +81 -79
  54. data/app/services/hyrax/collections/permissions_service.rb +1 -1
  55. data/app/services/hyrax/curation_concern.rb +24 -2
  56. data/app/services/hyrax/default_middleware_stack.rb +11 -0
  57. data/app/services/hyrax/ensure_well_formed_admin_set_service.rb +3 -3
  58. data/app/services/hyrax/listeners/active_fedora_acl_index_listener.rb +1 -0
  59. data/app/services/hyrax/listeners/metadata_index_listener.rb +25 -9
  60. data/app/services/hyrax/permission_manager.rb +4 -4
  61. data/app/services/hyrax/solr_service.rb +1 -1
  62. data/app/services/hyrax/statistics/collections/over_time.rb +2 -1
  63. data/app/services/hyrax/workflow/abstract_notification.rb +2 -2
  64. data/app/services/hyrax/workflow/action_taken_service.rb +16 -4
  65. data/app/services/hyrax/workflow/activate_object.rb +5 -4
  66. data/app/services/hyrax/workflow/changes_required_notification.rb +5 -4
  67. data/app/services/hyrax/workflow/deactivate_object.rb +7 -5
  68. data/app/services/hyrax/workflow/deposited_notification.rb +8 -4
  69. data/app/services/hyrax/workflow/grant_edit_to_depositor.rb +7 -3
  70. data/app/services/hyrax/workflow/grant_read_to_depositor.rb +10 -3
  71. data/app/services/hyrax/workflow/revoke_edit_from_depositor.rb +8 -2
  72. data/app/services/hyrax/workflow/workflow_action_service.rb +4 -1
  73. data/app/views/hyrax/admin/admin_sets/_form.html.erb +1 -1
  74. data/app/views/hyrax/dashboard/collections/_collection_title.html.erb +1 -1
  75. data/app/views/hyrax/dashboard/collections/_form.html.erb +1 -1
  76. data/app/views/hyrax/dashboard/collections/_sort_and_per_page.html.erb +1 -1
  77. data/app/views/hyrax/homepage/index.html.erb +1 -1
  78. data/app/views/hyrax/my/collections/_modal_collection_types_to_create.html.erb +1 -1
  79. data/app/views/layouts/hyrax/dashboard.html.erb +1 -0
  80. data/app/views/layouts/hyrax.html.erb +1 -0
  81. data/app/views/shared/_read_only.html.erb +5 -0
  82. data/chart/hyrax/Chart.yaml +2 -2
  83. data/chart/hyrax/templates/deployment.yaml +6 -0
  84. data/config/features.rb +3 -0
  85. data/config/initializers/1_healthz.rb +1 -0
  86. data/config/initializers/listeners.rb +2 -1
  87. data/config/locales/hyrax.en.yml +1 -0
  88. data/db/seeds.rb +1 -1
  89. data/documentation/developing-your-hyrax-based-app.md +1 -1
  90. data/documentation/legacyREADME.md +1 -1
  91. data/hyrax.gemspec +1 -1
  92. data/lib/generators/hyrax/templates/catalog_controller.rb +3 -1
  93. data/lib/generators/hyrax/templates/config/initializers/hyrax.rb +10 -0
  94. data/lib/generators/hyrax/work/templates/feature_spec.rb.erb +1 -1
  95. data/lib/generators/hyrax/work_resource/templates/indexer_spec.rb.erb +1 -0
  96. data/lib/hyrax/collection_name.rb +6 -2
  97. data/lib/hyrax/configuration.rb +28 -0
  98. data/lib/hyrax/form_fields.rb +1 -0
  99. data/lib/hyrax/publisher.rb +12 -0
  100. data/lib/hyrax/resource_sync/change_list_writer.rb +2 -2
  101. data/lib/hyrax/resource_sync/resource_list_writer.rb +2 -2
  102. data/lib/hyrax/specs/shared_specs/hydra_works.rb +2 -0
  103. data/lib/hyrax/specs/shared_specs/indexers.rb +6 -0
  104. data/lib/hyrax/transactions/collection_create.rb +25 -0
  105. data/lib/hyrax/transactions/collection_update.rb +20 -0
  106. data/lib/hyrax/transactions/container.rb +26 -0
  107. data/lib/hyrax/transactions/steps/add_to_collections.rb +13 -1
  108. data/lib/hyrax/transactions/steps/apply_collection_type_permissions.rb +29 -0
  109. data/lib/hyrax/transactions/steps/save.rb +18 -6
  110. data/lib/hyrax/transactions/steps/set_collection_type_gid.rb +35 -0
  111. data/lib/hyrax/version.rb +1 -1
  112. data/lib/tasks/default_admin_set.rake +12 -11
  113. data/template.rb +1 -1
  114. metadata +16 -9
@@ -2,38 +2,53 @@
2
2
  module Hyrax
3
3
  module Ability
4
4
  module CollectionAbility
5
- def collection_abilities # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
5
+ def collection_abilities # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
6
+ models = [Hyrax::PcdmCollection, Hyrax.config.collection_class].uniq
6
7
  if admin?
7
- can :manage, ::Collection
8
- can :manage_any, ::Collection
9
- can :create_any, ::Collection
10
- can :view_admin_show_any, ::Collection
8
+ models.each do |collection_model|
9
+ can :manage, collection_model
10
+ can :manage_any, collection_model
11
+ can :create_any, collection_model
12
+ can :view_admin_show_any, collection_model
13
+ end
11
14
  else
12
- can :manage_any, ::Collection if Hyrax::Collections::PermissionsService.can_manage_any_collection?(ability: self)
13
- can :create_any, ::Collection if Hyrax::CollectionTypes::PermissionsService.can_create_any_collection_type?(ability: self)
14
- can :view_admin_show_any, ::Collection if Hyrax::Collections::PermissionsService.can_view_admin_show_for_any_collection?(ability: self)
15
+ models.each { |collection_model| can :manage_any, collection_model } if
16
+ Hyrax::Collections::PermissionsService.can_manage_any_collection?(ability: self)
15
17
 
16
- can [:edit, :update, :destroy], ::Collection do |collection| # for test by solr_doc, see solr_document_ability.rb
17
- test_edit(collection.id)
18
- end
18
+ models.each { |collection_model| can :create_any, collection_model } if
19
+ Hyrax::CollectionTypes::PermissionsService.can_create_any_collection_type?(ability: self)
20
+
21
+ models.each { |collection_model| can :view_admin_show_any, collection_model } if
22
+ Hyrax::Collections::PermissionsService.can_view_admin_show_for_any_collection?(ability: self)
23
+
24
+ models.each do |collection_model|
25
+ can [:edit, :update, :destroy], collection_model do |collection|
26
+ test_edit(collection.id)
27
+ end
28
+
29
+ can :deposit, collection_model do |collection|
30
+ Hyrax::Collections::PermissionsService.can_deposit_in_collection?(ability: self, collection_id: collection.id)
31
+ end
32
+
33
+ can :view_admin_show, collection_model do |collection| # admin show page
34
+ Hyrax::Collections::PermissionsService.can_view_admin_show_for_collection?(ability: self, collection_id: collection.id)
35
+ end
19
36
 
20
- can :deposit, ::Collection do |collection|
21
- Hyrax::Collections::PermissionsService.can_deposit_in_collection?(ability: self, collection_id: collection.id)
37
+ can :read, collection_model do |collection| # public show page
38
+ test_read(collection.id)
39
+ end
22
40
  end
41
+
23
42
  can :deposit, ::SolrDocument do |solr_doc|
24
43
  Hyrax::Collections::PermissionsService.can_deposit_in_collection?(ability: self, collection_id: solr_doc.id) # checks collections and admin_sets
25
44
  end
26
-
27
- can :view_admin_show, ::Collection do |collection| # admin show page
28
- Hyrax::Collections::PermissionsService.can_view_admin_show_for_collection?(ability: self, collection_id: collection.id)
45
+ can :deposit, String do |collection_id|
46
+ Hyrax::Collections::PermissionsService.can_deposit_in_collection?(ability: self, collection_id: collection_id)
29
47
  end
48
+
30
49
  can :view_admin_show, ::SolrDocument do |solr_doc| # admin show page
31
50
  Hyrax::Collections::PermissionsService.can_view_admin_show_for_collection?(ability: self, collection_id: solr_doc.id) # checks collections and admin_sets
32
51
  end
33
-
34
- can :read, ::Collection do |collection| # public show page # for test by solr_doc, see solr_document_ability.rb
35
- test_read(collection.id)
36
- end
37
52
  end
38
53
  end
39
54
  end
@@ -8,7 +8,7 @@ module Hyrax
8
8
  can :create_collection_type, CollectionType
9
9
  else
10
10
  can :create_collection_of_type, CollectionType do |collection_type|
11
- Hyrax::CollectionTypes::PermissionsService.can_create_collection_of_type?(user: current_user, collection_type: collection_type)
11
+ Hyrax::CollectionTypes::PermissionsService.can_create_collection_of_type?(ability: self, collection_type: collection_type)
12
12
  end
13
13
  end
14
14
  end
@@ -103,7 +103,7 @@ module Hyrax
103
103
  test_download(id)
104
104
  end
105
105
 
106
- can :download, SolrDocument do |obj|
106
+ can :download, ::SolrDocument do |obj|
107
107
  cache.put(obj.id, obj)
108
108
  test_download(obj.id)
109
109
  end
@@ -397,7 +397,7 @@ module Hyrax
397
397
  end
398
398
 
399
399
  def curation_concerns_models
400
- [::FileSet, ::Collection] + Hyrax.config.curation_concerns
400
+ [::FileSet, Hyrax.config.collection_class] + Hyrax.config.curation_concerns
401
401
  end
402
402
 
403
403
  def can_review_submissions?
@@ -53,7 +53,7 @@ module Hyrax
53
53
  ##
54
54
  # @return [Boolean]
55
55
  def collection?
56
- hydra_model == ::Collection
56
+ hydra_model == Hyrax.config.collection_class
57
57
  end
58
58
 
59
59
  ##
@@ -76,7 +76,7 @@ module Hyrax
76
76
 
77
77
  # Method to return the model
78
78
  def hydra_model(classifier: ActiveFedora.model_mapper)
79
- "::#{first('has_model_ssim')}".safe_constantize ||
79
+ first('has_model_ssim')&.safe_constantize ||
80
80
  classifier.classifier(self).best_model
81
81
  end
82
82
 
@@ -4,9 +4,15 @@ module Hyrax
4
4
  ##
5
5
  # Valkyrie model for Admin Set domain objects.
6
6
  class AdministrativeSet < Hyrax::Resource
7
+ include Hyrax::Schema(:core_metadata)
8
+
7
9
  attribute :alternative_title, Valkyrie::Types::Set.of(Valkyrie::Types::String)
8
10
  attribute :creator, Valkyrie::Types::Set.of(Valkyrie::Types::String)
9
11
  attribute :description, Valkyrie::Types::Set.of(Valkyrie::Types::String)
10
- attribute :title, Valkyrie::Types::Set.of(Valkyrie::Types::String)
12
+
13
+ def collection_type_gid
14
+ # allow AdministrativeSet to behave more like a regular PcdmCollection
15
+ Hyrax::CollectionType.find_or_create_admin_set_type.to_global_id
16
+ end
11
17
  end
12
18
  end
@@ -14,6 +14,6 @@ module Hyrax
14
14
 
15
15
  attribute :access_to, Valkyrie::Types::ID
16
16
  attribute :agent, Valkyrie::Types::String
17
- attribute :mode, Valkyrie::Types::String
17
+ attribute :mode, Valkyrie::Types::Coercible::Symbol
18
18
  end
19
19
  end
@@ -216,6 +216,8 @@ module Hyrax
216
216
  end
217
217
 
218
218
  ##
219
+ # @param interpret_visibility [Boolean] whether to retain the existing
220
+ # visibility when applying permission template ACLs
219
221
  # @return [Boolean]
220
222
  def reset_access_controls(interpret_visibility: false)
221
223
  reset_access_controls_for(collection: source_model,
@@ -223,8 +225,11 @@ module Hyrax
223
225
  end
224
226
 
225
227
  ##
228
+ # @param collection [::Collection, Hyrax::Resource]
229
+ # @param interpret_visibility [Boolean] whether to retain the existing
230
+ # visibility when applying permission template ACLs
226
231
  # @return [Boolean]
227
- def reset_access_controls_for(collection:, interpret_visibility: false)
232
+ def reset_access_controls_for(collection:, interpret_visibility: false) # rubocop:disable Metrics/MethodLength
228
233
  interpreted_read_groups = read_groups
229
234
 
230
235
  if interpret_visibility
@@ -233,10 +238,19 @@ module Hyrax
233
238
  interpreted_read_groups += visibilities.additions_for(visibility: collection.visibility)
234
239
  end
235
240
 
236
- collection.update!(edit_users: edit_users,
237
- edit_groups: edit_groups,
238
- read_users: read_users,
239
- read_groups: interpreted_read_groups.uniq)
241
+ case collection
242
+ when Valkyrie::Resource
243
+ collection.permission_manager.edit_groups = edit_groups
244
+ collection.permission_manager.edit_users = edit_users
245
+ collection.permission_manager.read_groups = interpreted_read_groups
246
+ collection.permission_manager.read_users = read_users
247
+ collection.permission_manager.acl.save
248
+ else
249
+ collection.update!(edit_users: edit_users,
250
+ edit_groups: edit_groups,
251
+ read_users: read_users,
252
+ read_groups: interpreted_read_groups.uniq)
253
+ end
240
254
  end
241
255
 
242
256
  private
@@ -14,6 +14,7 @@ module Hyrax
14
14
  attribute :on_behalf_of, Valkyrie::Types::String
15
15
  attribute :proxy_depositor, Valkyrie::Types::String
16
16
  attribute :state, Valkyrie::Types::URI.default(Hyrax::ResourceStatus::ACTIVE)
17
+ attribute :rendering_ids, Valkyrie::Types::Array.of(Valkyrie::Types::ID).meta(ordered: true)
17
18
  attribute :representative_id, Valkyrie::Types::ID
18
19
  attribute :thumbnail_id, Valkyrie::Types::ID
19
20
 
@@ -1,7 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
  module Hyrax
3
+ ##
3
4
  # A simple data object for holding a user, work and their workflow proxies
5
+ #
6
+ # this is a glorified Struct that resolves +Sipity::Enitity(work)+
7
+ # and +Sipity::Agent(user)+ for the input given, then provides readers
8
+ # for its instance variables.
9
+ #
10
+ # @example
11
+ # info = WorkflowActionInfo.new(my_work, current_user)
12
+ #
13
+ # info.agent # => #<Sipity::Agent...>
14
+ # info.entity # => #<Sipity::Entity...>
15
+ # info.work == my_work # => true
16
+ # info.user == current_user # => true
4
17
  class WorkflowActionInfo
18
+ ##
19
+ # @param work [Object]
20
+ # @param user [::User]
5
21
  def initialize(work, user)
6
22
  @work = work
7
23
  @user = user
@@ -11,4 +11,21 @@ module Sipity
11
11
  agent.proxy_for.to_s
12
12
  end
13
13
  end
14
+
15
+ ##
16
+ # A comment without a database record; always returns an empty string
17
+ class NullComment
18
+ attr_reader :agent, :entity
19
+
20
+ def initialize(agent:, entity:)
21
+ @agent = agent
22
+ @entity = entity
23
+ end
24
+
25
+ ##
26
+ # @return [String]
27
+ def comment
28
+ ''
29
+ end
30
+ end
14
31
  end
data/app/models/sipity.rb CHANGED
@@ -56,28 +56,37 @@ module Sipity
56
56
  #
57
57
  # @return [Sipity::Entity]
58
58
  # rubocop:disable Naming/MethodName, Metrics/CyclomaticComplexity, Metrics/MethodLength
59
- def Entity(input, &block)
59
+ def Entity(input, &block) # rubocop:disable Metrics/AbcSize
60
+ Rails.logger.debug("Trying to make an Entity for #{input.inspect}")
61
+
60
62
  result = case input
61
63
  when Sipity::Entity
62
64
  input
63
65
  when URI::GID, GlobalID
66
+ Rails.logger.debug("Entity() got a GID, searching by proxy")
64
67
  Entity.find_by(proxy_for_global_id: input.to_s)
65
68
  when SolrDocument
69
+ Rails.logger.debug("Entity() got a SolrDocument, retrying on #{input.to_model}")
66
70
  Entity(input.to_model)
67
71
  when Draper::Decorator
72
+ Rails.logger.debug("Entity() got a Decorator, retrying on #{input.model}")
68
73
  Entity(input.model)
69
74
  when Sipity::Comment
75
+ Rails.logger.debug("Entity() got a Comment, retrying on #{input.entity}")
70
76
  Entity(input.entity)
71
77
  when Valkyrie::Resource
78
+ Rails.logger.debug("Entity() got a Resource, retrying on #{Hyrax::GlobalID(input)}")
72
79
  Entity(Hyrax::GlobalID(input))
73
80
  else
81
+ Rails.logger.debug("Entity() got something else, testing #to_global_id")
74
82
  Entity(input.to_global_id) if input.respond_to?(:to_global_id)
75
83
  end
76
84
 
85
+ Rails.logger.debug("Entity(): attempting conversion on #{result}")
77
86
  handle_conversion(input, result, :to_sipity_entity, &block)
78
87
  rescue URI::GID::MissingModelIdError
79
88
  Entity(nil)
80
- end
89
+ end # rubocop:enable Metrics/AbcSize
81
90
  module_function :Entity
82
91
  # rubocop:enable Naming/MethodName, Metrics/CyclomaticComplexity, Metrics/MethodLength
83
92
 
@@ -21,13 +21,12 @@ module Hyrax
21
21
 
22
22
  # AdminSet cannot be deleted if default set or non-empty
23
23
  def disable_delete?
24
- AdminSet.default_set?(id) || any_items?
24
+ default_set? || any_items?
25
25
  end
26
26
 
27
27
  # Message to display if deletion is disabled
28
28
  def disabled_message
29
- return I18n.t('hyrax.admin.admin_sets.delete.error_default_set') if AdminSet.default_set?(id)
30
-
29
+ return I18n.t('hyrax.admin.admin_sets.delete.error_default_set') if default_set?
31
30
  I18n.t('hyrax.admin.admin_sets.delete.error_not_empty') if any_items?
32
31
  end
33
32
 
@@ -63,5 +62,11 @@ module Hyrax
63
62
  return false unless current_ability.can?(:edit, solr_document)
64
63
  !disable_delete?
65
64
  end
65
+
66
+ private
67
+
68
+ def default_set?
69
+ Hyrax::AdminSetCreateService.default_admin_set?(id: id)
70
+ end
66
71
  end
67
72
  end
@@ -116,13 +116,13 @@ module Hyrax
116
116
 
117
117
  # The total number of parents that this collection belongs to, visible or not.
118
118
  def total_parent_collections
119
- parent_collections.nil? ? 0 : parent_collections.response['numFound']
119
+ parent_collections.blank? ? 0 : parent_collections.response['numFound']
120
120
  end
121
121
 
122
122
  # The number of parent collections shown on the current page. This will differ from total_parent_collections
123
123
  # due to pagination.
124
124
  def parent_collection_count
125
- parent_collections.nil? ? 0 : parent_collections.documents.size
125
+ parent_collections.blank? ? 0 : parent_collections.documents.size
126
126
  end
127
127
 
128
128
  def user_can_nest_collection?
@@ -182,7 +182,7 @@ module Hyrax
182
182
  "deprecated. Use available_parent_collections_data " \
183
183
  "helper instead.")
184
184
  return @available_parents if @available_parents.present?
185
- collection = ::Collection.find(id)
185
+ collection = Hyrax.config.collection_class.find(id)
186
186
  colls = Hyrax::Collections::NestedCollectionQueryService.available_parent_collections(child: collection, scope: scope, limit_to_id: nil)
187
187
  @available_parents = colls.map do |col|
188
188
  { "id" => col.id, "title_first" => col.title.first }
@@ -248,7 +248,8 @@ module Hyrax
248
248
  # @return [Boolean] a flag indicating whether to display collection deposit
249
249
  # options.
250
250
  def show_deposit_for?(collections:)
251
- collections.present? || current_ability.can?(:create_any, ::Collection)
251
+ collections.present? ||
252
+ current_ability.can?(:create_any, Hyrax.config.collection_class)
252
253
  end
253
254
 
254
255
  ##
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
  module Hyrax
3
3
  class AbstractTypeRelation < ActiveFedora::Relation
4
- def initialize(opts = {})
4
+ def initialize(allowable_types: nil, **opts)
5
+ @allowable_types = allowable_types
5
6
  super(DummyModel, opts)
6
7
  end
7
8
 
8
9
  def allowable_types
9
- raise NotImplementedException, "Implement allowable_types in a subclass"
10
+ @allowable_types ||
11
+ raise(NotImplementedException, "Implement allowable_types in a subclass")
10
12
  end
11
13
 
12
14
  def equivalent_class?(klass)
@@ -9,7 +9,7 @@ module Hyrax
9
9
 
10
10
  # This overrides the models in FilterByType
11
11
  def models
12
- [::AdminSet, ::Collection]
12
+ [::AdminSet, ::Collection, Hyrax.config.collection_model.safe_constantize].uniq.compact
13
13
  end
14
14
 
15
15
  # adds a filter to exclude collections and admin sets created by the
@@ -3,7 +3,7 @@ module Hyrax
3
3
  # A relation that scopes to all user visible models (e.g. works + collections + file sets)
4
4
  class ExposedModelsRelation < AbstractTypeRelation
5
5
  def allowable_types
6
- Hyrax.config.curation_concerns + [::Collection, ::FileSet]
6
+ (Hyrax.config.curation_concerns + [Hyrax.config.collection_class, ::Collection, ::FileSet]).uniq
7
7
  end
8
8
  end
9
9
  end
@@ -53,8 +53,7 @@ module Hyrax
53
53
 
54
54
  def collection_classes
55
55
  return [] if only_works?
56
- # to_class_uri is deprecated in AF 11
57
- [::Collection]
56
+ [::Collection, Hyrax.config.collection_class].uniq
58
57
  end
59
58
  end
60
59
  end
@@ -21,6 +21,6 @@ class Hyrax::My::CollectionsSearchBuilder < ::Hyrax::CollectionSearchBuilder
21
21
  # This overrides the models in FilterByType
22
22
  # @return [Array<Class>] a list of classes to include
23
23
  def models
24
- [::AdminSet, ::Collection, Hyrax::AdministrativeSet]
24
+ [::AdminSet, Hyrax::AdministrativeSet, Hyrax.config.collection_model.safe_constantize].compact
25
25
  end
26
26
  end
@@ -1,46 +1,99 @@
1
1
  # frozen_string_literal: true
2
2
  module Hyrax
3
- # Responsible for creating an AdminSet and its corresponding data:
3
+ # Responsible for creating a Hyrax::AdministrativeSet and its corresponding data.
4
4
  #
5
5
  # * An associated permission template
6
6
  # * Available workflows
7
7
  # * An active workflow
8
8
  #
9
- # @see AdminSet
9
+ # @see Hyrax::AdministrativeSet
10
10
  # @see Hyrax::PermissionTemplate
11
11
  # @see Sipity::Workflow
12
- class AdminSetCreateService
13
- # @api public
14
- # Creates the default AdminSet and corresponding data
15
- # @param admin_set_id [String] The default admin set ID
16
- # @param title [Array<String>] The title of the default admin set
17
- # @return [TrueClass]
18
- # @see AdminSet
19
- def self.create_default_admin_set(admin_set_id:, title:)
20
- admin_set = AdminSet.new(id: admin_set_id, title: Array.wrap(title))
21
- begin
22
- new(admin_set: admin_set, creating_user: nil).create
23
- rescue ActiveFedora::IllegalOperation
24
- # It is possible that another thread created the AdminSet just before this method
25
- # was called, so ActiveFedora will raise IllegalOperation. In this case we can safely
26
- # ignore the error.
27
- Rails.logger.error("AdminSet ID=#{AdminSet::DEFAULT_ID} may or may not have been created due to threading issues.")
12
+ class AdminSetCreateService # rubocop:disable Metrics/ClassLength
13
+ DEFAULT_ID = 'admin_set/default'
14
+ DEFAULT_TITLE = ['Default Admin Set'].freeze
15
+
16
+ class_attribute :permissions_create_service
17
+ self.permissions_create_service = Hyrax::Collections::PermissionsCreateService
18
+
19
+ class << self
20
+ # @api public
21
+ # Creates the default Hyrax::AdministrativeSet and corresponding data
22
+ # @param admin_set_id [String] The default admin set ID
23
+ # @param title [Array<String>] The title of the default admin set
24
+ # @return [TrueClass]
25
+ # @see Hyrax::AdministrativeSet
26
+ # @deprecated
27
+ # TODO: When this deprecated method is removed, update private method
28
+ # .create_default_admin_set! to remove the parameters.
29
+ def create_default_admin_set(admin_set_id: DEFAULT_ID, title: DEFAULT_TITLE)
30
+ Deprecation.warn("'##{__method__}' will be removed in Hyrax 4.0. " \
31
+ "Instead, use 'Hyrax::AdminSetCreateService.find_or_create_default_admin_set'.")
32
+ create_default_admin_set!(admin_set_id: admin_set_id, title: title).present?
33
+ rescue RuntimeError => _err
34
+ false
28
35
  end
29
- end
30
36
 
31
- # @api public
32
- # Creates a non-default AdminSet and corresponding data
33
- # @param admin_set [AdminSet] the admin set to operate on
34
- # @param creating_user [User] the user who created the admin set
35
- # @return [TrueClass, FalseClass] true if it was successful
36
- # @see AdminSet
37
- # @raise [RuntimeError] if you attempt to create a default admin set via this mechanism
38
- def self.call(admin_set:, creating_user:, **kwargs)
39
- raise "Use .create_default_admin_set to create a default admin set" if admin_set.default_set?
40
- new(admin_set: admin_set, creating_user: creating_user, **kwargs).create
37
+ # @api public
38
+ # Finds the default AdministrativeSet if it exists; otherwise, creates it and corresponding data
39
+ # @return [Hyrax::AdministrativeSet] The default admin set.
40
+ # @see Hyrax::AdministrativeSet
41
+ # @raise [RuntimeError] if admin set cannot be persisted
42
+ def find_or_create_default_admin_set
43
+ Hyrax.query_service.find_by(id: DEFAULT_ID)
44
+ rescue Valkyrie::Persistence::ObjectNotFoundError
45
+ create_default_admin_set!
46
+ end
47
+
48
+ # @api public
49
+ # Is the admin_set the default Hyrax::AdministrativeSet
50
+ # @param id [#to_s] the id of the admin set to check
51
+ def default_admin_set?(id:)
52
+ id.to_s == DEFAULT_ID
53
+ end
54
+
55
+ # @api public
56
+ # Creates a non-default Hyrax::AdministrativeSet and corresponding data
57
+ # @param admin_set [Hyrax::AdministrativeSet | AdminSet] the admin set to operate on
58
+ # @param creating_user [User] the user who created the admin set
59
+ # @return [TrueClass, FalseClass] true if it was successful
60
+ # @see Hyrax::AdministrativeSet
61
+ # @raise [RuntimeError] if you attempt to create a default admin set via this mechanism
62
+ # @deprecated
63
+ def call(admin_set:, creating_user:, **kwargs)
64
+ Deprecation.warn("'##{__method__}' will be removed in Hyrax 4.0. " \
65
+ "Warning: This method may hide runtime errors. " \
66
+ "Instead, use 'Hyrax::AdminSetCreateService.call!'. ")
67
+ call!(admin_set: admin_set, creating_user: creating_user, **kwargs).present?
68
+ rescue RuntimeError => err
69
+ raise err if default_admin_set?(id: admin_set.id)
70
+ false
71
+ end
72
+
73
+ # @api public
74
+ # Creates a non-default Hyrax::AdministrativeSet and corresponding data
75
+ # @param admin_set [Hyrax::AdministrativeSet] the admin set to operate on
76
+ # @param creating_user [User] the user who created the admin set
77
+ # @return [Hyrax::AdministrativeSet] The fully created admin set.
78
+ # @see Hyrax::AdministrativeSet
79
+ # @raise [RuntimeError] if you attempt to create a default admin set via this mechanism
80
+ # @raise [RuntimeError] if admin set cannot be persisted
81
+ def call!(admin_set:, creating_user:, **kwargs)
82
+ raise "Use .find_or_create_default_admin_set to create a default admin set" if default_admin_set?(id: admin_set.id)
83
+ new(admin_set: admin_set, creating_user: creating_user, **kwargs).create!
84
+ end
85
+
86
+ private
87
+
88
+ # TODO: Parameters admin_set_id and title are defined to support .create_default_admin_set
89
+ # which is deprecated. When it is removed, the parameters will no longer be required.
90
+ def create_default_admin_set!(admin_set_id: DEFAULT_ID, title: DEFAULT_TITLE)
91
+ admin_set = Hyrax::AdministrativeSet.new(id: admin_set_id, title: Array.wrap(title))
92
+ new(admin_set: admin_set, creating_user: nil).create!
93
+ end
41
94
  end
42
95
 
43
- # @param admin_set [AdminSet] the admin set to operate on
96
+ # @param admin_set [Hyrax::AdministrativeSet | AdminSet] the admin set to operate on
44
97
  # @param creating_user [User] the user who created the admin set (if any).
45
98
  # @param workflow_importer [#call] imports the workflow
46
99
  def initialize(admin_set:, creating_user:, workflow_importer: default_workflow_importer)
@@ -53,40 +106,69 @@ module Hyrax
53
106
 
54
107
  # Creates an admin set, setting the creator and the default access controls.
55
108
  # @return [TrueClass, FalseClass] true if it was successful
109
+ # @deprecated
56
110
  def create
57
- admin_set.creator = [creating_user.user_key] if creating_user
58
- admin_set.save.tap do |result|
59
- if result
60
- ActiveRecord::Base.transaction do
61
- permission_template = create_permission_template
62
- workflow = create_workflows_for(permission_template: permission_template)
63
- create_default_access_for(permission_template: permission_template, workflow: workflow) if admin_set.default_set?
64
- end
65
- end
66
- end
111
+ Deprecation.warn("'##{__method__}' will be removed in Hyrax 4.0. " \
112
+ "Warning: This method may hide runtime errors. " \
113
+ "Instead, use 'Hyrax::AdminSetCreateService.create!'. ")
114
+ create!.persisted?
115
+ rescue RuntimeError => _err
116
+ false
117
+ end
118
+
119
+ # Creates an admin set, setting the creator and the default access controls.
120
+ # @return [Hyrax::AdministrativeSet] The fully created admin set.
121
+ # @raise [RuntimeError] if admin set cannot be persisted
122
+ def create!
123
+ admin_set.respond_to?(:valkyrie_resource) ? active_fedora_create! : valkyrie_create!
67
124
  end
68
125
 
69
126
  private
70
127
 
71
- def access_grants_attributes
72
- [
73
- { agent_type: 'group', agent_id: admin_group_name, access: Hyrax::PermissionTemplateAccess::MANAGE }
74
- ].tap do |attribute_list|
75
- # Grant manage access to the creating_user if it exists. Should exist for all but default Admin Set
76
- attribute_list << { agent_type: 'user', agent_id: creating_user.user_key, access: Hyrax::PermissionTemplateAccess::MANAGE } if creating_user
77
- end
128
+ def default_admin_set?(id:)
129
+ self.class.default_admin_set?(id: id)
78
130
  end
79
131
 
80
132
  def admin_group_name
81
133
  ::Ability.admin_group_name
82
134
  end
83
135
 
84
- ##
85
- # @return [PermissionTemplate]
86
- def create_permission_template
87
- permission_template = PermissionTemplate.create!(source_id: admin_set.id, access_grants_attributes: access_grants_attributes)
88
- permission_template.reset_access_controls_for(collection: admin_set)
89
- permission_template
136
+ # Creates an admin set, setting the creator and the default access controls.
137
+ # @return [Hyrax::AdministrativeSet] The fully created admin set.
138
+ # @raise [RuntimeError] if admin set cannot be persisted
139
+ def valkyrie_create!
140
+ admin_set.creator = [creating_user.user_key] if creating_user
141
+ updated_admin_set = Hyrax.persister.save(resource: admin_set).tap do |result|
142
+ if result
143
+ ActiveRecord::Base.transaction do
144
+ permission_template = permissions_create_service.create_default(collection: result,
145
+ creating_user: creating_user)
146
+ workflow = create_workflows_for(permission_template: permission_template)
147
+ create_default_access_for(permission_template: permission_template, workflow: workflow) if default_admin_set?(id: admin_set.id)
148
+ end
149
+ end
150
+ end
151
+ Hyrax.publisher.publish('collection.metadata.updated', collection: updated_admin_set, user: creating_user)
152
+ updated_admin_set
153
+ end
154
+
155
+ # Creates an admin set, setting the creator and the default access controls.
156
+ # @return [Hyrax::AdministrativeSet] The fully created admin set.
157
+ # @raise [RuntimeError] if admin set cannot be persisted
158
+ def active_fedora_create!
159
+ admin_set.creator = [creating_user.user_key] if creating_user
160
+ admin_set.save.tap do |result|
161
+ if result
162
+ ActiveRecord::Base.transaction do
163
+ permission_template = permissions_create_service.create_default(collection: admin_set,
164
+ creating_user: creating_user)
165
+ workflow = create_workflows_for(permission_template: permission_template)
166
+ create_default_access_for(permission_template: permission_template, workflow: workflow) if default_admin_set?(id: admin_set.id)
167
+ end
168
+ end
169
+ end
170
+ raise 'Admin set failed to persist.' unless admin_set.persisted?
171
+ admin_set.valkyrie_resource
90
172
  end
91
173
 
92
174
  def create_workflows_for(permission_template:)
@@ -121,7 +203,7 @@ module Hyrax
121
203
  end
122
204
  end
123
205
 
124
- # Gives deposit access to registered users to default AdminSet
206
+ # Give registered users deposit access to default admin set
125
207
  def create_default_access_for(permission_template:, workflow:)
126
208
  permission_template.access_grants.create(agent_type: 'group', agent_id: ::Ability.registered_group_name, access: Hyrax::PermissionTemplateAccess::DEPOSIT)
127
209
  deposit = Sipity::Role[Hyrax::RoleRegistry::DEPOSITING]