gds-sso 19.0.0 → 20.0.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 +20 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ce653302bc22f4fd60d83307eff612eac4a491eff439eed0c602c288d798ef9
|
4
|
+
data.tar.gz: de16391f9abe70acb77dbb6b00ca2b2f3e5da82965777bf281099e03e8420204
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51ad269ab4ba83b3b21c8fe9cdcc8b713c3b14c98e2068a4f6c06b198f75e7641ad087b15422bffabfcb5313e43ba255dce86f5ed6ea7ab6c0c8b92b151656ec
|
7
|
+
data.tar.gz: 261cae8502648293bdd629d09379df37efd5ca632ffb0360463807d609174c9f532ebdce31993a48e55f6fd3576a09c792209a907c7647daa549b62623f044c3
|
@@ -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,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gds-sso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 20.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GOV.UK Dev
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-03-26 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: oauth2
|
@@ -58,34 +57,28 @@ dependencies:
|
|
58
57
|
requirements:
|
59
58
|
- - ">="
|
60
59
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
- - "<"
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '6'
|
60
|
+
version: '5'
|
65
61
|
type: :runtime
|
66
62
|
prerelease: false
|
67
63
|
version_requirements: !ruby/object:Gem::Requirement
|
68
64
|
requirements:
|
69
65
|
- - ">="
|
70
66
|
- !ruby/object:Gem::Version
|
71
|
-
version: '
|
72
|
-
- - "<"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '6'
|
67
|
+
version: '5'
|
75
68
|
- !ruby/object:Gem::Dependency
|
76
69
|
name: rails
|
77
70
|
requirement: !ruby/object:Gem::Requirement
|
78
71
|
requirements:
|
79
72
|
- - ">="
|
80
73
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
74
|
+
version: '7'
|
82
75
|
type: :runtime
|
83
76
|
prerelease: false
|
84
77
|
version_requirements: !ruby/object:Gem::Requirement
|
85
78
|
requirements:
|
86
79
|
- - ">="
|
87
80
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
81
|
+
version: '7'
|
89
82
|
- !ruby/object:Gem::Dependency
|
90
83
|
name: warden
|
91
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -174,30 +167,30 @@ dependencies:
|
|
174
167
|
name: rubocop-govuk
|
175
168
|
requirement: !ruby/object:Gem::Requirement
|
176
169
|
requirements:
|
177
|
-
- -
|
170
|
+
- - '='
|
178
171
|
- !ruby/object:Gem::Version
|
179
|
-
version:
|
172
|
+
version: 5.0.2
|
180
173
|
type: :development
|
181
174
|
prerelease: false
|
182
175
|
version_requirements: !ruby/object:Gem::Requirement
|
183
176
|
requirements:
|
184
|
-
- -
|
177
|
+
- - '='
|
185
178
|
- !ruby/object:Gem::Version
|
186
|
-
version:
|
179
|
+
version: 5.0.2
|
187
180
|
- !ruby/object:Gem::Dependency
|
188
181
|
name: sqlite3
|
189
182
|
requirement: !ruby/object:Gem::Requirement
|
190
183
|
requirements:
|
191
184
|
- - "~>"
|
192
185
|
- !ruby/object:Gem::Version
|
193
|
-
version: '1
|
186
|
+
version: '2.1'
|
194
187
|
type: :development
|
195
188
|
prerelease: false
|
196
189
|
version_requirements: !ruby/object:Gem::Requirement
|
197
190
|
requirements:
|
198
191
|
- - "~>"
|
199
192
|
- !ruby/object:Gem::Version
|
200
|
-
version: '1
|
193
|
+
version: '2.1'
|
201
194
|
- !ruby/object:Gem::Dependency
|
202
195
|
name: timecop
|
203
196
|
requirement: !ruby/object:Gem::Requirement
|
@@ -244,6 +237,8 @@ files:
|
|
244
237
|
- config/routes.rb
|
245
238
|
- lib/gds-sso.rb
|
246
239
|
- lib/gds-sso/api_access.rb
|
240
|
+
- lib/gds-sso/authorise_user.rb
|
241
|
+
- lib/gds-sso/authorised_user_constraint.rb
|
247
242
|
- lib/gds-sso/bearer_token.rb
|
248
243
|
- lib/gds-sso/config.rb
|
249
244
|
- lib/gds-sso/controller_methods.rb
|
@@ -272,6 +267,8 @@ files:
|
|
272
267
|
- spec/support/timecop.rb
|
273
268
|
- spec/system/authentication_and_authorisation_spec.rb
|
274
269
|
- spec/unit/api_access_spec.rb
|
270
|
+
- spec/unit/authorise_user_spec.rb
|
271
|
+
- spec/unit/authorised_user_constraint_spec.rb
|
275
272
|
- spec/unit/bearer_token_spec.rb
|
276
273
|
- spec/unit/config_spec.rb
|
277
274
|
- spec/unit/mock_bearer_token_spec.rb
|
@@ -282,7 +279,6 @@ homepage: https://github.com/alphagov/gds-sso
|
|
282
279
|
licenses:
|
283
280
|
- MIT
|
284
281
|
metadata: {}
|
285
|
-
post_install_message:
|
286
282
|
rdoc_options: []
|
287
283
|
require_paths:
|
288
284
|
- lib
|
@@ -290,15 +286,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
290
286
|
requirements:
|
291
287
|
- - ">="
|
292
288
|
- !ruby/object:Gem::Version
|
293
|
-
version: '3.
|
289
|
+
version: '3.2'
|
294
290
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
295
291
|
requirements:
|
296
292
|
- - ">="
|
297
293
|
- !ruby/object:Gem::Version
|
298
294
|
version: '0'
|
299
295
|
requirements: []
|
300
|
-
rubygems_version: 3.
|
301
|
-
signing_key:
|
296
|
+
rubygems_version: 3.6.6
|
302
297
|
specification_version: 4
|
303
298
|
summary: Client for GDS' OAuth 2-based SSO
|
304
299
|
test_files:
|
@@ -319,6 +314,8 @@ test_files:
|
|
319
314
|
- spec/support/timecop.rb
|
320
315
|
- spec/system/authentication_and_authorisation_spec.rb
|
321
316
|
- spec/unit/api_access_spec.rb
|
317
|
+
- spec/unit/authorise_user_spec.rb
|
318
|
+
- spec/unit/authorised_user_constraint_spec.rb
|
322
319
|
- spec/unit/bearer_token_spec.rb
|
323
320
|
- spec/unit/config_spec.rb
|
324
321
|
- spec/unit/mock_bearer_token_spec.rb
|