ddr-models 3.0.0.alpha.4 → 3.0.0.beta.1

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/app/models/collection.rb +6 -2
  4. data/config/initializers/active_fedora_base.rb +3 -4
  5. data/ddr-models.gemspec +4 -3
  6. data/lib/ddr/auth/effective_roles.rb +1 -5
  7. data/lib/ddr/auth/inherited_roles.rb +2 -5
  8. data/lib/ddr/auth/resource_roles.rb +1 -4
  9. data/lib/ddr/auth/roles.rb +3 -3
  10. data/lib/ddr/auth/roles/role.rb +54 -101
  11. data/lib/ddr/auth/roles/role_attribute.rb +16 -0
  12. data/lib/ddr/auth/roles/role_set.rb +19 -72
  13. data/lib/ddr/auth/roles/role_set_manager.rb +68 -0
  14. data/lib/ddr/auth/roles/role_set_query.rb +10 -22
  15. data/lib/ddr/auth/roles/role_type.rb +1 -0
  16. data/lib/ddr/auth/roles/role_validator.rb +11 -0
  17. data/lib/ddr/models.rb +2 -1
  18. data/lib/ddr/models/base.rb +78 -17
  19. data/lib/ddr/models/has_admin_metadata.rb +6 -4
  20. data/lib/ddr/models/has_content.rb +0 -10
  21. data/lib/ddr/models/solr_document.rb +6 -2
  22. data/lib/ddr/models/validatable.rb +20 -0
  23. data/lib/ddr/models/validator.rb +8 -0
  24. data/lib/ddr/models/version.rb +1 -1
  25. data/lib/ddr/vocab/roles.rb +14 -10
  26. data/spec/auth/effective_permissions_spec.rb +1 -1
  27. data/spec/auth/effective_roles_spec.rb +5 -5
  28. data/spec/auth/roles/role_set_manager_spec.rb +86 -0
  29. data/spec/auth/roles/role_set_query_spec.rb +50 -67
  30. data/spec/auth/roles/role_set_spec.rb +41 -0
  31. data/spec/auth/roles/role_spec.rb +45 -42
  32. data/spec/models/collection_spec.rb +1 -1
  33. data/spec/models/has_admin_metadata_spec.rb +2 -2
  34. data/spec/models/indexing_spec.rb +2 -2
  35. data/spec/models/search_builder_spec.rb +3 -3
  36. data/spec/models/solr_document_spec.rb +3 -3
  37. data/spec/support/shared_examples_for_non_collection_models.rb +1 -1
  38. metadata +33 -18
  39. data/lib/ddr/auth/roles/detached_role_set.rb +0 -59
  40. data/lib/ddr/auth/roles/property_role_set.rb +0 -46
  41. data/lib/ddr/auth/roles/roles_datastream.rb +0 -9
  42. data/lib/ddr/models/describable.rb +0 -79
  43. data/spec/auth/roles/detached_role_set_spec.rb +0 -50
  44. data/spec/auth/roles/property_role_set_spec.rb +0 -32
@@ -0,0 +1,68 @@
1
+ module Ddr::Auth
2
+ module Roles
3
+ class RoleSetManager
4
+
5
+ attr_reader :object
6
+ attr_accessor :role_set
7
+
8
+ def initialize(object)
9
+ @object = object
10
+ load
11
+ end
12
+
13
+ def grant(*roles)
14
+ granted = RoleSet.new(roles: roles)
15
+ role_set.merge(granted)
16
+ persist
17
+ end
18
+
19
+ def granted?(role)
20
+ if role.is_a?(Role)
21
+ role_set.include?(role)
22
+ else
23
+ !where(role).empty?
24
+ end
25
+ end
26
+
27
+ def revoke(*roles)
28
+ revoked = RoleSet.new(roles: roles)
29
+ role_set.roles -= revoked.roles
30
+ persist
31
+ end
32
+
33
+ def revoke_all
34
+ role_set.clear
35
+ persist
36
+ end
37
+
38
+ def replace(*roles)
39
+ self.role_set = RoleSet.new(roles: roles)
40
+ persist
41
+ end
42
+
43
+ protected
44
+
45
+ def respond_to_missing?(name, include_all=false)
46
+ role_set.respond_to?(name, include_all)
47
+ end
48
+
49
+ def method_missing(name, *args, &block)
50
+ if role_set.respond_to?(name)
51
+ return role_set.send(name, *args, &block)
52
+ end
53
+ super
54
+ end
55
+
56
+ private
57
+
58
+ def persist
59
+ object.access_roles = role_set.to_json
60
+ end
61
+
62
+ def load
63
+ self.role_set = RoleSet.from_json(object.access_roles)
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -8,14 +8,13 @@ module Ddr::Auth
8
8
  class RoleSetQuery
9
9
  include Enumerable
10
10
 
11
- attr_reader :role_set
11
+ attr_reader :criteria, :role_set
12
+
13
+ delegate :each, :agents, :permissions, :empty?, to: :result
12
14
 
13
15
  def initialize(role_set)
14
16
  @role_set = role_set
15
- end
16
-
17
- def criteria
18
- @criteria ||= {}
17
+ @criteria = {}
19
18
  end
20
19
 
21
20
  def where(conditions={})
@@ -45,24 +44,13 @@ module Ddr::Auth
45
44
  end
46
45
  alias_method :type, :role_type
47
46
 
48
- def each(&block)
49
- role_set.select { |role| matches_all?(role) }.each(&block)
50
- end
51
-
52
- # Return the list of agents for the Roles matching the criteria.
53
- # @return [Array] the agents
54
- def agents
55
- map { |role| role.agent.first }
56
- end
57
-
58
- # Return a list of the permissions granted to the Roles matching the criteria.
59
- # @return [Array<Symbol>] the permissions
60
- def permissions
61
- map(&:permissions).flatten.uniq
47
+ def merge(other_query)
48
+ where(other_query.criteria)
62
49
  end
63
50
 
64
- def detach
65
- DetachedRoleSet.new(self)
51
+ def result
52
+ matching_roles = role_set.select { |role| matches_all?(role) }
53
+ RoleSet.new(roles: matching_roles)
66
54
  end
67
55
 
68
56
  private
@@ -77,7 +65,7 @@ module Ddr::Auth
77
65
  end
78
66
 
79
67
  def matches_one?(role, key, value)
80
- Array(value).include?(role.send(key).first)
68
+ Array(value).include? role.send(key)
81
69
  end
82
70
 
83
71
  end
@@ -16,6 +16,7 @@ module Ddr
16
16
  def to_s
17
17
  title
18
18
  end
19
+ # alias_method :to_str, :to_s
19
20
 
20
21
  end
21
22
  end
@@ -0,0 +1,11 @@
1
+ module Ddr::Auth
2
+ module Roles
3
+ class RoleValidator < Ddr::Models::Validator
4
+
5
+ validates :agent, presence: true
6
+ validates :role_type, inclusion: { in: Roles.type_map.keys }
7
+ validates :scope, inclusion: { in: Roles::SCOPES }
8
+
9
+ end
10
+ end
11
+ end
@@ -34,7 +34,6 @@ module Ddr
34
34
  autoload :ChecksumInvalid, 'ddr/models/error'
35
35
  autoload :ContentModelError, 'ddr/models/error'
36
36
  autoload :DerivativeGenerationFailure, 'ddr/models/error'
37
- autoload :Describable
38
37
  autoload :Error
39
38
  autoload :EventLoggable
40
39
  autoload :FileManagement
@@ -54,6 +53,8 @@ module Ddr
54
53
  autoload :StructDiv
55
54
  autoload :Structure
56
55
  autoload :UrlSafeId
56
+ autoload :Validatable
57
+ autoload :Validator
57
58
  autoload :YearFacet
58
59
 
59
60
  autoload_under "licenses" do
@@ -3,7 +3,6 @@ module Ddr::Models
3
3
  extend Deprecation
4
4
 
5
5
  include ObjectApi
6
- include Describable
7
6
  include Governable
8
7
  include HasThumbnail
9
8
  include EventLoggable
@@ -17,20 +16,18 @@ module Ddr::Models
17
16
  notify_event :deletion
18
17
  end
19
18
 
20
- def inspect
21
- "#<#{model_and_id}, uri: \"#{uri}\">"
22
- end
23
-
24
- def attached_files_profile
25
- AttachedFilesProfile.new(attached_files)
19
+ DescriptiveMetadata.mapping.each do |name, term|
20
+ property name, predicate: term.predicate do |index|
21
+ index.as :stored_searchable
22
+ end
26
23
  end
27
24
 
28
- def copy_admin_policy_or_roles_from(other)
29
- copy_admin_policy_from(other) || copy_resource_roles_from(other)
25
+ def self.find_by_identifier(identifier)
26
+ find(Ddr::Index::Fields::IDENTIFIER_ALL => identifier)
30
27
  end
31
28
 
32
- def association_query(association)
33
- raise NotImplementedError, "The previous implementation does not work with ActiveFedora 9."
29
+ def inspect
30
+ "#<#{model_and_id}, uri: \"#{uri}\">"
34
31
  end
35
32
 
36
33
  def model_and_id
@@ -42,12 +39,76 @@ module Ddr::Models
42
39
  model_and_id
43
40
  end
44
41
 
45
- # @override ActiveFedora::Core
46
- # See ActiveFedora overrides in engine initializers
47
- def adapt_to_cmodel
48
- super
49
- rescue ::TypeError
50
- raise ContentModelError, "Cannot adapt to nil content model."
42
+ def descMetadata
43
+ Deprecation.warn(Base, "`descMetadata` is deprecated; use `desc_metadata` instead.")
44
+ desc_metadata
45
+ end
46
+
47
+ def desc_metadata
48
+ @desc_metadata ||= DescriptiveMetadata.new(self)
49
+ end
50
+
51
+ def has_desc_metadata?
52
+ desc_metadata.has_content?
53
+ end
54
+
55
+ def desc_metadata_terms(*args)
56
+ return DescriptiveMetadata.unqualified_names.sort if args.empty?
57
+ arg = args.pop
58
+ terms = case arg.to_sym
59
+ when :empty
60
+ desc_metadata_terms.select { |t| desc_metadata_values(t).empty? }
61
+ when :present
62
+ desc_metadata_terms.select { |t| desc_metadata_values(t).present? }
63
+ when :defined_attributes
64
+ desc_metadata_terms & desc_metadata_attributes
65
+ when :required
66
+ desc_metadata_terms(:defined_attributes).select {|t| required? t}
67
+ when :dcterms
68
+ MetadataMapping.dc11.unqualified_names +
69
+ (MetadataMapping.dcterms.unqualified_names - MetadataMapping.dc11.unqualified_names)
70
+ when :dcterms_elements11
71
+ Ddr::Vocab::Vocabulary.term_names(::RDF::DC11)
72
+ when :duke
73
+ Ddr::Vocab::Vocabulary.term_names(Ddr::Vocab::DukeTerms)
74
+ else
75
+ raise ArgumentError, "Invalid argument: #{arg.inspect}"
76
+ end
77
+ if args.empty?
78
+ terms
79
+ else
80
+ terms | desc_metadata_terms(*args)
81
+ end
82
+ end
83
+ deprecation_deprecate :desc_metadata_terms
84
+
85
+ def desc_metadata_attributes
86
+ MetadataMapping.dc11.unqualified_names
87
+ end
88
+ deprecation_deprecate :desc_metadata_attributes
89
+
90
+ def desc_metadata_values(term)
91
+ Deprecation.warn(Base, "`desc_metadata_values` is deprecated; use `desc_metadata.values` instead.")
92
+ desc_metadata.values(term)
93
+ end
94
+
95
+ def set_desc_metadata_values(term, values)
96
+ Deprecation.warn(Base, "`set_desc_metadata_values` is deprecated; use `desc_metadata.set_values` instead.")
97
+ desc_metadata.set_values(term, values)
98
+ end
99
+
100
+ # Update all descMetadata terms with values in hash
101
+ # Note that term not having key in hash will be set to nil!
102
+ def set_desc_metadata(term_values_hash)
103
+ desc_metadata_terms.each { |t| set_desc_metadata_values(t, term_values_hash[t]) }
104
+ end
105
+
106
+ def attached_files_profile
107
+ AttachedFilesProfile.new(attached_files)
108
+ end
109
+
110
+ def copy_admin_policy_or_roles_from(other)
111
+ copy_admin_policy_from(other) || copy_resource_roles_from(other)
51
112
  end
52
113
 
53
114
  def has_extracted_text?
@@ -6,7 +6,9 @@ module Ddr::Models
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
- contains "accessRoles", class_name: "Ddr::Auth::Roles::RolesDatastream"
9
+ property :access_roles,
10
+ predicate: Ddr::Vocab::Roles.roleSet,
11
+ multiple: false
10
12
 
11
13
  property :admin_set,
12
14
  predicate: Ddr::Vocab::Asset.adminSet,
@@ -62,7 +64,7 @@ module Ddr::Models
62
64
  end
63
65
 
64
66
  def roles
65
- Ddr::Auth::Roles::PropertyRoleSet.new(accessRoles.roles)
67
+ Ddr::Auth::Roles::RoleSetManager.new(self)
66
68
  end
67
69
 
68
70
  def inherited_roles
@@ -78,13 +80,13 @@ module Ddr::Models
78
80
  end
79
81
 
80
82
  def grant_roles_to_creator(creator)
81
- roles.grant type: Ddr::Auth::Roles::EDITOR,
83
+ roles.grant role_type: Ddr::Auth::Roles::EDITOR,
82
84
  agent: creator,
83
85
  scope: Ddr::Auth::Roles::RESOURCE_SCOPE
84
86
  end
85
87
 
86
88
  def copy_resource_roles_from(other)
87
- roles.grant *(other.roles.in_resource_scope)
89
+ roles.grant *(Ddr::Auth::ResourceRoles.call(other))
88
90
  end
89
91
 
90
92
  def effective_permissions(agents)
@@ -6,16 +6,6 @@ module Ddr
6
6
  extend ActiveSupport::Concern
7
7
  extend Deprecation
8
8
 
9
- MASTER_FILE_TYPES = [ "image/tiff" ]
10
-
11
- def master_file?
12
- if respond_to?(:file_use) && file_use.present?
13
- file_use == Ddr::Models::HasStructMetadata::FILE_USE_MASTER
14
- else
15
- MASTER_FILE_TYPES.include?(content_type)
16
- end
17
- end
18
-
19
9
  included do
20
10
  contains Ddr::Datastreams::CONTENT
21
11
  contains Ddr::Datastreams::EXTRACTED_TEXT, class_name: 'Ddr::Datastreams::PlainTextDatastream'
@@ -19,7 +19,7 @@ module Ddr::Models
19
19
  end
20
20
 
21
21
  def pid
22
- Deprecation.warn(SolrDocument, "Use `id` instead.")
22
+ Deprecation.warn(SolrDocument, "`pid` is deprecated; use `id` instead.")
23
23
  id
24
24
  end
25
25
 
@@ -52,6 +52,10 @@ module Ddr::Models
52
52
  id.sub(/:/, "-")
53
53
  end
54
54
 
55
+ def access_roles
56
+ get(Ddr::Index::Fields::ACCESS_ROLE)
57
+ end
58
+
55
59
  def object_profile
56
60
  @object_profile ||= get_json(Ddr::Index::Fields::OBJECT_PROFILE)
57
61
  end
@@ -177,7 +181,7 @@ module Ddr::Models
177
181
  end
178
182
 
179
183
  def roles
180
- @roles ||= Ddr::Auth::Roles::DetachedRoleSet.from_json(access_role)
184
+ @roles ||= Ddr::Auth::Roles::RoleSetManager.new(self)
181
185
  end
182
186
 
183
187
  def struct_maps
@@ -0,0 +1,20 @@
1
+ require "forwardable"
2
+
3
+ module Ddr::Models
4
+ module Validatable
5
+
6
+ def self.included(base)
7
+ base.extend Forwardable
8
+ base.def_delegators :validator, :valid?, :invalid?, :errors
9
+
10
+ class << base
11
+ attr_accessor :validator
12
+ end
13
+ end
14
+
15
+ def validator
16
+ @validator ||= self.class.validator.new(self)
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ require "delegate"
2
+
3
+ module Ddr::Models
4
+ class Validator < SimpleDelegator
5
+ include ActiveModel::Validations
6
+
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  module Ddr
2
2
  module Models
3
- VERSION = "3.0.0.alpha.4"
3
+ VERSION = "3.0.0.beta.1"
4
4
  end
5
5
  end
@@ -3,24 +3,28 @@ module Ddr
3
3
  class Roles < RDF::StrictVocabulary("http://repository.lib.duke.edu/vocab/roles/")
4
4
 
5
5
  term :Role,
6
- label: "Role",
7
- comment: "An assertion of a role granted to an agent."
6
+ label: "Role",
7
+ comment: "An assertion of a role granted to an agent."
8
8
 
9
9
  property :hasRole,
10
- label: "Has Role",
11
- comment: "Asserts the granting of a role on the subject to an agent."
10
+ label: "Has Role",
11
+ comment: "Asserts the granting of a role on the subject to an agent."
12
12
 
13
13
  property :type,
14
- label: "Type",
15
- comment: "The type of role granted to the agent."
14
+ label: "Type",
15
+ comment: "The type of role granted to the agent."
16
16
 
17
17
  property :agent,
18
- label: "Agent",
19
- comment: "The agent to whom the role is granted."
18
+ label: "Agent",
19
+ comment: "The agent to whom the role is granted."
20
20
 
21
21
  property :scope,
22
- label: "Scope",
23
- comment: "The scope within which the role applies."
22
+ label: "Scope",
23
+ comment: "The scope within which the role applies."
24
+
25
+ property :roleSet,
26
+ label: "Role Set",
27
+ comment: "A set of roles asserted on the subject"
24
28
 
25
29
  end
26
30
  end
@@ -8,7 +8,7 @@ module Ddr::Auth
8
8
  before do
9
9
  resource.admin_policy = policy
10
10
  resource.roles.grant FactoryGirl.build(:role, :downloader, :public)
11
- policy.roles.grant type: "Editor", agent: "Editors", scope: "policy"
11
+ policy.roles.grant role_type: "Editor", agent: "Editors", scope: "policy"
12
12
  end
13
13
 
14
14
  it "should return the list of permissions granted to the agents on the resource in resource scope, plus the permissions granted to the agents on the resource's policy in policy scope" do