dor-rights-auth 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/dor/rights_auth.rb +243 -0
  2. 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: