ey_gatekeeper 0.1.34
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/lib/ey_gatekeeper/access_control_list.rb +133 -0
- data/lib/ey_gatekeeper/client/consumer.rb +63 -0
- data/lib/ey_gatekeeper/client/middlewares/authentication.rb +77 -0
- data/lib/ey_gatekeeper/client/middlewares/service_token_authentication.rb +39 -0
- data/lib/ey_gatekeeper/client/server_response.rb +37 -0
- data/lib/ey_gatekeeper/client.rb +44 -0
- data/lib/ey_gatekeeper/responses.rb +67 -0
- data/lib/ey_gatekeeper/token.rb +29 -0
- data/lib/ey_gatekeeper/util.rb +23 -0
- data/lib/ey_gatekeeper/version.rb +5 -0
- data/lib/ey_gatekeeper.rb +54 -0
- data/spec/access_control_list_spec.rb +192 -0
- data/spec/auth_service_spec.rb +332 -0
- data/spec/consumer_spec.rb +80 -0
- data/spec/fallback_spec.rb +76 -0
- data/spec/impersonation_spec.rb +50 -0
- data/spec/responses_spec.rb +23 -0
- data/spec/service_token_authentication_spec.rb +10 -0
- data/spec/spec_helper.rb +133 -0
- metadata +129 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EY::GateKeeper::Client::Consumer do
|
4
|
+
before do
|
5
|
+
user_key_data = {
|
6
|
+
'key' => 'user',
|
7
|
+
'secret' => 'bar',
|
8
|
+
'access_controls' => {
|
9
|
+
'xdna://domains' => [],
|
10
|
+
},
|
11
|
+
'cloudkit_user' => 'xcloud',
|
12
|
+
'user' => 'id://user'
|
13
|
+
}.to_json
|
14
|
+
|
15
|
+
service_key_data = {
|
16
|
+
'key' => 'service',
|
17
|
+
'secret' => 'bar',
|
18
|
+
'access_controls' => {
|
19
|
+
'xdna://domains' => ['GET'],
|
20
|
+
},
|
21
|
+
'cloudkit_user' => 'xcloud',
|
22
|
+
'user' => 'id://service'
|
23
|
+
}.to_json
|
24
|
+
|
25
|
+
store = EY::GateKeeper::AuthStore.new
|
26
|
+
store.post('/gatekeeper_credentials', :json => user_key_data)
|
27
|
+
store.post('/gatekeeper_credentials', :json => service_key_data)
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with valid credentials and an impersonation token" do
|
31
|
+
before do
|
32
|
+
@user = EY::GateKeeper.new('user','bar')
|
33
|
+
end
|
34
|
+
subject { EY::GateKeeper.new('service','bar') }
|
35
|
+
|
36
|
+
it "should be able to impersonate a user" do
|
37
|
+
subject.get('/domains').status.should == 200
|
38
|
+
subject.impersonate!(@user.token.token)
|
39
|
+
subject.get('/domains').status.should == 401
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should be able to stop impersonating a user" do
|
43
|
+
subject.get('/domains').status.should == 200
|
44
|
+
subject.impersonate!(@user.token.token)
|
45
|
+
subject.get('/domains').status.should == 401
|
46
|
+
subject.just_me!
|
47
|
+
subject.get('/domains').status.should == 200
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EY::GateKeeper::Responses do
|
4
|
+
|
5
|
+
subject { EY::GateKeeper::Responses }
|
6
|
+
|
7
|
+
its(:possible_responses) { should have_at_least(7).responses }
|
8
|
+
|
9
|
+
context ".string" do
|
10
|
+
it "should return a canned response when a valid response key is passed" do
|
11
|
+
subject.string(subject.possible_responses.first).should_not be_empty
|
12
|
+
subject.string(subject.possible_responses.first).should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return an empty string when no response key is passed" do
|
16
|
+
subject.string.should be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return an empty string when an unknown response key is passed" do
|
20
|
+
subject.string(:foozle_bam_boozle).should be_empty
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EY::GateKeeper::Client::Middleware::ServiceTokenAuthentication do
|
4
|
+
let(:service_client) { ServiceClient.new('77zxcvbnm77', '77zxcvbnm77') }
|
5
|
+
|
6
|
+
it "fetches a token and passes it to the service" do
|
7
|
+
service_client.get('/').body.should_not be_empty
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
2
|
+
|
3
|
+
require 'ey_gatekeeper/server'
|
4
|
+
require 'ey_gatekeeper'
|
5
|
+
|
6
|
+
require 'rack/test'
|
7
|
+
|
8
|
+
class ServiceClient < Rack::Client::Simple
|
9
|
+
def initialize(xdna_key, xdna_secret)
|
10
|
+
app = Rack::Builder.new do
|
11
|
+
use EY::GateKeeper::Client::Middleware::ServiceTokenAuthentication, 'http://gatekeeper.local', xdna_key, xdna_secret
|
12
|
+
run lambda {|e| [200, { 'Content-Type' => 'text/plain' }, [e['HTTP_AUTH_TOKEN']]] }
|
13
|
+
end
|
14
|
+
super(app)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
EY::GateKeeper.mock!
|
20
|
+
|
21
|
+
module EY::GateKeeper::TestMethods
|
22
|
+
def app; EY::GateKeeper::Client.mock_app end
|
23
|
+
|
24
|
+
def test_key
|
25
|
+
"hello"
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_secret
|
29
|
+
"world"
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_role_1_access_controls
|
33
|
+
{
|
34
|
+
"xdna://domains" => ["GET"],
|
35
|
+
"xdna://" => ["GET"]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_role_2_access_controls
|
40
|
+
{
|
41
|
+
"xdna://domains" => ["GET","PUT"],
|
42
|
+
"xdna://" => []
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_test_roles
|
47
|
+
create_role("Test1", test_role_1_access_controls)
|
48
|
+
create_role("Test2", test_role_2_access_controls)
|
49
|
+
[ find_role("Test1"), find_role("Test2") ]
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_token(key = EY::GateKeeper::Client.master_key, secret = EY::GateKeeper::Client.master_secret)
|
53
|
+
get '/_authenticate', {}, {
|
54
|
+
'HTTP_AUTHORIZATION' => ["#{key}:#{secret}"].pack('m*')
|
55
|
+
}
|
56
|
+
|
57
|
+
last_response.status.should == 200
|
58
|
+
last_response.content_type.should == 'application/json'
|
59
|
+
|
60
|
+
JSON.parse(last_response.body)
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_role(name, access_controls)
|
64
|
+
role_data = {
|
65
|
+
'name' => name,
|
66
|
+
'access_controls' => access_controls
|
67
|
+
}
|
68
|
+
auth_store.put("/gatekeeper_roles/#{name}", :json => role_data.to_json).status.should == 201
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_key_with_roles(*roles)
|
72
|
+
key_data = {
|
73
|
+
'access_controls' => { 'xdna://' => [] },
|
74
|
+
'gatekeeper_roles' => roles.map { |role| "/gatekeeper_roles/#{role}" },
|
75
|
+
'key' => test_key,
|
76
|
+
'secret' => test_secret,
|
77
|
+
'cloudkit_user' => 'xcloud'
|
78
|
+
}
|
79
|
+
auth_store.post("/gatekeeper_credentials",
|
80
|
+
:json => key_data.to_json).status.should == 201
|
81
|
+
end
|
82
|
+
|
83
|
+
def expire_token(token)
|
84
|
+
stored_token_data = find_token(token).parsed_content
|
85
|
+
stored_token_data['expires'] = 0
|
86
|
+
save_token(token, stored_token_data)
|
87
|
+
end
|
88
|
+
|
89
|
+
def restrict_token(token)
|
90
|
+
stored_token_data = find_token(token).parsed_content
|
91
|
+
stored_token_data['access_controls'] = {}
|
92
|
+
save_token(token, stored_token_data)
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_key(key,secret)
|
96
|
+
result = auth_store.get("/gatekeeper_credentials", :search => {:key => key, :secret => secret})
|
97
|
+
result.status.should == 200
|
98
|
+
result.parsed_content["total"].should == 1
|
99
|
+
auth_store.get(result.parsed_content["uris"].first).parsed_content
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_role(role)
|
103
|
+
auth_store.get("/gatekeeper_roles/#{role}")
|
104
|
+
end
|
105
|
+
|
106
|
+
def find_token(token)
|
107
|
+
auth_store.get("/gatekeeper_tokens/#{token}")
|
108
|
+
end
|
109
|
+
|
110
|
+
def save_token(token, data)
|
111
|
+
etag = find_token(token).etag
|
112
|
+
auth_store.put(
|
113
|
+
"/gatekeeper_tokens/#{token}",
|
114
|
+
:json => data.to_json,
|
115
|
+
:etag => etag
|
116
|
+
).status.should == 200
|
117
|
+
end
|
118
|
+
|
119
|
+
def auth_store
|
120
|
+
@store ||= EY::GateKeeper::AuthStore.new
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
RSpec.configure do |config|
|
125
|
+
config.color_enabled = config.tty = true
|
126
|
+
|
127
|
+
config.before(:each) do
|
128
|
+
EY::GateKeeper.reset!
|
129
|
+
end
|
130
|
+
|
131
|
+
config.include Rack::Test::Methods
|
132
|
+
config.include EY::GateKeeper::TestMethods
|
133
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ey_gatekeeper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.34
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Engine Yard
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-06-22 00:00:00.000000000 -03:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: json
|
17
|
+
requirement: &2169581240 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2169581240
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rack-client
|
28
|
+
requirement: &2169580620 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.1.pre.j
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2169580620
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: excon
|
39
|
+
requirement: &2169580020 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2169580020
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rspec
|
50
|
+
requirement: &2169579520 !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: *2169579520
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rack-test
|
61
|
+
requirement: &2169578900 !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: *2169578900
|
70
|
+
description: I am the gatekeeper, are you the keymaster?
|
71
|
+
email:
|
72
|
+
- gems@engineyard.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- lib/ey_gatekeeper/access_control_list.rb
|
78
|
+
- lib/ey_gatekeeper/client/consumer.rb
|
79
|
+
- lib/ey_gatekeeper/client/middlewares/authentication.rb
|
80
|
+
- lib/ey_gatekeeper/client/middlewares/service_token_authentication.rb
|
81
|
+
- lib/ey_gatekeeper/client/server_response.rb
|
82
|
+
- lib/ey_gatekeeper/client.rb
|
83
|
+
- lib/ey_gatekeeper/responses.rb
|
84
|
+
- lib/ey_gatekeeper/token.rb
|
85
|
+
- lib/ey_gatekeeper/util.rb
|
86
|
+
- lib/ey_gatekeeper/version.rb
|
87
|
+
- lib/ey_gatekeeper.rb
|
88
|
+
- spec/access_control_list_spec.rb
|
89
|
+
- spec/auth_service_spec.rb
|
90
|
+
- spec/consumer_spec.rb
|
91
|
+
- spec/fallback_spec.rb
|
92
|
+
- spec/impersonation_spec.rb
|
93
|
+
- spec/responses_spec.rb
|
94
|
+
- spec/service_token_authentication_spec.rb
|
95
|
+
- spec/spec_helper.rb
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: http://github.com/engineyard/ey_gatekeeper
|
98
|
+
licenses: []
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 1.5.2
|
118
|
+
signing_key:
|
119
|
+
specification_version: 3
|
120
|
+
summary: I am the gatekeeper, are you the keymaster?
|
121
|
+
test_files:
|
122
|
+
- spec/access_control_list_spec.rb
|
123
|
+
- spec/auth_service_spec.rb
|
124
|
+
- spec/consumer_spec.rb
|
125
|
+
- spec/fallback_spec.rb
|
126
|
+
- spec/impersonation_spec.rb
|
127
|
+
- spec/responses_spec.rb
|
128
|
+
- spec/service_token_authentication_spec.rb
|
129
|
+
- spec/spec_helper.rb
|