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

Sign up to get free protection for your applications and to get access to all the features.
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