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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ed265d93ca6307ec23a3d9055d0f6965f8cb00cb
4
- data.tar.gz: 48a3f01ac1cd908e49695d612be9737143102553
3
+ metadata.gz: 7a968b891893ea815c1d2cdfd34f7b30fd7b0037
4
+ data.tar.gz: ab7b098e5f87fa7f31793e878206031bd010c98b
5
5
  SHA512:
6
- metadata.gz: 5fb8f5bca78ed6874d69829f0555dd6b395e7133206494bc09cad31348dfdec131120acbb8f7b0c05b48a816006c68ab0bb46d4a5e5002dbdb4b112509512d39
7
- data.tar.gz: 88f6ac010d23f70f07f36c4a0ffb7364abdbfa5e956d2b835ee11085c7de77010f15e4e6e8b65eaa209760951c0e5217e37aba32c5772158aaf2d985c343eaa0
6
+ metadata.gz: 76508b87a3e44c630e445d2ac5f89286ff08c59ffac61f07902e5e9e3ef59d54db78e2b1707d578f905c4c682008fc178ce770f8b61aa326a67490db2975a727
7
+ data.tar.gz: 3b288f688a6513a82feada181e1fe8c60dde16fbb4bba03c809b5c0dcc21730008e551ab6c5575fa63f01bec9fd861f757431e5dcb09b664d7e091e37fcf11a7
data/Gemfile CHANGED
@@ -3,5 +3,3 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem "devise"
6
-
7
- gem "active-fedora", github: "projecthydra/active_fedora", ref: "f85b4eab16f45cb4c1491a27bb20b05821bd9c44"
@@ -46,8 +46,12 @@ class Collection < Ddr::Models::Base
46
46
  end
47
47
 
48
48
  def grant_roles_to_creator(creator)
49
- roles.grant type: Ddr::Auth::Roles::CURATOR, agent: creator.agent, scope: Ddr::Auth::Roles::RESOURCE_SCOPE
50
- roles.grant type: Ddr::Auth::Roles::CURATOR, agent: creator.agent, scope: Ddr::Auth::Roles::POLICY_SCOPE
49
+ roles.grant role_type: Ddr::Auth::Roles::CURATOR,
50
+ agent: creator.agent,
51
+ scope: Ddr::Auth::Roles::RESOURCE_SCOPE
52
+ roles.grant role_type: Ddr::Auth::Roles::CURATOR,
53
+ agent: creator.agent,
54
+ scope: Ddr::Auth::Roles::POLICY_SCOPE
51
55
  end
52
56
 
53
57
  private
@@ -1,5 +1,4 @@
1
- module ActiveFedora
2
- class Base
1
+ ActiveFedora::Base.class_eval do
3
2
 
4
3
  def can_have_attachments?
5
4
  has_association? :attachments
@@ -26,8 +25,9 @@ module ActiveFedora
26
25
  end
27
26
 
28
27
  def describable?
29
- self.is_a? Ddr::Models::Describable
28
+ self.is_a? Ddr::Models::Base
30
29
  end
30
+ deprecation_deprecate :describable?
31
31
 
32
32
  def governable?
33
33
  has_association? :admin_policy
@@ -85,5 +85,4 @@ module ActiveFedora
85
85
  !association(assoc).nil?
86
86
  end
87
87
 
88
- end
89
88
  end
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
 
21
21
  s.add_dependency "rails", "~> 4.1.13"
22
22
  s.add_dependency "active-triples", "~> 0.7.2"
23
- s.add_dependency "active-fedora", "~> 9.5"
23
+ s.add_dependency "active-fedora", "~> 9.6.2"
24
24
  s.add_dependency "hydra-validations", "~> 0.5"
25
25
  s.add_dependency "devise", "~> 3.4"
26
26
  s.add_dependency "omniauth-shibboleth", "~> 1.2.0"
@@ -31,7 +31,8 @@ Gem::Specification.new do |s|
31
31
  s.add_dependency "net-ldap", "~> 0.11"
32
32
  s.add_dependency "cancancan", "~> 1.12"
33
33
  s.add_dependency "ddr-aux-client", "~> 1.2", ">= 1.2.2"
34
- s.add_dependency "ddr-antivirus", "2.0.0"
34
+ s.add_dependency "ddr-antivirus", "~> 2.1.1"
35
+ s.add_dependency "virtus", "~> 1.0.5"
35
36
 
36
37
  s.add_development_dependency "bundler", "~> 1.10"
37
38
  s.add_development_dependency "rake"
@@ -41,5 +42,5 @@ Gem::Specification.new do |s|
41
42
  s.add_development_dependency "factory_girl_rails", "~> 4.4"
42
43
  s.add_development_dependency "jettywrapper", "~> 2.0"
43
44
  s.add_development_dependency "database_cleaner"
44
- s.add_development_dependency "blacklight", "~> 5.15"
45
+ s.add_development_dependency "blacklight", "~> 5.15.0"
45
46
  end
@@ -3,19 +3,15 @@ require "delegate"
3
3
  module Ddr::Auth
4
4
  class EffectiveRoles < SimpleDelegator
5
5
 
6
- # @param obj [Object] an object that receives :roles and returns a RoleSet
7
- # @param agents [String, Array<String>] agent(s) to match roles
8
- # @return [Ddr::Auth::Roles::RoleSetQuery]
9
6
  def self.call(obj, agents)
10
7
  new(obj).call(agents)
11
8
  end
12
9
 
13
- # @param agents [String, Array<String>] agent(s) to match roles
14
- # @return [Ddr::Auth::Roles::RoleSetQuery]
15
10
  def call(agents)
16
11
  ResourceRoles.call(self)
17
12
  .merge(InheritedRoles.call(self))
18
13
  .agent(agents)
14
+ .result
19
15
  end
20
16
 
21
17
  end
@@ -3,18 +3,15 @@ require "delegate"
3
3
  module Ddr::Auth
4
4
  class InheritedRoles < SimpleDelegator
5
5
 
6
- # @param obj [Object] an object that receives :roles and returns a RoleSet
7
- # @return [Ddr::Auth::Roles::RoleSetQuery]
8
6
  def self.call(obj)
9
7
  new(obj).call
10
8
  end
11
9
 
12
- # @return [Ddr::Auth::Roles::DetachedRoleSet]
13
10
  def call
14
11
  if has_admin_policy?
15
- admin_policy.roles.in_policy_scope.detach
12
+ admin_policy.roles.in_policy_scope.result
16
13
  else
17
- Roles::DetachedRoleSet.new
14
+ Roles::RoleSet.new
18
15
  end
19
16
  end
20
17
 
@@ -3,15 +3,12 @@ require "delegate"
3
3
  module Ddr::Auth
4
4
  class ResourceRoles < SimpleDelegator
5
5
 
6
- # @param obj [Object] an object that receives :roles and returns a RoleSet
7
- # @return [Ddr::Auth::Roles::RoleSetQuery]
8
6
  def self.call(obj)
9
7
  new(obj).call
10
8
  end
11
9
 
12
- # @return [Ddr::Auth::Roles::DetachedRoleSet]
13
10
  def call
14
- roles.in_resource_scope.detach
11
+ roles.in_resource_scope.result
15
12
  end
16
13
 
17
14
  end
@@ -2,14 +2,14 @@ module Ddr::Auth
2
2
  module Roles
3
3
  extend ActiveSupport::Autoload
4
4
 
5
- autoload :DetachedRoleSet
6
- autoload :PropertyRoleSet
7
5
  autoload :Role
6
+ autoload :RoleAttribute
8
7
  autoload :RoleSet
8
+ autoload :RoleSetManager
9
9
  autoload :RoleSetQuery
10
- autoload :RolesDatastream
11
10
  autoload :RoleType
12
11
  autoload :RoleTypes
12
+ autoload :RoleValidator
13
13
 
14
14
  include RoleTypes
15
15
 
@@ -1,117 +1,70 @@
1
- module Ddr
2
- module Auth
3
- module Roles
4
- #
5
- # The assignment of a role to an agent within a scope.
6
- #
7
- class Role < ActiveTriples::Resource
8
-
9
- DEFAULT_SCOPE = Roles::RESOURCE_SCOPE
10
-
11
- include Hydra::Validations
12
-
13
- configure type: Ddr::Vocab::Roles.Role
14
- property :role_type, predicate: Ddr::Vocab::Roles.type
15
- property :agent, predicate: Ddr::Vocab::Roles.agent
16
- property :scope, predicate: Ddr::Vocab::Roles.scope
17
-
18
- validates :agent, presence: true, cardinality: { is: 1 }
19
- validates :role_type, inclusion: { in: Roles.type_map.keys }, cardinality: { is: 1 }
20
- validates :scope, inclusion: { in: Roles::SCOPES }, cardinality: { is: 1 }
21
-
22
- class << self
23
-
24
- # Build a Role instance from hash attributes
25
- # @param args [Hash] the attributes
26
- # @return [Role] the role
27
- # @example
28
- # Role.build type: "Curator", agent: "bob", scope: "resource"
29
- def build(args={})
30
- new.tap do |role|
31
- role.attributes = build_attributes(args)
32
- if role.invalid?
33
- raise Ddr::Models::Error, "Invalid #{self.name}: #{role.errors.full_messages.join('; ')}"
34
- end
35
- end
36
- end
37
-
38
- alias_method :deserialize, :build
39
-
40
- # Deserialize a Role from JSON
41
- # @param json [String] the JSON string
42
- # @return [Role] the role
43
- def from_json(json)
44
- deserialize JSON.parse(json)
45
- end
46
-
47
- private
48
-
49
- def build_attributes(args={})
50
- # symbolize keys and stringify values
51
- attrs = args.each_with_object({}) do |(k, v), memo|
52
- memo[k.to_sym] = Array(v).first.to_s
53
- end
54
- # set default scope if necessary
55
- attrs[:scope] ||= DEFAULT_SCOPE
56
- # accept :type key for role_type attribute
57
- if attrs.key?(:type)
58
- attrs[:role_type] = attrs.delete(:type)
59
- end
60
- attrs
61
- end
62
-
63
- end
64
-
65
- # Roles are considered equivalent (== and eql?) if they
66
- # are of the same type and have the same agent and scope.
67
- # @param other [Object] the object of comparison
68
- # @return [Boolean] the result
69
- def ==(other)
70
- if self.class == other.class
71
- self.to_h == other.to_h
72
- else
73
- super
74
- end
75
- end
1
+ require "json"
2
+ require "virtus"
3
+
4
+ module Ddr::Auth
5
+ module Roles
6
+ #
7
+ # The assignment of a role to an agent within a scope.
8
+ #
9
+ class Role
10
+ extend Deprecation
11
+ include Virtus.value_object
12
+ include Ddr::Models::Validatable
13
+
14
+ self.validator = RoleValidator
15
+
16
+ DEFAULT_SCOPE = Roles::RESOURCE_SCOPE
17
+
18
+ values do
19
+ attribute :agent, RoleAttribute
20
+ attribute :role_type, RoleAttribute
21
+ attribute :scope, RoleAttribute, default: DEFAULT_SCOPE
22
+ end
76
23
 
77
- def eql?(other)
78
- (self == other) && (hash == other.hash)
24
+ class << self
25
+ def build(*args)
26
+ Deprecation.warn(Role, "`build` is deprecated; use `new` instead.")
27
+ new(*args)
79
28
  end
80
29
 
81
- def hash
82
- to_h.hash
30
+ def from_json(json)
31
+ new JSON.parse(json)
83
32
  end
33
+ end
84
34
 
85
- def to_s
86
- to_h.to_s
87
- end
35
+ def initialize(*args)
36
+ super
37
+ validate!
38
+ end
88
39
 
89
- def in_resource_scope?
90
- scope.first == Roles::RESOURCE_SCOPE
91
- end
40
+ def to_s
41
+ to_h.to_s
42
+ end
92
43
 
93
- def in_policy_scope?
94
- scope.first == Roles::POLICY_SCOPE
95
- end
44
+ def to_json
45
+ JSON.dump(to_h)
46
+ end
96
47
 
97
- def inspect
98
- "#<#{self.class.name} role_type=#{role_type.first.inspect}, " \
99
- "agent=#{agent.first.inspect}, scope=#{scope.first.inspect}>"
48
+ def validate!
49
+ if invalid?
50
+ raise Ddr::Models::Error, "Invalid Role: #{errors.full_messages.join('; ')}"
100
51
  end
52
+ end
101
53
 
102
- def to_h
103
- as_json
104
- end
105
- alias_method :to_hash, :to_h
106
- alias_method :serialize, :to_h
54
+ def in_resource_scope?
55
+ scope == Roles::RESOURCE_SCOPE
56
+ end
107
57
 
108
- # Returns the permissions associated with the role
109
- # @return [Array<Symbol>] the permissions
110
- def permissions
111
- Roles.type_map[role_type.first].permissions
112
- end
58
+ def in_policy_scope?
59
+ scope == Roles::POLICY_SCOPE
60
+ end
113
61
 
62
+ # Returns the permissions associated with the role
63
+ # @return [Array<Symbol>] the permissions
64
+ def permissions
65
+ Roles.type_map[role_type].permissions
114
66
  end
67
+
115
68
  end
116
69
  end
117
70
  end
@@ -0,0 +1,16 @@
1
+ require "virtus"
2
+
3
+ module Ddr::Auth
4
+ module Roles
5
+ class RoleAttribute < Virtus::Attribute
6
+
7
+ def coerce(value)
8
+ if value.is_a? Array
9
+ return coerce(value.first)
10
+ end
11
+ value.to_s
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -1,102 +1,49 @@
1
+ require "set"
2
+ require "virtus"
3
+
1
4
  module Ddr::Auth
2
5
  module Roles
3
6
  #
4
7
  # Wraps a set of Roles
5
8
  #
6
- # @abstract
7
- #
8
9
  class RoleSet
10
+ include Virtus.model
9
11
  include Enumerable
12
+ include ActiveModel::Serializers::JSON
10
13
 
11
- attr_reader :role_set
14
+ attribute :roles, Set[Role]
12
15
 
13
- delegate :where, :agent, :scope, :role_type, :type, :agents, :permissions,
16
+ delegate :where, :agent, :scope, :role_type,
14
17
  :in_policy_scope, :in_resource_scope,
15
18
  to: :query
16
19
 
17
- delegate :empty?, :clear, to: :role_set
18
-
19
- def initialize(role_set)
20
- @role_set = role_set
21
- end
22
-
23
- # Grants roles - i.e., adds them to the role set
24
- # @example - default scope ("resource")
25
- # grant type: "Curator", agent: "bob"
26
- # @example - explicit scope
27
- # grant type: "Curator", agent: "sue", scope: "policy"
28
- # @param roles [Role, Hash, RoleSet, Array] the role(s) to grant
29
- def grant(*roles)
30
- raise NotImplementedError, "Subclasses must implement `grant`."
31
- end
32
-
33
- # Return true/false depending on whether the role has been granted
34
- # @param role [Ddr::Auth::Roles::Role, Hash] the role
35
- # @return [Boolean] whether the role has been granted
36
- def granted?(role)
37
- include? coerce(role)
38
- end
20
+ delegate :each, :empty?, :clear, to: :roles
39
21
 
40
- # Revokes roles - i.e., removes them from the role set
41
- # @example
42
- # revoke type: "Curator", agent: "bob", scope: "resource"
43
- # @param roles [Role, Hash, RoleSet, Array] the role(s) to revoke
44
- def revoke(*roles)
45
- raise NotImplementedError, "Subclasses must implement `revoke`."
22
+ def self.from_json(json)
23
+ new.from_json(json.present? ? json : "{}")
46
24
  end
47
25
 
48
- # Replace the current roles in the role set with new roles
49
- # @param roles [Role, Hash, RoleSet, Array] the role(s) to grant
50
- def replace(*roles)
51
- revoke_all
52
- grant(*roles)
53
- end
54
-
55
- # Remove all roles from the role set
56
- # @return [RoleSet] self
57
- def revoke_all
58
- raise NotImplementedError, "Subclasses must implement `revoke_all`."
26
+ def ==(other)
27
+ instance_of?(other.class) && self.roles == other.roles
59
28
  end
60
29
 
61
- # Return the RoleSet serialized as JSON
62
- # @return [String] the JSON string
63
- def to_json
64
- serialize.to_json
30
+ def merge(other)
31
+ self.roles += other.roles
32
+ self
65
33
  end
66
34
 
67
- # Return the RoleSet serialized as an Array of serialized Roles
68
- # @return [Array<Hash>]
69
- def serialize
70
- to_a.map(&:serialize)
35
+ def permissions
36
+ map(&:permissions).flatten.uniq
71
37
  end
72
38
 
73
- def ==(other)
74
- if other.is_a? RoleSet
75
- self.to_set == other.to_set
76
- else
77
- super
78
- end
39
+ def agents
40
+ map(&:agent).uniq
79
41
  end
80
42
 
81
- private
82
-
83
43
  def query
84
44
  RoleSetQuery.new(self)
85
45
  end
86
46
 
87
- def coerce(obj)
88
- case obj
89
- when RoleSet
90
- coerce(obj.role_set)
91
- when Array, Set
92
- obj.map { |r| coerce(r) }.flatten
93
- when Role
94
- obj
95
- else
96
- Role.build(obj)
97
- end
98
- end
99
-
100
47
  end
101
48
  end
102
49
  end