Class: Hyrax::PermissionTemplate

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/hyrax/permission_template.rb

Overview

TODO:

write up what “default embargo behavior”, when it is applied, and how it interacts with embargoes specified by user input.

Holds policy data about the workflow and permissions applied objects when they are deposited through an Administrative Set or a Collection. Each template record has a #source (through #source_id); the template's rules inform the behavior of objects deposited through that #source.

The PermissionTemplate specifies:

  • an #active_workflow that the object will enter and be processed through.

  • #access_grants that can be applied to each object (especially at deposit time).

  • an embargo configuration (#release_date #release_period) for default embargo behavior.

Additionally, the PermissionTemplate grants authority to perform actions that relate to the Administrative Set/Collection itself. Rules for who can deposit to, view(?!), or manage the admin set are governed by related PermissionTemplateAccess records. Administrat Sets should have a manager granted by some such record.

Examples:

cerating a permission template and manager for an admin set

admin_set = Hyrax::AdministrativeSet.new(title: 'My Admin Set')
admin_set = Hyrax.persister.save(resource: admin_set)

template = PermissionTemplate.create!(source_id: admin_set.id.to_s)
Hyrax::PermissionTemplateAccess.create!(permission_template: template,
                                       agent_type: Hyrax::PermissionTemplateAccess::USER,
                                       agent_id: user.user_key,
                                       access: Hyrax::PermissionTemplateAccess::MANAGE)

See Also:

Constant Summary collapse

RELEASE_TEXT_VALUE_FIXED =

Valid Release Period values

'fixed'
RELEASE_TEXT_VALUE_NO_DELAY =
'now'
RELEASE_TEXT_VALUE_BEFORE_DATE =

Valid Release Varies sub-options

'before'
RELEASE_TEXT_VALUE_EMBARGO =
'embargo'
RELEASE_TEXT_VALUE_6_MONTHS =
'6mos'
RELEASE_TEXT_VALUE_1_YEAR =
'1yr'
RELEASE_TEXT_VALUE_2_YEARS =
'2yrs'
RELEASE_TEXT_VALUE_3_YEARS =
'3yrs'
RELEASE_EMBARGO_PERIODS =

Key/value pair of valid embargo periods. Values are number of months embargoed.

{
  RELEASE_TEXT_VALUE_6_MONTHS => 6,
  RELEASE_TEXT_VALUE_1_YEAR => 12,
  RELEASE_TEXT_VALUE_2_YEARS => 24,
  RELEASE_TEXT_VALUE_3_YEARS => 36
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#access_grantsHyrax::PermissionTemplateAccess


50
# File 'app/models/hyrax/permission_template.rb', line 50

has_many :access_grants, class_name: 'Hyrax::PermissionTemplateAccess', dependent: :destroy

#active_workflowSipity::Workflow

Returns:


50
# File 'app/models/hyrax/permission_template.rb', line 50

has_many :access_grants, class_name: 'Hyrax::PermissionTemplateAccess', dependent: :destroy

#available_workflowsEnumerable<Sipity::Workflow>

Returns:


50
# File 'app/models/hyrax/permission_template.rb', line 50

has_many :access_grants, class_name: 'Hyrax::PermissionTemplateAccess', dependent: :destroy

#source_idString

Returns identifier for the Collection or AdministrativeSet to which this template applies.

Returns:


50
# File 'app/models/hyrax/permission_template.rb', line 50

has_many :access_grants, class_name: 'Hyrax::PermissionTemplateAccess', dependent: :destroy

Instance Method Details

#admin_setAdminSet

Deprecated.

Use #source instead

A bit of an analogue for a `belongs_to :admin_set` as it crosses from Fedora to the DB

Returns:

Raises:


98
99
100
101
102
103
104
# File 'app/models/hyrax/permission_template.rb', line 98

def admin_set
  Deprecation.warn("#admin_set is deprecated; use #source instead.")
  return AdminSet.find(source_id) if AdminSet.exists?(source_id)
  raise Hyrax::ObjectNotFoundError
rescue ActiveFedora::ActiveFedoraError # TODO: remove the rescue when active_fedora issue #1276 is fixed
  raise Hyrax::ObjectNotFoundError
end

#agent_ids_for(agent_type:, access:) ⇒ Array<String>

Retrieve the agent_ids associated with the given agent_type and access

Parameters:

  • agent_type (String)
  • access (String)

Returns:

  • (Array<String>)

    of agent_ids that match the given parameters


68
69
70
# File 'app/models/hyrax/permission_template.rb', line 68

def agent_ids_for(agent_type:, access:)
  access_grants.where(agent_type: agent_type, access: access).pluck(:agent_id)
end

#collectionCollection

Deprecated.

Use #source instead

A bit of an analogue for a `belongs_to :collection` as it crosses from Fedora to the DB

Returns:

Raises:


110
111
112
113
114
115
116
# File 'app/models/hyrax/permission_template.rb', line 110

def collection
  Deprecation.warn("#collection is deprecated; use #source instead.")
  return ::Collection.find(source_id) if ::Collection.exists?(source_id)
  raise Hyrax::ObjectNotFoundError
rescue ActiveFedora::ActiveFedoraError # TODO: remove the rescue when active_fedora issue #1276 is fixed
  raise Hyrax::ObjectNotFoundError
end

#edit_groupsArray<String>

Returns:

  • (Array<String>)

203
204
205
# File 'app/models/hyrax/permission_template.rb', line 203

def edit_groups
  agent_ids_for(access: 'manage', agent_type: 'group')
end

#edit_usersArray<String>

Returns:

  • (Array<String>)

197
198
199
# File 'app/models/hyrax/permission_template.rb', line 197

def edit_users
  agent_ids_for(access: 'manage', agent_type: 'user')
end

#read_groupsArray<String>

Returns:

  • (Array<String>)

216
217
218
219
220
# File 'app/models/hyrax/permission_template.rb', line 216

def read_groups
  (agent_ids_for(access: 'view', agent_type: 'group') +
    agent_ids_for(access: 'deposit', agent_type: 'group')).uniq -
    [::Ability.registered_group_name, ::Ability.public_group_name]
end

#read_usersArray<String>

Returns:

  • (Array<String>)

209
210
211
212
# File 'app/models/hyrax/permission_template.rb', line 209

def read_users
  (agent_ids_for(access: 'view', agent_type: 'user') +
    agent_ids_for(access: 'deposit', agent_type: 'user')).uniq
end

#release_before_date?Boolean

Does this permission template require a date (or embargo) that all works are released before NOTE: date will be in release_date

Returns:

  • (Boolean)

151
152
153
154
# File 'app/models/hyrax/permission_template.rb', line 151

def release_before_date?
  # All PermissionTemplate embargoes are dynamically determined release before dates
  release_period == RELEASE_TEXT_VALUE_BEFORE_DATE || release_max_embargo?
end

#release_dateObject

Override release_date getter to return a dynamically calculated date of release based one release requirements. Returns embargo date when release_max_embargo?==true. Returns today's date when release_no_delay?==true.

See Also:


167
168
169
170
171
172
173
174
175
176
# File 'app/models/hyrax/permission_template.rb', line 167

def release_date
  # If no release delays allowed, return today's date as release date
  return Time.zone.today if release_no_delay?

  # If this isn't an embargo, just return release_date from database
  return self[:release_date] unless release_max_embargo?

  # Otherwise (if an embargo), return latest embargo date by adding specified months to today's date
  Time.zone.today + RELEASE_EMBARGO_PERIODS.fetch(release_period).months
end

#release_fixed_date?Boolean

Does this permission template require a specific date of release for all works NOTE: date will be in release_date

Returns:

  • (Boolean)

140
141
142
# File 'app/models/hyrax/permission_template.rb', line 140

def release_fixed_date?
  release_period == RELEASE_TEXT_VALUE_FIXED
end

#release_max_embargo?Boolean

Is there a maximum embargo period specified by this permission template NOTE: latest embargo date returned by release_date, maximum embargo period will be in release_period

Returns:

  • (Boolean)

158
159
160
161
# File 'app/models/hyrax/permission_template.rb', line 158

def release_max_embargo?
  # Is it a release period in one of our valid embargo periods?
  RELEASE_EMBARGO_PERIODS.key?(release_period)
end

#release_no_delay?Boolean

Does this permission template require no release delays (i.e. no embargoes allowed)

Returns:

  • (Boolean)

145
146
147
# File 'app/models/hyrax/permission_template.rb', line 145

def release_no_delay?
  release_period == RELEASE_TEXT_VALUE_NO_DELAY
end

#reset_access_controls(interpret_visibility: false) ⇒ Boolean

Deprecated.

Use #reset_access_controls_for instead

Parameters:

  • interpret_visibility (Boolean) (defaults to: false)

    whether to retain the existing visibility when applying permission template ACLs

Returns:

  • (Boolean)

227
228
229
230
231
# File 'app/models/hyrax/permission_template.rb', line 227

def reset_access_controls(interpret_visibility: false)
  Deprecation.warn("#reset_access_controls is deprecated; use #reset_access_controls_for instead.")
  reset_access_controls_for(collection: source_model,
                            interpret_visibility: interpret_visibility)
end

#reset_access_controls_for(collection:, interpret_visibility: false) ⇒ Boolean

Parameters:

  • collection (::Collection, Hyrax::Resource)
  • interpret_visibility (Boolean) (defaults to: false)

    whether to retain the existing visibility when applying permission template ACLs

Returns:

  • (Boolean)

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'app/models/hyrax/permission_template.rb', line 238

def reset_access_controls_for(collection:, interpret_visibility: false) # rubocop:disable Metrics/MethodLength
  interpreted_read_groups = read_groups

  if interpret_visibility
    visibilities = Hyrax::VisibilityMap.instance
    interpreted_read_groups -= visibilities.deletions_for(visibility: collection.visibility)
    interpreted_read_groups += visibilities.additions_for(visibility: collection.visibility)
  end

  case collection
  when Valkyrie::Resource
    collection.permission_manager.edit_groups = edit_groups
    collection.permission_manager.edit_users  = edit_users
    collection.permission_manager.read_groups = interpreted_read_groups
    collection.permission_manager.read_users  = read_users
    collection.permission_manager.acl.save
  else
    collection.update!(edit_users: edit_users,
                       edit_groups: edit_groups,
                       read_users: read_users,
                       read_groups: interpreted_read_groups.uniq)
  end
end

#sourceHyrax::Resource

Note:

this is a convenience method for Hyrax.query_service.find_by(id: template.source_id)

Returns the collection this template is associated with.

Returns:


76
77
78
# File 'app/models/hyrax/permission_template.rb', line 76

def source
  Hyrax.query_service.find_by(id: source_id)
end

#source_modelAdminSet, ::Collection

Note:

This method will eventually be replaced by #source which returns a Hyrax::Resource object. Many methods are equally able to process both Hyrax::Resource and ActiveFedora::Base. Only call this method if you need the ActiveFedora::Base object.

A bit of an analogue for a `belongs_to :source_model` as it crosses from Fedora to the DB

Returns:

Raises:

See Also:


88
89
90
91
92
# File 'app/models/hyrax/permission_template.rb', line 88

def source_model
  ActiveFedora::Base.find(source_id)
rescue ActiveFedora::ObjectNotFoundError
  raise Hyrax::ObjectNotFoundError
end

#valid_release_date?(date) ⇒ Boolean

Determines whether a given release date is valid based on this template's requirements

Parameters:

  • date (Date)

    to validate

Returns:

  • (Boolean)

180
181
182
183
# File 'app/models/hyrax/permission_template.rb', line 180

def valid_release_date?(date)
  # Validate date against all release date requirements
  check_no_delay_requirements(date) && check_before_date_requirements(date) && check_fixed_date_requirements(date)
end

#valid_visibility?(value) ⇒ Boolean

Determines whether a given visibility setting is valid based on this template's requirements

Parameters:

  • value (String)
    • visibility value to validate

Returns:

  • (Boolean)

187
188
189
190
191
192
193
# File 'app/models/hyrax/permission_template.rb', line 187

def valid_visibility?(value)
  # If template doesn't specify a visiblity (i.e. is "varies"), then any visibility is valid
  return true if visibility.blank?

  # Validate that passed in value matches visibility requirement exactly
  visibility == value
end