pebblebed 0.0.22 → 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -152,3 +152,10 @@ For some pebbles Pebblebed may furnish a richer client with helper methods. This
152
152
  augmented client in the `/lib/pebblebed/clients` folder and naming the class `Pebblebed::<YourPebbleName>Client`. For
153
153
  an example of this see `CheckpointClient` which in addition to the common http-methods provides the method `me` which
154
154
  returns the logged in user and `god?` which checks whether she's a god(dess).
155
+
156
+ Troubleshooting
157
+ ===============
158
+
159
+ When something fails, say you're trying to post to grove using a pebblebed connector, it might be a good idea to try the same thing from command line first:
160
+
161
+ curl -XPOST 'http://example.com/api/grove/v1/posts/post.todo:dna.org.a.b' --data '{"session":"session_name","post":{"document": {"body": "Hello Grove!"},"tags": ["welcome", "tutorial"]}}' -H "Content-Type: application/json"
@@ -0,0 +1,85 @@
1
+ # Models the checkpoint group access data for one identity
2
+ module Pebblebed
3
+ module Security
4
+ class AccessData
5
+ attr_reader :group_ids
6
+
7
+ def initialize(data)
8
+ if data[:subtrees] || data[:group_ids]
9
+ @group_ids = Set.new(data[:group_ids])
10
+ @subtrees = Set.new
11
+ data[:subtrees].each do |subtree|
12
+ @subtrees << subtree.split('.')
13
+ end
14
+ else
15
+ # Assume this is a /identities/:id/memberships result from checkpoint
16
+ parse_checkpoint_record(data)
17
+ end
18
+ end
19
+
20
+ # Takes a path (possibly with wildcards) and returns
21
+ # any subtrees that are relevant to determine accessibility
22
+ # to restricted content in a query of documents in that
23
+ # wildcard_path. All relevant subtrees are guaranteed to be
24
+ # returned, but not all returned subtrees are guaranteed to be
25
+ # relevant. I.e. some irrelevant subtrees may be returned.
26
+ # (If the path does not use wildcards, relevance is
27
+ # guaranteed.)
28
+ def relevant_subtrees(wildcard_path)
29
+ pristine = self.class.pristine_path(wildcard_path)
30
+ intersecting_subtrees(pristine)
31
+ end
32
+
33
+ def subtrees
34
+ @subtrees.map { |subtree| subtree.join('.') }
35
+ end
36
+
37
+ private
38
+
39
+ # Takes a path possibly containing wildcard characters and returns
40
+ # a superset path that just contains proper labels. E.g. "a.b.c|d.*" returns
41
+ # "a.b"
42
+ def self.pristine_path(wildcard_path)
43
+ result = []
44
+ wildcard_path.split('.').each do |label|
45
+ break unless Pebblebed::Uid.valid_label?(label)
46
+ result << label
47
+ end
48
+ result.join('.')
49
+ end
50
+
51
+ # Returns any subtrees that "intersect" the provided location. That is
52
+ # they are either supersets of the location ("a.b" is a superset of "a.b.c")
53
+ # or subsets ("a.b.c.d" is a subset of "a.b.c"). Also exact matches are returned
54
+ # ('a.b.c' matches 'a.b.c', duh!)
55
+ def intersecting_subtrees(location)
56
+ location = location.split('.')
57
+ result = []
58
+ @subtrees.each do |subtree|
59
+ if subtree.length >= location.length
60
+ # is this a subset tree?
61
+ result << subtree if location == subtree[0...location.length]
62
+ else
63
+ # is this a superset tree?
64
+ result << subtree if subtree == location[0...subtree.length]
65
+ end
66
+ end
67
+ result.map { |subtree| subtree.join('.') }
68
+ end
69
+
70
+ # Initializes the instance with data from a checkpoint GET /identities/:id/memberships request
71
+ def parse_checkpoint_record(memberships_record)
72
+ @group_ids = Set.new
73
+ @subtrees = Set.new
74
+ memberships_record['memberships'].each do |membership|
75
+ @group_ids << membership['membership']['group_id']
76
+ end
77
+ memberships_record['groups'].each do |group|
78
+ group['group']['subtrees'].each do |subtree|
79
+ @subtrees << subtree.split('.')
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,33 @@
1
+ # A class that helps
2
+ module Pebblebed
3
+ module Security
4
+ class Client
5
+ IDENTITY_MEMBERSHIPS_TTL = 10*60
6
+
7
+ def initialize(connector)
8
+ @connector = connector
9
+ @access_data = {} # Memoized identity access data records
10
+ end
11
+
12
+ # Returns an object representing the current access data for a given identity
13
+ def access_data_for(identity)
14
+ identity = identity.id unless identity.is_a?(Numeric)
15
+ return @access_data[identity] if @access_data[identity]
16
+ membership_data = fetch_membership_data_for(identity)
17
+ result = Pebblebed::Security::AccessData.new(membership_data)
18
+ @access_data[identity] = result
19
+ result
20
+ end
21
+
22
+ private
23
+
24
+ def fetch_membership_data_for(identity_id)
25
+ result = Pebblebed.memcached.fetch("identity_membership_data:#{identity}", IDENTITY_MEMBERSHIPS_TTL) do
26
+ @connector.checkpoint.get("/identities/#{identity}/memberships").to_json
27
+ end
28
+ JSON.parse(result)
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,94 @@
1
+ # Listens to security configuration updates and lets the client application
2
+ # register custom handlers for each event.
3
+ module Pebblebed
4
+ module Security
5
+ class Listener
6
+
7
+ def initialize(options)
8
+ @app_name = options[:app_name]
9
+ @handlers = {:group => {}, :group_membership => {}, :group_subtree => {}}
10
+ end
11
+
12
+ def start
13
+ @thread ||= Thread.new do
14
+ process
15
+ end
16
+ end
17
+
18
+ def stop
19
+ @thread.kill if @thread
20
+ @thread = nil
21
+ end
22
+
23
+ def on_group_declared(&block)
24
+ @handlers[:group][:create] = block
25
+ @handlers[:group][:update] = block
26
+ end
27
+
28
+ def on_group_removed(&block)
29
+ @handlers[:group][:delete] = block
30
+ end
31
+
32
+ def on_subtree_declared(&block)
33
+ @handlers[:group_subtree][:create] = block
34
+ @handlers[:group_subtree][:update] = block
35
+ end
36
+
37
+ def on_subtree_removed(&block)
38
+ @handlers[:group_subtree][:delete] = block
39
+ end
40
+
41
+ def on_membership_declared(&block)
42
+ @handlers[:group_membership][:create] = block
43
+ @handlers[:group_membership][:update] = block
44
+ end
45
+
46
+ def on_membership_removed(&block)
47
+ @handlers[:group_membership][:delete] = block
48
+ end
49
+
50
+ private
51
+
52
+ # Subscribe to queue and handle incoming messages
53
+ def process
54
+ river = Pebblebed::River.new
55
+ queue_options = {
56
+ :name => "#{@app_name}.security_listener",
57
+ :path => '**',
58
+ :klass => 'group|group_membership|group_subtree',
59
+ :event => '**',
60
+ :interval => 1
61
+ }
62
+ queue = river.queue queue_options
63
+ queue.subscribe(ack: true) do |message|
64
+ consider message
65
+ end
66
+ end
67
+
68
+ # Parse an incoming message and pass it on
69
+ def consider(message)
70
+ payload = JSON.parse(message[:payload])
71
+ event = payload['event']
72
+ attributes = payload['attributes']
73
+ klass = Pebblebed::Uid.raw_parse(payload['uid']).first
74
+ handle(event, klass, attributes)
75
+ end
76
+
77
+ # Determines the correct event handler for the message and calls it
78
+ def handle(event, klass, attributes)
79
+ event_handler = @handlers[klass.to_sym][event.to_sym]
80
+ return unless event_handler
81
+ case klass
82
+ when 'group'
83
+ event_handler.call(:id => attributes['id'], :label => attributes['label'])
84
+ when 'group_membership'
85
+ event_handler.call(:group_id => attributes['group_id'],
86
+ :identity_id => attributes['identity_id'])
87
+ when 'group_subtree'
88
+ event_handler.call(:group_id => attributes['group_id'],
89
+ :location => attributes['location'])
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
data/lib/pebblebed/uid.rb CHANGED
@@ -116,29 +116,31 @@ module Pebblebed
116
116
  stars_are_solitary?(path) && pipes_are_interleaved?(path) && carets_are_leading?(path) && stars_are_terminating?(path)
117
117
  end
118
118
 
119
- # a.*.c is valid
119
+ # a.*.c is accepted
120
120
  # a.*b.c is not
121
+ # A later rule ensures that * always falls at the end of a path
121
122
  def stars_are_solitary?(path)
122
123
  !path.split('.').any? {|s| s.match(/.+\*|\*.+/)}
123
124
  end
124
125
 
125
- # a.b|c.d is valid
126
+ # a.b|c.d is accepted
126
127
  # a.|b.c is not
127
128
  def pipes_are_interleaved?(path)
128
129
  !path.split('.').any? {|s| s.match(/^\||\|$/)}
129
130
  end
130
131
 
131
- # a.^b.c is valid
132
+ # a.^b.c is accepted
132
133
  # a.b^c.d is not
133
134
  def carets_are_leading?(path)
134
135
  !path.split('.').any? {|s| s.match(/.+\^|\^$/) }
135
136
  end
136
137
 
137
- # a.b.* is valid
138
+ # a.b.* is accepted
138
139
  # *.b.c is not
139
140
  def stars_are_terminating?(path)
140
141
  path !~ /.*\*\.\w/
141
142
  end
143
+
142
144
  end
143
145
  end
144
146
 
@@ -1,3 +1,3 @@
1
1
  module Pebblebed
2
- VERSION = "0.0.22"
2
+ VERSION = "0.0.23"
3
3
  end
data/lib/pebblebed.rb CHANGED
@@ -10,3 +10,6 @@ require 'pebblebed/clients/quorum_client'
10
10
  require 'pebblebed/parts'
11
11
  require 'pebblebed/river'
12
12
  require 'pebblebed/labels'
13
+ require 'pebblebed/security/access_data'
14
+ require 'pebblebed/security/client'
15
+ require 'pebblebed/security/listener'
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'pebblebed/uid'
3
+ require 'pebblebed/security/access_data'
4
+
5
+ describe Pebblebed::Security::AccessData do
6
+ let :access_data do
7
+ Pebblebed::Security::AccessData.new(
8
+ :groups => [1,2,3],
9
+ :subtrees => ['a.b', 'a.b.c.d.e', 'a.c.d', 'a.c.e.f']
10
+ )
11
+ end
12
+
13
+ it "can calculate a pristine path" do
14
+ Pebblebed::Security::AccessData.pristine_path("a.b.c|d").should eq "a.b"
15
+ Pebblebed::Security::AccessData.pristine_path("a.b").should eq "a.b"
16
+ end
17
+
18
+ it "can calculate relevant paths" do
19
+ access_data.relevant_subtrees('a.b').sort.should eq ['a.b', 'a.b.c.d.e']
20
+ access_data.relevant_subtrees('a.b.c').sort.should eq ['a.b', 'a.b.c.d.e']
21
+ access_data.relevant_subtrees('a.c.e').sort.should eq ['a.c.e.f']
22
+ access_data.relevant_subtrees('a.*').sort.should eq ['a.b', 'a.b.c.d.e', 'a.c.d', 'a.c.e.f']
23
+ end
24
+
25
+ it "can parse a checkpoint record" do
26
+ record = {
27
+ 'memberships' => [
28
+ {'membership' => {'id' => 10, 'group_id' => 1, 'identity_id' => 1}},
29
+ {'membership' => {'id' => 20, 'group_id' => 2, 'identity_id' => 1}},
30
+ ],
31
+ 'groups' => [
32
+ {'group' => {'id' => 1, 'label' => "group_1", 'subtrees' => ["a.b.c"]}},
33
+ {'group' => {'id' => 2, 'label' => "group_2", 'subtrees' => ["a.c.d.c"]}}
34
+ ]
35
+ }
36
+ ad = Pebblebed::Security::AccessData.new(record)
37
+ ad.subtrees.sort.should eq ['a.b.c', 'a.c.d.c']
38
+ ad.group_ids.sort.should eq [1,2]
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'pebblebed/uid'
3
+ require 'pebblebed/security/access_data'
4
+ require 'pebblebed/security/client'
5
+
6
+ describe Pebblebed::Security::Client do
7
+ let :client do
8
+ Pebblebed::Security::Client.new(nil)
9
+ end
10
+
11
+ let :sample_memberships_record do
12
+ {
13
+ 'memberships' => [
14
+ {'membership' => {'id' => 10, 'group_id' => 1, 'identity_id' => 1}},
15
+ {'membership' => {'id' => 20, 'group_id' => 2, 'identity_id' => 1}},
16
+ ],
17
+ 'groups' => [
18
+ {'group' => {'id' => 1, 'label' => "group_1", 'subtrees' => ["a.b.c"]}},
19
+ {'group' => {'id' => 2, 'label' => "group_2", 'subtrees' => ["a.c.d.c"]}}
20
+ ]
21
+ }
22
+ end
23
+
24
+ it "can fetch access_data" do
25
+ client.stub(:fetch_membership_data_for).and_return(sample_memberships_record)
26
+ ad = client.access_data_for(1)
27
+ ad.subtrees.sort.should eq ['a.b.c', 'a.c.d.c']
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'pebblebed/uid'
3
+ require 'pebblebed/security/listener'
4
+
5
+ describe Pebblebed::Security::Listener do
6
+ let :listener do
7
+ Pebblebed::Security::Listener.new(:app_name => "test")
8
+ end
9
+
10
+ it "can generate events from incoming messages" do
11
+ the_attrs = nil
12
+ listener.on_group_declared do |attrs|
13
+ the_attrs = attrs
14
+ end
15
+ message = {:payload => {
16
+ 'event' => 'create',
17
+ 'uid' => 'group:abc.groups$10',
18
+ 'attributes' => {
19
+ 'id' => 10,
20
+ 'label' => 'the_label'
21
+ }
22
+ }.to_json}
23
+ listener.send(:consider, message)
24
+ the_attrs[:id].should eq 10
25
+ end
26
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pebblebed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.22
4
+ version: 0.0.23
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-09-07 00:00:00.000000000 Z
13
+ date: 2012-09-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
17
- requirement: &70305565590520 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,15 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *70305565590520
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
26
31
  - !ruby/object:Gem::Dependency
27
32
  name: rake
28
- requirement: &70305565590060 !ruby/object:Gem::Requirement
33
+ requirement: !ruby/object:Gem::Requirement
29
34
  none: false
30
35
  requirements:
31
36
  - - ! '>='
@@ -33,10 +38,15 @@ dependencies:
33
38
  version: '0'
34
39
  type: :development
35
40
  prerelease: false
36
- version_requirements: *70305565590060
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: simplecov
39
- requirement: &70305565589480 !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
40
50
  none: false
41
51
  requirements:
42
52
  - - ! '>='
@@ -44,10 +54,15 @@ dependencies:
44
54
  version: '0'
45
55
  type: :development
46
56
  prerelease: false
47
- version_requirements: *70305565589480
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
48
63
  - !ruby/object:Gem::Dependency
49
64
  name: deepstruct
50
- requirement: &70305565588760 !ruby/object:Gem::Requirement
65
+ requirement: !ruby/object:Gem::Requirement
51
66
  none: false
52
67
  requirements:
53
68
  - - ! '>='
@@ -55,10 +70,15 @@ dependencies:
55
70
  version: 0.0.2
56
71
  type: :runtime
57
72
  prerelease: false
58
- version_requirements: *70305565588760
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: 0.0.2
59
79
  - !ruby/object:Gem::Dependency
60
80
  name: curb
61
- requirement: &70305565588160 !ruby/object:Gem::Requirement
81
+ requirement: !ruby/object:Gem::Requirement
62
82
  none: false
63
83
  requirements:
64
84
  - - ! '>='
@@ -66,10 +86,15 @@ dependencies:
66
86
  version: 0.7.14
67
87
  type: :runtime
68
88
  prerelease: false
69
- version_requirements: *70305565588160
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: 0.7.14
70
95
  - !ruby/object:Gem::Dependency
71
96
  name: yajl-ruby
72
- requirement: &70305565587700 !ruby/object:Gem::Requirement
97
+ requirement: !ruby/object:Gem::Requirement
73
98
  none: false
74
99
  requirements:
75
100
  - - ! '>='
@@ -77,10 +102,15 @@ dependencies:
77
102
  version: '0'
78
103
  type: :runtime
79
104
  prerelease: false
80
- version_requirements: *70305565587700
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
81
111
  - !ruby/object:Gem::Dependency
82
112
  name: queryparams
83
- requirement: &70305565609740 !ruby/object:Gem::Requirement
113
+ requirement: !ruby/object:Gem::Requirement
84
114
  none: false
85
115
  requirements:
86
116
  - - ! '>='
@@ -88,10 +118,15 @@ dependencies:
88
118
  version: '0'
89
119
  type: :runtime
90
120
  prerelease: false
91
- version_requirements: *70305565609740
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
92
127
  - !ruby/object:Gem::Dependency
93
128
  name: futurevalue
94
- requirement: &70305565608660 !ruby/object:Gem::Requirement
129
+ requirement: !ruby/object:Gem::Requirement
95
130
  none: false
96
131
  requirements:
97
132
  - - ! '>='
@@ -99,10 +134,15 @@ dependencies:
99
134
  version: '0'
100
135
  type: :runtime
101
136
  prerelease: false
102
- version_requirements: *70305565608660
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
103
143
  - !ruby/object:Gem::Dependency
104
144
  name: pathbuilder
105
- requirement: &70305565607720 !ruby/object:Gem::Requirement
145
+ requirement: !ruby/object:Gem::Requirement
106
146
  none: false
107
147
  requirements:
108
148
  - - ! '>='
@@ -110,10 +150,15 @@ dependencies:
110
150
  version: '0'
111
151
  type: :runtime
112
152
  prerelease: false
113
- version_requirements: *70305565607720
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
114
159
  - !ruby/object:Gem::Dependency
115
160
  name: nokogiri
116
- requirement: &70305565606900 !ruby/object:Gem::Requirement
161
+ requirement: !ruby/object:Gem::Requirement
117
162
  none: false
118
163
  requirements:
119
164
  - - ! '>='
@@ -121,10 +166,15 @@ dependencies:
121
166
  version: '0'
122
167
  type: :runtime
123
168
  prerelease: false
124
- version_requirements: *70305565606900
169
+ version_requirements: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ! '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
125
175
  - !ruby/object:Gem::Dependency
126
176
  name: i18n
127
- requirement: &70305565605840 !ruby/object:Gem::Requirement
177
+ requirement: !ruby/object:Gem::Requirement
128
178
  none: false
129
179
  requirements:
130
180
  - - ! '>='
@@ -132,10 +182,15 @@ dependencies:
132
182
  version: '0'
133
183
  type: :runtime
134
184
  prerelease: false
135
- version_requirements: *70305565605840
185
+ version_requirements: !ruby/object:Gem::Requirement
186
+ none: false
187
+ requirements:
188
+ - - ! '>='
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
136
191
  - !ruby/object:Gem::Dependency
137
192
  name: activesupport
138
- requirement: &70305565603700 !ruby/object:Gem::Requirement
193
+ requirement: !ruby/object:Gem::Requirement
139
194
  none: false
140
195
  requirements:
141
196
  - - ! '>='
@@ -143,10 +198,15 @@ dependencies:
143
198
  version: '0'
144
199
  type: :runtime
145
200
  prerelease: false
146
- version_requirements: *70305565603700
201
+ version_requirements: !ruby/object:Gem::Requirement
202
+ none: false
203
+ requirements:
204
+ - - ! '>='
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
147
207
  - !ruby/object:Gem::Dependency
148
208
  name: bunny
149
- requirement: &70305565602840 !ruby/object:Gem::Requirement
209
+ requirement: !ruby/object:Gem::Requirement
150
210
  none: false
151
211
  requirements:
152
212
  - - ! '>='
@@ -154,7 +214,12 @@ dependencies:
154
214
  version: '0'
155
215
  type: :runtime
156
216
  prerelease: false
157
- version_requirements: *70305565602840
217
+ version_requirements: !ruby/object:Gem::Requirement
218
+ none: false
219
+ requirements:
220
+ - - ! '>='
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
158
223
  description: Development tools for working with Pebblebed
159
224
  email:
160
225
  - katrina@bengler.no
@@ -180,6 +245,9 @@ files:
180
245
  - lib/pebblebed/parts.rb
181
246
  - lib/pebblebed/river.rb
182
247
  - lib/pebblebed/river/subscription.rb
248
+ - lib/pebblebed/security/access_data.rb
249
+ - lib/pebblebed/security/client.rb
250
+ - lib/pebblebed/security/listener.rb
183
251
  - lib/pebblebed/sinatra.rb
184
252
  - lib/pebblebed/uid.rb
185
253
  - lib/pebblebed/uid_query.rb
@@ -194,6 +262,9 @@ files:
194
262
  - spec/mockcached.rb
195
263
  - spec/river_spec.rb
196
264
  - spec/river_subscription_spec.rb
265
+ - spec/security/access_data_spec.rb
266
+ - spec/security/client_spec.rb
267
+ - spec/security/listener_spec.rb
197
268
  - spec/spec_helper.rb
198
269
  - spec/uid_query_spec.rb
199
270
  - spec/uid_spec.rb
@@ -209,15 +280,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
209
280
  - - ! '>='
210
281
  - !ruby/object:Gem::Version
211
282
  version: '0'
283
+ segments:
284
+ - 0
285
+ hash: 4364516963973573943
212
286
  required_rubygems_version: !ruby/object:Gem::Requirement
213
287
  none: false
214
288
  requirements:
215
289
  - - ! '>='
216
290
  - !ruby/object:Gem::Version
217
291
  version: '0'
292
+ segments:
293
+ - 0
294
+ hash: 4364516963973573943
218
295
  requirements: []
219
296
  rubyforge_project: pebblebed
220
- rubygems_version: 1.8.15
297
+ rubygems_version: 1.8.24
221
298
  signing_key:
222
299
  specification_version: 3
223
300
  summary: Development tools for working with Pebblebed
@@ -231,6 +308,9 @@ test_files:
231
308
  - spec/mockcached.rb
232
309
  - spec/river_spec.rb
233
310
  - spec/river_subscription_spec.rb
311
+ - spec/security/access_data_spec.rb
312
+ - spec/security/client_spec.rb
313
+ - spec/security/listener_spec.rb
234
314
  - spec/spec_helper.rb
235
315
  - spec/uid_query_spec.rb
236
316
  - spec/uid_spec.rb