pebblebed 0.0.25 → 0.0.26

Sign up to get free protection for your applications and to get access to all the features.
data/lib/pebblebed.rb CHANGED
@@ -3,7 +3,6 @@ require 'pebblebed/http'
3
3
  require 'pebblebed/connector'
4
4
  require 'pebblebed/config'
5
5
  require 'pebblebed/uid'
6
- require 'pebblebed/uid_query'
7
6
  require 'pebblebed/clients/abstract_client'
8
7
  require 'pebblebed/clients/generic_client'
9
8
  require 'pebblebed/clients/quorum_client'
@@ -11,6 +11,7 @@ require 'active_support'
11
11
  module Pebblebed
12
12
  class HttpError < Exception
13
13
  attr_reader :status, :message
14
+
14
15
  def initialize(message, status = nil)
15
16
  @message = message
16
17
  @status = status
@@ -21,7 +22,7 @@ module Pebblebed
21
22
  end
22
23
 
23
24
  def to_s
24
- "#<Pebblebed::HttpError #{@status} #{message}>"
25
+ "#<#{self.class.name} #{@status} #{message}>"
25
26
  end
26
27
 
27
28
  def inspect
@@ -29,6 +30,10 @@ module Pebblebed
29
30
  end
30
31
  end
31
32
 
33
+ class HttpNotFoundError < HttpError
34
+
35
+ end
36
+
32
37
  module Http
33
38
  class CurlResult
34
39
  def initialize(curl_result)
@@ -91,11 +96,15 @@ module Pebblebed
91
96
  end
92
97
 
93
98
  def self.handle_http_errors(result)
94
- if result.status >= 400
99
+ if result.status == 404
100
+ errmsg = "Resource not found: '#{result.url}'"
101
+ errmsg << extract_error_summary(result.body)
102
+ # ActiveSupport::SafeBuffer.new is the same as errmsg.html_safe in rails
103
+ raise HttpNotFoundError.new(ActiveSupport::SafeBuffer.new(errmsg), result.status)
104
+ elsif result.status >= 400
95
105
  errmsg = "Service request to '#{result.url}' failed (#{result.status}):"
96
106
  errmsg << extract_error_summary(result.body)
97
107
  raise HttpError.new(ActiveSupport::SafeBuffer.new(errmsg), result.status)
98
- # ActiveSupport::SafeBuffer.new is the same as errmsg.html_safe in rails
99
108
  end
100
109
  result
101
110
  end
@@ -67,6 +67,11 @@ module Sinatra
67
67
 
68
68
  def self.registered(app)
69
69
  app.helpers(Sinatra::Pebblebed::Helpers)
70
+
71
+ app.error ::Pebblebed::HttpNotFoundError do
72
+ [404, env['sinatra.error'].message]
73
+ end
74
+
70
75
  end
71
76
 
72
77
  def declare_pebbles(&block)
@@ -1,3 +1,3 @@
1
1
  module Pebblebed
2
- VERSION = "0.0.25"
2
+ VERSION = "0.0.26"
3
3
  end
data/pebblebed.gemspec CHANGED
@@ -22,6 +22,8 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency "rspec"
23
23
  s.add_development_dependency "rake"
24
24
  s.add_development_dependency "simplecov"
25
+ s.add_development_dependency "sinatra" # for testing purposes
26
+ s.add_development_dependency "rack-test" # for testing purposes
25
27
 
26
28
  s.add_runtime_dependency "deepstruct", ">= 0.0.2"
27
29
  s.add_runtime_dependency "curb", ">= 0.7.14"
data/spec/http_spec.rb CHANGED
@@ -22,6 +22,8 @@ describe Pebblebed::Http do
22
22
 
23
23
  after :all do
24
24
  mock_pebble.shutdown
25
+ # give webrick some time to cool down
26
+ sleep 0.1
25
27
  end
26
28
 
27
29
  it "knows how to pack params into a http query string" do
@@ -44,8 +46,16 @@ describe Pebblebed::Http do
44
46
  url.to_s.should eq "http://example.org/api/foo/bar"
45
47
  end
46
48
 
47
- it "raises an exception if there is a http-error" do
48
- -> { Pebblebed::Http.send(:handle_http_errors, DeepStruct.wrap(status:400, url:"/foobar", body:"Oh noes")) }.should raise_error Pebblebed::HttpError
49
+ it "raises an HttpNotFoundError if there is a 404 error" do
50
+ -> { Pebblebed::Http.send(:handle_http_errors, DeepStruct.wrap(status: 404, url: "/foobar", body: "Not found")) }.should raise_error Pebblebed::HttpNotFoundError
51
+ end
52
+
53
+ it "includes the url of the failed resource in the error message" do
54
+ -> { Pebblebed::Http.send(:handle_http_errors, DeepStruct.wrap(status: 404, url: "/nosuchresource", body: "Not found")) }.should raise_error Pebblebed::HttpNotFoundError, /\/nosuchresource/
55
+ end
56
+
57
+ it "raises an HttpError if there is any other http-error" do
58
+ -> { Pebblebed::Http.send(:handle_http_errors, DeepStruct.wrap(status: 400, url: "/foobar", body: "Oh noes")) }.should raise_error Pebblebed::HttpError
49
59
  end
50
60
 
51
61
  it "encodes posts and puts as json if the params is a hash" do
data/spec/mock_pebble.rb CHANGED
@@ -46,7 +46,7 @@ class MockPebble
46
46
  end
47
47
 
48
48
  def start
49
- @server = WEBrick::HTTPServer.new(:Port => 8666, :AccessLog => [])
49
+ @server = WEBrick::HTTPServer.new(:Port => 8666, Logger: WEBrick::Log.new("/dev/null"), :AccessLog => [])
50
50
  @server.mount "/api/mock/v1", Servlet
51
51
  @server_thread = Thread.new do
52
52
  @server.start
@@ -0,0 +1,128 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pebblebed'
4
+ require 'pebblebed/sinatra'
5
+ require 'sinatra/base'
6
+ require 'rack/test'
7
+
8
+ class TestApp < Sinatra::Base
9
+ register Sinatra::Pebblebed
10
+
11
+ set :show_exceptions, :after_handler
12
+
13
+ assign_provisional_identity :unless => lambda {
14
+ params[:provisional] != 'yes'
15
+ }
16
+
17
+ get '/public' do
18
+ "You are a guest here"
19
+ end
20
+
21
+ get '/private' do
22
+ require_identity
23
+ "You are logged in"
24
+ end
25
+
26
+ get '/root' do
27
+ require_god
28
+ "You are most powerful"
29
+ end
30
+
31
+ get '/nonexistant' do
32
+ raise Pebblebed::HttpNotFoundError, "Not found /nonexistant"
33
+ end
34
+
35
+ end
36
+
37
+ describe Sinatra::Pebblebed do
38
+ include Rack::Test::Methods
39
+
40
+ def app
41
+ TestApp
42
+ end
43
+
44
+ let(:guest) { DeepStruct.wrap({}) }
45
+ let(:alice) { DeepStruct.wrap(:identity => {:id => 1, :god => false}) }
46
+ let(:odin) { DeepStruct.wrap(:identity => {:id => 2, :god => true}) }
47
+
48
+ let(:checkpoint) { stub(:get => identity, :service_url => 'http://example.com') }
49
+
50
+ before :each do
51
+ Pebblebed::Connector.any_instance.stub(:checkpoint).and_return checkpoint
52
+ end
53
+
54
+ context "a guest" do
55
+ let(:identity) { guest }
56
+
57
+ specify "can see public endpoint" do
58
+ get '/public'
59
+ last_response.body.should == 'You are a guest here'
60
+ end
61
+
62
+ it "can assign a provisional identity" do
63
+ get '/public', :provisional => 'yes'
64
+ last_response.status.should == 302
65
+ end
66
+
67
+ specify "cannot see private endpoints" do
68
+ get '/private'
69
+ last_response.status.should == 403
70
+ end
71
+
72
+ it "cannot see root endpoints" do
73
+ get '/root'
74
+ last_response.status.should == 403
75
+ end
76
+ end
77
+
78
+ context "as a user" do
79
+ let(:identity) { alice }
80
+
81
+ specify "can see public endpoint" do
82
+ get '/public'
83
+ last_response.body.should == 'You are a guest here'
84
+ end
85
+
86
+ specify "can see private endpoints" do
87
+ get '/private'
88
+ last_response.body.should == 'You are logged in'
89
+ end
90
+
91
+ it "cannot see root endpoints" do
92
+ get '/root'
93
+ last_response.status.should == 403
94
+ end
95
+ end
96
+
97
+ context "as a god" do
98
+ let(:identity) { odin }
99
+
100
+ specify "can see public endpoint" do
101
+ get '/public'
102
+ last_response.body.should == 'You are a guest here'
103
+ end
104
+
105
+ specify "can see private endpoints" do
106
+ get '/private'
107
+ last_response.body.should == 'You are logged in'
108
+ end
109
+
110
+ it "cannot see root endpoints" do
111
+ get '/root'
112
+ last_response.body.should == 'You are most powerful'
113
+ end
114
+ end
115
+
116
+ describe "error handling" do
117
+ let(:identity) { guest }
118
+ it "Adds graceful handling of HttpNotFoundError exceptions" do
119
+ get '/nonexistant'
120
+ last_response.status.should == 404
121
+ end
122
+ it "Gives the error message of HttpNotFoundError as response body" do
123
+ get '/nonexistant'
124
+ last_response.status.should == 404
125
+ last_response.body.should == 'Not found /nonexistant'
126
+ end
127
+ end
128
+ 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.25
4
+ version: 0.0.26
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-10-15 00:00:00.000000000 Z
13
+ date: 2012-10-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
17
- requirement: &70097905491200 !ruby/object:Gem::Requirement
17
+ requirement: &70127313138320 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *70097905491200
25
+ version_requirements: *70127313138320
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rake
28
- requirement: &70097905489860 !ruby/object:Gem::Requirement
28
+ requirement: &70127313137220 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70097905489860
36
+ version_requirements: *70127313137220
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: simplecov
39
- requirement: &70097905488820 !ruby/object:Gem::Requirement
39
+ requirement: &70127313136580 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,32 @@ dependencies:
44
44
  version: '0'
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *70097905488820
47
+ version_requirements: *70127313136580
48
+ - !ruby/object:Gem::Dependency
49
+ name: sinatra
50
+ requirement: &70127313135380 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *70127313135380
59
+ - !ruby/object:Gem::Dependency
60
+ name: rack-test
61
+ requirement: &70127313134840 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *70127313134840
48
70
  - !ruby/object:Gem::Dependency
49
71
  name: deepstruct
50
- requirement: &70097905487880 !ruby/object:Gem::Requirement
72
+ requirement: &70127313134000 !ruby/object:Gem::Requirement
51
73
  none: false
52
74
  requirements:
53
75
  - - ! '>='
@@ -55,10 +77,10 @@ dependencies:
55
77
  version: 0.0.2
56
78
  type: :runtime
57
79
  prerelease: false
58
- version_requirements: *70097905487880
80
+ version_requirements: *70127313134000
59
81
  - !ruby/object:Gem::Dependency
60
82
  name: curb
61
- requirement: &70097905487020 !ruby/object:Gem::Requirement
83
+ requirement: &70127313132320 !ruby/object:Gem::Requirement
62
84
  none: false
63
85
  requirements:
64
86
  - - ! '>='
@@ -66,10 +88,10 @@ dependencies:
66
88
  version: 0.7.14
67
89
  type: :runtime
68
90
  prerelease: false
69
- version_requirements: *70097905487020
91
+ version_requirements: *70127313132320
70
92
  - !ruby/object:Gem::Dependency
71
93
  name: yajl-ruby
72
- requirement: &70097905486260 !ruby/object:Gem::Requirement
94
+ requirement: &70127313130020 !ruby/object:Gem::Requirement
73
95
  none: false
74
96
  requirements:
75
97
  - - ! '>='
@@ -77,10 +99,10 @@ dependencies:
77
99
  version: '0'
78
100
  type: :runtime
79
101
  prerelease: false
80
- version_requirements: *70097905486260
102
+ version_requirements: *70127313130020
81
103
  - !ruby/object:Gem::Dependency
82
104
  name: queryparams
83
- requirement: &70097905485480 !ruby/object:Gem::Requirement
105
+ requirement: &70127313128400 !ruby/object:Gem::Requirement
84
106
  none: false
85
107
  requirements:
86
108
  - - ! '>='
@@ -88,10 +110,10 @@ dependencies:
88
110
  version: '0'
89
111
  type: :runtime
90
112
  prerelease: false
91
- version_requirements: *70097905485480
113
+ version_requirements: *70127313128400
92
114
  - !ruby/object:Gem::Dependency
93
115
  name: futurevalue
94
- requirement: &70097905478360 !ruby/object:Gem::Requirement
116
+ requirement: &70127313127340 !ruby/object:Gem::Requirement
95
117
  none: false
96
118
  requirements:
97
119
  - - ! '>='
@@ -99,10 +121,10 @@ dependencies:
99
121
  version: '0'
100
122
  type: :runtime
101
123
  prerelease: false
102
- version_requirements: *70097905478360
124
+ version_requirements: *70127313127340
103
125
  - !ruby/object:Gem::Dependency
104
126
  name: pathbuilder
105
- requirement: &70097905477600 !ruby/object:Gem::Requirement
127
+ requirement: &70127313125940 !ruby/object:Gem::Requirement
106
128
  none: false
107
129
  requirements:
108
130
  - - ! '>='
@@ -110,10 +132,10 @@ dependencies:
110
132
  version: '0'
111
133
  type: :runtime
112
134
  prerelease: false
113
- version_requirements: *70097905477600
135
+ version_requirements: *70127313125940
114
136
  - !ruby/object:Gem::Dependency
115
137
  name: nokogiri
116
- requirement: &70097905477000 !ruby/object:Gem::Requirement
138
+ requirement: &70127313124680 !ruby/object:Gem::Requirement
117
139
  none: false
118
140
  requirements:
119
141
  - - ! '>='
@@ -121,10 +143,10 @@ dependencies:
121
143
  version: '0'
122
144
  type: :runtime
123
145
  prerelease: false
124
- version_requirements: *70097905477000
146
+ version_requirements: *70127313124680
125
147
  - !ruby/object:Gem::Dependency
126
148
  name: i18n
127
- requirement: &70097905476320 !ruby/object:Gem::Requirement
149
+ requirement: &70127313122960 !ruby/object:Gem::Requirement
128
150
  none: false
129
151
  requirements:
130
152
  - - ! '>='
@@ -132,10 +154,10 @@ dependencies:
132
154
  version: '0'
133
155
  type: :runtime
134
156
  prerelease: false
135
- version_requirements: *70097905476320
157
+ version_requirements: *70127313122960
136
158
  - !ruby/object:Gem::Dependency
137
159
  name: activesupport
138
- requirement: &70097905475740 !ruby/object:Gem::Requirement
160
+ requirement: &70127313121480 !ruby/object:Gem::Requirement
139
161
  none: false
140
162
  requirements:
141
163
  - - ! '>='
@@ -143,10 +165,10 @@ dependencies:
143
165
  version: '0'
144
166
  type: :runtime
145
167
  prerelease: false
146
- version_requirements: *70097905475740
168
+ version_requirements: *70127313121480
147
169
  - !ruby/object:Gem::Dependency
148
170
  name: bunny
149
- requirement: &70097905475020 !ruby/object:Gem::Requirement
171
+ requirement: &70127313118900 !ruby/object:Gem::Requirement
150
172
  none: false
151
173
  requirements:
152
174
  - - ! '>='
@@ -154,7 +176,7 @@ dependencies:
154
176
  version: '0'
155
177
  type: :runtime
156
178
  prerelease: false
157
- version_requirements: *70097905475020
179
+ version_requirements: *70127313118900
158
180
  description: Development tools for working with Pebblebed
159
181
  email:
160
182
  - katrina@bengler.no
@@ -185,7 +207,6 @@ files:
185
207
  - lib/pebblebed/security/listener.rb
186
208
  - lib/pebblebed/sinatra.rb
187
209
  - lib/pebblebed/uid.rb
188
- - lib/pebblebed/uid_query.rb
189
210
  - lib/pebblebed/version.rb
190
211
  - pebblebed.gemspec
191
212
  - spec/config_spec.rb
@@ -200,8 +221,8 @@ files:
200
221
  - spec/security/access_data_spec.rb
201
222
  - spec/security/client_spec.rb
202
223
  - spec/security/listener_spec.rb
224
+ - spec/sinatra_spec.rb
203
225
  - spec/spec_helper.rb
204
- - spec/uid_query_spec.rb
205
226
  - spec/uid_spec.rb
206
227
  homepage: ''
207
228
  licenses: []
@@ -240,6 +261,6 @@ test_files:
240
261
  - spec/security/access_data_spec.rb
241
262
  - spec/security/client_spec.rb
242
263
  - spec/security/listener_spec.rb
264
+ - spec/sinatra_spec.rb
243
265
  - spec/spec_helper.rb
244
- - spec/uid_query_spec.rb
245
266
  - spec/uid_spec.rb
@@ -1,31 +0,0 @@
1
- module Pebblebed
2
- class UIDQuery
3
-
4
- attr_reader :uids, :path, :oid
5
- def initialize(uids)
6
- @multiple = uids =~ /\,/
7
- if list?
8
- @uids = uids.split(',')
9
- else
10
- @klass, @path, @oid = Uid.parse(uids)
11
- @uids = uids
12
- end
13
- end
14
-
15
- def list?
16
- !!@multiple
17
- end
18
-
19
- def one?
20
- !(list? || wildcard?)
21
- end
22
-
23
- def wildcard?
24
- Uid.valid_wildcard_path?(path) || wildcard_oid?
25
- end
26
-
27
- def wildcard_oid?
28
- !list? && (oid == '*' || oid.nil?)
29
- end
30
- end
31
- end
@@ -1,51 +0,0 @@
1
- require 'spec_helper'
2
- require 'pebblebed/uid'
3
- require 'pebblebed/uid_query'
4
-
5
- describe Pebblebed::UIDQuery do
6
- context "with comma separated uids." do
7
- subject { Pebblebed::UIDQuery.new("xyz:a.b.c$1,xyz:a.b.c$2") }
8
-
9
- its(:list?) { should be_true }
10
- its(:wildcard?) { should be_false }
11
- its(:one?) { should be_false }
12
- its(:uids) { should eq(["xyz:a.b.c$1", "xyz:a.b.c$2"]) }
13
-
14
- end
15
-
16
- context "with a wildcard path." do
17
- subject { Pebblebed::UIDQuery.new("xyz:a.b.*") }
18
-
19
- its(:list?) { should be_false }
20
- its(:wildcard?) { should be_true }
21
- its(:one?) { should be_false }
22
- its(:uids) { should eq("xyz:a.b.*") }
23
- end
24
-
25
- context "without any oid." do
26
- subject { Pebblebed::UIDQuery.new("xyz:a.b.c") }
27
-
28
- its(:list?) { should be_false }
29
- its(:wildcard?) { should be_true }
30
- its(:one?) { should be_false }
31
- its(:uids) { should eq("xyz:a.b.c") }
32
- end
33
-
34
- context "with a wildcard oid." do
35
- subject { Pebblebed::UIDQuery.new("xyz:a.b.c$*") }
36
-
37
- its(:list?) { should be_false }
38
- its(:wildcard?) { should be_true }
39
- its(:one?) { should be_false }
40
- its(:uids) { should eq("xyz:a.b.c$*") }
41
- end
42
-
43
- context "with a completely constrained uid" do
44
- subject { Pebblebed::UIDQuery.new("xyz:a.b.c$1") }
45
-
46
- its(:list?) { should be_false }
47
- its(:wildcard?) { should be_false }
48
- its(:one?) { should be_true }
49
- its(:uids) { should eq("xyz:a.b.c$1") }
50
- end
51
- end