hyrax-acl 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +174 -0
- data/README.md +7 -0
- data/hyrax-acl.gemspec +29 -0
- data/lib/hyrax/acl/access_control.rb +46 -0
- data/lib/hyrax/acl/access_control_change_set.rb +12 -0
- data/lib/hyrax/acl/access_control_list.rb +226 -0
- data/lib/hyrax/acl/agent.rb +20 -0
- data/lib/hyrax/acl/custom_queries/find_access_control.rb +30 -0
- data/lib/hyrax/acl/custom_queries.rb +13 -0
- data/lib/hyrax/acl/group.rb +35 -0
- data/lib/hyrax/acl/permission.rb +21 -0
- data/lib/hyrax/acl/version.rb +6 -0
- data/lib/hyrax/acl.rb +13 -0
- data/lib/hyrax.rb +2 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4d6daf35ffa5e520d644843770558e98616318e3f46e7ff71ee790ed294e4151
|
4
|
+
data.tar.gz: fa15a23186d21120d9bdaeccf57adf244d51ec64854d4619915ac752c86af120
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 71bac13a9baf582a197e16939e4780514d015effd330c91bb7e583d3393f5cac1acc112f70a86910f78ba28ae33558ee63b599245af0d83e0c2c4bafc0fac8d1
|
7
|
+
data.tar.gz: 4de625e404ce9219d1ea20f2f84b02a88e6abff7037ba8e00cf3e3a1327cfd0957b42e372f6d9e6bafa41a78d762f52321203636104e1c1d08e15620eea24ecf
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionpack (7.0.3)
|
5
|
+
actionview (= 7.0.3)
|
6
|
+
activesupport (= 7.0.3)
|
7
|
+
rack (~> 2.0, >= 2.2.0)
|
8
|
+
rack-test (>= 0.6.3)
|
9
|
+
rails-dom-testing (~> 2.0)
|
10
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
11
|
+
actionview (7.0.3)
|
12
|
+
activesupport (= 7.0.3)
|
13
|
+
builder (~> 3.1)
|
14
|
+
erubi (~> 1.4)
|
15
|
+
rails-dom-testing (~> 2.0)
|
16
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
17
|
+
activemodel (7.0.3)
|
18
|
+
activesupport (= 7.0.3)
|
19
|
+
activemodel-serializers-xml (1.0.2)
|
20
|
+
activemodel (> 5.x)
|
21
|
+
activesupport (> 5.x)
|
22
|
+
builder (~> 3.1)
|
23
|
+
activesupport (7.0.3)
|
24
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
25
|
+
i18n (>= 1.6, < 2)
|
26
|
+
minitest (>= 5.1)
|
27
|
+
tzinfo (~> 2.0)
|
28
|
+
builder (3.2.4)
|
29
|
+
concurrent-ruby (1.1.10)
|
30
|
+
crass (1.0.6)
|
31
|
+
declarative (0.0.20)
|
32
|
+
declarative-builder (0.1.0)
|
33
|
+
declarative-option (< 0.2.0)
|
34
|
+
declarative-option (0.1.1)
|
35
|
+
diff-lcs (1.5.0)
|
36
|
+
disposable (0.4.7)
|
37
|
+
declarative (>= 0.0.9, < 1.0.0)
|
38
|
+
declarative-builder (< 0.2.0)
|
39
|
+
declarative-option (< 0.2.0)
|
40
|
+
representable (>= 2.4.0, <= 3.1.0)
|
41
|
+
uber (< 0.2.0)
|
42
|
+
draper (4.0.2)
|
43
|
+
actionpack (>= 5.0)
|
44
|
+
activemodel (>= 5.0)
|
45
|
+
activemodel-serializers-xml (>= 1.0)
|
46
|
+
activesupport (>= 5.0)
|
47
|
+
request_store (>= 1.0)
|
48
|
+
ruby2_keywords
|
49
|
+
dry-configurable (0.15.0)
|
50
|
+
concurrent-ruby (~> 1.0)
|
51
|
+
dry-core (~> 0.6)
|
52
|
+
dry-container (0.9.0)
|
53
|
+
concurrent-ruby (~> 1.0)
|
54
|
+
dry-configurable (~> 0.13, >= 0.13.0)
|
55
|
+
dry-core (0.7.1)
|
56
|
+
concurrent-ruby (~> 1.0)
|
57
|
+
dry-inflector (0.2.1)
|
58
|
+
dry-logic (1.2.0)
|
59
|
+
concurrent-ruby (~> 1.0)
|
60
|
+
dry-core (~> 0.5, >= 0.5)
|
61
|
+
dry-struct (1.4.0)
|
62
|
+
dry-core (~> 0.5, >= 0.5)
|
63
|
+
dry-types (~> 1.5)
|
64
|
+
ice_nine (~> 0.11)
|
65
|
+
dry-types (1.5.1)
|
66
|
+
concurrent-ruby (~> 1.0)
|
67
|
+
dry-container (~> 0.3)
|
68
|
+
dry-core (~> 0.5, >= 0.5)
|
69
|
+
dry-inflector (~> 0.1, >= 0.1.2)
|
70
|
+
dry-logic (~> 1.0, >= 1.0.2)
|
71
|
+
erubi (1.10.0)
|
72
|
+
faraday (0.17.5)
|
73
|
+
multipart-post (>= 1.2, < 3)
|
74
|
+
htmlentities (4.3.4)
|
75
|
+
i18n (1.10.0)
|
76
|
+
concurrent-ruby (~> 1.0)
|
77
|
+
ice_nine (0.11.2)
|
78
|
+
json (2.6.2)
|
79
|
+
json-canonicalization (0.3.0)
|
80
|
+
json-ld (3.2.1)
|
81
|
+
htmlentities (~> 4.3)
|
82
|
+
json-canonicalization (~> 0.3)
|
83
|
+
link_header (~> 0.0, >= 0.0.8)
|
84
|
+
multi_json (~> 1.15)
|
85
|
+
rack (~> 2.2)
|
86
|
+
rdf (~> 3.2)
|
87
|
+
link_header (0.0.8)
|
88
|
+
loofah (2.18.0)
|
89
|
+
crass (~> 1.0.2)
|
90
|
+
nokogiri (>= 1.5.9)
|
91
|
+
method_source (1.0.0)
|
92
|
+
minitest (5.16.1)
|
93
|
+
multi_json (1.15.0)
|
94
|
+
multipart-post (2.2.3)
|
95
|
+
nokogiri (1.13.6-x86_64-linux)
|
96
|
+
racc (~> 1.4)
|
97
|
+
racc (1.6.0)
|
98
|
+
rack (2.2.3.1)
|
99
|
+
rack-test (2.0.0)
|
100
|
+
rack (>= 1.3)
|
101
|
+
rails-dom-testing (2.0.3)
|
102
|
+
activesupport (>= 4.2.0)
|
103
|
+
nokogiri (>= 1.6)
|
104
|
+
rails-html-sanitizer (1.4.3)
|
105
|
+
loofah (~> 2.3)
|
106
|
+
railties (7.0.3)
|
107
|
+
actionpack (= 7.0.3)
|
108
|
+
activesupport (= 7.0.3)
|
109
|
+
method_source
|
110
|
+
rake (>= 12.2)
|
111
|
+
thor (~> 1.0)
|
112
|
+
zeitwerk (~> 2.5)
|
113
|
+
rake (13.0.6)
|
114
|
+
rdf (3.2.8)
|
115
|
+
link_header (~> 0.0, >= 0.0.8)
|
116
|
+
rdf-vocab (3.2.1)
|
117
|
+
rdf (~> 3.2, >= 3.2.4)
|
118
|
+
reform (2.5.0)
|
119
|
+
disposable (>= 0.4.2, < 0.5.0)
|
120
|
+
representable (>= 2.4.0, < 3.1.0)
|
121
|
+
uber (< 0.2.0)
|
122
|
+
reform-rails (0.2.3)
|
123
|
+
activemodel (>= 5.0)
|
124
|
+
reform (>= 2.3.1, < 3.0.0)
|
125
|
+
representable (3.0.4)
|
126
|
+
declarative (< 0.1.0)
|
127
|
+
declarative-option (< 0.2.0)
|
128
|
+
uber (< 0.2.0)
|
129
|
+
request_store (1.5.1)
|
130
|
+
rack (>= 1.4)
|
131
|
+
rspec (3.11.0)
|
132
|
+
rspec-core (~> 3.11.0)
|
133
|
+
rspec-expectations (~> 3.11.0)
|
134
|
+
rspec-mocks (~> 3.11.0)
|
135
|
+
rspec-core (3.11.0)
|
136
|
+
rspec-support (~> 3.11.0)
|
137
|
+
rspec-expectations (3.11.0)
|
138
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
139
|
+
rspec-support (~> 3.11.0)
|
140
|
+
rspec-mocks (3.11.1)
|
141
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
142
|
+
rspec-support (~> 3.11.0)
|
143
|
+
rspec-support (3.11.0)
|
144
|
+
ruby2_keywords (0.0.5)
|
145
|
+
thor (1.2.1)
|
146
|
+
tzinfo (2.0.4)
|
147
|
+
concurrent-ruby (~> 1.0)
|
148
|
+
uber (0.1.0)
|
149
|
+
valkyrie (2.2.0)
|
150
|
+
activemodel
|
151
|
+
activesupport
|
152
|
+
disposable (~> 0.4.5)
|
153
|
+
draper
|
154
|
+
dry-struct
|
155
|
+
dry-types (~> 1.0)
|
156
|
+
faraday (< 1.0)
|
157
|
+
json
|
158
|
+
json-ld
|
159
|
+
railties
|
160
|
+
rdf (~> 3.0, >= 3.0.10)
|
161
|
+
rdf-vocab
|
162
|
+
reform (~> 2.2)
|
163
|
+
reform-rails
|
164
|
+
zeitwerk (2.6.0)
|
165
|
+
|
166
|
+
PLATFORMS
|
167
|
+
x86_64-linux
|
168
|
+
|
169
|
+
DEPENDENCIES
|
170
|
+
rspec
|
171
|
+
valkyrie (~> 2)
|
172
|
+
|
173
|
+
BUNDLED WITH
|
174
|
+
2.2.16
|
data/README.md
ADDED
data/hyrax-acl.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hyrax/acl/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.authors = ["Project Surfliner"]
|
8
|
+
spec.email = ["tomjohnson@ucsb.edu"]
|
9
|
+
spec.description = 'Access Control List models and support for Hyrax'
|
10
|
+
spec.summary = <<-SUMMARY
|
11
|
+
Hyrax Access Control List
|
12
|
+
SUMMARY
|
13
|
+
|
14
|
+
spec.homepage = "http://github.com/samvera-labs/hyrax-acl"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR).select { |f| File.dirname(f) !~ %r{\A"?spec\/?} }
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
18
|
+
spec.name = "hyrax-acl"
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
spec.version = Hyrax::Acl::VERSION
|
21
|
+
spec.license = 'Apache-2.0'
|
22
|
+
spec.metadata = { "rubygems_mfa_required" => "true" }
|
23
|
+
|
24
|
+
spec.required_ruby_version = '>= 2.7'
|
25
|
+
|
26
|
+
spec.add_dependency "valkyrie", "~> 2"
|
27
|
+
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hyrax
|
4
|
+
module Acl
|
5
|
+
##
|
6
|
+
# A list of permissions pertaining to a specific object.
|
7
|
+
#
|
8
|
+
# `AccessControl`s consist of a set of permissions and an `#access_to`
|
9
|
+
# reference to the object that set governs.
|
10
|
+
#
|
11
|
+
# @see Hyrax::AccessControlList for a low level DSL for managing
|
12
|
+
# `AccessControl` and `Permission` relationships for `Hyrax::Resource`
|
13
|
+
# @see Hyrax::PermissionManager for `read_groups`/`read_users` style setters
|
14
|
+
# and getters
|
15
|
+
# @see Hyrax::VisibilityWriter, Hyrax::VisibilityReader for
|
16
|
+
# "open"/"restricted" style visibility management
|
17
|
+
class AccessControl < Valkyrie::Resource
|
18
|
+
##
|
19
|
+
# @!attribute [rw] access_to
|
20
|
+
# Supports query for ACLs at the resource level. Permissions should be
|
21
|
+
# grouped under an AccessControl with a matching `#access_to` so they can
|
22
|
+
# be retrieved in batch.
|
23
|
+
#
|
24
|
+
# @return [Valkyrie::ID] the id of the Resource these permissions apply to
|
25
|
+
# @!attribute [rw] permissions
|
26
|
+
# @return [Enumerable<Hyrax::Acl::Permission>]
|
27
|
+
attribute :access_to, Valkyrie::Types::ID
|
28
|
+
attribute :permissions, Valkyrie::Types::Set.of(Hyrax::Acl::Permission)
|
29
|
+
|
30
|
+
##
|
31
|
+
# A finder/factory method for getting an appropriate ACL for a given
|
32
|
+
# resource.
|
33
|
+
#
|
34
|
+
# @param resource [Valkyrie::Resource]
|
35
|
+
# @param query_service [#find_inverse_references_by]
|
36
|
+
#
|
37
|
+
# @return [AccessControl]
|
38
|
+
# @raise [ArgumentError] if the resource is not persisted
|
39
|
+
def self.for(resource:, query_service:)
|
40
|
+
Hyrax::Acl::CustomQueries::FindAccessControl.new(query_service: query_service).find_access_control_for(resource: resource)
|
41
|
+
rescue Valkyrie::Persistence::ObjectNotFoundError
|
42
|
+
new(access_to: resource.id, permissions: [])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hyrax
|
4
|
+
module Acl
|
5
|
+
##
|
6
|
+
# A ChangeSet for Hyrax::Acl::AccessControl.
|
7
|
+
class AccessControlChangeSet < Valkyrie::ChangeSet
|
8
|
+
property :access_to, type: Valkyrie::Types::ID, default: nil
|
9
|
+
property :permissions, type: Valkyrie::Types::Set.of(Hyrax::Acl::Permission), default: nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hyrax
|
4
|
+
module Acl
|
5
|
+
##
|
6
|
+
# @api public
|
7
|
+
#
|
8
|
+
# ACLs for `Hyrax::Resource` models
|
9
|
+
#
|
10
|
+
# Allows managing `Hyrax::Permission` entries referring to a specific
|
11
|
+
# `Hyrax::Resource.
|
12
|
+
#
|
13
|
+
class AccessControlList
|
14
|
+
DISCOVER = :discover
|
15
|
+
EDIT = :edit
|
16
|
+
READ = :read
|
17
|
+
|
18
|
+
##
|
19
|
+
# @!attribute [rw] resource
|
20
|
+
# @return [Valkyrie::Resource]
|
21
|
+
# @!attribute [r] persister
|
22
|
+
# @return [#save]
|
23
|
+
# @!attribute [r] query_service
|
24
|
+
# @return [#find_inverse_references_by]
|
25
|
+
attr_reader :persister, :query_service
|
26
|
+
attr_accessor :resource
|
27
|
+
|
28
|
+
##
|
29
|
+
# @param resource [Valkyrie::Resource]
|
30
|
+
# @param persister [#save] defaults to the configured Hyrax persister
|
31
|
+
# @param query_service [#find_inverse_references_by] defaults to the
|
32
|
+
# configured Hyrax query service
|
33
|
+
def initialize(resource:, persister:, query_service:)
|
34
|
+
self.resource = resource
|
35
|
+
@persister = persister
|
36
|
+
@query_service = query_service
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# @api public
|
41
|
+
#
|
42
|
+
# @param permission [Hyrax::Permission]
|
43
|
+
#
|
44
|
+
# @return [Boolean]
|
45
|
+
def <<(permission)
|
46
|
+
permission.access_to = resource.id
|
47
|
+
|
48
|
+
change_set.permissions += [permission]
|
49
|
+
|
50
|
+
true
|
51
|
+
end
|
52
|
+
alias add <<
|
53
|
+
|
54
|
+
##
|
55
|
+
# @api public
|
56
|
+
#
|
57
|
+
# @param permission [Hyrax::Permission]
|
58
|
+
#
|
59
|
+
# @return [Boolean]
|
60
|
+
def delete(permission)
|
61
|
+
change_set.permissions -= [permission]
|
62
|
+
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# @api public
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# user = User.find('user_id')
|
71
|
+
#
|
72
|
+
# acl.grant(:read).to(user)
|
73
|
+
def grant(mode)
|
74
|
+
ModeGrant.new(self, mode)
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Discover grant
|
79
|
+
# @agent [Hyrax::Acl::Agent] agent
|
80
|
+
def has_discover?(agent:)
|
81
|
+
has_grant?(mode: DISCOVER, agent: agent)
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Read grant
|
86
|
+
# @agent [Hyrax::Acl::Agent] agent
|
87
|
+
def has_read?(agent:)
|
88
|
+
has_grant?(mode: READ, agent: agent)
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Edit grant
|
93
|
+
# @agent [Hyrax::Acl::Agent] agent
|
94
|
+
def has_edit?(agent:)
|
95
|
+
has_grant?(mode: EDIT, agent: agent)
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Edit grant
|
100
|
+
# @agent [Hyrax::Acl::Agent] agent
|
101
|
+
def has_grant?(mode:, agent:)
|
102
|
+
permissions.any? do |permission|
|
103
|
+
permission.mode == mode && permission.agent == agent.agent_key
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# @api public
|
109
|
+
#
|
110
|
+
# @return [Boolean]
|
111
|
+
def pending_changes?
|
112
|
+
change_set.changed?
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# @api public
|
117
|
+
#
|
118
|
+
# @return [Set<Hyrax::Permission>]
|
119
|
+
def permissions
|
120
|
+
Set.new(change_set.permissions)
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# @api public
|
125
|
+
#
|
126
|
+
# @example
|
127
|
+
# user = User.find('user_id')
|
128
|
+
#
|
129
|
+
# acl.revoke(:read).from(user)
|
130
|
+
def revoke(mode)
|
131
|
+
ModeRevoke.new(self, mode)
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# @api public
|
136
|
+
#
|
137
|
+
# Saves the ACL for the resource, by saving each permission policy
|
138
|
+
#
|
139
|
+
# @yield [acl] gives self to the block only if the save is successful
|
140
|
+
# @return [Boolean]
|
141
|
+
def save
|
142
|
+
return true unless pending_changes?
|
143
|
+
|
144
|
+
change_set.sync
|
145
|
+
persister.save(resource: change_set.resource)
|
146
|
+
yield self if block_given?
|
147
|
+
@change_set = nil
|
148
|
+
|
149
|
+
true
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
##
|
155
|
+
# @api private
|
156
|
+
def access_control_model
|
157
|
+
AccessControl.for(resource: resource, query_service: query_service)
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# @api private
|
162
|
+
def change_set
|
163
|
+
@change_set ||= AccessControlChangeSet.new(access_control_model)
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# @abstract
|
168
|
+
# @api private
|
169
|
+
class ModeEditor
|
170
|
+
def initialize(acl, mode)
|
171
|
+
@acl = acl
|
172
|
+
@mode = mode.to_sym
|
173
|
+
end
|
174
|
+
|
175
|
+
private
|
176
|
+
|
177
|
+
##
|
178
|
+
# Returns the identifier used by ACLs to identify agents.
|
179
|
+
#
|
180
|
+
# This defaults to the `:agent_key`, but if that method doesn’t exist,
|
181
|
+
# `:user_key` will be used as a fallback.
|
182
|
+
def id_for(agent:)
|
183
|
+
key = agent.try(:agent_key) || agent.user_key
|
184
|
+
key.to_s
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
##
|
189
|
+
# @api private
|
190
|
+
#
|
191
|
+
# A short-term memory object for the permission granting DSL. Use with
|
192
|
+
# method chaining, as in: `acl.grant(:edit).to(user)`.
|
193
|
+
class ModeGrant < ModeEditor
|
194
|
+
##
|
195
|
+
# @api public
|
196
|
+
# @return [Hyrax::AccessControlList]
|
197
|
+
def to(user_or_group)
|
198
|
+
agent_id = id_for(agent: user_or_group)
|
199
|
+
|
200
|
+
@acl << Hyrax::Acl::Permission.new(access_to: @acl.resource.id, agent: agent_id, mode: @mode)
|
201
|
+
@acl
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# @api private
|
207
|
+
#
|
208
|
+
# A short-term memory object for the permission revoking DSL. Use with
|
209
|
+
# method chaining, as in: `acl.revoke(:edit).from(user)`.
|
210
|
+
class ModeRevoke < ModeEditor
|
211
|
+
##
|
212
|
+
# @api public
|
213
|
+
# @return [Hyrax::AccessControlList]
|
214
|
+
def from(user_or_group)
|
215
|
+
permission_for_deletion = @acl.permissions.find do |p|
|
216
|
+
p.mode == @mode &&
|
217
|
+
p.agent.to_s == id_for(agent: user_or_group)
|
218
|
+
end
|
219
|
+
|
220
|
+
@acl.delete(permission_for_deletion) if permission_for_deletion
|
221
|
+
@acl
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hyrax
|
4
|
+
module Acl
|
5
|
+
class Agent
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(name)
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# @return [String] a local identifier in ACL
|
14
|
+
# data
|
15
|
+
def agent_key
|
16
|
+
name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hyrax
|
3
|
+
module Acl
|
4
|
+
module CustomQueries
|
5
|
+
# @example
|
6
|
+
# Hyrax.custom_queries.find_access_control_for(resource: resource)
|
7
|
+
class FindAccessControl
|
8
|
+
def self.queries
|
9
|
+
[:find_access_control_for]
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(query_service:)
|
13
|
+
@query_service = query_service
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :query_service
|
17
|
+
delegate :resource_factory, to: :query_service
|
18
|
+
|
19
|
+
def find_access_control_for(resource: )
|
20
|
+
query_service
|
21
|
+
.find_inverse_references_by(resource: resource, property: :access_to)
|
22
|
+
.find { |r| r.is_a?(Hyrax::Acl::AccessControl) } ||
|
23
|
+
raise(Valkyrie::Persistence::ObjectNotFoundError)
|
24
|
+
rescue ArgumentError # some adapters raise ArgumentError for missing resources
|
25
|
+
raise(Valkyrie::Persistence::ObjectNotFoundError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hyrax/acl/custom_queries/find_access_control'
|
4
|
+
|
5
|
+
module Hyrax
|
6
|
+
module Acl
|
7
|
+
##
|
8
|
+
# @see https://github.com/samvera/valkyrie/wiki/Queries#custom-queries
|
9
|
+
# @see https://github.com/samvera/hyrax/wiki/Hyrax-Valkyrie-Usage-Guide#custom-queriesy
|
10
|
+
module CustomQueries
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hyrax
|
3
|
+
module Acl
|
4
|
+
class Group < Agent
|
5
|
+
DEFAULT_NAME_PREFIX = 'group/'
|
6
|
+
|
7
|
+
def self.name_prefix
|
8
|
+
DEFAULT_NAME_PREFIX
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# @return [Hyrax::Group]
|
13
|
+
def self.from_agent_key(key)
|
14
|
+
new(key.delete_prefix(name_prefix))
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(name)
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# @return [String] a local identifier for this group; for use (e.g.) in ACL
|
23
|
+
# data
|
24
|
+
def agent_key
|
25
|
+
self.class.name_prefix + name
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# @return [Boolean]
|
30
|
+
def ==(other)
|
31
|
+
other.class == self.class && other.name == name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hyrax
|
4
|
+
module Acl
|
5
|
+
##
|
6
|
+
# Valkyrie native permissions (access policies) for Hyrax
|
7
|
+
#
|
8
|
+
# Permissions are persisted independently from `Hyrax::Resource`s (works,
|
9
|
+
# collections, file sets, etc...) since their scope is different. Access policies
|
10
|
+
# may be application-specific and tend to update more frequently than resource
|
11
|
+
# metadata. This approach also allows policies to be persisted using a
|
12
|
+
# different database or adapter than is used for curatorial objects.
|
13
|
+
class Permission < Valkyrie::Resource
|
14
|
+
include Dry::Equalizer(:access_to, :agent, :mode)
|
15
|
+
|
16
|
+
attribute :access_to, Valkyrie::Types::ID
|
17
|
+
attribute :agent, Valkyrie::Types::String
|
18
|
+
attribute :mode, Valkyrie::Types::Coercible::Symbol
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/hyrax/acl.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'valkyrie'
|
2
|
+
require 'hyrax/acl/agent'
|
3
|
+
require 'hyrax/acl/group'
|
4
|
+
require 'hyrax/acl/permission'
|
5
|
+
require 'hyrax/acl/access_control'
|
6
|
+
require 'hyrax/acl/custom_queries'
|
7
|
+
require 'hyrax/acl/access_control_change_set'
|
8
|
+
require 'hyrax/acl/access_control_list'
|
9
|
+
|
10
|
+
##
|
11
|
+
# Hyrax Access Control Lists
|
12
|
+
module Acl
|
13
|
+
end
|
data/lib/hyrax.rb
ADDED
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hyrax-acl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Project Surfliner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-07-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: valkyrie
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Access Control List models and support for Hyrax
|
42
|
+
email:
|
43
|
+
- tomjohnson@ucsb.edu
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".rspec"
|
49
|
+
- Gemfile
|
50
|
+
- Gemfile.lock
|
51
|
+
- README.md
|
52
|
+
- hyrax-acl.gemspec
|
53
|
+
- lib/hyrax.rb
|
54
|
+
- lib/hyrax/acl.rb
|
55
|
+
- lib/hyrax/acl/access_control.rb
|
56
|
+
- lib/hyrax/acl/access_control_change_set.rb
|
57
|
+
- lib/hyrax/acl/access_control_list.rb
|
58
|
+
- lib/hyrax/acl/agent.rb
|
59
|
+
- lib/hyrax/acl/custom_queries.rb
|
60
|
+
- lib/hyrax/acl/custom_queries/find_access_control.rb
|
61
|
+
- lib/hyrax/acl/group.rb
|
62
|
+
- lib/hyrax/acl/permission.rb
|
63
|
+
- lib/hyrax/acl/version.rb
|
64
|
+
homepage: http://github.com/samvera-labs/hyrax-acl
|
65
|
+
licenses:
|
66
|
+
- Apache-2.0
|
67
|
+
metadata:
|
68
|
+
rubygems_mfa_required: 'true'
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '2.7'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubygems_version: 3.1.4
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Hyrax Access Control List
|
88
|
+
test_files: []
|