dor-rights-auth 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/dor/rights_auth.rb +169 -39
- data/lib/dor/xsd/druid.xsd +9 -0
- data/lib/dor/xsd/druidlist.xsd +12 -0
- data/lib/dor/xsd/humanlist.xsd +7 -0
- data/lib/dor/xsd/illustration.xml +39 -0
- data/lib/dor/xsd/rights.xsd +23 -0
- data/lib/dor/xsd/rights_basics.xsd +64 -0
- data/lib/dor/xsd/rights_types.xsd +98 -0
- metadata +72 -102
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c895adda420f96705ed01622032fbf43c1b733e4
|
4
|
+
data.tar.gz: a8e3f2516e6db25ad27e71c10ee222d5c1092c6a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: beab4b017e6e1b83766572b2efe83d7ab006ca61bff8f70dd78e1921f5bab1744bc1ec7ec01e535f05d1ec57c1b42d6f5c7e76954853161192ece8ecc41140a3
|
7
|
+
data.tar.gz: 84ec859efe66b495bfd836953cd6ada723544c3c7be2a924150fb812ea7cf573aa9888546ec1a4c761f1df67099b766200309f1321cc07643d7faf3434b72e49
|
data/lib/dor/rights_auth.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'nokogiri'
|
2
2
|
require 'time'
|
3
3
|
|
4
|
+
# We handle the ugly stuff, so you don't have to.
|
5
|
+
|
4
6
|
module Dor
|
5
|
-
|
6
|
-
# The Individual Right
|
7
|
+
|
8
|
+
# The Individual Right
|
7
9
|
Rights = Struct.new(:value, :rule)
|
8
10
|
|
9
11
|
# Rights for an object or File
|
@@ -28,15 +30,18 @@ module Dor
|
|
28
30
|
# end
|
29
31
|
|
30
32
|
class RightsAuth
|
31
|
-
|
33
|
+
|
32
34
|
CONTAINS_STANFORD_XPATH = "contains(translate(text(), 'STANFORD', 'stanford'), 'stanford')"
|
33
35
|
|
34
|
-
attr_accessor :obj_lvl, :file, :embargoed
|
36
|
+
attr_accessor :obj_lvl, :file, :embargoed, :index_elements
|
37
|
+
|
38
|
+
# note: index_elements is only valid for the xml as parsed, not after subsequent manipulation
|
35
39
|
|
36
40
|
def initialize
|
37
41
|
@file = {}
|
42
|
+
@index_elements = {}
|
38
43
|
end
|
39
|
-
|
44
|
+
|
40
45
|
# Returns true if the object is under embargo.
|
41
46
|
# @return [Boolean]
|
42
47
|
def embargoed?
|
@@ -68,7 +73,7 @@ module Dor
|
|
68
73
|
return false unless @obj_lvl.agent.has_key? agent_name
|
69
74
|
@obj_lvl.agent[agent_name].value && @obj_lvl.agent[agent_name].rule.nil?
|
70
75
|
end
|
71
|
-
|
76
|
+
|
72
77
|
alias_method :allowed_read_agent?, :agent_unrestricted?
|
73
78
|
|
74
79
|
# Returns true if the file is stanford-only readable AND has no rule attribute
|
@@ -78,23 +83,23 @@ module Dor
|
|
78
83
|
# @return [Boolean]
|
79
84
|
def stanford_only_unrestricted_file?(file_name)
|
80
85
|
return stanford_only_unrestricted? if( @file[file_name].nil? || @file[file_name].group[:stanford].nil? )
|
81
|
-
|
86
|
+
|
82
87
|
@file[file_name].group[:stanford].value && @file[file_name].group[:stanford].rule.nil?
|
83
88
|
end
|
84
89
|
|
85
90
|
# Returns true if the file is world readable AND has no rule attribute
|
86
|
-
# If world rights do not exist for this file, then object level rights are returned
|
91
|
+
# If world rights do not exist for this file, then object level rights are returned
|
87
92
|
# @see #world_unrestricted?
|
88
93
|
# @param [String] file_name Name of file that is tested for world rights
|
89
94
|
# @return [Boolean]
|
90
95
|
def world_unrestricted_file?(file_name)
|
91
96
|
return world_unrestricted? if( @file[file_name].nil? || @file[file_name].world.nil? )
|
92
|
-
|
97
|
+
|
93
98
|
@file[file_name].world.value && @file[file_name].world.rule.nil?
|
94
99
|
end
|
95
100
|
|
96
101
|
alias_method :public_unrestricted_file?, :world_unrestricted_file?
|
97
|
-
|
102
|
+
|
98
103
|
# Returns whether an object-level world node exists, and the value of its rule attribute
|
99
104
|
# @return [Array<(Boolean, String)>] First value: existance of node. Second Value: rule attribute, nil otherwise
|
100
105
|
# @example Using multiple variable assignment to read both array elements
|
@@ -110,7 +115,7 @@ module Dor
|
|
110
115
|
def stanford_only_rights
|
111
116
|
[@obj_lvl.group[:stanford].value, @obj_lvl.group[:stanford].rule]
|
112
117
|
end
|
113
|
-
|
118
|
+
|
114
119
|
# Returns whether an object-level agent node exists for the passed in agent, and the value of its rule attribute
|
115
120
|
# @param [String] agent_name name of the app or thing that is tested for access
|
116
121
|
# @return (see #world_rights)
|
@@ -121,7 +126,7 @@ module Dor
|
|
121
126
|
return [false, nil] if(@obj_lvl.agent[agent_name].nil?)
|
122
127
|
[@obj_lvl.agent[agent_name].value, @obj_lvl.agent[agent_name].rule]
|
123
128
|
end
|
124
|
-
|
129
|
+
|
125
130
|
# Returns whether a file-level world node exists, and the value of its rule attribute
|
126
131
|
# If a world node does not exist for this file, then object-level world rights are returned
|
127
132
|
# @see #world_rights
|
@@ -131,10 +136,10 @@ module Dor
|
|
131
136
|
# world_exists, world_rule = rights.world_rights_for_file('somefile')
|
132
137
|
def world_rights_for_file(file_name)
|
133
138
|
return world_rights if( @file[file_name].nil? || @file[file_name].world.nil? )
|
134
|
-
|
139
|
+
|
135
140
|
[@file[file_name].world.value, @file[file_name].world.rule]
|
136
141
|
end
|
137
|
-
|
142
|
+
|
138
143
|
# Returns whether a file-level group/stanford node exists, and the value of its rule attribute
|
139
144
|
# If a group/stanford node does not exist for this file, then object-level group/stanford rights are returned
|
140
145
|
# @see #stanford_only_rights
|
@@ -144,10 +149,10 @@ module Dor
|
|
144
149
|
# su_only_exists, su_only_rule = rights.stanford_only_rights_for_file('somefile')
|
145
150
|
def stanford_only_rights_for_file(file_name)
|
146
151
|
return stanford_only_rights if( @file[file_name].nil? || @file[file_name].group[:stanford].nil?)
|
147
|
-
|
152
|
+
|
148
153
|
[@file[file_name].group[:stanford].value, @file[file_name].group[:stanford].rule]
|
149
154
|
end
|
150
|
-
|
155
|
+
|
151
156
|
# Returns whether a file-level agent-node exists, and the value of its rule attribute
|
152
157
|
# If an agent-node does not exist for this file, then object-level agent rights are returned
|
153
158
|
# @param [String] file_name name of the file being tested
|
@@ -157,38 +162,164 @@ module Dor
|
|
157
162
|
# agent_exists, agent_rule = rights.agent_rights_for_file('filex', 'someapp')
|
158
163
|
def agent_rights_for_file(file_name, agent_name)
|
159
164
|
return agent_rights(agent_name) if( @file[file_name].nil?) # look at object level agent rights if the file-name is not stored
|
160
|
-
|
165
|
+
|
161
166
|
return [false, nil] if( @file[file_name].agent[agent_name].nil?) # file rules exist, but not for this agent
|
162
|
-
|
167
|
+
|
163
168
|
[@file[file_name].agent[agent_name].value, @file[file_name].agent[agent_name].rule]
|
164
169
|
end
|
165
170
|
|
171
|
+
# Check formedness of rightsMetadata -- to be replaced with XSD once formalized, one fine day
|
172
|
+
# @param [Nokogiri::XML] the rightsMetadata document
|
173
|
+
# @return [Array] list of things that are wrong with it
|
174
|
+
def RightsAuth.validate_lite(doc)
|
175
|
+
if (doc.nil? || doc.at_xpath("//rightsMetadata").nil?)
|
176
|
+
return ["no_rightsMetadata"]
|
177
|
+
end
|
178
|
+
errors = []
|
179
|
+
maindiscover = doc.at_xpath("//rightsMetadata/access[@type='discover' and not(file)]")
|
180
|
+
mainread = doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]")
|
181
|
+
|
182
|
+
if maindiscover.nil?
|
183
|
+
errors.push "no_discover_access", "no_discover_machine"
|
184
|
+
elsif maindiscover.at_xpath("./machine").nil?
|
185
|
+
errors.push "no_discover_machine"
|
186
|
+
elsif (maindiscover.at_xpath("./machine/world[not(@rule)]").nil? && maindiscover.at_xpath("./machine/none").nil?)
|
187
|
+
errors.push "discover_machine_unrecognized"
|
188
|
+
end
|
189
|
+
if mainread.nil?
|
190
|
+
errors.push "no_read_access", "no_read_machine"
|
191
|
+
elsif mainread.at_xpath("./machine").nil?
|
192
|
+
errors.push "no_read_machine"
|
193
|
+
else
|
194
|
+
## TODO: deeper read validation?
|
195
|
+
end
|
196
|
+
|
197
|
+
errors
|
198
|
+
end
|
199
|
+
|
200
|
+
# Assemble various characterizing terms for index from XML
|
201
|
+
# @param [Nokogiri::XML] the rightsMetadata document
|
202
|
+
# @return [Array] Strings of interest to the Solr index
|
203
|
+
def RightsAuth.extract_index_terms(doc)
|
204
|
+
terms = []
|
205
|
+
machine = doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine")
|
206
|
+
terms.push "none_discover" if doc.at_xpath("//rightsMetadata/access[@type='discover']/machine/none")
|
207
|
+
terms.push "world_discover" if doc.at_xpath("//rightsMetadata/access[@type='discover']/machine/world[not(@rule)]")
|
208
|
+
return terms if machine.nil?
|
209
|
+
|
210
|
+
terms.push "has_group_rights" if machine.at_xpath("./group")
|
211
|
+
terms.push "has_rule" if machine.at_xpath(".//@rule")
|
212
|
+
|
213
|
+
if (machine.at_xpath("./group[not(@rule) and #{CONTAINS_STANFORD_XPATH}]"))
|
214
|
+
terms.push "group|stanford"
|
215
|
+
elsif (machine.at_xpath("./group[@rule and #{CONTAINS_STANFORD_XPATH}]"))
|
216
|
+
terms.push "group|stanford_with_rule"
|
217
|
+
elsif (machine.at_xpath("./group"))
|
218
|
+
terms.push "group|#{machine.at_xpath("./group").value.downcase}"
|
219
|
+
end
|
220
|
+
|
221
|
+
if (machine.at_xpath("./none"))
|
222
|
+
terms.push "none_read"
|
223
|
+
elsif (machine.at_xpath("./world[not(@rule)]"))
|
224
|
+
terms.push "world_read"
|
225
|
+
elsif (machine.at_xpath("./world/@rule"))
|
226
|
+
terms.push "world|#{machine.at_xpath("./world/@rule").value.downcase}"
|
227
|
+
end
|
228
|
+
|
229
|
+
# now some statistical generation
|
230
|
+
names = machine.element_children.collect { |node| node.name }
|
231
|
+
kidcount = names.each_with_object(Hash.new(0)){ |word,counts| counts[word] += 1 }
|
232
|
+
countphrase = kidcount.sort.collect{|k,v| "#{k}#{v}"}.join("|")
|
233
|
+
terms.push "profile:" + countphrase unless countphrase.empty?
|
234
|
+
|
235
|
+
filemachines = doc.xpath("//rightsMetadata/access[@type='read' and file]/machine")
|
236
|
+
unless filemachines.empty?
|
237
|
+
terms.push "has_file_rights", "file_rights_count|#{filemachines.count}"
|
238
|
+
counts = Hash.new(0)
|
239
|
+
filemachines.each { |filemachine|
|
240
|
+
filemachine.element_children.each { |node|
|
241
|
+
counts[node.name] += 1
|
242
|
+
}
|
243
|
+
}
|
244
|
+
counts.each { |k,v|
|
245
|
+
terms.push "file_has_#{k}", "file_rights_for_#{k}|#{v}"
|
246
|
+
}
|
247
|
+
end
|
248
|
+
|
249
|
+
terms
|
250
|
+
end
|
251
|
+
|
252
|
+
# Give the index what it needs
|
253
|
+
# @param [Nokogiri::XML] the rightsMetadata document
|
254
|
+
# @return [Hash] Strings of interest to the Solr index, including:
|
255
|
+
# {
|
256
|
+
# :primary => '...', # string of foremost rights category, if determinable
|
257
|
+
# :errors => [...], # known error cases
|
258
|
+
# :terms => [...] # array of non-error characterizations and stats strings
|
259
|
+
# }
|
260
|
+
def RightsAuth.extract_access_rights(doc)
|
261
|
+
errors = validate_lite(doc)
|
262
|
+
stuff = {
|
263
|
+
:primary => nil,
|
264
|
+
:errors => errors,
|
265
|
+
:terms => []
|
266
|
+
}
|
267
|
+
|
268
|
+
if (errors.include? "no_rightsMetadata")
|
269
|
+
stuff[:primary] = 'dark'
|
270
|
+
return stuff # short circuit if no metadata -- no point going on
|
271
|
+
end
|
272
|
+
|
273
|
+
stuff[:terms] = extract_index_terms(doc)
|
274
|
+
|
275
|
+
if (stuff[:terms].include?("none_discover"))
|
276
|
+
stuff[:primary] = 'dark'
|
277
|
+
elsif (errors.include?("no_discover_access") || errors.include?("no_discover_machine"))
|
278
|
+
stuff[:primary] = 'dark'
|
279
|
+
elsif (errors.include?("no_read_machine") || stuff[:terms].include?("none_read"))
|
280
|
+
stuff[:primary] = 'citation'
|
281
|
+
elsif (stuff[:terms].include? "world_read")
|
282
|
+
stuff[:primary] = 'world'
|
283
|
+
elsif (stuff[:terms].include? "group|stanford")
|
284
|
+
stuff[:primary] = 'stanford'
|
285
|
+
elsif (stuff[:terms].include? "has_rule")
|
286
|
+
stuff[:primary] = 'complicated'
|
287
|
+
end
|
288
|
+
stuff
|
289
|
+
end
|
290
|
+
|
291
|
+
|
166
292
|
# Create a Dor::RightsAuth object from xml
|
167
|
-
# @param [String] xml rightsMetadata xml that will be parsed to build a RightsAuth object
|
168
|
-
# @
|
169
|
-
|
293
|
+
# @param [String|Nokogiri::XML::Document] xml rightsMetadata xml that will be parsed to build a RightsAuth object
|
294
|
+
# @param [Boolean] forindex, flag for requesting index_elements be parsed
|
295
|
+
# @return [Dor::RightsAuth] object created after parsing rightsMetadata xml
|
296
|
+
def RightsAuth.parse(xml, forindex=false)
|
170
297
|
rights = Dor::RightsAuth.new
|
171
298
|
rights.obj_lvl = EntityRights.new
|
172
299
|
rights.obj_lvl.world = Rights.new
|
173
|
-
|
174
|
-
doc = Nokogiri::XML(xml)
|
300
|
+
|
301
|
+
doc = xml.is_a?(Nokogiri::XML::Document) ? xml.clone : Nokogiri::XML(xml)
|
175
302
|
if(doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/world"))
|
176
303
|
rights.obj_lvl.world.value = true
|
177
304
|
rule = doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/world/@rule")
|
178
|
-
rights.obj_lvl.world.rule = rule.value if(rule)
|
305
|
+
rights.obj_lvl.world.rule = rule.value if(rule)
|
179
306
|
else
|
180
|
-
|
307
|
+
rights.obj_lvl.world.value = false
|
181
308
|
end
|
182
309
|
|
183
|
-
# TODO do we still need this??????
|
310
|
+
# TODO do we still need this??????
|
184
311
|
# if(doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]"))
|
185
312
|
# rights[:readable] = true
|
186
313
|
# else
|
187
314
|
# rights[:readable] = false
|
188
315
|
# end
|
189
|
-
|
316
|
+
|
190
317
|
rights.obj_lvl.group = { :stanford => Rights.new }
|
191
|
-
|
318
|
+
|
319
|
+
if (forindex)
|
320
|
+
rights.index_elements = extract_access_rights(doc)
|
321
|
+
end
|
322
|
+
|
192
323
|
if(doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/group[#{CONTAINS_STANFORD_XPATH}]"))
|
193
324
|
rights.obj_lvl.group[:stanford].value = true
|
194
325
|
rule = doc.at_xpath("//rightsMetadata/access[@type='read' and not(file)]/machine/group[#{CONTAINS_STANFORD_XPATH}]/@rule")
|
@@ -204,7 +335,7 @@ module Dor
|
|
204
335
|
r.rule = node['rule']
|
205
336
|
rights.obj_lvl.agent[node.content] = r
|
206
337
|
end
|
207
|
-
|
338
|
+
|
208
339
|
# Initialze embargo_status to false
|
209
340
|
rights.embargoed = false
|
210
341
|
embargo_node = doc.at_xpath("//rightsMetadata/access[@type='read']/machine/embargoReleaseDate")
|
@@ -212,11 +343,11 @@ module Dor
|
|
212
343
|
embargo_dt = Time.parse(embargo_node.content)
|
213
344
|
rights.embargoed = true if(embargo_dt > Time.now)
|
214
345
|
end
|
215
|
-
|
216
|
-
access_with_files = doc.xpath(
|
346
|
+
|
347
|
+
access_with_files = doc.xpath("//rightsMetadata/access[@type='read' and file]")
|
217
348
|
access_with_files.each do |access_node|
|
218
|
-
stanford_access = Rights.new
|
219
|
-
world_access
|
349
|
+
stanford_access = Rights.new
|
350
|
+
world_access = Rights.new
|
220
351
|
if access_node.at_xpath("machine/group[#{CONTAINS_STANFORD_XPATH}]")
|
221
352
|
stanford_access.value = true
|
222
353
|
rule = access_node.at_xpath("machine/group[#{CONTAINS_STANFORD_XPATH}]/@rule")
|
@@ -224,7 +355,7 @@ module Dor
|
|
224
355
|
else
|
225
356
|
stanford_access.value = false
|
226
357
|
end
|
227
|
-
|
358
|
+
|
228
359
|
if access_node.at_xpath("machine/world")
|
229
360
|
world_access.value = true
|
230
361
|
rule = access_node.at_xpath("machine/world/@rule")
|
@@ -232,7 +363,7 @@ module Dor
|
|
232
363
|
else
|
233
364
|
world_access.value = false
|
234
365
|
end
|
235
|
-
|
366
|
+
|
236
367
|
file_agents = {}
|
237
368
|
access_node.xpath("machine/agent").each do |node|
|
238
369
|
r = Rights.new
|
@@ -240,20 +371,19 @@ module Dor
|
|
240
371
|
r.rule = node['rule']
|
241
372
|
file_agents[node.content] = r
|
242
373
|
end
|
243
|
-
|
374
|
+
|
244
375
|
access_node.xpath('file').each do |f|
|
245
376
|
file_rights = EntityRights.new
|
246
377
|
file_rights.world = world_access
|
247
378
|
file_rights.group = { :stanford => stanford_access }
|
248
379
|
file_rights.agent = file_agents
|
249
|
-
|
380
|
+
|
250
381
|
rights.file[f.content] = file_rights
|
251
382
|
end
|
252
383
|
end
|
253
384
|
|
254
385
|
rights
|
255
386
|
end
|
256
|
-
|
387
|
+
|
257
388
|
end
|
258
389
|
end
|
259
|
-
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
3
|
+
<xs:simpleType name="druidstring">
|
4
|
+
<xs:restriction base="xs:string">
|
5
|
+
<xs:pattern value="[a-zA-Z]{2}[0-9]{3}[a-zA-Z]{2}[0-9]{4}"/>
|
6
|
+
<xs:whiteSpace value="collapse"/>
|
7
|
+
</xs:restriction>
|
8
|
+
</xs:simpleType>
|
9
|
+
</xs:schema>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<xs:schema
|
3
|
+
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dor="http://sul.stanford.edu">
|
4
|
+
<xs:include schemaLocation="druid.xsd"/>
|
5
|
+
<xs:element name="druidlist">
|
6
|
+
<xs:complexType>
|
7
|
+
<xs:sequence>
|
8
|
+
<xs:element name="druid" type="druidstring" minOccurs="0" maxOccurs="unbounded"/>
|
9
|
+
</xs:sequence>
|
10
|
+
</xs:complexType>
|
11
|
+
</xs:element>
|
12
|
+
</xs:schema>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<rightsMetadata objectId="druid">
|
2
|
+
<copyright>
|
3
|
+
<human type="copyright">(c) 2009 by Jasper Wilcox. All rights reserved.</human>
|
4
|
+
</copyright>
|
5
|
+
<access type="discover"> <!-- This covers core metadata -- identity, descriptive, content and rights -->
|
6
|
+
<machine>
|
7
|
+
<world/>
|
8
|
+
</machine>
|
9
|
+
</access>
|
10
|
+
<access type="read"> <!-- applies to file contents of an object, e.g., viewing an image online or downloading a file -->
|
11
|
+
<human>This document is available only to the Stanford faculty, staff and student community</human>
|
12
|
+
<machine>
|
13
|
+
<world/> <!-- either all (world) or nothing (none) would stand alone (apart from embargo date) -->
|
14
|
+
<none/> <!-- else access would be some combination of the following -->
|
15
|
+
<policy>druid:hx551yt4502</policy>
|
16
|
+
<agent>application_id</agent>
|
17
|
+
<person type="sunetid">user_id</person>
|
18
|
+
<group>stanford</group> <!-- special form for interpretation as the stanford:stanford privgroup -->
|
19
|
+
<group type="suWorkgroup">stanford:faculty</group>
|
20
|
+
<group type="suWorkgroup">stanford:student</group>
|
21
|
+
<embargoReleaseDate>2011-03-01</embargoReleaseDate> <!-- informational for PURL use; set via embargoMetadata -->
|
22
|
+
</machine>
|
23
|
+
</access>
|
24
|
+
<access type="read"> <!-- alternate common read form -->
|
25
|
+
<machine>
|
26
|
+
<group>stanford</group>
|
27
|
+
<world rule="no-download"/>
|
28
|
+
</machine>
|
29
|
+
</access>
|
30
|
+
<access type="read"> <!-- file-specific rules -->
|
31
|
+
<file id="restricted.doc"/>
|
32
|
+
<group>stanford</group>
|
33
|
+
</access>
|
34
|
+
<use>
|
35
|
+
<human type="useAndReproduction">You may re-distribute this object, unaltered, with attribution to the author.</human>
|
36
|
+
<human type="creativeCommons">CC Attribution Non-Commercial license</human>
|
37
|
+
<machine type="creativeCommons">by-nc</machine>
|
38
|
+
</use>
|
39
|
+
</rightsMetadata>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
3
|
+
<xs:include schemaLocation="rights_types.xsd"/>
|
4
|
+
|
5
|
+
<xs:element name="rightsMetadata">
|
6
|
+
<xs:complexType>
|
7
|
+
<xs:sequence>
|
8
|
+
<xs:choice minOccurs="2" maxOccurs="unbounded">
|
9
|
+
<!-- without forced order, we cannot guarantee required elements without fully enumerating 120 combinations!-->
|
10
|
+
<xs:element name="access" type="discovertype"/>
|
11
|
+
<xs:element name="access" type="readtype"/>
|
12
|
+
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
13
|
+
<xs:element name="access" type="readwithfile"/>
|
14
|
+
<xs:element name="copyright" type="copyrightusetype"/>
|
15
|
+
<xs:element name="use" type="copyrightusetype"/>
|
16
|
+
</xs:choice>
|
17
|
+
</xs:choice>
|
18
|
+
</xs:sequence>
|
19
|
+
<xs:attribute name="objectId" type="xs:string" use="required"/>
|
20
|
+
</xs:complexType>
|
21
|
+
</xs:element>
|
22
|
+
|
23
|
+
</xs:schema>
|
@@ -0,0 +1,64 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
3
|
+
|
4
|
+
<xs:simpleType name="trueemptytype">
|
5
|
+
<xs:restriction base="xs:string">
|
6
|
+
<xs:length value="0"/>
|
7
|
+
</xs:restriction>
|
8
|
+
</xs:simpleType>
|
9
|
+
<xs:simpleType name="accesstypeattribute">
|
10
|
+
<xs:restriction base="xs:string">
|
11
|
+
<xs:enumeration value="read" />
|
12
|
+
<xs:enumeration value="discover" />
|
13
|
+
</xs:restriction>
|
14
|
+
</xs:simpleType>
|
15
|
+
<xs:simpleType name="accesstypeattributeread">
|
16
|
+
<xs:restriction base="xs:string">
|
17
|
+
<xs:enumeration value="read" />
|
18
|
+
</xs:restriction>
|
19
|
+
</xs:simpleType>
|
20
|
+
<xs:simpleType name="accesstypeattributediscover">
|
21
|
+
<xs:restriction base="xs:string">
|
22
|
+
<xs:enumeration value="discover" />
|
23
|
+
</xs:restriction>
|
24
|
+
</xs:simpleType>
|
25
|
+
<xs:simpleType name="collapsedstring">
|
26
|
+
<xs:restriction base="xs:string">
|
27
|
+
<xs:whiteSpace value="collapse"/>
|
28
|
+
</xs:restriction>
|
29
|
+
</xs:simpleType>
|
30
|
+
<xs:complexType name="ruleoptionaltype">
|
31
|
+
<xs:attribute name="rule" type="xs:string"/>
|
32
|
+
</xs:complexType>
|
33
|
+
<xs:complexType name="rulerequiredtype">
|
34
|
+
<xs:attribute name="rule" type="xs:string" use="required"/>
|
35
|
+
</xs:complexType>
|
36
|
+
<xs:complexType name="typeoptionaltype">
|
37
|
+
<xs:attribute name="type" type="xs:string"/>
|
38
|
+
</xs:complexType>
|
39
|
+
<xs:complexType name="typerequiredtype">
|
40
|
+
<xs:attribute name="type" type="xs:string" use="required"/>
|
41
|
+
</xs:complexType>
|
42
|
+
<xs:complexType name="rulerequiredtypeoptional">
|
43
|
+
<xs:complexContent>
|
44
|
+
<xs:extension base="rulerequiredtype">
|
45
|
+
<xs:attribute name="type" type="xs:string"/>
|
46
|
+
</xs:extension>
|
47
|
+
</xs:complexContent>
|
48
|
+
</xs:complexType>
|
49
|
+
<xs:complexType name="collapsedstringoptionaltype">
|
50
|
+
<xs:simpleContent>
|
51
|
+
<xs:extension base="collapsedstring">
|
52
|
+
<xs:attribute name="type" type="xs:string"/>
|
53
|
+
</xs:extension>
|
54
|
+
</xs:simpleContent>
|
55
|
+
</xs:complexType>
|
56
|
+
<xs:complexType name="collapsedstringrequiredtype">
|
57
|
+
<xs:simpleContent>
|
58
|
+
<xs:extension base="collapsedstring">
|
59
|
+
<xs:attribute name="type" type="xs:string" use="required"/>
|
60
|
+
</xs:extension>
|
61
|
+
</xs:simpleContent>
|
62
|
+
</xs:complexType>
|
63
|
+
|
64
|
+
</xs:schema>
|
@@ -0,0 +1,98 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
3
|
+
<xs:include schemaLocation="rights_basics.xsd"/>
|
4
|
+
|
5
|
+
<xs:complexType name="copyrightusetype">
|
6
|
+
<!--
|
7
|
+
TODO: consider get rid of human elements. DESTROY ALL HUMANS!
|
8
|
+
TODO: use full URIs to designate rights values.
|
9
|
+
-->
|
10
|
+
<xs:sequence>
|
11
|
+
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
12
|
+
<xs:element name="human" type="typeoptionaltype"/>
|
13
|
+
<xs:element name="machine" type="collapsedstringrequiredtype"/>
|
14
|
+
</xs:choice>
|
15
|
+
</xs:sequence>
|
16
|
+
</xs:complexType>
|
17
|
+
|
18
|
+
<!-- the "machine" elements in "use" and "copyright"(?) are different than the others (no child elements) -->
|
19
|
+
<xs:complexType name="machinetype"><!-- For the deeper non-"use" machine elements -->
|
20
|
+
<xs:choice>
|
21
|
+
<xs:element name="none" type="xs:string"/>
|
22
|
+
<xs:element name="world" type="xs:string"/>
|
23
|
+
</xs:choice>
|
24
|
+
<xs:attribute name="type" type="xs:string"/>
|
25
|
+
</xs:complexType>
|
26
|
+
|
27
|
+
<xs:complexType name="maybehuman">
|
28
|
+
<xs:sequence>
|
29
|
+
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
30
|
+
<xs:element name="human" type="typeoptionaltype"/>
|
31
|
+
</xs:choice>
|
32
|
+
</xs:sequence>
|
33
|
+
</xs:complexType>
|
34
|
+
|
35
|
+
<xs:complexType name="allornothing">
|
36
|
+
<xs:choice>
|
37
|
+
<xs:element name="none" type="trueemptytype"/>
|
38
|
+
<xs:element name="world" type="trueemptytype"/>
|
39
|
+
</xs:choice>
|
40
|
+
</xs:complexType>
|
41
|
+
|
42
|
+
<xs:complexType name="meatyoptions">
|
43
|
+
<xs:sequence>
|
44
|
+
<xs:choice minOccurs="1" maxOccurs="1">
|
45
|
+
<xs:element name="none" type="trueemptytype"/>
|
46
|
+
<xs:element name="world" type="trueemptytype"/>
|
47
|
+
<xs:sequence> <!-- if one of the above, then NONE of the below -->
|
48
|
+
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
49
|
+
<xs:element name="world" type="rulerequiredtype"/>
|
50
|
+
<xs:element name="group" type="ruleoptionaltype"/>
|
51
|
+
<xs:element name="human" type="typeoptionaltype"/>
|
52
|
+
<xs:element name="person" type="typerequiredtype"/>
|
53
|
+
<xs:element name="agent" type="typeoptionaltype"/>
|
54
|
+
<xs:element name="embargoReleaseDate" type="xs:date"/>
|
55
|
+
</xs:choice>
|
56
|
+
</xs:sequence>
|
57
|
+
</xs:choice>
|
58
|
+
</xs:sequence>
|
59
|
+
</xs:complexType>
|
60
|
+
|
61
|
+
<xs:complexType name="readtype">
|
62
|
+
<xs:complexContent>
|
63
|
+
<xs:extension base="meatyoptions">
|
64
|
+
<xs:attribute name="type" type="accesstypeattributeread" use="required"/>
|
65
|
+
</xs:extension>
|
66
|
+
</xs:complexContent>
|
67
|
+
</xs:complexType>
|
68
|
+
|
69
|
+
<xs:complexType name="discovertype">
|
70
|
+
<xs:complexContent>
|
71
|
+
<xs:extension base="meatyoptions">
|
72
|
+
<xs:attribute name="type" type="accesstypeattributediscover" use="required"/>
|
73
|
+
</xs:extension>
|
74
|
+
</xs:complexContent>
|
75
|
+
</xs:complexType>
|
76
|
+
|
77
|
+
<xs:complexType name="readwithfile">
|
78
|
+
<xs:complexContent>
|
79
|
+
<xs:extension base="readtype">
|
80
|
+
<xs:sequence>
|
81
|
+
<xs:element name="file" type="accesstypeattributeread" minOccurs="1" maxOccurs="unbounded"/>
|
82
|
+
</xs:sequence>
|
83
|
+
</xs:extension>
|
84
|
+
</xs:complexContent>
|
85
|
+
</xs:complexType>
|
86
|
+
|
87
|
+
<!--
|
88
|
+
<xs:complexType name="discovertype">
|
89
|
+
<xs:complexContent>
|
90
|
+
<xs:extension base="cyborgtype">
|
91
|
+
<xs:element name="machine" type="xs:string" minOccurs="1"/>
|
92
|
+
</xs:extension>
|
93
|
+
<xs:attribute name="type" type="accesstypeattributediscover" use="required"/>
|
94
|
+
</xs:complexContent>
|
95
|
+
</xs:complexType>
|
96
|
+
-->
|
97
|
+
|
98
|
+
</xs:schema>
|
metadata
CHANGED
@@ -1,138 +1,108 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: dor-rights-auth
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 0
|
10
|
-
version: 1.0.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Willy Mene
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
21
|
-
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
-
none: false
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
hash: 3
|
27
|
-
segments:
|
28
|
-
- 0
|
29
|
-
version: "0"
|
30
|
-
prerelease: false
|
31
|
-
type: :runtime
|
11
|
+
date: 2015-04-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
32
14
|
name: nokogiri
|
33
|
-
requirement:
|
34
|
-
|
35
|
-
version_requirements: &id002 !ruby/object:Gem::Requirement
|
36
|
-
none: false
|
37
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
38
17
|
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
|
41
|
-
|
42
|
-
- 0
|
43
|
-
version: "0"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
44
21
|
prerelease: false
|
45
|
-
|
46
|
-
|
47
|
-
requirement: *id002
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
version_requirements: &id003 !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
52
24
|
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
type: :development
|
60
|
-
name: ruby-debug
|
61
|
-
requirement: *id003
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
version_requirements: &id004 !ruby/object:Gem::Requirement
|
64
|
-
none: false
|
65
|
-
requirements:
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
66
31
|
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
|
69
|
-
|
70
|
-
- 0
|
71
|
-
version: "0"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
72
35
|
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
73
48
|
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
74
56
|
name: yard
|
75
|
-
requirement:
|
76
|
-
|
77
|
-
version_requirements: &id005 !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
|
-
requirements:
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
80
59
|
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
|
83
|
-
segments:
|
84
|
-
- 0
|
85
|
-
version: "0"
|
86
|
-
prerelease: false
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
87
62
|
type: :development
|
88
|
-
|
89
|
-
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
90
69
|
description: Parses rightsMetadata xml into a useable object
|
91
|
-
email:
|
70
|
+
email:
|
92
71
|
- wmene@stanford.edu
|
93
72
|
executables: []
|
94
|
-
|
95
73
|
extensions: []
|
96
|
-
|
97
74
|
extra_rdoc_files: []
|
98
|
-
|
99
|
-
files:
|
75
|
+
files:
|
100
76
|
- lib/dor/rights_auth.rb
|
77
|
+
- lib/dor/xsd/druid.xsd
|
78
|
+
- lib/dor/xsd/druidlist.xsd
|
79
|
+
- lib/dor/xsd/humanlist.xsd
|
80
|
+
- lib/dor/xsd/illustration.xml
|
81
|
+
- lib/dor/xsd/rights.xsd
|
82
|
+
- lib/dor/xsd/rights_basics.xsd
|
83
|
+
- lib/dor/xsd/rights_types.xsd
|
101
84
|
homepage:
|
102
85
|
licenses: []
|
103
|
-
|
86
|
+
metadata: {}
|
104
87
|
post_install_message:
|
105
88
|
rdoc_options: []
|
106
|
-
|
107
|
-
require_paths:
|
89
|
+
require_paths:
|
108
90
|
- lib
|
109
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
-
|
111
|
-
requirements:
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
112
93
|
- - ">="
|
113
|
-
- !ruby/object:Gem::Version
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
version: "0"
|
118
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
-
none: false
|
120
|
-
requirements:
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
121
98
|
- - ">="
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
hash: 23
|
124
|
-
segments:
|
125
|
-
- 1
|
126
|
-
- 3
|
127
|
-
- 6
|
99
|
+
- !ruby/object:Gem::Version
|
128
100
|
version: 1.3.6
|
129
101
|
requirements: []
|
130
|
-
|
131
102
|
rubyforge_project:
|
132
|
-
rubygems_version:
|
103
|
+
rubygems_version: 2.2.2
|
133
104
|
signing_key:
|
134
|
-
specification_version:
|
105
|
+
specification_version: 4
|
135
106
|
summary: Parses rightsMetadata xml into a useable object
|
136
107
|
test_files: []
|
137
|
-
|
138
108
|
has_rdoc:
|