aker 3.0.0.pre
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/CHANGELOG.md +210 -0
- data/README.md +282 -0
- data/assets/aker/form/login.css +73 -0
- data/assets/aker/form/login.html.erb +44 -0
- data/lib/aker/authorities/automatic_access.rb +36 -0
- data/lib/aker/authorities/composite.rb +301 -0
- data/lib/aker/authorities/static.rb +283 -0
- data/lib/aker/authorities/support/find_sole_user.rb +24 -0
- data/lib/aker/authorities/support.rb +9 -0
- data/lib/aker/authorities.rb +46 -0
- data/lib/aker/cas/authority.rb +79 -0
- data/lib/aker/cas/configuration_helper.rb +85 -0
- data/lib/aker/cas/middleware/logout_responder.rb +49 -0
- data/lib/aker/cas/middleware/ticket_remover.rb +35 -0
- data/lib/aker/cas/middleware.rb +6 -0
- data/lib/aker/cas/proxy_mode.rb +108 -0
- data/lib/aker/cas/rack_proxy_callback.rb +188 -0
- data/lib/aker/cas/service_mode.rb +88 -0
- data/lib/aker/cas/service_url.rb +62 -0
- data/lib/aker/cas/user_ext.rb +64 -0
- data/lib/aker/cas.rb +31 -0
- data/lib/aker/central_parameters.rb +101 -0
- data/lib/aker/configuration.rb +534 -0
- data/lib/aker/deprecation.rb +105 -0
- data/lib/aker/form/custom_views_mode.rb +80 -0
- data/lib/aker/form/login_form_asset_provider.rb +56 -0
- data/lib/aker/form/middleware/custom_view_login_responder.rb +19 -0
- data/lib/aker/form/middleware/login_renderer.rb +72 -0
- data/lib/aker/form/middleware/login_responder.rb +71 -0
- data/lib/aker/form/middleware/logout_responder.rb +26 -0
- data/lib/aker/form/middleware.rb +10 -0
- data/lib/aker/form/mode.rb +118 -0
- data/lib/aker/form.rb +26 -0
- data/lib/aker/group.rb +67 -0
- data/lib/aker/group_membership.rb +162 -0
- data/lib/aker/ldap/authority.rb +392 -0
- data/lib/aker/ldap/user_ext.rb +19 -0
- data/lib/aker/ldap.rb +22 -0
- data/lib/aker/modes/base.rb +85 -0
- data/lib/aker/modes/http_basic.rb +100 -0
- data/lib/aker/modes/support/attempted_path.rb +22 -0
- data/lib/aker/modes/support/rfc_2617.rb +32 -0
- data/lib/aker/modes/support.rb +12 -0
- data/lib/aker/modes.rb +48 -0
- data/lib/aker/rack/authenticate.rb +37 -0
- data/lib/aker/rack/configuration_helper.rb +18 -0
- data/lib/aker/rack/default_logout_responder.rb +36 -0
- data/lib/aker/rack/environment_helper.rb +34 -0
- data/lib/aker/rack/facade.rb +102 -0
- data/lib/aker/rack/failure.rb +69 -0
- data/lib/aker/rack/logout.rb +63 -0
- data/lib/aker/rack/request_ext.rb +19 -0
- data/lib/aker/rack/session_timer.rb +95 -0
- data/lib/aker/rack/setup.rb +77 -0
- data/lib/aker/rack.rb +107 -0
- data/lib/aker/test/helpers.rb +22 -0
- data/lib/aker/test.rb +8 -0
- data/lib/aker/user.rb +231 -0
- data/lib/aker/version.rb +3 -0
- data/lib/aker.rb +51 -0
- data/spec/aker/aker-sample.yml +11 -0
- data/spec/aker/authorities/automatic_access_spec.rb +52 -0
- data/spec/aker/authorities/composite_spec.rb +488 -0
- data/spec/aker/authorities/nu-schema.jar +0 -0
- data/spec/aker/authorities/static_spec.rb +455 -0
- data/spec/aker/authorities/support/find_sole_user_spec.rb +33 -0
- data/spec/aker/authorities_spec.rb +16 -0
- data/spec/aker/cas/authority_spec.rb +106 -0
- data/spec/aker/cas/configuration_helper_spec.rb +92 -0
- data/spec/aker/cas/middleware/logout_responder_spec.rb +47 -0
- data/spec/aker/cas/middleware/ticket_remover_spec.rb +49 -0
- data/spec/aker/cas/proxy_mode_spec.rb +185 -0
- data/spec/aker/cas/rack_proxy_callback_spec.rb +190 -0
- data/spec/aker/cas/service_mode_spec.rb +122 -0
- data/spec/aker/cas/service_url_spec.rb +114 -0
- data/spec/aker/cas/user_ext_spec.rb +27 -0
- data/spec/aker/cas_spec.rb +19 -0
- data/spec/aker/central_parameters_spec.rb +44 -0
- data/spec/aker/configuration_spec.rb +465 -0
- data/spec/aker/deprecation_spec.rb +115 -0
- data/spec/aker/form/a_form_mode.rb +129 -0
- data/spec/aker/form/custom_views_mode_spec.rb +34 -0
- data/spec/aker/form/login_form_asset_provider_spec.rb +80 -0
- data/spec/aker/form/middleware/a_form_login_responder.rb +89 -0
- data/spec/aker/form/middleware/custom_view_login_responder_spec.rb +47 -0
- data/spec/aker/form/middleware/login_renderer_spec.rb +56 -0
- data/spec/aker/form/middleware/login_responder_spec.rb +34 -0
- data/spec/aker/form/middleware/logout_responder_spec.rb +55 -0
- data/spec/aker/form/mode_spec.rb +15 -0
- data/spec/aker/form_spec.rb +11 -0
- data/spec/aker/group_membership_spec.rb +208 -0
- data/spec/aker/group_spec.rb +66 -0
- data/spec/aker/ldap/authority_spec.rb +414 -0
- data/spec/aker/ldap/ldap-users.ldif +197 -0
- data/spec/aker/ldap_spec.rb +11 -0
- data/spec/aker/modes/a_aker_mode.rb +41 -0
- data/spec/aker/modes/http_basic_spec.rb +127 -0
- data/spec/aker/modes/support/attempted_path_spec.rb +32 -0
- data/spec/aker/modes_spec.rb +11 -0
- data/spec/aker/rack/authenticate_spec.rb +78 -0
- data/spec/aker/rack/default_logout_responder_spec.rb +67 -0
- data/spec/aker/rack/facade_spec.rb +154 -0
- data/spec/aker/rack/failure_spec.rb +151 -0
- data/spec/aker/rack/logout_spec.rb +63 -0
- data/spec/aker/rack/request_ext_spec.rb +29 -0
- data/spec/aker/rack/session_timer_spec.rb +134 -0
- data/spec/aker/rack/setup_spec.rb +87 -0
- data/spec/aker/rack_spec.rb +216 -0
- data/spec/aker/test/helpers_spec.rb +44 -0
- data/spec/aker/user_spec.rb +362 -0
- data/spec/aker_spec.rb +80 -0
- data/spec/deprecation_helper.rb +58 -0
- data/spec/java_helper.rb +5 -0
- data/spec/logger_helper.rb +17 -0
- data/spec/matchers.rb +31 -0
- data/spec/mock_builder.rb +25 -0
- data/spec/spec_helper.rb +52 -0
- metadata +265 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
|
2
|
+
|
|
3
|
+
module Aker
|
|
4
|
+
describe Rack do
|
|
5
|
+
after do
|
|
6
|
+
::Warden::Strategies.clear!
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe ".use_in" do
|
|
10
|
+
let(:builder) { Aker::Spec::MockBuilder.new }
|
|
11
|
+
let(:configuration) { Aker::Configuration.new(:slices => []) }
|
|
12
|
+
|
|
13
|
+
before do
|
|
14
|
+
Aker.configuration = configuration
|
|
15
|
+
|
|
16
|
+
Aker::Rack.use_in(builder)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "fails with a useful message if there's no configuration" do
|
|
20
|
+
builder.reset!
|
|
21
|
+
Aker.configuration = nil
|
|
22
|
+
|
|
23
|
+
lambda { Aker::Rack.use_in(builder) }.
|
|
24
|
+
should raise_error(/Please set one or the other before calling use_in./)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "setting up modes" do
|
|
28
|
+
before do
|
|
29
|
+
configuration.register_mode Aker::Modes::HttpBasic
|
|
30
|
+
|
|
31
|
+
builder.reset!
|
|
32
|
+
Aker::Rack.use_in(builder)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'installs the modes registered in the configuration' do
|
|
36
|
+
::Warden::Strategies[:http_basic].should == Aker::Modes::HttpBasic
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'does not install other modes just because they exist' do
|
|
40
|
+
::Warden::Strategies[:cas].should be_nil
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "configuring warden" do
|
|
45
|
+
it "uses a manager" do
|
|
46
|
+
builder.should be_using(Warden::Manager)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "gives the manager the failure app" do
|
|
50
|
+
mock_manager = Class.new do
|
|
51
|
+
attr_accessor :failure_app
|
|
52
|
+
end.new
|
|
53
|
+
|
|
54
|
+
_, _, actual_block = builder.find_use_of(Warden::Manager)
|
|
55
|
+
actual_block.call(mock_manager)
|
|
56
|
+
|
|
57
|
+
mock_manager.failure_app.class.should == Aker::Rack::Failure
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe "modifying the Rack stack" do
|
|
62
|
+
let(:ui_mode) do
|
|
63
|
+
Class.new(Warden::Strategies::Base) do
|
|
64
|
+
def authenticate!; end
|
|
65
|
+
def self.prepend_middleware(builder); builder.use :ui_ware_before; end
|
|
66
|
+
def self.append_middleware(builder); builder.use :ui_ware_after; end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
let(:api_mode_a) do
|
|
71
|
+
Class.new(Warden::Strategies::Base) do
|
|
72
|
+
def authenticate!; end
|
|
73
|
+
def self.prepend_middleware(builder); builder.use :api_ware_before; end
|
|
74
|
+
def self.append_middleware(builder); builder.use :api_ware_after; end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
let(:api_mode_b) do
|
|
79
|
+
Class.new(Warden::Strategies::Base) do
|
|
80
|
+
def authenticate!; end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
before do
|
|
85
|
+
rebuild!
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
let(:config) do
|
|
89
|
+
Aker::Configuration.new(:slices => [Rack::Slice.new]) do
|
|
90
|
+
ui_mode :ui_mode
|
|
91
|
+
api_modes :api_mode_a, :api_mode_b
|
|
92
|
+
|
|
93
|
+
before_authentication_middleware do |builder|
|
|
94
|
+
builder.use :global_before
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
after_authentication_middleware do |builder|
|
|
98
|
+
builder.use :global_after
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def rebuild!
|
|
104
|
+
builder.reset!
|
|
105
|
+
|
|
106
|
+
Warden::Strategies.add(:ui_mode, ui_mode)
|
|
107
|
+
Warden::Strategies.add(:api_mode_a, api_mode_a)
|
|
108
|
+
Warden::Strategies.add(:api_mode_b, api_mode_b)
|
|
109
|
+
|
|
110
|
+
Aker::Rack.use_in(builder, config)
|
|
111
|
+
|
|
112
|
+
@indexes = builder.uses.each_with_index.map { |u, i| [u.first, i] }.
|
|
113
|
+
inject({}) { |h, (mw, i)| h[mw] = i; h }
|
|
114
|
+
@logout_index = @indexes[Aker::Rack::Logout]
|
|
115
|
+
@session_timer_index = @indexes[Aker::Rack::SessionTimer]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "uses the Setup middleware first" do
|
|
119
|
+
builder.uses[0].first.should == Aker::Rack::Setup
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "prepends middleware for UI modes after the setup middleware" do
|
|
123
|
+
@indexes[:ui_ware_before].should == @indexes[Aker::Rack::Setup] + 1
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "prepends middleware for API modes after UI modes" do
|
|
127
|
+
@indexes[:api_ware_before].should == @indexes[:ui_ware_before] + 1
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'attaches the global before middleware immediately before warden' do
|
|
131
|
+
@indexes[:global_before].should == @indexes[Warden::Manager] - 1
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "attaches the session timer middleware after the warden middleware" do
|
|
135
|
+
@indexes[Aker::Rack::SessionTimer].should > @indexes[Warden::Manager]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "attaches the session timer middleware before the authentication middleware" do
|
|
139
|
+
@indexes[Aker::Rack::SessionTimer].should < @indexes[Aker::Rack::Authenticate]
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it 'attaches the global after middleware immediately after Aker::Rack::Authenticate' do
|
|
143
|
+
@indexes[:global_after].should == @indexes[Aker::Rack::Authenticate] + 1
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "attaches the logout middleware after the global after middleware" do
|
|
147
|
+
@indexes[Aker::Rack::Logout].should == @indexes[:global_after] + 1
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "attaches the default logout responder at the end of the chain" do
|
|
151
|
+
builder.uses.map { |u| u.first }.last.should == Aker::Rack::DefaultLogoutResponder
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "appends middleware for UI modes directly after the logout middleware" do
|
|
155
|
+
@indexes[:ui_ware_after].should == @indexes[Aker::Rack::Logout] + 1
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "appends middleware for API modes after appended UI middleware" do
|
|
159
|
+
@indexes[:api_ware_after].should == @indexes[:ui_ware_after] + 1
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "uses middleware for the global configuration if no specific configuration is provided" do
|
|
163
|
+
Aker.configure {
|
|
164
|
+
ui_mode :ui_mode
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
builder = Aker::Spec::MockBuilder.new
|
|
168
|
+
Aker::Rack.use_in(builder)
|
|
169
|
+
|
|
170
|
+
builder.uses[0].first.should == Aker::Rack::Setup
|
|
171
|
+
builder.uses[1].first.should == :ui_ware_before
|
|
172
|
+
builder.uses[2].first.should_not == :api_ware_before
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "attaches the aker middleware" do
|
|
177
|
+
builder.should be_using(Aker::Rack::Setup, configuration)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "passes on the configuration to the setup middleware if provided" do
|
|
181
|
+
b = Aker::Spec::MockBuilder.new
|
|
182
|
+
config = Aker::Configuration.new { portal :hello }
|
|
183
|
+
|
|
184
|
+
Aker::Rack.use_in(b, config)
|
|
185
|
+
|
|
186
|
+
b.should be_using(Aker::Rack::Setup, config)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
describe Rack::Slice do
|
|
192
|
+
let(:configuration) { Configuration.new(:slices => [Rack::Slice.new]) }
|
|
193
|
+
|
|
194
|
+
describe 'parameter defaults' do
|
|
195
|
+
describe 'for :policy' do
|
|
196
|
+
subject { configuration.parameters_for(:policy) }
|
|
197
|
+
|
|
198
|
+
it 'has [:session-timeout-seconds]' do
|
|
199
|
+
subject[:'session-timeout-seconds'].should == 1800
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
describe 'for :rack' do
|
|
204
|
+
subject { configuration.parameters_for(:rack) }
|
|
205
|
+
|
|
206
|
+
it 'has [:login_path]' do
|
|
207
|
+
subject[:login_path].should == '/login'
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it 'has [:logout_path]' do
|
|
211
|
+
subject[:logout_path].should == '/logout'
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require File.expand_path("../../../spec_helper", __FILE__)
|
|
2
|
+
require "rack/test"
|
|
3
|
+
|
|
4
|
+
module Aker::Test
|
|
5
|
+
describe Helpers do
|
|
6
|
+
describe "#login_env" do
|
|
7
|
+
before do
|
|
8
|
+
Aker.configure do
|
|
9
|
+
s = Aker::Authorities::Static.new
|
|
10
|
+
|
|
11
|
+
s.valid_credentials!(:user, "jo", "50-50")
|
|
12
|
+
authorities s
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
@test_case = Class.new do
|
|
16
|
+
include Aker::Test::Helpers
|
|
17
|
+
end.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
shared_examples_for "a login helper" do
|
|
21
|
+
it "generates a Rack environment containing an authenticated user" do
|
|
22
|
+
@env['aker.check'].user.should_not be_nil
|
|
23
|
+
@env['aker.check'].user.username.should == 'jo'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe 'given a username' do
|
|
28
|
+
before do
|
|
29
|
+
@env = @test_case.login_env("jo")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it_should_behave_like "a login helper"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe 'given a Aker::User object' do
|
|
36
|
+
before do
|
|
37
|
+
@env = @test_case.login_env(Aker::User.new("jo"))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it_should_behave_like "a login helper"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
|
2
|
+
|
|
3
|
+
module Aker
|
|
4
|
+
describe User do
|
|
5
|
+
before do
|
|
6
|
+
@u = User.new("jo", :airport)
|
|
7
|
+
@u.first_name = "Jocelyn"
|
|
8
|
+
@u.last_name = "Jordan"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe "#full_name" do
|
|
12
|
+
it "works with both names" do
|
|
13
|
+
@u.full_name.should == "Jocelyn Jordan"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "uses the user name with no names" do
|
|
17
|
+
@u.first_name = nil
|
|
18
|
+
@u.last_name = nil
|
|
19
|
+
@u.full_name.should == "jo"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "works with just the last name" do
|
|
23
|
+
@u.first_name = nil
|
|
24
|
+
@u.full_name.should == "Jordan"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "works with just the first name" do
|
|
28
|
+
@u.last_name = nil
|
|
29
|
+
@u.full_name.should == "Jocelyn"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "#default_portal" do
|
|
34
|
+
it "is always a symbol" do
|
|
35
|
+
u = User.new('jo')
|
|
36
|
+
u.default_portal = 'foo'
|
|
37
|
+
u.default_portal.should == :foo
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "#portals" do
|
|
42
|
+
it "is always an array" do
|
|
43
|
+
User.new('J').portals.should == []
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "#may_access?" do
|
|
48
|
+
it "permits access to a known portal" do
|
|
49
|
+
@u.may_access?(:airport).should be_true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "supports string-named portals" do
|
|
53
|
+
@u.may_access?("airport").should be_true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "refuses access to an unknown portal" do
|
|
57
|
+
@u.may_access?(:seaport).should be_false
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "uses the default portal if available" do
|
|
61
|
+
@u.default_portal = :airport
|
|
62
|
+
@u.may_access?.should be_true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "fails without a portal if there's no default" do
|
|
66
|
+
lambda { @u.may_access? }.should raise_error(/No default portal/)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "#group_memberships" do
|
|
71
|
+
it "is a Aker::GroupMemberships instance" do
|
|
72
|
+
User.new('jo').group_memberships(:ENU).class.should == GroupMemberships
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "defaults to the groups for the default portal" do
|
|
76
|
+
jo = User.new('jo')
|
|
77
|
+
jo.default_portal = :ENU
|
|
78
|
+
jo.group_memberships(:ENU) << GroupMembership.new(Group.new('Developer'))
|
|
79
|
+
jo.group_memberships(:NOTIS) << GroupMembership.new(Group.new('Admin'))
|
|
80
|
+
|
|
81
|
+
jo.group_memberships.include?('Developer').should be_true
|
|
82
|
+
jo.group_memberships.include?('Admin').should be_false
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "locates a portal given as a string" do
|
|
86
|
+
jo = User.new('jo')
|
|
87
|
+
jo.group_memberships(:ENU) << GroupMembership.new(Group.new('Developer'))
|
|
88
|
+
jo.group_memberships("ENU").size.should == 1
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "fails without the portal parameter if there's no default portal" do
|
|
92
|
+
lambda { User.new('jo').group_memberships }.should raise_error(/No default portal/)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe "#permit?" do
|
|
97
|
+
before do
|
|
98
|
+
@user = User.new('jo')
|
|
99
|
+
@user.portals = [:ENU, :NOTIS]
|
|
100
|
+
@user.default_portal = :ENU
|
|
101
|
+
@user.group_memberships(:ENU) << GroupMembership.new(Group.new('Developer'))
|
|
102
|
+
@user.group_memberships(:NOTIS) << GroupMembership.new(Group.new('Admin'))
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "returns true if the user matches any of the groups in the default portal" do
|
|
106
|
+
@user.permit?(:Developer, :Admin).should be_true
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "returns false if the user does not match any of the groups in the default portal" do
|
|
110
|
+
@user.permit?(:Admin).should be_false
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe "with an explicit portal" do
|
|
114
|
+
it "returns true if the user is in any of the groups" do
|
|
115
|
+
@user.permit?(:Developer, :Admin, :portal => :NOTIS).should be_true
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "returns false if the user is not in any of the groups" do
|
|
119
|
+
@user.permit?(:Developer, :portal => :NOTIS).should be_false
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
describe "without any groups" do
|
|
124
|
+
describe "with the default portal" do
|
|
125
|
+
it "returns true if the user is in the portal" do
|
|
126
|
+
@user.permit?.should be_true
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "returns false if the user is not in the portal" do
|
|
130
|
+
@user.default_portal = :BSPORE
|
|
131
|
+
@user.permit?.should be_false
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
describe "with an explicit portal" do
|
|
136
|
+
it "returns true if the user is in the portal" do
|
|
137
|
+
@user.permit?(:portal => :NOTIS).should be_true
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "returns false if the user is not in the portal" do
|
|
141
|
+
@user.permit?(:portal => :BSPORE).should be_false
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
describe "with a block" do
|
|
147
|
+
it "yields to a passed block if the user matches the group" do
|
|
148
|
+
executed = nil
|
|
149
|
+
@user.permit? :Developer do
|
|
150
|
+
executed = true
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
executed.should be_true
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "does not yield if the user doesn't match the group" do
|
|
157
|
+
executed = nil
|
|
158
|
+
@user.permit? :Admin do
|
|
159
|
+
executed = true
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
executed.should be_nil
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "returns the block's return value if the user matches the group" do
|
|
166
|
+
@user.permit?(:Developer) { "block value" }.should == "block value"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "returns nil if the user does not match the group" do
|
|
170
|
+
@user.permit?(:Admin) { "block value" }.should == nil
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
describe "#merge!" do
|
|
176
|
+
before do
|
|
177
|
+
@a = User.new("jo")
|
|
178
|
+
@b = User.new("jo")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "modifies the target group in place" do
|
|
182
|
+
@b.last_name = "Miller"
|
|
183
|
+
@a.merge!(@b)
|
|
184
|
+
@a.last_name.should == "Miller"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "returns self" do
|
|
188
|
+
@a.merge!(@b).object_id.should == @a.object_id
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "does not copy attributes which are already set" do
|
|
192
|
+
@a.first_name = "Josephine"
|
|
193
|
+
@b.first_name = "Jocelyn"
|
|
194
|
+
@a.merge!(@b).first_name.should == "Josephine"
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it "does not fail if reading an attribute throws an exception" do
|
|
198
|
+
@b.should_receive(:first_name).and_throw("I don't know. Leave me alone.")
|
|
199
|
+
lambda { @a.merge!(@b) }.should_not raise_error
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe "of the default portal" do
|
|
203
|
+
it "sets the target default portal if there isn't one already" do
|
|
204
|
+
@b.default_portal = :ENU
|
|
205
|
+
@a.merge!(@b)
|
|
206
|
+
@a.default_portal.should == :ENU
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it "leaves the default portal alone if it is already set" do
|
|
210
|
+
@a.default_portal = :NOTIS
|
|
211
|
+
@b.default_portal = :ENU
|
|
212
|
+
@a.merge!(@b)
|
|
213
|
+
@a.default_portal.should == :NOTIS
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
describe "of portals" do
|
|
218
|
+
before do
|
|
219
|
+
@a.portals = [:ENU, :NOTIS]
|
|
220
|
+
@b.portals = [:SQLSubmit, :ENU]
|
|
221
|
+
@a.merge!(@b)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "removes duplicates" do
|
|
225
|
+
@a.portals.size.should == 3
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "includes portals that are in the source and target lists" do
|
|
229
|
+
@a.may_access?(:ENU).should be_true
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it "preserves portals that are only in the original list" do
|
|
233
|
+
@a.may_access?(:NOTIS).should be_true
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "adds portals that are only in the new list" do
|
|
237
|
+
@a.may_access?(:SQLSubmit).should be_true
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "works when the source portals are not set" do
|
|
241
|
+
@b.portals = nil
|
|
242
|
+
lambda { @a.merge!(@b) }.should_not raise_error
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it "works when the target portals are not set" do
|
|
246
|
+
@a.portals = nil
|
|
247
|
+
lambda { @a.merge!(@b) }.should_not raise_error
|
|
248
|
+
@a.portals.size.should == 2
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
describe "of group memberships" do
|
|
253
|
+
before do
|
|
254
|
+
@a.group_memberships(:ENU) << GroupMembership.new(Group.new("User"))
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it "adds memberships for a new portal" do
|
|
258
|
+
@b.group_memberships(:NOTIS) << GroupMembership.new(Group.new("Admin"))
|
|
259
|
+
@a.merge!(@b)
|
|
260
|
+
@a.group_memberships(:NOTIS).include?("Admin").should be_true
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it "does not merge group memberships when some are already known" do
|
|
264
|
+
@b.group_memberships(:ENU) << GroupMembership.new(Group.new("Developer"))
|
|
265
|
+
@a.merge!(@b)
|
|
266
|
+
@a.group_memberships(:ENU).size.should == 1
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
describe 'of identifiers' do
|
|
271
|
+
before do
|
|
272
|
+
@a.identifiers[:ssn] = "123-45-6789"
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
it 'preserves an identifier that is already set' do
|
|
276
|
+
@b.identifiers[:ssn] = "321-54-9876"
|
|
277
|
+
@a.merge!(@b)
|
|
278
|
+
|
|
279
|
+
@a.identifiers[:ssn].should == "123-45-6789"
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it 'copies an identifier that is new' do
|
|
283
|
+
@b.identifiers[:netid] = 'bob789'
|
|
284
|
+
@a.merge!(@b)
|
|
285
|
+
|
|
286
|
+
@a.identifiers[:netid].should == 'bob789'
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
it 'leaves alone an identifier that is not present in the argument' do
|
|
290
|
+
@b.identifiers[:netid] = 'bob789'
|
|
291
|
+
@a.merge!(@b)
|
|
292
|
+
|
|
293
|
+
@a.identifiers[:ssn].should == "123-45-6789"
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
describe 'nu_employee_id' do
|
|
299
|
+
describe 'setter' do
|
|
300
|
+
before do
|
|
301
|
+
@u.nu_employee_id = "1234"
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it "is deprecated" do
|
|
305
|
+
deprecation_message.should =~ /nu_employee_id is deprecated\. Use identifiers\[:nu_employee_id\] instead..*3.0/
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it 'sets the value in #identifers' do
|
|
309
|
+
@u.identifiers[:nu_employee_id].should == "1234"
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
describe 'getter' do
|
|
314
|
+
before do
|
|
315
|
+
@u.identifiers[:nu_employee_id] = "funfzehn"
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
let!(:subject) { @u.nu_employee_id }
|
|
319
|
+
|
|
320
|
+
it 'is deprecated' do
|
|
321
|
+
deprecation_message.should =~ /nu_employee_id is deprecated\. Use identifiers\[:nu_employee_id\] instead..*3.0/
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it 'reads the value from #identifiers' do
|
|
325
|
+
subject.should == "funfzehn"
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
describe 'personnel_id' do
|
|
331
|
+
describe 'setter' do
|
|
332
|
+
before do
|
|
333
|
+
@u.personnel_id = "1234"
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
it "is deprecated" do
|
|
337
|
+
deprecation_message.should =~ /personnel_id is deprecated\. Use identifiers\[:personnel_id\] instead..*3.0/
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
it 'sets the value in #identifers' do
|
|
341
|
+
@u.identifiers[:personnel_id].should == "1234"
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
describe 'getter' do
|
|
346
|
+
before do
|
|
347
|
+
@u.identifiers[:personnel_id] = "funfzehn"
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
let!(:subject) { @u.personnel_id }
|
|
351
|
+
|
|
352
|
+
it 'is deprecated' do
|
|
353
|
+
deprecation_message.should =~ /personnel_id is deprecated\. Use identifiers\[:personnel_id\] instead..*3.0/
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
it 'reads the value from #identifiers' do
|
|
357
|
+
subject.should == "funfzehn"
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end
|
data/spec/aker_spec.rb
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
|
2
|
+
|
|
3
|
+
require 'aker'
|
|
4
|
+
|
|
5
|
+
describe Aker do
|
|
6
|
+
before do
|
|
7
|
+
Aker.authority = nil
|
|
8
|
+
Aker.configuration = nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
after do
|
|
12
|
+
Aker.authority = nil
|
|
13
|
+
Aker.configuration = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "::VERSION" do
|
|
17
|
+
it "exists" do
|
|
18
|
+
lambda { Aker::VERSION }.should_not raise_error
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "has three or four dot-separated parts" do
|
|
22
|
+
Aker::VERSION.split('.').size.should be_between(3, 4)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "configuration" do
|
|
27
|
+
it "can be set directly" do
|
|
28
|
+
Aker.configuration = Aker::Configuration.new { portal :ENU }
|
|
29
|
+
Aker.configuration.portal.should == :ENU
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "does not accumulate direct set configurations" do
|
|
33
|
+
Aker.configuration = Aker::Configuration.new { api_mode :basic }
|
|
34
|
+
Aker.configuration = Aker::Configuration.new { portal :ENU }
|
|
35
|
+
Aker.configuration.api_modes.should == [] # the default
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "can be configured using #configure" do
|
|
39
|
+
Aker.configure { portal :ENU }
|
|
40
|
+
Aker.configuration.portal.should == :ENU
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "accumulates #configure configurations" do
|
|
44
|
+
Aker.configure { api_modes :basic, :cas_proxy }
|
|
45
|
+
Aker.configure { portal :LIMS }
|
|
46
|
+
Aker.configuration.api_modes.should == [:basic, :cas_proxy]
|
|
47
|
+
Aker.configuration.portal.should == :LIMS
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe "authority" do
|
|
52
|
+
before do
|
|
53
|
+
@auth = Aker::Authorities::Static.new
|
|
54
|
+
@auth.valid_credentials!(:cas, "jo", "ST-12345")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "can be set directly" do
|
|
58
|
+
Aker.authority = @auth
|
|
59
|
+
Aker.authority.valid_credentials?(:cas, "ST-12345").should_not be_nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "uses the composite authority from the configuration by default" do
|
|
63
|
+
Aker.configuration = Aker::Configuration.new {
|
|
64
|
+
a = Aker::Authorities::Static.new
|
|
65
|
+
a.valid_credentials!(:magic, "jo", "man")
|
|
66
|
+
authority a
|
|
67
|
+
}
|
|
68
|
+
Aker.configuration.logger = spec_logger
|
|
69
|
+
Aker.authority.valid_credentials?(:magic, "man").username.should == "jo"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "prefers a directly-set authority" do
|
|
73
|
+
Aker.configuration = Aker::Configuration.new { authority :static }
|
|
74
|
+
Aker.configuration.logger = spec_logger
|
|
75
|
+
Aker.authority.valid_credentials?(:cas, "ST-12345").should be_nil
|
|
76
|
+
Aker.authority = @auth
|
|
77
|
+
Aker.authority.valid_credentials?(:cas, "ST-12345").should_not be_nil
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|