aker 3.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/CHANGELOG.md +210 -0
  2. data/README.md +282 -0
  3. data/assets/aker/form/login.css +73 -0
  4. data/assets/aker/form/login.html.erb +44 -0
  5. data/lib/aker/authorities/automatic_access.rb +36 -0
  6. data/lib/aker/authorities/composite.rb +301 -0
  7. data/lib/aker/authorities/static.rb +283 -0
  8. data/lib/aker/authorities/support/find_sole_user.rb +24 -0
  9. data/lib/aker/authorities/support.rb +9 -0
  10. data/lib/aker/authorities.rb +46 -0
  11. data/lib/aker/cas/authority.rb +79 -0
  12. data/lib/aker/cas/configuration_helper.rb +85 -0
  13. data/lib/aker/cas/middleware/logout_responder.rb +49 -0
  14. data/lib/aker/cas/middleware/ticket_remover.rb +35 -0
  15. data/lib/aker/cas/middleware.rb +6 -0
  16. data/lib/aker/cas/proxy_mode.rb +108 -0
  17. data/lib/aker/cas/rack_proxy_callback.rb +188 -0
  18. data/lib/aker/cas/service_mode.rb +88 -0
  19. data/lib/aker/cas/service_url.rb +62 -0
  20. data/lib/aker/cas/user_ext.rb +64 -0
  21. data/lib/aker/cas.rb +31 -0
  22. data/lib/aker/central_parameters.rb +101 -0
  23. data/lib/aker/configuration.rb +534 -0
  24. data/lib/aker/deprecation.rb +105 -0
  25. data/lib/aker/form/custom_views_mode.rb +80 -0
  26. data/lib/aker/form/login_form_asset_provider.rb +56 -0
  27. data/lib/aker/form/middleware/custom_view_login_responder.rb +19 -0
  28. data/lib/aker/form/middleware/login_renderer.rb +72 -0
  29. data/lib/aker/form/middleware/login_responder.rb +71 -0
  30. data/lib/aker/form/middleware/logout_responder.rb +26 -0
  31. data/lib/aker/form/middleware.rb +10 -0
  32. data/lib/aker/form/mode.rb +118 -0
  33. data/lib/aker/form.rb +26 -0
  34. data/lib/aker/group.rb +67 -0
  35. data/lib/aker/group_membership.rb +162 -0
  36. data/lib/aker/ldap/authority.rb +392 -0
  37. data/lib/aker/ldap/user_ext.rb +19 -0
  38. data/lib/aker/ldap.rb +22 -0
  39. data/lib/aker/modes/base.rb +85 -0
  40. data/lib/aker/modes/http_basic.rb +100 -0
  41. data/lib/aker/modes/support/attempted_path.rb +22 -0
  42. data/lib/aker/modes/support/rfc_2617.rb +32 -0
  43. data/lib/aker/modes/support.rb +12 -0
  44. data/lib/aker/modes.rb +48 -0
  45. data/lib/aker/rack/authenticate.rb +37 -0
  46. data/lib/aker/rack/configuration_helper.rb +18 -0
  47. data/lib/aker/rack/default_logout_responder.rb +36 -0
  48. data/lib/aker/rack/environment_helper.rb +34 -0
  49. data/lib/aker/rack/facade.rb +102 -0
  50. data/lib/aker/rack/failure.rb +69 -0
  51. data/lib/aker/rack/logout.rb +63 -0
  52. data/lib/aker/rack/request_ext.rb +19 -0
  53. data/lib/aker/rack/session_timer.rb +95 -0
  54. data/lib/aker/rack/setup.rb +77 -0
  55. data/lib/aker/rack.rb +107 -0
  56. data/lib/aker/test/helpers.rb +22 -0
  57. data/lib/aker/test.rb +8 -0
  58. data/lib/aker/user.rb +231 -0
  59. data/lib/aker/version.rb +3 -0
  60. data/lib/aker.rb +51 -0
  61. data/spec/aker/aker-sample.yml +11 -0
  62. data/spec/aker/authorities/automatic_access_spec.rb +52 -0
  63. data/spec/aker/authorities/composite_spec.rb +488 -0
  64. data/spec/aker/authorities/nu-schema.jar +0 -0
  65. data/spec/aker/authorities/static_spec.rb +455 -0
  66. data/spec/aker/authorities/support/find_sole_user_spec.rb +33 -0
  67. data/spec/aker/authorities_spec.rb +16 -0
  68. data/spec/aker/cas/authority_spec.rb +106 -0
  69. data/spec/aker/cas/configuration_helper_spec.rb +92 -0
  70. data/spec/aker/cas/middleware/logout_responder_spec.rb +47 -0
  71. data/spec/aker/cas/middleware/ticket_remover_spec.rb +49 -0
  72. data/spec/aker/cas/proxy_mode_spec.rb +185 -0
  73. data/spec/aker/cas/rack_proxy_callback_spec.rb +190 -0
  74. data/spec/aker/cas/service_mode_spec.rb +122 -0
  75. data/spec/aker/cas/service_url_spec.rb +114 -0
  76. data/spec/aker/cas/user_ext_spec.rb +27 -0
  77. data/spec/aker/cas_spec.rb +19 -0
  78. data/spec/aker/central_parameters_spec.rb +44 -0
  79. data/spec/aker/configuration_spec.rb +465 -0
  80. data/spec/aker/deprecation_spec.rb +115 -0
  81. data/spec/aker/form/a_form_mode.rb +129 -0
  82. data/spec/aker/form/custom_views_mode_spec.rb +34 -0
  83. data/spec/aker/form/login_form_asset_provider_spec.rb +80 -0
  84. data/spec/aker/form/middleware/a_form_login_responder.rb +89 -0
  85. data/spec/aker/form/middleware/custom_view_login_responder_spec.rb +47 -0
  86. data/spec/aker/form/middleware/login_renderer_spec.rb +56 -0
  87. data/spec/aker/form/middleware/login_responder_spec.rb +34 -0
  88. data/spec/aker/form/middleware/logout_responder_spec.rb +55 -0
  89. data/spec/aker/form/mode_spec.rb +15 -0
  90. data/spec/aker/form_spec.rb +11 -0
  91. data/spec/aker/group_membership_spec.rb +208 -0
  92. data/spec/aker/group_spec.rb +66 -0
  93. data/spec/aker/ldap/authority_spec.rb +414 -0
  94. data/spec/aker/ldap/ldap-users.ldif +197 -0
  95. data/spec/aker/ldap_spec.rb +11 -0
  96. data/spec/aker/modes/a_aker_mode.rb +41 -0
  97. data/spec/aker/modes/http_basic_spec.rb +127 -0
  98. data/spec/aker/modes/support/attempted_path_spec.rb +32 -0
  99. data/spec/aker/modes_spec.rb +11 -0
  100. data/spec/aker/rack/authenticate_spec.rb +78 -0
  101. data/spec/aker/rack/default_logout_responder_spec.rb +67 -0
  102. data/spec/aker/rack/facade_spec.rb +154 -0
  103. data/spec/aker/rack/failure_spec.rb +151 -0
  104. data/spec/aker/rack/logout_spec.rb +63 -0
  105. data/spec/aker/rack/request_ext_spec.rb +29 -0
  106. data/spec/aker/rack/session_timer_spec.rb +134 -0
  107. data/spec/aker/rack/setup_spec.rb +87 -0
  108. data/spec/aker/rack_spec.rb +216 -0
  109. data/spec/aker/test/helpers_spec.rb +44 -0
  110. data/spec/aker/user_spec.rb +362 -0
  111. data/spec/aker_spec.rb +80 -0
  112. data/spec/deprecation_helper.rb +58 -0
  113. data/spec/java_helper.rb +5 -0
  114. data/spec/logger_helper.rb +17 -0
  115. data/spec/matchers.rb +31 -0
  116. data/spec/mock_builder.rb +25 -0
  117. data/spec/spec_helper.rb +52 -0
  118. 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