dor-rights-auth 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/dor/rights_auth.rb +243 -0
- metadata +153 -0
@@ -0,0 +1,243 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
#require 'helpers/cacheable'
|
3
|
+
|
4
|
+
module Dor
|
5
|
+
# The Individual Right
|
6
|
+
Rights = Struct.new(:value, :rule)
|
7
|
+
|
8
|
+
# Rights for an object or File
|
9
|
+
EntityRights = Struct.new(:world, :group, :agent)
|
10
|
+
# class EntityRights
|
11
|
+
# @world = #Rights
|
12
|
+
# @group {
|
13
|
+
# :stanford => #Rights
|
14
|
+
# }
|
15
|
+
# @agent {
|
16
|
+
# 'app1' => #Rights,
|
17
|
+
# 'app2' => #Rights
|
18
|
+
# }
|
19
|
+
# end
|
20
|
+
|
21
|
+
# class Dor::RightsAuth
|
22
|
+
# @object_level = # EntityRights
|
23
|
+
# @file {
|
24
|
+
# 'file1' => EntityRights,
|
25
|
+
# 'file2' => EntityRights
|
26
|
+
# }
|
27
|
+
# end
|
28
|
+
|
29
|
+
class RightsAuth
|
30
|
+
|
31
|
+
attr_accessor :obj_lvl, :file
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@file = {}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns true if the object is world readable AND has no rule attribute
|
38
|
+
# @return [Boolean]
|
39
|
+
def world_unrestricted?
|
40
|
+
@obj_lvl.world.value && @obj_lvl.world.rule.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method :public_unrestricted?, :world_unrestricted?
|
44
|
+
|
45
|
+
def readable?
|
46
|
+
public_unrestricted? || stanford_only_unrestricted? # TODO stanford_only or public with rule, figure out if this is still a legit method
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns true if the object is stanford-only readable AND has no rule attribute
|
50
|
+
# @return [Boolean]
|
51
|
+
def stanford_only_unrestricted?
|
52
|
+
@obj_lvl.group[:stanford].value && @obj_lvl.group[:stanford].rule.nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns true if the passed in agent (usually an application) is allowed access to the object without a rule
|
56
|
+
# @param [String] agent_name Name of the agent that wants to access this object
|
57
|
+
# @return [Boolean]
|
58
|
+
def agent_unrestricted?(agent_name)
|
59
|
+
return false unless @obj_lvl.agent.has_key? agent_name
|
60
|
+
@obj_lvl.agent[agent_name].value && @obj_lvl.agent[agent_name].rule.nil?
|
61
|
+
end
|
62
|
+
|
63
|
+
alias_method :allowed_read_agent?, :agent_unrestricted?
|
64
|
+
|
65
|
+
# Returns true if the file is stanford-only readable AND has no rule attribute
|
66
|
+
# If rights do not exist for this file, then object level rights are returned
|
67
|
+
# @see #stanford_only_unrestricted?
|
68
|
+
# @param [String] file_name Name of the file that is tested for stanford_only rights
|
69
|
+
# @return [Boolean]
|
70
|
+
def stanford_only_unrestricted_file?(file_name)
|
71
|
+
return stanford_only_unrestricted? if( @file[file_name].nil? || @file[file_name].group[:stanford].nil? )
|
72
|
+
|
73
|
+
@file[file_name].group[:stanford].value && @file[file_name].group[:stanford].rule.nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns true if the file is world readable AND has no rule attribute
|
77
|
+
# If world rights do not exist for this file, then object level rights are returned
|
78
|
+
# @see #world_unrestricted?
|
79
|
+
# @param [String] file_name Name of file that is tested for world rights
|
80
|
+
# @return [Boolean]
|
81
|
+
def world_unrestricted_file?(file_name)
|
82
|
+
return world_unrestricted? if( @file[file_name].nil? || @file[file_name].world.nil? )
|
83
|
+
|
84
|
+
@file[file_name].world.value && @file[file_name].world.rule.nil?
|
85
|
+
end
|
86
|
+
|
87
|
+
alias_method :public_unrestricted_file?, :world_unrestricted_file?
|
88
|
+
|
89
|
+
# Returns whether an object-level world node exists, and the value of its rule attribute
|
90
|
+
# @return [Array<(Boolean, String)>] First value: existance of node. Second Value: rule attribute, nil otherwise
|
91
|
+
# @example Using multiple variable assignment to read both array elements
|
92
|
+
# world_exists, world_rule = rights.world_rights
|
93
|
+
def world_rights
|
94
|
+
[@obj_lvl.world.value, @obj_lvl.world.rule]
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns whether and object-level group/stanford node exists, and the value of its rule attribute
|
98
|
+
# @return (see #world_rights)
|
99
|
+
# @example Using multiple variable assignment to read both array elements
|
100
|
+
# su_only_exists, su_only_rule = rights.stanford_only_rights
|
101
|
+
def stanford_only_rights
|
102
|
+
[@obj_lvl.group[:stanford].value, @obj_lvl.group[:stanford].rule]
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns whether an object-level agent node exists for the passed in agent, and the value of its rule attribute
|
106
|
+
# @param [String] agent_name name of the app or thing that is tested for access
|
107
|
+
# @return (see #world_rights)
|
108
|
+
# @example Using multiple variable assignment to read both array elements
|
109
|
+
# agent_exists, agent_rule = rights.agent_rights('someapp')
|
110
|
+
# @note should be called after doing a check for world_unrestricted?
|
111
|
+
def agent_rights(agent_name)
|
112
|
+
return [false, nil] if(@obj_lvl.agent[agent_name].nil?)
|
113
|
+
[@obj_lvl.agent[agent_name].value, @obj_lvl.agent[agent_name].rule]
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns whether a file-level world node exists, and the value of its rule attribute
|
117
|
+
# If a world node does not exist for this file, then object-level world rights are returned
|
118
|
+
# @see #world_rights
|
119
|
+
# @param [String] file_name name of the file
|
120
|
+
# @return (see #world_rights)
|
121
|
+
# @example Using multiple variable assignment to read both array elements
|
122
|
+
# world_exists, world_rule = rights.world_rights_for_file('somefile')
|
123
|
+
def world_rights_for_file(file_name)
|
124
|
+
return world_rights if( @file[file_name].nil? || @file[file_name].world.nil? )
|
125
|
+
|
126
|
+
[@file[file_name].world.value, @file[file_name].world.rule]
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns whether a file-level group/stanford node exists, and the value of its rule attribute
|
130
|
+
# If a group/stanford node does not exist for this file, then object-level group/stanford rights are returned
|
131
|
+
# @see #stanford_only_rights
|
132
|
+
# @param (see #world_rights_for_file)
|
133
|
+
# @return (see #world_rights)
|
134
|
+
# @example Using multiple variable assignment to read both array elements
|
135
|
+
# su_only_exists, su_only_rule = rights.stanford_only_rights_for_file('somefile')
|
136
|
+
def stanford_only_rights_for_file(file_name)
|
137
|
+
return stanford_only_rights if( @file[file_name].nil? || @file[file_name].group[:stanford].nil?)
|
138
|
+
|
139
|
+
[@file[file_name].group[:stanford].value, @file[file_name].group[:stanford].rule]
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns whether a file-level agent-node exists, and the value of its rule attribute
|
143
|
+
# If an agent-node does not exist for this file, then object-level agent rights are returned
|
144
|
+
# @param [String] file_name name of the file being tested
|
145
|
+
# @param [String] agent_name name of the agent being tested
|
146
|
+
# @return (see #world_rights)
|
147
|
+
# @example Using multiple variable assignment to read both array elements
|
148
|
+
# agent_exists, agent_rule = rights.agent_rights_for_file('filex', 'someapp')
|
149
|
+
def agent_rights_for_file(file_name, agent_name)
|
150
|
+
return agent_rights(agent_name) if( @file[file_name].nil?) # look at object level agent rights if the file-name is not stored
|
151
|
+
|
152
|
+
return [false, nil] if( @file[file_name].agent[agent_name].nil?) # file rules exist, but not for this agent
|
153
|
+
|
154
|
+
[@file[file_name].agent[agent_name].value, @file[file_name].agent[agent_name].rule]
|
155
|
+
end
|
156
|
+
|
157
|
+
# Fetch the rightsMetadata xml from the RightsMD service
|
158
|
+
# Parse the xml and create a Dor::RightsAuth object
|
159
|
+
# @param [String] xml rightsMetadata xml that will be parsed to build a RightsAuth object
|
160
|
+
# @return Dor::RightsAuth created after parsing rightsMetadata xml
|
161
|
+
def RightsAuth.parse(xml)
|
162
|
+
rights = Dor::RightsAuth.new
|
163
|
+
rights.obj_lvl = EntityRights.new
|
164
|
+
rights.obj_lvl.world = Rights.new
|
165
|
+
|
166
|
+
doc = Nokogiri::XML(xml)
|
167
|
+
if(doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/world"))
|
168
|
+
rights.obj_lvl.world.value = true
|
169
|
+
rule = doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/world/@rule")
|
170
|
+
rights.obj_lvl.world.rule = rule.value if(rule)
|
171
|
+
else
|
172
|
+
rights.obj_lvl.world.value = false
|
173
|
+
end
|
174
|
+
|
175
|
+
# TODO do we still need this??????
|
176
|
+
# if(doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]"))
|
177
|
+
# rights[:readable] = true
|
178
|
+
# else
|
179
|
+
# rights[:readable] = false
|
180
|
+
# end
|
181
|
+
|
182
|
+
rights.obj_lvl.group = { :stanford => Rights.new }
|
183
|
+
|
184
|
+
if(doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/group[text() = 'stanford']"))
|
185
|
+
rights.obj_lvl.group[:stanford].value = true
|
186
|
+
rule = doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/group[text() = 'stanford']/@rule")
|
187
|
+
rights.obj_lvl.group[:stanford].rule = rule.value if(rule)
|
188
|
+
else
|
189
|
+
rights.obj_lvl.group[:stanford].value = false
|
190
|
+
end
|
191
|
+
|
192
|
+
rights.obj_lvl.agent = {}
|
193
|
+
doc.xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/agent").each do |node|
|
194
|
+
r = Rights.new
|
195
|
+
r.value = true
|
196
|
+
r.rule = node['rule']
|
197
|
+
rights.obj_lvl.agent[node.content] = r
|
198
|
+
end
|
199
|
+
|
200
|
+
access_with_files = doc.xpath( "//rightsMetadata/access[@type='read' and file]")
|
201
|
+
access_with_files.each do |access_node|
|
202
|
+
stanford_access = Rights.new
|
203
|
+
world_access = Rights.new
|
204
|
+
if access_node.at_xpath("machine/group[text()='stanford']")
|
205
|
+
stanford_access.value = true
|
206
|
+
rule = access_node.at_xpath("machine/group[text()='stanford']/@rule")
|
207
|
+
stanford_access.rule = rule.value if (rule)
|
208
|
+
else
|
209
|
+
stanford_access.value = false
|
210
|
+
end
|
211
|
+
|
212
|
+
if access_node.at_xpath("machine/world")
|
213
|
+
world_access.value = true
|
214
|
+
rule = access_node.at_xpath("machine/world/@rule")
|
215
|
+
world_access.rule = rule.value if (rule)
|
216
|
+
else
|
217
|
+
world_access.value = false
|
218
|
+
end
|
219
|
+
|
220
|
+
file_agents = {}
|
221
|
+
access_node.xpath("machine/agent").each do |node|
|
222
|
+
r = Rights.new
|
223
|
+
r.value = true
|
224
|
+
r.rule = node['rule']
|
225
|
+
file_agents[node.content] = r
|
226
|
+
end
|
227
|
+
|
228
|
+
access_node.xpath('file').each do |f|
|
229
|
+
file_rights = EntityRights.new
|
230
|
+
file_rights.world = world_access
|
231
|
+
file_rights.group = { :stanford => stanford_access }
|
232
|
+
file_rights.agent = file_agents
|
233
|
+
|
234
|
+
rights.file[f.content] = file_rights
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
rights
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dor-rights-auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 63
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 0.8.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Willy Mene
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-06-12 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
requirement: *id001
|
32
|
+
name: nokogiri
|
33
|
+
type: :runtime
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
hash: 3
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
version: "0"
|
45
|
+
requirement: *id002
|
46
|
+
name: rest-client
|
47
|
+
type: :runtime
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - <
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 2
|
58
|
+
- 0
|
59
|
+
version: "2.0"
|
60
|
+
requirement: *id003
|
61
|
+
name: rspec
|
62
|
+
type: :development
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
requirement: *id004
|
75
|
+
name: ruby-debug
|
76
|
+
type: :development
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
requirement: *id005
|
89
|
+
name: yard
|
90
|
+
type: :development
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
hash: 3
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
version: "0"
|
102
|
+
requirement: *id006
|
103
|
+
name: lyberteam-gems-devel
|
104
|
+
type: :development
|
105
|
+
description: Parses rightsMetadata xml into a useable object
|
106
|
+
email:
|
107
|
+
- wmene@stanford.edu
|
108
|
+
executables: []
|
109
|
+
|
110
|
+
extensions: []
|
111
|
+
|
112
|
+
extra_rdoc_files: []
|
113
|
+
|
114
|
+
files:
|
115
|
+
- lib/dor/rights_auth.rb
|
116
|
+
homepage:
|
117
|
+
licenses: []
|
118
|
+
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
hash: 3
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
version: "0"
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
hash: 23
|
139
|
+
segments:
|
140
|
+
- 1
|
141
|
+
- 3
|
142
|
+
- 6
|
143
|
+
version: 1.3.6
|
144
|
+
requirements: []
|
145
|
+
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 1.8.10
|
148
|
+
signing_key:
|
149
|
+
specification_version: 3
|
150
|
+
summary: Parses rightsMetadata xml into a useable object
|
151
|
+
test_files: []
|
152
|
+
|
153
|
+
has_rdoc:
|