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
data/lib/aker/rack.rb
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require 'aker'
|
|
2
|
+
require 'warden'
|
|
3
|
+
|
|
4
|
+
##
|
|
5
|
+
# Integration of Aker with {http://rack.rubyforge.org/ Rack}.
|
|
6
|
+
module Aker::Rack
|
|
7
|
+
autoload :Authenticate, 'aker/rack/authenticate'
|
|
8
|
+
autoload :ConfigurationHelper, 'aker/rack/configuration_helper'
|
|
9
|
+
autoload :DefaultLogoutResponder, 'aker/rack/default_logout_responder'
|
|
10
|
+
autoload :EnvironmentHelper, 'aker/rack/environment_helper'
|
|
11
|
+
autoload :Facade, 'aker/rack/facade'
|
|
12
|
+
autoload :Failure, 'aker/rack/failure'
|
|
13
|
+
autoload :Logout, 'aker/rack/logout'
|
|
14
|
+
autoload :RequestExt, 'aker/rack/request_ext'
|
|
15
|
+
autoload :SessionTimer, 'aker/rack/session_timer'
|
|
16
|
+
autoload :Setup, 'aker/rack/setup'
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
##
|
|
20
|
+
# Configures all the necessary middleware for Aker into the given
|
|
21
|
+
# rack application stack. With `Rack::Builder`:
|
|
22
|
+
#
|
|
23
|
+
# Rack::Builder.new do
|
|
24
|
+
# Aker::Rack.use_in(self) # self is the builder instance
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# Aker's middleware stack relies on the existence of a session,
|
|
28
|
+
# so the session-enabling middleware must be higher in the
|
|
29
|
+
# application stack than Aker.
|
|
30
|
+
#
|
|
31
|
+
# @param [#use] builder the target application builder. This
|
|
32
|
+
# could be a `Rack::Builder` object or something that acts like
|
|
33
|
+
# one.
|
|
34
|
+
# @param [Aker::Configuration,nil] configuration the
|
|
35
|
+
# configuration to apply to this use. If nil, uses the global
|
|
36
|
+
# configuration ({Aker.configuration}).
|
|
37
|
+
# @return [void]
|
|
38
|
+
def use_in(builder, configuration=nil)
|
|
39
|
+
effective_configuration = configuration || Aker.configuration
|
|
40
|
+
unless effective_configuration
|
|
41
|
+
fail "No configuration was provided and there's no global configuration. " <<
|
|
42
|
+
"Please set one or the other before calling use_in."
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
install_modes(effective_configuration)
|
|
46
|
+
|
|
47
|
+
builder.use Setup, effective_configuration
|
|
48
|
+
|
|
49
|
+
with_mode_middlewares(builder, effective_configuration) do
|
|
50
|
+
effective_configuration.install_middleware(:before_authentication, builder)
|
|
51
|
+
builder.use Warden::Manager do |manager|
|
|
52
|
+
manager.failure_app = Aker::Rack::Failure.new
|
|
53
|
+
end
|
|
54
|
+
builder.use SessionTimer
|
|
55
|
+
builder.use Authenticate
|
|
56
|
+
effective_configuration.install_middleware(:after_authentication, builder)
|
|
57
|
+
builder.use Logout
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
builder.use DefaultLogoutResponder
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# @return [void]
|
|
67
|
+
def install_modes(configuration)
|
|
68
|
+
configuration.registered_modes.each do |mode|
|
|
69
|
+
Warden::Strategies.add(mode.key, mode)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
##
|
|
74
|
+
# @return [void]
|
|
75
|
+
def with_mode_middlewares(builder, conf)
|
|
76
|
+
mode_classes(conf).each { |m| m.prepend_middleware(builder) if m.respond_to?(:prepend_middleware) }
|
|
77
|
+
yield
|
|
78
|
+
mode_classes(conf).each { |m| m.append_middleware(builder) if m.respond_to?(:append_middleware) }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def mode_classes(configuration)
|
|
82
|
+
return [] unless configuration
|
|
83
|
+
|
|
84
|
+
[configuration.ui_mode, configuration.api_modes].flatten.map do |key|
|
|
85
|
+
Warden::Strategies[key]
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def logout_path(configuration)
|
|
90
|
+
configuration.parameters_for(:rack)[:logout_path]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
##
|
|
95
|
+
# @private
|
|
96
|
+
class Slice < Aker::Configuration::Slice
|
|
97
|
+
def initialize
|
|
98
|
+
super do
|
|
99
|
+
rack_parameters :login_path => '/login', :logout_path => '/logout'
|
|
100
|
+
|
|
101
|
+
policy_parameters :'session-timeout-seconds' => 1800
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
Aker::Configuration.add_default_slice(Aker::Rack::Slice.new)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w(.. test))
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Contains helpers for writing tests on aker-protected code.
|
|
5
|
+
module Aker::Test::Helpers
|
|
6
|
+
##
|
|
7
|
+
# Generates an environment hash that marks `user` as logged in. You can use
|
|
8
|
+
# the generated hash in pre-existing requests, merge the hash with the
|
|
9
|
+
# environment generated by `Rack::MockRequest.env_for`, etc.
|
|
10
|
+
#
|
|
11
|
+
# @param [String,Aker::User] user
|
|
12
|
+
# a user's username or a {Aker::User} object. Your Aker configuration
|
|
13
|
+
# must use an authority that implements `find_user` for username lookup to
|
|
14
|
+
# work.
|
|
15
|
+
# @return [Hash<String, Aker::Rack::Facade>] a Hash of the form
|
|
16
|
+
# `{'aker' => (a Aker::Rack::Facade)}`
|
|
17
|
+
def login_env(user)
|
|
18
|
+
u = Aker::User === user ? user : Aker.authority.find_user(user)
|
|
19
|
+
|
|
20
|
+
{ 'aker.check' => Aker::Rack::Facade.new(Aker.configuration, u) }
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/aker/test.rb
ADDED
data/lib/aker/user.rb
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
require 'aker'
|
|
2
|
+
|
|
3
|
+
module Aker
|
|
4
|
+
##
|
|
5
|
+
# @private
|
|
6
|
+
module DeprecatedUser
|
|
7
|
+
[:nu_employee_id, :personnel_id].each do |deprec_id|
|
|
8
|
+
define_method deprec_id do
|
|
9
|
+
Deprecation.notify(
|
|
10
|
+
"#{deprec_id} is deprecated. Use identifiers[#{deprec_id.inspect}] instead.", "3.0")
|
|
11
|
+
identifiers[deprec_id]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
define_method "#{deprec_id}=" do |value|
|
|
15
|
+
Deprecation.notify(
|
|
16
|
+
"#{deprec_id} is deprecated. Use identifiers[#{deprec_id.inspect}] instead.", "3.0")
|
|
17
|
+
identifiers[deprec_id] = value
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class User
|
|
23
|
+
include DeprecatedUser
|
|
24
|
+
|
|
25
|
+
ATTRIBUTES = :username, :first_name, :middle_name, :last_name,
|
|
26
|
+
:title, :business_phone, :fax, :email, :address, :city, :state, :country
|
|
27
|
+
|
|
28
|
+
attr_accessor *ATTRIBUTES
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# Specifies a default portal to use for subsequent calls which
|
|
32
|
+
# take a portal as a parameter.
|
|
33
|
+
#
|
|
34
|
+
# @return [Symbol, nil]
|
|
35
|
+
attr_accessor :default_portal
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# The portals to which this user has access.
|
|
39
|
+
#
|
|
40
|
+
# @return [Array<Symbol>]
|
|
41
|
+
# @see #may_access?
|
|
42
|
+
attr_accessor :portals
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# Creates a new instance.
|
|
46
|
+
#
|
|
47
|
+
# @param [String] username the username for this new user
|
|
48
|
+
# @param [Array<Symbol>] portals the portals to which this user
|
|
49
|
+
# has access.
|
|
50
|
+
def initialize(username, portals=[])
|
|
51
|
+
@username = username
|
|
52
|
+
@portals = [*portals]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# @param [#to_sym,nil] portal the portal in question. If nil,
|
|
57
|
+
# uses {#default_portal}.
|
|
58
|
+
# @return [Boolean] true if the user has access, otherwise false.
|
|
59
|
+
def may_access?(portal=nil)
|
|
60
|
+
portals.include?((portal || required_default_portal).to_sym)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
##
|
|
64
|
+
# @overload permit?(*groups, options={})
|
|
65
|
+
# Determines whether this user has access to any of the given
|
|
66
|
+
# groups.
|
|
67
|
+
# @param [Array<#to_sym>] groups the names of the groups to query
|
|
68
|
+
# @param [Hash] options additional constraints on the query
|
|
69
|
+
# @option options [#to_sym] :portal (#default_portal) the portal
|
|
70
|
+
# within which to do the group check
|
|
71
|
+
# @return [Boolean]
|
|
72
|
+
#
|
|
73
|
+
# @overload permit?(*groups, options={}, &block)
|
|
74
|
+
# Evaluates the given block if the user is in any of the given
|
|
75
|
+
# groups.
|
|
76
|
+
# @param [Array<#to_sym>] groups the names of the groups to use
|
|
77
|
+
# as the condition
|
|
78
|
+
# @param [Hash] options additional constraints on the condition
|
|
79
|
+
# @option options [#to_sym] :portal (#default_portal) the portal
|
|
80
|
+
# within which to do the group check
|
|
81
|
+
# @return [Object,nil] the value of the block if it is
|
|
82
|
+
# executed; otherwise nil
|
|
83
|
+
def permit?(*args)
|
|
84
|
+
options = args.last.is_a?(Hash) ? args.pop : { }
|
|
85
|
+
portal = options[:portal] || default_portal
|
|
86
|
+
|
|
87
|
+
permitted =
|
|
88
|
+
if args.empty?
|
|
89
|
+
may_access?(portal)
|
|
90
|
+
else
|
|
91
|
+
args.detect { |group| group_memberships(portal).include?(group.to_sym) }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if block_given?
|
|
95
|
+
permitted ? yield : nil
|
|
96
|
+
else
|
|
97
|
+
permitted
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# A display-friendly name for this user. Uses `first_name` and
|
|
103
|
+
# `last_name` if available, otherwise it just uses the username.
|
|
104
|
+
#
|
|
105
|
+
# @return [String]
|
|
106
|
+
def full_name
|
|
107
|
+
display_name_parts = [first_name, last_name].compact
|
|
108
|
+
if display_name_parts.empty?
|
|
109
|
+
username
|
|
110
|
+
else
|
|
111
|
+
display_name_parts.join(' ')
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
##
|
|
116
|
+
# A mapping of identifers that apply to this user. The values that
|
|
117
|
+
# might be set in this hash are defined by authorities.
|
|
118
|
+
#
|
|
119
|
+
# @since 2.2.0
|
|
120
|
+
# @return [Hash<Symbol, Object>] the identifiers for this user.
|
|
121
|
+
def identifiers
|
|
122
|
+
@identifiers ||= {}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def portals
|
|
126
|
+
@portals ||= []
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
##
|
|
130
|
+
# Exposes the {GroupMemberships group memberships} for a
|
|
131
|
+
# this user on a particular portal.
|
|
132
|
+
#
|
|
133
|
+
# This method never returns `nil`. Therefore, its return value
|
|
134
|
+
# should not be used to determine if a user has access to a portal
|
|
135
|
+
# — only for groups. Use {#may_access?} to determine portal
|
|
136
|
+
# access.
|
|
137
|
+
#
|
|
138
|
+
# @param [#to_sym,nil] portal the portal to get the memberships
|
|
139
|
+
# for. If nil, uses {#default_portal}.
|
|
140
|
+
#
|
|
141
|
+
# @return [GroupMemberships] for a particular portal
|
|
142
|
+
#
|
|
143
|
+
# @see GroupMemberships#include?
|
|
144
|
+
def group_memberships(portal=nil)
|
|
145
|
+
portal = (portal || required_default_portal).to_sym
|
|
146
|
+
all_group_memberships[portal] ||= GroupMemberships.new(portal)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
##
|
|
150
|
+
# Exposes all the group memberships that this instance knows
|
|
151
|
+
# about. In general, {#group_memberships} is preferred unless you
|
|
152
|
+
# really need to iterate over everything.
|
|
153
|
+
#
|
|
154
|
+
# @return [Hash<Symbol, GroupMemberships>]
|
|
155
|
+
def all_group_memberships
|
|
156
|
+
@gms ||= {}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def default_portal=(val)
|
|
160
|
+
@default_portal = val.nil? ? nil : val.to_sym
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
##
|
|
164
|
+
# Modifies this user record in place, adding attributes from the
|
|
165
|
+
# other user. Merge rules:
|
|
166
|
+
#
|
|
167
|
+
# * For portals: the resulting portal list is a union of the
|
|
168
|
+
# portal list for this and the _other_ user.
|
|
169
|
+
# * For group memberships: group memberships are added from
|
|
170
|
+
# the _other_ user for all portals which this user doesn't
|
|
171
|
+
# already have group memberships. (That is, the group
|
|
172
|
+
# membership lists for a particular portal are not merged.)
|
|
173
|
+
# This rule is to prevent ambiguity if different
|
|
174
|
+
# authorities have different group hierarchies. In
|
|
175
|
+
# practice only one authority is providing authorization
|
|
176
|
+
# information for a portal, so this shouldn't matter.
|
|
177
|
+
# * For identifiers: any identifier in the _other_ user that is
|
|
178
|
+
# not already set in this user is copied over.
|
|
179
|
+
# * For all other attributes: an attribute is copied from
|
|
180
|
+
# _other_ if that attribute is not already set in this
|
|
181
|
+
# user.
|
|
182
|
+
#
|
|
183
|
+
# Note that these semantics are different from the semantics of
|
|
184
|
+
# `Hash#merge!` in the ruby standard library.
|
|
185
|
+
#
|
|
186
|
+
# @param [Aker::User] other the user from which to take attribute
|
|
187
|
+
# values
|
|
188
|
+
#
|
|
189
|
+
# @return [Aker::User] self
|
|
190
|
+
def merge!(other)
|
|
191
|
+
ATTRIBUTES.each do |getter|
|
|
192
|
+
already_set =
|
|
193
|
+
begin
|
|
194
|
+
self.send(getter)
|
|
195
|
+
rescue
|
|
196
|
+
false
|
|
197
|
+
end
|
|
198
|
+
unless already_set
|
|
199
|
+
setter = :"#{getter}="
|
|
200
|
+
value =
|
|
201
|
+
begin
|
|
202
|
+
other.send(getter)
|
|
203
|
+
rescue
|
|
204
|
+
nil # skip inaccessible attributes
|
|
205
|
+
end
|
|
206
|
+
self.send setter, value
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
self.default_portal ||= other.default_portal
|
|
211
|
+
self.portals |= other.portals
|
|
212
|
+
other.all_group_memberships.keys.each do |other_portal|
|
|
213
|
+
if self.group_memberships(other_portal).empty?
|
|
214
|
+
self.group_memberships(other_portal).concat(other.group_memberships(other_portal))
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
other.identifiers.each do |ident, value|
|
|
218
|
+
identifiers[ident] ||= value
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
self
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
protected
|
|
225
|
+
|
|
226
|
+
def required_default_portal
|
|
227
|
+
default_portal or raise "No default portal set. Please specify one explicitly."
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
data/lib/aker/version.rb
ADDED
data/lib/aker.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Aker
|
|
2
|
+
autoload :CentralParameters, 'aker/central_parameters'
|
|
3
|
+
autoload :Configuration, 'aker/configuration'
|
|
4
|
+
autoload :Deprecation, 'aker/deprecation'
|
|
5
|
+
autoload :Group, 'aker/group'
|
|
6
|
+
autoload :GroupMemberships, 'aker/group_membership'
|
|
7
|
+
autoload :GroupMembership, 'aker/group_membership'
|
|
8
|
+
autoload :User, 'aker/user'
|
|
9
|
+
autoload :Test, 'aker/test'
|
|
10
|
+
autoload :VERSION, 'aker/version'
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
##
|
|
14
|
+
# @return [Configuration,nil] the single configuration for the
|
|
15
|
+
# system using aker. Created/updated using {.configure
|
|
16
|
+
# configure}.
|
|
17
|
+
attr_accessor :configuration
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# @return [Object,nil] a single authentication/authorization entry
|
|
21
|
+
# point conforming to the authority protocol as defined by
|
|
22
|
+
# {Aker::Authorities::Composite}. By default, it is
|
|
23
|
+
# automatically derived from the {.configuration configuration}.
|
|
24
|
+
# @see Aker::Configuration#composite_authority
|
|
25
|
+
attr_accessor :authority
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Create/update the global aker configuration. Accepts a block
|
|
29
|
+
# containing expressions in the {Configuration} DSL.
|
|
30
|
+
#
|
|
31
|
+
# @see Aker.configuration
|
|
32
|
+
# @return [Configuration]
|
|
33
|
+
def configure(&block)
|
|
34
|
+
@configuration ||= Aker::Configuration.new
|
|
35
|
+
@configuration.enhance(&block)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def authority
|
|
39
|
+
@authority || (@configuration && @configuration.composite_authority)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# These files are required instead of autoloaded so that their
|
|
45
|
+
# configuration slices are installed immediately.
|
|
46
|
+
require 'aker/authorities'
|
|
47
|
+
require 'aker/cas'
|
|
48
|
+
require 'aker/form'
|
|
49
|
+
require 'aker/ldap'
|
|
50
|
+
require 'aker/modes'
|
|
51
|
+
require 'aker/rack'
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require File.expand_path("../../../spec_helper", __FILE__)
|
|
2
|
+
|
|
3
|
+
module Aker::Authorities
|
|
4
|
+
describe AutomaticAccess do
|
|
5
|
+
describe "initialization" do
|
|
6
|
+
it "fails if the configuration has no portal" do
|
|
7
|
+
lambda { AutomaticAccess.new(Aker::Configuration.new) }.should raise_error(
|
|
8
|
+
"AutomaticAccess is unnecessary if you don't have a portal configured.")
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "#amplify!" do
|
|
13
|
+
before do
|
|
14
|
+
@authority = AutomaticAccess.new(Aker::Configuration.new { portal :ENU })
|
|
15
|
+
@user = Aker::User.new('jo')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "adds the configured portal to the portal list" do
|
|
19
|
+
@authority.amplify!(@user)
|
|
20
|
+
@user.portals.should include(:ENU)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "does not add the portal if it is already there" do
|
|
24
|
+
@user.portals << :ENU
|
|
25
|
+
@authority.amplify!(@user)
|
|
26
|
+
@user.portals.size.should == 1
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "sets the default portal if it isn't already set" do
|
|
30
|
+
@authority.amplify!(@user)
|
|
31
|
+
@user.default_portal.should == :ENU
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "leaves an existing default portal alone" do
|
|
35
|
+
@user.default_portal = :NOTIS
|
|
36
|
+
@authority.amplify!(@user)
|
|
37
|
+
@user.default_portal.should == :NOTIS
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "returns the user" do
|
|
41
|
+
@authority.amplify!(@user).should === @user
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "grants the user access" do
|
|
45
|
+
@user.may_access?(:ENU).should be_false
|
|
46
|
+
@authority.amplify!(@user)
|
|
47
|
+
@user.may_access?(:ENU).should be_true
|
|
48
|
+
@user.may_access?.should be_true
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|