hydra-access-controls 5.4.0.pre1 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,6 +25,7 @@ module Hydra::Ability
25
25
  @current_user = user || Hydra::Ability.user_class.new # guest user (not logged in)
26
26
  @user = @current_user # just in case someone was using this in an override. Just don't.
27
27
  @session = session
28
+ @permission_doc_cache = {}
28
29
  hydra_default_permissions()
29
30
  end
30
31
 
@@ -71,7 +72,7 @@ module Hydra::Ability
71
72
  end
72
73
 
73
74
  can :edit, SolrDocument do |obj|
74
- @permissions_solr_document = obj
75
+ @permission_doc_cache[obj.id] = obj
75
76
  test_edit(obj.id)
76
77
  end
77
78
  end
@@ -87,7 +88,7 @@ module Hydra::Ability
87
88
  end
88
89
 
89
90
  can :read, SolrDocument do |obj|
90
- @permissions_solr_document = obj
91
+ @permission_doc_cache[obj.id] = obj
91
92
  test_read(obj.id)
92
93
  end
93
94
  end
@@ -101,18 +102,18 @@ module Hydra::Ability
101
102
  protected
102
103
 
103
104
  def permissions_doc(pid)
104
- return @permissions_solr_document if @permissions_solr_document
105
- response, @permissions_solr_document = get_permissions_solr_response_for_doc_id(pid)
106
- @permissions_solr_document
105
+ return @permission_doc_cache[pid] if @permission_doc_cache[pid]
106
+ _, doc = get_permissions_solr_response_for_doc_id(pid)
107
+ #puts "PERM: #{@permissions_solr_document.inspect}"
108
+ @permission_doc_cache[pid] = doc
107
109
  end
108
110
 
109
111
 
110
112
  def test_edit(pid, deprecated_user=nil, deprecated_session=nil)
111
113
  ActiveSupport::Deprecation.warn("No need to pass user or session to test_edit, use the instance_variables", caller()) if deprecated_user || deprecated_session
112
- permissions_doc(pid)
113
114
  logger.debug("[CANCAN] Checking edit permissions for user: #{current_user.user_key} with groups: #{user_groups.inspect}")
114
- group_intersection = user_groups & edit_groups
115
- result = !group_intersection.empty? || edit_persons.include?(current_user.user_key)
115
+ group_intersection = user_groups & edit_groups(pid)
116
+ result = !group_intersection.empty? || edit_persons(pid).include?(current_user.user_key)
116
117
  logger.debug("[CANCAN] decision: #{result}")
117
118
  result
118
119
  end
@@ -120,39 +121,43 @@ module Hydra::Ability
120
121
  def test_read(pid, deprecated_user=nil, deprecated_session=nil)
121
122
  ActiveSupport::Deprecation.warn("No need to pass user or session to test_read, use the instance_variables", caller()) if deprecated_user || deprecated_session
122
123
  permissions_doc(pid)
123
- logger.debug("[CANCAN] Checking edit permissions for user: #{current_user.user_key} with groups: #{user_groups.inspect}")
124
- group_intersection = user_groups & read_groups
125
- result = !group_intersection.empty? || read_persons.include?(current_user.user_key)
124
+ logger.debug("[CANCAN] Checking read permissions for user: #{current_user.user_key} with groups: #{user_groups.inspect}")
125
+ group_intersection = user_groups & read_groups(pid)
126
+ result = !group_intersection.empty? || read_persons(pid).include?(current_user.user_key)
126
127
  logger.debug("[CANCAN] decision: #{result}")
127
128
  result
128
129
  end
129
130
 
130
- def edit_groups
131
+ def edit_groups(pid)
131
132
  edit_group_field = Hydra.config[:permissions][:edit][:group]
132
- eg = ((@permissions_solr_document == nil || @permissions_solr_document.fetch(edit_group_field,nil) == nil) ? [] : @permissions_solr_document.fetch(edit_group_field,nil))
133
+ doc = permissions_doc(pid)
134
+ eg = ((doc == nil || doc.fetch(edit_group_field,nil) == nil) ? [] : doc.fetch(edit_group_field,nil))
133
135
  logger.debug("[CANCAN] edit_groups: #{eg.inspect}")
134
136
  return eg
135
137
  end
136
138
 
137
139
  # edit implies read, so read_groups is the union of edit and read groups
138
- def read_groups
140
+ def read_groups(pid)
139
141
  read_group_field = Hydra.config[:permissions][:read][:group]
140
- rg = edit_groups | ((@permissions_solr_document == nil || @permissions_solr_document.fetch(read_group_field,nil) == nil) ? [] : @permissions_solr_document.fetch(read_group_field,nil))
142
+ doc = permissions_doc(pid)
143
+ rg = edit_groups(pid) | ((doc == nil || doc.fetch(read_group_field,nil) == nil) ? [] : doc.fetch(read_group_field,nil))
141
144
  logger.debug("[CANCAN] read_groups: #{rg.inspect}")
142
145
  return rg
143
146
  end
144
147
 
145
- def edit_persons
148
+ def edit_persons(pid)
146
149
  edit_person_field = Hydra.config[:permissions][:edit][:individual]
147
- ep = ((@permissions_solr_document == nil || @permissions_solr_document.fetch(edit_person_field,nil) == nil) ? [] : @permissions_solr_document.fetch(edit_person_field,nil))
150
+ doc = permissions_doc(pid)
151
+ ep = ((doc == nil || doc.fetch(edit_person_field,nil) == nil) ? [] : doc.fetch(edit_person_field,nil))
148
152
  logger.debug("[CANCAN] edit_persons: #{ep.inspect}")
149
153
  return ep
150
154
  end
151
155
 
152
156
  # edit implies read, so read_persons is the union of edit and read persons
153
- def read_persons
157
+ def read_persons(pid)
154
158
  read_individual_field = Hydra.config[:permissions][:read][:individual]
155
- rp = edit_persons | ((@permissions_solr_document == nil || @permissions_solr_document.fetch(read_individual_field,nil) == nil) ? [] : @permissions_solr_document.fetch(read_individual_field,nil))
159
+ doc = permissions_doc(pid)
160
+ rp = edit_persons(pid) | ((doc == nil || doc.fetch(read_individual_field,nil) == nil) ? [] : doc.fetch(read_individual_field,nil))
156
161
  logger.debug("[CANCAN] read_persons: #{rp.inspect}")
157
162
  return rp
158
163
  end
@@ -89,6 +89,22 @@ module Hydra::AccessControlsEnforcement
89
89
 
90
90
  protected
91
91
 
92
+ def gated_discovery_filters
93
+ # Grant access to public content
94
+ permission_types = discovery_permissions
95
+ user_access_filters = []
96
+
97
+ permission_types.each do |type|
98
+ user_access_filters << "#{type}_access_group_t:public"
99
+ end
100
+
101
+ # Grant access based on user id & role
102
+ solr_access_filters_logic.each do |method_name|
103
+ user_access_filters += send(method_name, permission_types)
104
+ end
105
+ user_access_filters
106
+ end
107
+
92
108
  # If someone hits the show action while their session's viewing_context is in edit mode,
93
109
  # this will redirect them to the edit action.
94
110
  # If they do not have sufficient privileges to edit documents, it will silently switch their session to browse mode.
@@ -211,21 +227,10 @@ module Hydra::AccessControlsEnforcement
211
227
  # @param user_parameters the current user-subitted parameters
212
228
  def apply_gated_discovery(solr_parameters, user_parameters)
213
229
  solr_parameters[:fq] ||= []
214
- # Grant access to public content
215
- permission_types = discovery_permissions
216
- user_access_filters = []
217
-
218
- permission_types.each do |type|
219
- user_access_filters << "#{type}_access_group_t:public"
220
- end
221
-
222
- # Grant access based on user id & role
223
- solr_access_filters_logic.each do |method_name|
224
- user_access_filters += send(method_name, permission_types)
225
- end
226
- solr_parameters[:fq] << user_access_filters.join(" OR ")
230
+ solr_parameters[:fq] << gated_discovery_filters.join(" OR ")
227
231
  logger.debug("Solr parameters: #{ solr_parameters.inspect }")
228
232
  end
233
+
229
234
 
230
235
  def apply_role_permissions(permission_types)
231
236
  # for roles
@@ -39,11 +39,12 @@ module Hydra::PolicyAwareAbility
39
39
 
40
40
  # Returns the permissions solr document for policy_pid
41
41
  # The document is stored in an instance variable, so calling this multiple times will only query solr once.
42
- # To force reload, set @policy_permissions_solr_document to nil
42
+ # To force reload, set @policy_permissions_solr_cache to {}
43
43
  def policy_permissions_doc(policy_pid)
44
- return @policy_permissions_solr_document if @policy_permissions_solr_document
45
- response, @policy_permissions_solr_document = get_permissions_solr_response_for_doc_id(policy_pid)
46
- @policy_permissions_solr_document
44
+ @policy_permissions_solr_cache ||= {}
45
+ return @policy_permissions_solr_cache[policy_pid] if @policy_permissions_solr_cache[policy_pid]
46
+ _, doc = get_permissions_solr_response_for_doc_id(policy_pid)
47
+ @policy_permissions_solr_cache[policy_pid] = doc
47
48
  end
48
49
 
49
50
  # Tests whether the object's governing policy object grants edit access for the current user
@@ -3,15 +3,15 @@ module Hydra::PolicyAwareAccessControlsEnforcement
3
3
 
4
4
  # Extends Hydra::AccessControlsEnforcement.apply_gated_discovery to reflect policy-provided access
5
5
  # appends the result of policy_clauses into the :fq
6
+ # @param solr_parameters the current solr parameters
7
+ # @param user_parameters the current user-subitted parameters
6
8
  def apply_gated_discovery(solr_parameters, user_parameters)
7
- super
8
- additional_clauses = policy_clauses
9
- unless additional_clauses.nil? || additional_clauses.empty?
10
- solr_parameters[:fq].first << " OR " + additional_clauses
11
- logger.debug("POLICY-aware Solr parameters: #{ solr_parameters.inspect }")
12
- end
9
+ solr_parameters[:fq] ||= []
10
+ solr_parameters[:fq] << gated_discovery_filters.join(" OR ")
11
+ logger.debug("POLICY-aware Solr parameters: #{ solr_parameters.inspect }")
13
12
  end
14
-
13
+
14
+
15
15
  # returns solr query for finding all objects whose policies grant discover access to current_user
16
16
  def policy_clauses
17
17
  policy_pids = policies_with_access
@@ -64,5 +64,16 @@ module Hydra::PolicyAwareAccessControlsEnforcement
64
64
  return Hydra.config[:permissions][:policy_class]
65
65
  end
66
66
  end
67
+
68
+ protected
69
+
70
+ def gated_discovery_filters
71
+ filters = super
72
+ additional_clauses = policy_clauses
73
+ unless additional_clauses.blank?
74
+ filters << additional_clauses
75
+ end
76
+ filters
77
+ end
67
78
 
68
79
  end
@@ -269,120 +269,18 @@ describe Ability do
269
269
 
270
270
  end
271
271
 
272
- #
273
- # Policy-based Access Controls
274
- #
275
- describe "When accessing assets with Policies associated" do
272
+ describe "calling ability on two separate objects" do
276
273
  before do
277
- @user = FactoryGirl.build(:martia_morocco)
278
- RoleMapper.stub(:roles).with(@user.user_key).and_return(@user.roles)
274
+ @asset1 = FactoryGirl.create(:org_read_access_asset)
275
+ @asset2 = FactoryGirl.create(:asset)
276
+ @user = FactoryGirl.build(:calvin_collaborator) # has access to @asset1, but not @asset2
279
277
  end
280
278
  subject { Ability.new(@user) }
281
- context "Given a policy grants read access to a group I belong to" do
282
- before do
283
- @policy = Hydra::AdminPolicy.new
284
- @policy.default_permissions = [{:type=>"group", :access=>"read", :name=>"africana-faculty"}]
285
- @policy.save
286
- end
287
- after { @policy.delete }
288
- context "And a subscribing asset does not grant access" do
289
- before do
290
- @asset = ModsAsset.new()
291
- @asset.admin_policy = @policy
292
- @asset.save
293
- end
294
- after { @asset.delete }
295
- it "Then I should be able to view the asset" do
296
- subject.can?(:read, @asset).should be_true
297
- end
298
- it "Then I should not be able to edit, update and destroy the asset" do
299
- subject.can?(:edit, @asset).should be_false
300
- subject.can?(:update, @asset).should be_false
301
- subject.can?(:destroy, @asset).should be_false
302
- end
303
- end
304
- end
305
- context "Given a policy grants edit access to a group I belong to" do
306
- before do
307
- @policy = Hydra::AdminPolicy.new
308
- @policy.default_permissions = [{:type=>"group", :access=>"edit", :name=>"africana-faculty"}]
309
- @policy.save
310
- end
311
- after { @policy.delete }
312
- context "And a subscribing asset does not grant access" do
313
- before do
314
- @asset = ModsAsset.new()
315
- @asset.admin_policy = @policy
316
- @asset.save
317
- end
318
- after { @asset.delete }
319
- it "Then I should be able to view the asset" do
320
- subject.can?(:read, @asset).should be_true
321
- end
322
- it "Then I should be able to edit/update/destroy the asset" do
323
- subject.can?(:edit, @asset).should be_true
324
- subject.can?(:update, @asset).should be_true
325
- subject.can?(:destroy, @asset).should be_true
326
- end
327
- end
328
- context "And a subscribing asset grants read access to me as an individual" do
329
- before do
330
- @asset = ModsAsset.new()
331
- @asset.read_users = [@user.uid]
332
- @asset.admin_policy = @policy
333
- @asset.save
334
- end
335
- after { @asset.delete }
336
- it "Then I should be able to view the asset" do
337
- subject.can?(:read, @asset).should be_true
338
- end
339
- it "Then I should be able to edit/update/destroy the asset" do
340
- subject.can?(:edit, @asset).should be_true
341
- subject.can?(:update, @asset).should be_true
342
- subject.can?(:destroy, @asset).should be_true
343
- end
344
- end
345
- end
346
-
347
- context "Given a policy does not grant access to any group I belong to" do
348
- before do
349
- @policy = Hydra::AdminPolicy.new
350
- @policy.save
351
- end
352
- after { @policy.delete }
353
- context "And a subscribing asset does not grant access" do
354
- before do
355
- @asset = ModsAsset.new()
356
- @asset.admin_policy = @policy
357
- @asset.save
358
- end
359
- after { @asset.delete }
360
- it "Then I should not be able to view the asset" do
361
- subject.can?(:read, @asset).should be_false
362
- end
363
- it "Then I should not be able to edit/update/destroy the asset" do
364
- subject.can?(:edit, @asset).should be_false
365
- subject.can?(:update, @asset).should be_false
366
- subject.can?(:destroy, @asset).should be_false
367
- end
368
- end
369
- context "And a subscribing asset grants read access to me as an individual" do
370
- before do
371
- @asset = ModsAsset.new()
372
- @asset.read_users = [@user.uid]
373
- @asset.admin_policy = @policy
374
- @asset.save
375
- end
376
- after { @asset.delete }
377
- it "Then I should be able to view the asset" do
378
- subject.can?(:read, @asset).should be_true
379
- end
380
- it "Then I should not be able to edit/update/destroy the asset" do
381
- subject.can?(:edit, @asset).should be_false
382
- subject.can?(:update, @asset).should be_false
383
- subject.can?(:destroy, @asset).should be_false
384
- end
385
- end
279
+ it "should be readable in the first instance and not in the second instance" do
280
+ # We had a bug around this where it keeps returning the access for the first object queried
281
+ subject.can?(:edit, @asset1).should be_true
282
+ subject.can?(:edit, @asset2).should be_false
386
283
  end
387
284
  end
285
+
388
286
  end
@@ -124,5 +124,121 @@ describe Hydra::AdminPolicy do
124
124
 
125
125
  end
126
126
 
127
+ #
128
+ # Policy-based Access Controls
129
+ #
130
+ describe "When accessing assets with Policies associated" do
131
+ before do
132
+ @user = FactoryGirl.build(:martia_morocco)
133
+ RoleMapper.stub(:roles).with(@user.user_key).and_return(@user.roles)
134
+ end
135
+ subject { Ability.new(@user) }
136
+ context "Given a policy grants read access to a group I belong to" do
137
+ before do
138
+ @policy = Hydra::AdminPolicy.new
139
+ @policy.default_permissions = [{:type=>"group", :access=>"read", :name=>"africana-faculty"}]
140
+ @policy.save
141
+ end
142
+ after { @policy.delete }
143
+ context "And a subscribing asset does not grant access" do
144
+ before do
145
+ @asset = ModsAsset.new()
146
+ @asset.admin_policy = @policy
147
+ @asset.save
148
+ end
149
+ after { @asset.delete }
150
+ it "Then I should be able to view the asset" do
151
+ subject.can?(:read, @asset).should be_true
152
+ end
153
+ it "Then I should not be able to edit, update and destroy the asset" do
154
+ subject.can?(:edit, @asset).should be_false
155
+ subject.can?(:update, @asset).should be_false
156
+ subject.can?(:destroy, @asset).should be_false
157
+ end
158
+ end
159
+ end
160
+ context "Given a policy grants edit access to a group I belong to" do
161
+ before do
162
+ @policy = Hydra::AdminPolicy.new
163
+ @policy.default_permissions = [{:type=>"group", :access=>"edit", :name=>"africana-faculty"}]
164
+ @policy.save
165
+ end
166
+ after { @policy.delete }
167
+ context "And a subscribing asset does not grant access" do
168
+ before do
169
+ @asset = ModsAsset.new()
170
+ @asset.admin_policy = @policy
171
+ @asset.save
172
+ end
173
+ after { @asset.delete }
174
+ it "Then I should be able to view the asset" do
175
+ subject.can?(:read, @asset).should be_true
176
+ end
177
+ it "Then I should be able to edit/update/destroy the asset" do
178
+ subject.can?(:edit, @asset).should be_true
179
+ subject.can?(:update, @asset).should be_true
180
+ subject.can?(:destroy, @asset).should be_true
181
+ end
182
+ end
183
+ context "And a subscribing asset grants read access to me as an individual" do
184
+ before do
185
+ @asset = ModsAsset.new()
186
+ @asset.read_users = [@user.uid]
187
+ @asset.admin_policy = @policy
188
+ @asset.save
189
+ end
190
+ after { @asset.delete }
191
+ it "Then I should be able to view the asset" do
192
+ subject.can?(:read, @asset).should be_true
193
+ end
194
+ it "Then I should be able to edit/update/destroy the asset" do
195
+ subject.can?(:edit, @asset).should be_true
196
+ subject.can?(:update, @asset).should be_true
197
+ subject.can?(:destroy, @asset).should be_true
198
+ end
199
+ end
200
+ end
201
+
202
+ context "Given a policy does not grant access to any group I belong to" do
203
+ before do
204
+ @policy = Hydra::AdminPolicy.new
205
+ @policy.save
206
+ end
207
+ after { @policy.delete }
208
+ context "And a subscribing asset does not grant access" do
209
+ before do
210
+ @asset = ModsAsset.new()
211
+ @asset.admin_policy = @policy
212
+ @asset.save
213
+ end
214
+ after { @asset.delete }
215
+ it "Then I should not be able to view the asset" do
216
+ subject.can?(:read, @asset).should be_false
217
+ end
218
+ it "Then I should not be able to edit/update/destroy the asset" do
219
+ subject.can?(:edit, @asset).should be_false
220
+ subject.can?(:update, @asset).should be_false
221
+ subject.can?(:destroy, @asset).should be_false
222
+ end
223
+ end
224
+ context "And a subscribing asset grants read access to me as an individual" do
225
+ before do
226
+ @asset = ModsAsset.new()
227
+ @asset.read_users = [@user.uid]
228
+ @asset.admin_policy = @policy
229
+ @asset.save
230
+ end
231
+ after { @asset.delete }
232
+ it "Then I should be able to view the asset" do
233
+ subject.can?(:read, @asset).should be_true
234
+ end
235
+ it "Then I should not be able to edit/update/destroy the asset" do
236
+ subject.can?(:edit, @asset).should be_false
237
+ subject.can?(:update, @asset).should be_false
238
+ subject.can?(:destroy, @asset).should be_false
239
+ end
240
+ end
241
+ end
242
+ end
127
243
 
128
244
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra-access-controls
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.0.pre1
5
- prerelease: 6
4
+ version: 5.4.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Chris Beer
@@ -11,14 +11,14 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-01-23 00:00:00.000000000 Z
14
+ date: 2013-02-06 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
- - - ! '>='
21
+ - - ">="
22
22
  - !ruby/object:Gem::Version
23
23
  version: '0'
24
24
  type: :runtime
@@ -26,7 +26,7 @@ dependencies:
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  none: false
28
28
  requirements:
29
- - - ! '>='
29
+ - - ">="
30
30
  - !ruby/object:Gem::Version
31
31
  version: '0'
32
32
  - !ruby/object:Gem::Dependency
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  none: false
36
36
  requirements:
37
- - - ! '>='
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
40
  type: :runtime
@@ -42,7 +42,7 @@ dependencies:
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  none: false
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  - !ruby/object:Gem::Dependency
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirement: !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
- - - ! '>='
53
+ - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  type: :runtime
@@ -58,7 +58,7 @@ dependencies:
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  none: false
60
60
  requirements:
61
- - - ! '>='
61
+ - - ">="
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  - !ruby/object:Gem::Dependency
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirement: !ruby/object:Gem::Requirement
67
67
  none: false
68
68
  requirements:
69
- - - ! '>='
69
+ - - ">="
70
70
  - !ruby/object:Gem::Version
71
71
  version: '0'
72
72
  type: :runtime
@@ -74,7 +74,7 @@ dependencies:
74
74
  version_requirements: !ruby/object:Gem::Requirement
75
75
  none: false
76
76
  requirements:
77
- - - ! '>='
77
+ - - ">="
78
78
  - !ruby/object:Gem::Version
79
79
  version: '0'
80
80
  - !ruby/object:Gem::Dependency
@@ -82,7 +82,7 @@ dependencies:
82
82
  requirement: !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
- - - ! '>='
85
+ - - ">="
86
86
  - !ruby/object:Gem::Version
87
87
  version: '0'
88
88
  type: :runtime
@@ -90,7 +90,7 @@ dependencies:
90
90
  version_requirements: !ruby/object:Gem::Requirement
91
91
  none: false
92
92
  requirements:
93
- - - ! '>='
93
+ - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
96
  - !ruby/object:Gem::Dependency
@@ -98,7 +98,7 @@ dependencies:
98
98
  requirement: !ruby/object:Gem::Requirement
99
99
  none: false
100
100
  requirements:
101
- - - ! '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
@@ -106,7 +106,7 @@ dependencies:
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
- - - ! '>='
109
+ - - ">="
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  - !ruby/object:Gem::Dependency
@@ -114,7 +114,7 @@ dependencies:
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  none: false
116
116
  requirements:
117
- - - ! '>='
117
+ - - ">="
118
118
  - !ruby/object:Gem::Version
119
119
  version: '0'
120
120
  type: :development
@@ -122,7 +122,7 @@ dependencies:
122
122
  version_requirements: !ruby/object:Gem::Requirement
123
123
  none: false
124
124
  requirements:
125
- - - ! '>='
125
+ - - ">="
126
126
  - !ruby/object:Gem::Version
127
127
  version: '0'
128
128
  description: Access controls for project hydra
@@ -180,18 +180,21 @@ require_paths:
180
180
  required_ruby_version: !ruby/object:Gem::Requirement
181
181
  none: false
182
182
  requirements:
183
- - - ! '>='
183
+ - - ">="
184
184
  - !ruby/object:Gem::Version
185
185
  version: 1.9.3
186
186
  required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  none: false
188
188
  requirements:
189
- - - ! '>'
189
+ - - ">="
190
190
  - !ruby/object:Gem::Version
191
- version: 1.3.1
191
+ version: '0'
192
+ segments:
193
+ - 0
194
+ hash: -3641881465125225421
192
195
  requirements: []
193
196
  rubyforge_project:
194
- rubygems_version: 1.8.23
197
+ rubygems_version: 1.8.25
195
198
  signing_key:
196
199
  specification_version: 3
197
200
  summary: Access controls for project hydra