gds-sso 19.0.0 → 19.1.0
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.
- checksums.yaml +4 -4
- data/lib/gds-sso/authorise_user.rb +49 -0
- data/lib/gds-sso/authorised_user_constraint.rb +21 -0
- data/lib/gds-sso/config.rb +3 -0
- data/lib/gds-sso/controller_methods.rb +11 -34
- data/lib/gds-sso/failure_app.rb +1 -1
- data/lib/gds-sso/railtie.rb +4 -0
- data/lib/gds-sso/version.rb +1 -1
- data/lib/gds-sso/warden_config.rb +1 -1
- data/lib/gds-sso.rb +8 -4
- data/lib/omniauth/strategies/gds.rb +1 -1
- data/spec/controller/controller_methods_spec.rb +14 -47
- data/spec/internal/app/controllers/example_controller.rb +4 -1
- data/spec/internal/config/routes.rb +4 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/test_user.rb +2 -0
- data/spec/system/authentication_and_authorisation_spec.rb +23 -2
- data/spec/unit/authorise_user_spec.rb +69 -0
- data/spec/unit/authorised_user_constraint_spec.rb +50 -0
- data/spec/unit/railtie_spec.rb +19 -0
- metadata +18 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71c0501986a461e92a2a6b176ded8dce5c191f2b735465ab4bb0d62fa21692a6
|
4
|
+
data.tar.gz: c4498c2a13b319f7dcdf2f3280a5aeee424c7881c79ed031dc2242bddba4c9bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65e314e7c2d79c2268a391d03cc5a3ce8501c17f2c024890222a434491425ab68c06e28fb4c992f65c1181189ba0c6a7f5a4d9078e9db8905bc90440913e8f0c
|
7
|
+
data.tar.gz: 9191a650b590f2099a73b8d86153ea87c7e3f93ef54b965cf7804257729864e07fa215efff25174881afe53c325ac02d1f49319a5fd10f81d09a61786e7657c9
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module GDS
|
2
|
+
module SSO
|
3
|
+
class AuthoriseUser
|
4
|
+
def self.call(...) = new(...).call
|
5
|
+
|
6
|
+
def initialize(current_user, permissions)
|
7
|
+
@current_user = current_user
|
8
|
+
@permissions = permissions
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
case permissions
|
13
|
+
when String
|
14
|
+
unless current_user.has_permission?(permissions)
|
15
|
+
raise GDS::SSO::PermissionDeniedError, "Sorry, you don't seem to have the #{permissions} permission for this app."
|
16
|
+
end
|
17
|
+
when Hash
|
18
|
+
raise ArgumentError, "Must be either `any_of` or `all_of`" unless permissions.keys.size == 1
|
19
|
+
|
20
|
+
if permissions[:any_of]
|
21
|
+
authorise_user_with_at_least_one_of_permissions!(permissions[:any_of])
|
22
|
+
elsif permissions[:all_of]
|
23
|
+
authorise_user_with_all_permissions!(permissions[:all_of])
|
24
|
+
else
|
25
|
+
raise ArgumentError, "Must be either `any_of` or `all_of`"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :current_user, :permissions
|
33
|
+
|
34
|
+
def authorise_user_with_at_least_one_of_permissions!(permissions)
|
35
|
+
if permissions.none? { |permission| current_user.has_permission?(permission) }
|
36
|
+
raise GDS::SSO::PermissionDeniedError,
|
37
|
+
"Sorry, you don't seem to have any of the permissions: #{permissions.to_sentence} for this app."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def authorise_user_with_all_permissions!(permissions)
|
42
|
+
unless permissions.all? { |permission| current_user.has_permission?(permission) }
|
43
|
+
raise GDS::SSO::PermissionDeniedError,
|
44
|
+
"Sorry, you don't seem to have all of the permissions: #{permissions.to_sentence} for this app."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GDS
|
2
|
+
module SSO
|
3
|
+
class AuthorisedUserConstraint
|
4
|
+
def initialize(permissions)
|
5
|
+
@permissions = permissions
|
6
|
+
end
|
7
|
+
|
8
|
+
def matches?(request)
|
9
|
+
warden = request.env["warden"]
|
10
|
+
warden.authenticate! if !warden.authenticated? || warden.user.remotely_signed_out?
|
11
|
+
|
12
|
+
GDS::SSO::AuthoriseUser.call(warden.user, permissions)
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :permissions
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/gds-sso/config.rb
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
module GDS
|
2
2
|
module SSO
|
3
|
+
class PermissionDeniedError < StandardError
|
4
|
+
end
|
5
|
+
|
3
6
|
module ControllerMethods
|
4
|
-
|
7
|
+
# TODO: remove this for the next major release
|
8
|
+
class PermissionDeniedException < PermissionDeniedError
|
9
|
+
def initialize(...)
|
10
|
+
warn "GDS::SSO::ControllerMethods::PermissionDeniedException is deprecated, please replace with GDS::SSO::PermissionDeniedError"
|
11
|
+
super(...)
|
12
|
+
end
|
5
13
|
end
|
6
14
|
|
7
15
|
def self.included(base)
|
8
|
-
base.rescue_from
|
16
|
+
base.rescue_from PermissionDeniedError do |e|
|
9
17
|
if GDS::SSO::Config.api_only
|
10
18
|
render json: { message: e.message }, status: :forbidden
|
11
19
|
else
|
@@ -24,22 +32,7 @@ module GDS
|
|
24
32
|
# Otherwise current_user might be nil, and we'd error out
|
25
33
|
authenticate_user!
|
26
34
|
|
27
|
-
|
28
|
-
when String
|
29
|
-
unless current_user.has_permission?(permissions)
|
30
|
-
raise PermissionDeniedException, "Sorry, you don't seem to have the #{permissions} permission for this app."
|
31
|
-
end
|
32
|
-
when Hash
|
33
|
-
raise ArgumentError, "Must be either `any_of` or `all_of`" unless permissions.keys.size == 1
|
34
|
-
|
35
|
-
if permissions[:any_of]
|
36
|
-
authorise_user_with_at_least_one_of_permissions!(permissions[:any_of])
|
37
|
-
elsif permissions[:all_of]
|
38
|
-
authorise_user_with_all_permissions!(permissions[:all_of])
|
39
|
-
else
|
40
|
-
raise ArgumentError, "Must be either `any_of` or `all_of`"
|
41
|
-
end
|
42
|
-
end
|
35
|
+
GDS::SSO::AuthoriseUser.call(current_user, permissions)
|
43
36
|
end
|
44
37
|
|
45
38
|
def authenticate_user!
|
@@ -65,22 +58,6 @@ module GDS
|
|
65
58
|
def warden
|
66
59
|
request.env["warden"]
|
67
60
|
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
def authorise_user_with_at_least_one_of_permissions!(permissions)
|
72
|
-
if permissions.none? { |permission| current_user.has_permission?(permission) }
|
73
|
-
raise PermissionDeniedException,
|
74
|
-
"Sorry, you don't seem to have any of the permissions: #{permissions.to_sentence} for this app."
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def authorise_user_with_all_permissions!(permissions)
|
79
|
-
unless permissions.all? { |permission| current_user.has_permission?(permission) }
|
80
|
-
raise PermissionDeniedException,
|
81
|
-
"Sorry, you don't seem to have all of the permissions: #{permissions.to_sentence} for this app."
|
82
|
-
end
|
83
|
-
end
|
84
61
|
end
|
85
62
|
end
|
86
63
|
end
|
data/lib/gds-sso/failure_app.rb
CHANGED
@@ -52,7 +52,7 @@ module GDS
|
|
52
52
|
|
53
53
|
def api_unauthorized(message, bearer_error)
|
54
54
|
headers["WWW-Authenticate"] = %(Bearer error="#{bearer_error}")
|
55
|
-
render json: { message:
|
55
|
+
render json: { message: }, status: :unauthorized
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
data/lib/gds-sso/railtie.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
module GDS
|
2
2
|
module SSO
|
3
3
|
class Railtie < Rails::Railtie
|
4
|
+
config.action_dispatch.rescue_responses.merge!(
|
5
|
+
"GDS::SSO::PermissionDeniedError" => :forbidden,
|
6
|
+
)
|
7
|
+
|
4
8
|
initializer "gds-sso.initializer" do
|
5
9
|
GDS::SSO.config do |config|
|
6
10
|
config.cache = Rails.cache
|
data/lib/gds-sso/version.rb
CHANGED
@@ -29,7 +29,7 @@ Warden::Manager.serialize_from_session do |(uid, auth_timestamp)|
|
|
29
29
|
end
|
30
30
|
|
31
31
|
if auth_timestamp && ((auth_timestamp + GDS::SSO::Config.auth_valid_for) > Time.now.utc)
|
32
|
-
GDS::SSO::Config.user_klass.where(uid
|
32
|
+
GDS::SSO::Config.user_klass.where(uid:, remotely_signed_out: false).first
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
data/lib/gds-sso.rb
CHANGED
@@ -10,10 +10,13 @@ require "gds-sso/railtie" if defined?(Rails)
|
|
10
10
|
|
11
11
|
module GDS
|
12
12
|
module SSO
|
13
|
-
autoload :FailureApp,
|
14
|
-
autoload :ControllerMethods,
|
15
|
-
autoload :User,
|
16
|
-
autoload :ApiAccess,
|
13
|
+
autoload :FailureApp, "gds-sso/failure_app"
|
14
|
+
autoload :ControllerMethods, "gds-sso/controller_methods"
|
15
|
+
autoload :User, "gds-sso/user"
|
16
|
+
autoload :ApiAccess, "gds-sso/api_access"
|
17
|
+
autoload :AuthoriseUser, "gds-sso/authorise_user"
|
18
|
+
autoload :AuthorisedUserConstraint, "gds-sso/authorised_user_constraint"
|
19
|
+
autoload :PermissionDeniedError, "gds-sso/controller_methods"
|
17
20
|
|
18
21
|
# User to return as logged in during tests
|
19
22
|
mattr_accessor :test_user
|
@@ -52,6 +55,7 @@ module GDS
|
|
52
55
|
config.app_middleware.use Warden::Manager do |config|
|
53
56
|
config.default_strategies(*default_strategies)
|
54
57
|
config.failure_app = GDS::SSO::FailureApp
|
58
|
+
config.intercept_401 = GDS::SSO::Config.intercept_401_responses
|
55
59
|
end
|
56
60
|
end
|
57
61
|
end
|
@@ -1,57 +1,24 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
RSpec.describe GDS::SSO::ControllerMethods
|
4
|
-
|
5
|
-
|
3
|
+
RSpec.describe GDS::SSO::ControllerMethods do
|
4
|
+
describe "#authorise_user!" do
|
5
|
+
let(:current_user) { double }
|
6
|
+
let(:expected_error) { GDS::SSO::PermissionDeniedError }
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
context "when the user is authorised" do
|
9
|
+
it "does not raise an error" do
|
10
|
+
allow(current_user).to receive(:has_permission?).with("good").and_return(true)
|
10
11
|
|
11
|
-
|
12
|
+
expect { ControllerSpy.new(current_user).authorise_user!("good") }.not_to raise_error
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
+
context "when the user is not authorised" do
|
17
|
+
it "raises an error" do
|
18
|
+
allow(current_user).to receive(:has_permission?).with("bad").and_return(false)
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
context "with the `all_of` option" do
|
22
|
-
it "permits users with all of the required permissions" do
|
23
|
-
allow(current_user).to receive(:has_permission?).with("good").and_return(true)
|
24
|
-
allow(current_user).to receive(:has_permission?).with("bad").and_return(true)
|
25
|
-
|
26
|
-
expect { ControllerSpy.new(current_user).authorise_user!(all_of: %w[good bad]) }.not_to raise_error
|
27
|
-
end
|
28
|
-
|
29
|
-
it "does not permit users without all of the required permissions" do
|
30
|
-
allow(current_user).to receive(:has_permission?).with("good").and_return(false)
|
31
|
-
allow(current_user).to receive(:has_permission?).with("bad").and_return(true)
|
32
|
-
|
33
|
-
expect { ControllerSpy.new(current_user).authorise_user!(all_of: %w[good bad]) }.to raise_error(expected_error)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
context "with the `any_of` option" do
|
38
|
-
it "permits users with any of the required permissions" do
|
39
|
-
allow(current_user).to receive(:has_permission?).with("good").and_return(true)
|
40
|
-
allow(current_user).to receive(:has_permission?).with("bad").and_return(false)
|
41
|
-
|
42
|
-
expect { ControllerSpy.new(current_user).authorise_user!(any_of: %w[good bad]) }.not_to raise_error
|
43
|
-
end
|
44
|
-
|
45
|
-
it "does not permit users without any of the required permissions" do
|
46
|
-
allow(current_user).to receive(:has_permission?).and_return(false)
|
47
|
-
|
48
|
-
expect { ControllerSpy.new(current_user).authorise_user!(any_of: %w[good bad]) }.to raise_error(expected_error)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context "with none of `any_of` or `all_of`" do
|
53
|
-
it "raises an `ArgumentError`" do
|
54
|
-
expect { ControllerSpy.new(current_user).authorise_user!(whoops: "bad") }.to raise_error(ArgumentError)
|
20
|
+
expect { ControllerSpy.new(current_user).authorise_user!("bad") }.to raise_error(expected_error)
|
21
|
+
end
|
55
22
|
end
|
56
23
|
end
|
57
24
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class ExampleController < ApplicationController
|
2
2
|
before_action :authenticate_user!, except: :not_restricted
|
3
3
|
before_action -> { authorise_user!("execute") }, only: :this_requires_execute_permission
|
4
|
-
|
5
4
|
def not_restricted
|
6
5
|
render body: "jabberwocky"
|
7
6
|
end
|
@@ -13,4 +12,8 @@ class ExampleController < ApplicationController
|
|
13
12
|
def this_requires_execute_permission
|
14
13
|
render body: "you have execute permission"
|
15
14
|
end
|
15
|
+
|
16
|
+
def constraint_restricted
|
17
|
+
render body: "constraint restricted"
|
18
|
+
end
|
16
19
|
end
|
@@ -4,4 +4,8 @@ Rails.application.routes.draw do
|
|
4
4
|
get "/not-restricted" => "example#not_restricted"
|
5
5
|
get "/restricted" => "example#restricted"
|
6
6
|
get "/this-requires-execute-permission" => "example#this_requires_execute_permission"
|
7
|
+
|
8
|
+
constraints(GDS::SSO::AuthorisedUserConstraint.new("execute")) do
|
9
|
+
get "/constraint-restricted" => "example#constraint_restricted"
|
10
|
+
end
|
7
11
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/test_user.rb
CHANGED
@@ -119,6 +119,27 @@ RSpec.describe "Authenication and authorisation" do
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
+
context "when accessing a route that is restricted by the authorised user constraint" do
|
123
|
+
it "allows access when an authenticated user has correct permissions" do
|
124
|
+
stub_signon_authenticated(permissions: %w[execute])
|
125
|
+
visit "/constraint-restricted"
|
126
|
+
expect(page).to have_content("constraint restricted")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "redirects an unauthenticated request to signon" do
|
130
|
+
visit "/constraint-restricted"
|
131
|
+
expect(page.response_headers["Location"]).to match("/auth/gds")
|
132
|
+
visit page.response_headers["Location"]
|
133
|
+
expect(page.response_headers["Location"]).to match("http://signon/oauth/authorize")
|
134
|
+
end
|
135
|
+
|
136
|
+
it "restricts access when an authenticated user does not have the correct permissions" do
|
137
|
+
stub_signon_authenticated(permissions: %w[no-access])
|
138
|
+
visit "/constraint-restricted"
|
139
|
+
expect(page.status_code).to eq(403)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
122
143
|
def stub_signon_authenticated(permissions: [])
|
123
144
|
# visit restricted page to trigger redirect URL to record state attribute
|
124
145
|
visit "/auth/gds"
|
@@ -129,7 +150,7 @@ RSpec.describe "Authenication and authorisation" do
|
|
129
150
|
.to_return(body: { access_token: "token" }.to_json,
|
130
151
|
headers: { content_type: "application/json" })
|
131
152
|
|
132
|
-
stub_signon_user_request(permissions:
|
153
|
+
stub_signon_user_request(permissions:)
|
133
154
|
|
134
155
|
visit "/auth/gds/callback?code=code&state=#{state}"
|
135
156
|
end
|
@@ -142,7 +163,7 @@ RSpec.describe "Authenication and authorisation" do
|
|
142
163
|
uid: "123",
|
143
164
|
email: "test-user@example.com",
|
144
165
|
name: "Test User",
|
145
|
-
permissions
|
166
|
+
permissions:,
|
146
167
|
},
|
147
168
|
}.to_json,
|
148
169
|
headers: { content_type: "application/json" },
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "gds-sso/authorise_user"
|
3
|
+
|
4
|
+
describe GDS::SSO::AuthoriseUser do
|
5
|
+
describe "#call" do
|
6
|
+
let(:current_user) { double }
|
7
|
+
|
8
|
+
context "with a single string permission argument" do
|
9
|
+
let(:permissions) { "admin" }
|
10
|
+
let(:expected_error) { GDS::SSO::PermissionDeniedError }
|
11
|
+
|
12
|
+
it "permits users with the required permission" do
|
13
|
+
allow(current_user).to receive(:has_permission?).with("admin").and_return(true)
|
14
|
+
|
15
|
+
expect { described_class.call(current_user, permissions) }.not_to raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it "does not permit the users without the required permission" do
|
19
|
+
allow(current_user).to receive(:has_permission?).with("admin").and_return(false)
|
20
|
+
|
21
|
+
expect { described_class.call(current_user, permissions) }.to raise_error(expected_error)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with the `all_of` option" do
|
26
|
+
let(:permissions) { { all_of: %w[admin editor] } }
|
27
|
+
let(:expected_error) { GDS::SSO::PermissionDeniedError }
|
28
|
+
|
29
|
+
it "permits users with all of the required permissions" do
|
30
|
+
allow(current_user).to receive(:has_permission?).with("admin").and_return(true)
|
31
|
+
allow(current_user).to receive(:has_permission?).with("editor").and_return(true)
|
32
|
+
|
33
|
+
expect { described_class.call(current_user, permissions) }.not_to raise_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it "does not permit users without all of the required permissions" do
|
37
|
+
allow(current_user).to receive(:has_permission?).with("admin").and_return(false)
|
38
|
+
allow(current_user).to receive(:has_permission?).with("editor").and_return(true)
|
39
|
+
|
40
|
+
expect { described_class.call(current_user, permissions) }.to raise_error(expected_error)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with the `any_of` option" do
|
45
|
+
let(:permissions) { { any_of: %w[admin editor] } }
|
46
|
+
let(:expected_error) { GDS::SSO::PermissionDeniedError }
|
47
|
+
|
48
|
+
it "permits users with any of the required permissions" do
|
49
|
+
allow(current_user).to receive(:has_permission?).with("admin").and_return(true)
|
50
|
+
allow(current_user).to receive(:has_permission?).with("editor").and_return(false)
|
51
|
+
|
52
|
+
expect { described_class.call(current_user, permissions) }.not_to raise_error
|
53
|
+
end
|
54
|
+
|
55
|
+
it "does not permit users without any of the required permissions" do
|
56
|
+
allow(current_user).to receive(:has_permission?).and_return(false)
|
57
|
+
|
58
|
+
expect { described_class.call(current_user, permissions) }.to raise_error(expected_error)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with none of `any_of` or `all_of`" do
|
63
|
+
it "raises an `ArgumentError`" do
|
64
|
+
expect { described_class.call(current_user, { admin: true }) }
|
65
|
+
.to raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "gds-sso/authorised_user_constraint"
|
3
|
+
|
4
|
+
describe GDS::SSO::AuthorisedUserConstraint do
|
5
|
+
before do
|
6
|
+
allow(GDS::SSO::AuthoriseUser).to receive(:call).and_return(true)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#matches?" do
|
10
|
+
let(:user) { double("user", remotely_signed_out?: remotely_signed_out) }
|
11
|
+
let(:warden) do
|
12
|
+
double(
|
13
|
+
"warden",
|
14
|
+
authenticated?: user_authenticated,
|
15
|
+
user:,
|
16
|
+
authenticate!: nil,
|
17
|
+
)
|
18
|
+
end
|
19
|
+
let(:user_authenticated) { true }
|
20
|
+
let(:remotely_signed_out) { false }
|
21
|
+
let(:request) { double("request", env: { "warden" => warden }) }
|
22
|
+
|
23
|
+
it "authorises the user" do
|
24
|
+
expect(GDS::SSO::AuthoriseUser).to receive(:call).with(warden.user, %w[signin])
|
25
|
+
expect(warden).not_to receive(:authenticate!)
|
26
|
+
|
27
|
+
described_class.new(%w[signin]).matches?(request)
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when the user is not authenticated" do
|
31
|
+
let(:user_authenticated) { false }
|
32
|
+
|
33
|
+
it "authenticates the user" do
|
34
|
+
expect(warden).to receive(:authenticate!)
|
35
|
+
|
36
|
+
described_class.new(%w[signin]).matches?(request)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when the user is remotely signed out" do
|
41
|
+
let(:remotely_signed_out) { true }
|
42
|
+
|
43
|
+
it "authenticates the user" do
|
44
|
+
expect(warden).to receive(:authenticate!)
|
45
|
+
|
46
|
+
described_class.new(%w[signin]).matches?(request)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/spec/unit/railtie_spec.rb
CHANGED
@@ -11,4 +11,23 @@ RSpec.describe GDS::SSO::Railtie do
|
|
11
11
|
it "honours API only setting" do
|
12
12
|
expect(GDS::SSO::Config.api_only).to eq false
|
13
13
|
end
|
14
|
+
|
15
|
+
describe "configuring intercept_401_responses" do
|
16
|
+
it "sets warden intercept_401 to false when the configuration option is set to false" do
|
17
|
+
allow(GDS::SSO::Config).to receive(:intercept_401_responses).and_return(false)
|
18
|
+
|
19
|
+
expect(warden_manager.config[:intercept_401]).to be(false)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "sets warden intercept_401 to true when the configuration option is set to true" do
|
23
|
+
allow(GDS::SSO::Config).to receive(:intercept_401_responses).and_return(true)
|
24
|
+
|
25
|
+
expect(warden_manager.config[:intercept_401]).to be(true)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def warden_manager
|
30
|
+
middleware = Rails.application.config.middleware.find { |m| m.name.include?("Warden::Manager") }
|
31
|
+
Warden::Manager.new(nil, &middleware.block)
|
32
|
+
end
|
14
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gds-sso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 19.
|
4
|
+
version: 19.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GOV.UK Dev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oauth2
|
@@ -58,34 +58,28 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
- - "<"
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '6'
|
61
|
+
version: '5'
|
65
62
|
type: :runtime
|
66
63
|
prerelease: false
|
67
64
|
version_requirements: !ruby/object:Gem::Requirement
|
68
65
|
requirements:
|
69
66
|
- - ">="
|
70
67
|
- !ruby/object:Gem::Version
|
71
|
-
version: '
|
72
|
-
- - "<"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '6'
|
68
|
+
version: '5'
|
75
69
|
- !ruby/object:Gem::Dependency
|
76
70
|
name: rails
|
77
71
|
requirement: !ruby/object:Gem::Requirement
|
78
72
|
requirements:
|
79
73
|
- - ">="
|
80
74
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
75
|
+
version: '7'
|
82
76
|
type: :runtime
|
83
77
|
prerelease: false
|
84
78
|
version_requirements: !ruby/object:Gem::Requirement
|
85
79
|
requirements:
|
86
80
|
- - ">="
|
87
81
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
82
|
+
version: '7'
|
89
83
|
- !ruby/object:Gem::Dependency
|
90
84
|
name: warden
|
91
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -174,16 +168,16 @@ dependencies:
|
|
174
168
|
name: rubocop-govuk
|
175
169
|
requirement: !ruby/object:Gem::Requirement
|
176
170
|
requirements:
|
177
|
-
- -
|
171
|
+
- - '='
|
178
172
|
- !ruby/object:Gem::Version
|
179
|
-
version:
|
173
|
+
version: 4.16.1
|
180
174
|
type: :development
|
181
175
|
prerelease: false
|
182
176
|
version_requirements: !ruby/object:Gem::Requirement
|
183
177
|
requirements:
|
184
|
-
- -
|
178
|
+
- - '='
|
185
179
|
- !ruby/object:Gem::Version
|
186
|
-
version:
|
180
|
+
version: 4.16.1
|
187
181
|
- !ruby/object:Gem::Dependency
|
188
182
|
name: sqlite3
|
189
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -244,6 +238,8 @@ files:
|
|
244
238
|
- config/routes.rb
|
245
239
|
- lib/gds-sso.rb
|
246
240
|
- lib/gds-sso/api_access.rb
|
241
|
+
- lib/gds-sso/authorise_user.rb
|
242
|
+
- lib/gds-sso/authorised_user_constraint.rb
|
247
243
|
- lib/gds-sso/bearer_token.rb
|
248
244
|
- lib/gds-sso/config.rb
|
249
245
|
- lib/gds-sso/controller_methods.rb
|
@@ -272,6 +268,8 @@ files:
|
|
272
268
|
- spec/support/timecop.rb
|
273
269
|
- spec/system/authentication_and_authorisation_spec.rb
|
274
270
|
- spec/unit/api_access_spec.rb
|
271
|
+
- spec/unit/authorise_user_spec.rb
|
272
|
+
- spec/unit/authorised_user_constraint_spec.rb
|
275
273
|
- spec/unit/bearer_token_spec.rb
|
276
274
|
- spec/unit/config_spec.rb
|
277
275
|
- spec/unit/mock_bearer_token_spec.rb
|
@@ -290,14 +288,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
290
288
|
requirements:
|
291
289
|
- - ">="
|
292
290
|
- !ruby/object:Gem::Version
|
293
|
-
version: '3.
|
291
|
+
version: '3.1'
|
294
292
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
295
293
|
requirements:
|
296
294
|
- - ">="
|
297
295
|
- !ruby/object:Gem::Version
|
298
296
|
version: '0'
|
299
297
|
requirements: []
|
300
|
-
rubygems_version: 3.5.
|
298
|
+
rubygems_version: 3.5.9
|
301
299
|
signing_key:
|
302
300
|
specification_version: 4
|
303
301
|
summary: Client for GDS' OAuth 2-based SSO
|
@@ -319,6 +317,8 @@ test_files:
|
|
319
317
|
- spec/support/timecop.rb
|
320
318
|
- spec/system/authentication_and_authorisation_spec.rb
|
321
319
|
- spec/unit/api_access_spec.rb
|
320
|
+
- spec/unit/authorise_user_spec.rb
|
321
|
+
- spec/unit/authorised_user_constraint_spec.rb
|
322
322
|
- spec/unit/bearer_token_spec.rb
|
323
323
|
- spec/unit/config_spec.rb
|
324
324
|
- spec/unit/mock_bearer_token_spec.rb
|