gds-sso 14.1.0 → 15.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +11 -6
- data/app/controllers/api/user_controller.rb +30 -28
- data/app/controllers/authentications_controller.rb +3 -5
- data/app/views/layouts/unauthorised.html.erb +1 -1
- data/config/routes.rb +6 -5
- data/lib/gds-sso.rb +24 -17
- data/lib/gds-sso/api_access.rb +1 -1
- data/lib/gds-sso/bearer_token.rb +24 -23
- data/lib/gds-sso/config.rb +13 -2
- data/lib/gds-sso/controller_methods.rb +5 -6
- data/lib/gds-sso/failure_app.rb +7 -7
- data/lib/gds-sso/lint/user_spec.rb +27 -28
- data/lib/gds-sso/lint/user_test.rb +28 -28
- data/lib/gds-sso/user.rb +13 -13
- data/lib/gds-sso/version.rb +1 -1
- data/lib/gds-sso/warden_config.rb +21 -31
- data/spec/controller/api_user_controller_spec.rb +40 -37
- data/spec/controller/controller_methods_spec.rb +28 -28
- data/spec/internal/app/assets/config/manifest.js +0 -0
- data/spec/internal/app/controllers/application_controller.rb +1 -1
- data/spec/internal/app/controllers/example_controller.rb +1 -2
- data/spec/internal/config/initializers/gds-sso.rb +2 -2
- data/spec/internal/config/routes.rb +5 -2
- data/spec/internal/config/storage.yml +3 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +9 -5
- data/spec/internal/log/test.log +1048 -1114
- data/spec/requests/end_to_end_spec.rb +45 -46
- data/spec/spec_helper.rb +12 -13
- data/spec/support/signon_integration_helpers.rb +9 -7
- data/spec/support/timecop.rb +1 -1
- data/spec/unit/api_access_spec.rb +7 -7
- data/spec/unit/bearer_token_spec.rb +14 -15
- data/spec/unit/config_spec.rb +5 -5
- data/spec/unit/mock_bearer_token_spec.rb +4 -4
- data/spec/unit/session_serialisation_spec.rb +5 -5
- data/spec/unit/user_spec.rb +23 -24
- metadata +80 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2435fe77d5992ffde6d0cb2aaf09ed4449c17c73908e4509e0a9a0ad6dc2763
|
4
|
+
data.tar.gz: fdeae2412f7a8a2f665b6d3ef8da833fc49737bab89336517b52c89bd3148cc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5357aa5392b165604cda90222b0edd561dceff9ec8aa18da4bf40d4bf4818b65cc32b7df96f2ef8ae8a92b0e094a84e729448c4d5bd0a54a4ce1d62fbafde85
|
7
|
+
data.tar.gz: 8ad294caa8d1e2c09256f3e41e7cf380cd271d9b5c3504daef1e3e0651cba1130e9f29a92c1c66c183c373b156858d61755e998b99ab1ad125ed92906d28ce14
|
data/Rakefile
CHANGED
@@ -1,19 +1,24 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "bundler/setup"
|
2
|
+
require "bundler/gem_tasks"
|
3
3
|
|
4
4
|
Bundler::GemHelper.install_tasks
|
5
5
|
|
6
|
-
require
|
6
|
+
require "rspec/core/rake_task"
|
7
7
|
desc "Run all specs"
|
8
8
|
RSpec::Core::RakeTask.new(:spec) do |task|
|
9
|
-
task.pattern =
|
9
|
+
task.pattern = "spec/**/*_spec.rb"
|
10
10
|
end
|
11
11
|
|
12
12
|
namespace :spec do
|
13
13
|
desc "Run integration specs"
|
14
14
|
RSpec::Core::RakeTask.new(:integration) do |task|
|
15
|
-
task.pattern =
|
15
|
+
task.pattern = "spec/integration/**/*_spec.rb"
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
desc "Lint Ruby"
|
20
|
+
task :lint do
|
21
|
+
sh "bundle exec rubocop --format clang"
|
22
|
+
end
|
23
|
+
|
24
|
+
task default: %i[spec lint]
|
@@ -6,43 +6,45 @@ class Api::UserController < ActionController::Base
|
|
6
6
|
before_action :require_user_update_permission
|
7
7
|
|
8
8
|
def update
|
9
|
-
user_json = JSON.parse(request.body.read)[
|
9
|
+
user_json = JSON.parse(request.body.read)["user"]
|
10
10
|
oauth_hash = build_gds_oauth_hash(user_json)
|
11
11
|
GDS::SSO::Config.user_klass.find_for_gds_oauth(oauth_hash)
|
12
|
-
head :ok, content_type:
|
12
|
+
head :ok, content_type: "text/plain"
|
13
13
|
end
|
14
14
|
|
15
15
|
def reauth
|
16
|
-
user = GDS::SSO::Config.user_klass.where(:
|
16
|
+
user = GDS::SSO::Config.user_klass.where(uid: params[:uid]).first
|
17
17
|
if user.nil? || user.set_remotely_signed_out!
|
18
|
-
head :ok, content_type:
|
18
|
+
head :ok, content_type: "text/plain"
|
19
19
|
else
|
20
|
-
head 500, content_type:
|
20
|
+
head 500, content_type: "text/plain"
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
# This should mirror the object created by the omniauth-gds strategy/gem
|
26
|
-
# By doing this, we can reuse the code for creating/updating the user
|
27
|
-
def build_gds_oauth_hash(user_json)
|
28
|
-
OmniAuth::AuthHash.new(
|
29
|
-
uid: user_json['uid'],
|
30
|
-
provider: 'gds',
|
31
|
-
info: {
|
32
|
-
name: user_json['name'],
|
33
|
-
email: user_json['email']
|
34
|
-
},
|
35
|
-
extra: {
|
36
|
-
user: {
|
37
|
-
permissions: user_json['permissions'],
|
38
|
-
organisation_slug: user_json['organisation_slug'],
|
39
|
-
organisation_content_id: user_json['organisation_content_id'],
|
40
|
-
disabled: user_json['disabled'],
|
41
|
-
}
|
42
|
-
})
|
43
|
-
end
|
24
|
+
private
|
44
25
|
|
45
|
-
|
46
|
-
|
47
|
-
|
26
|
+
# This should mirror the object created by the omniauth-gds strategy/gem
|
27
|
+
# By doing this, we can reuse the code for creating/updating the user
|
28
|
+
def build_gds_oauth_hash(user_json)
|
29
|
+
OmniAuth::AuthHash.new(
|
30
|
+
uid: user_json["uid"],
|
31
|
+
provider: "gds",
|
32
|
+
info: {
|
33
|
+
name: user_json["name"],
|
34
|
+
email: user_json["email"],
|
35
|
+
},
|
36
|
+
extra: {
|
37
|
+
user: {
|
38
|
+
permissions: user_json["permissions"],
|
39
|
+
organisation_slug: user_json["organisation_slug"],
|
40
|
+
organisation_content_id: user_json["organisation_content_id"],
|
41
|
+
disabled: user_json["disabled"],
|
42
|
+
},
|
43
|
+
},
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def require_user_update_permission
|
48
|
+
authorise_user!("user_update_permission")
|
49
|
+
end
|
48
50
|
end
|
@@ -1,16 +1,14 @@
|
|
1
1
|
class AuthenticationsController < ActionController::Base
|
2
2
|
include GDS::SSO::ControllerMethods
|
3
3
|
|
4
|
-
before_action :authenticate_user!, :
|
4
|
+
before_action :authenticate_user!, only: :callback
|
5
5
|
layout false
|
6
6
|
|
7
7
|
def callback
|
8
|
-
redirect_to session["return_to"] ||
|
8
|
+
redirect_to session["return_to"] || "/"
|
9
9
|
end
|
10
10
|
|
11
|
-
def failure
|
12
|
-
|
13
|
-
end
|
11
|
+
def failure; end
|
14
12
|
|
15
13
|
def sign_out
|
16
14
|
logout
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<%= yield %>
|
8
8
|
</div>
|
9
9
|
<div id="footer" class="cf">
|
10
|
-
© <%= Date.today.year %> <a href="
|
10
|
+
© <%= Date.today.year %> <a href="https://www.gov.uk/government/organisations/government-digital-service">Government Digital Service</a>
|
11
11
|
</div>
|
12
12
|
</body>
|
13
13
|
</html>
|
data/config/routes.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
2
|
next if GDS::SSO::Config.api_only?
|
3
|
-
|
4
|
-
get
|
5
|
-
get
|
6
|
-
|
7
|
-
|
3
|
+
|
4
|
+
get "/auth/gds/callback", to: "authentications#callback", as: :gds_sign_in
|
5
|
+
get "/auth/gds/sign_out", to: "authentications#sign_out", as: :gds_sign_out
|
6
|
+
get "/auth/failure", to: "authentications#failure", as: :auth_failure
|
7
|
+
put "/auth/gds/api/users/:uid", to: "api/user#update"
|
8
|
+
post "/auth/gds/api/users/:uid/reauth", to: "api/user#reauth"
|
8
9
|
end
|
data/lib/gds-sso.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
require
|
1
|
+
require "rails"
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "gds-sso/config"
|
4
|
+
require "gds-sso/version"
|
5
|
+
require "gds-sso/warden_config"
|
6
|
+
require "omniauth"
|
7
|
+
require "omniauth-gds"
|
7
8
|
|
8
9
|
module GDS
|
9
10
|
module SSO
|
10
|
-
autoload :FailureApp,
|
11
|
-
autoload :ControllerMethods,
|
12
|
-
autoload :User,
|
13
|
-
autoload :ApiAccess,
|
11
|
+
autoload :FailureApp, "gds-sso/failure_app"
|
12
|
+
autoload :ControllerMethods, "gds-sso/controller_methods"
|
13
|
+
autoload :User, "gds-sso/user"
|
14
|
+
autoload :ApiAccess, "gds-sso/api_access"
|
14
15
|
|
15
16
|
# User to return as logged in during tests
|
16
17
|
mattr_accessor :test_user
|
@@ -22,24 +23,30 @@ module GDS
|
|
22
23
|
class Engine < ::Rails::Engine
|
23
24
|
# Force routes to be loaded if we are doing any eager load.
|
24
25
|
# TODO - check this one - Stolen from Devise because it looked sensible...
|
25
|
-
config.before_eager_load
|
26
|
+
config.before_eager_load(&:reload_routes!)
|
26
27
|
|
27
28
|
config.app_middleware.use ::OmniAuth::Builder do
|
28
29
|
next if GDS::SSO::Config.api_only?
|
30
|
+
|
29
31
|
provider :gds, GDS::SSO::Config.oauth_id, GDS::SSO::Config.oauth_secret,
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
client_options: {
|
33
|
+
site: GDS::SSO::Config.oauth_root_url,
|
34
|
+
authorize_url: "#{GDS::SSO::Config.oauth_root_url}/oauth/authorize",
|
35
|
+
token_url: "#{GDS::SSO::Config.oauth_root_url}/oauth/access_token",
|
36
|
+
connection_opts: {
|
37
|
+
headers: {
|
38
|
+
user_agent: "gds-sso/#{GDS::SSO::VERSION} (#{ENV['GOVUK_APP_NAME']})",
|
39
|
+
},
|
40
|
+
},
|
41
|
+
}
|
35
42
|
end
|
36
43
|
|
37
44
|
def self.default_strategies
|
38
|
-
Config.use_mock_strategies? ? [
|
45
|
+
Config.use_mock_strategies? ? %i[mock_gds_sso gds_bearer_token] : %i[gds_sso gds_bearer_token]
|
39
46
|
end
|
40
47
|
|
41
48
|
config.app_middleware.use Warden::Manager do |config|
|
42
|
-
config.default_strategies
|
49
|
+
config.default_strategies(*default_strategies)
|
43
50
|
config.failure_app = GDS::SSO::FailureApp
|
44
51
|
end
|
45
52
|
end
|
data/lib/gds-sso/api_access.rb
CHANGED
data/lib/gds-sso/bearer_token.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "multi_json"
|
2
|
+
require "oauth2"
|
3
|
+
require "gds-sso/version"
|
3
4
|
|
4
5
|
module GDS
|
5
6
|
module SSO
|
6
7
|
module BearerToken
|
7
8
|
def self.locate(token_string)
|
8
|
-
user_details = GDS::SSO::Config.cache.fetch([
|
9
|
+
user_details = GDS::SSO::Config.cache.fetch(["api-user-cache", token_string], expires_in: 5.minutes) do
|
9
10
|
access_token = OAuth2::AccessToken.new(oauth_client, token_string)
|
10
11
|
response_body = access_token.get("/user.json?client_id=#{CGI.escape(GDS::SSO::Config.oauth_id)}").body
|
11
12
|
omniauth_style_response(response_body)
|
@@ -20,12 +21,12 @@ module GDS
|
|
20
21
|
@oauth_client ||= OAuth2::Client.new(
|
21
22
|
GDS::SSO::Config.oauth_id,
|
22
23
|
GDS::SSO::Config.oauth_secret,
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
}
|
28
|
-
}
|
24
|
+
site: GDS::SSO::Config.oauth_root_url,
|
25
|
+
connection_opts: {
|
26
|
+
headers: {
|
27
|
+
user_agent: "gds-sso/#{GDS::SSO::VERSION} (#{ENV['GOVUK_APP_NAME']})",
|
28
|
+
},
|
29
|
+
}.merge(GDS::SSO::Config.connection_opts),
|
29
30
|
)
|
30
31
|
end
|
31
32
|
|
@@ -34,32 +35,32 @@ module GDS
|
|
34
35
|
# structure. Here we're addressing signon directly so
|
35
36
|
# we need to transform the response ourselves.
|
36
37
|
def self.omniauth_style_response(response_body)
|
37
|
-
input = MultiJson.decode(response_body)[
|
38
|
+
input = MultiJson.decode(response_body)["user"]
|
38
39
|
|
39
40
|
{
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
"uid" => input["uid"],
|
42
|
+
"info" => {
|
43
|
+
"email" => input["email"],
|
44
|
+
"name" => input["name"],
|
45
|
+
},
|
46
|
+
"extra" => {
|
47
|
+
"user" => {
|
48
|
+
"permissions" => input["permissions"],
|
49
|
+
"organisation_slug" => input["organisation_slug"],
|
50
|
+
"organisation_content_id" => input["organisation_content_id"],
|
51
|
+
},
|
44
52
|
},
|
45
|
-
'extra' => {
|
46
|
-
'user' => {
|
47
|
-
'permissions' => input['permissions'],
|
48
|
-
'organisation_slug' => input['organisation_slug'],
|
49
|
-
'organisation_content_id' => input['organisation_content_id'],
|
50
|
-
}
|
51
|
-
}
|
52
53
|
}
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
57
|
module MockBearerToken
|
57
|
-
def self.locate(
|
58
|
+
def self.locate(_token_string)
|
58
59
|
dummy_api_user = GDS::SSO.test_user || GDS::SSO::Config.user_klass.where(email: "dummyapiuser@domain.com").first
|
59
60
|
if dummy_api_user.nil?
|
60
61
|
dummy_api_user = GDS::SSO::Config.user_klass.new
|
61
62
|
dummy_api_user.email = "dummyapiuser@domain.com"
|
62
|
-
dummy_api_user.uid =
|
63
|
+
dummy_api_user.uid = rand(10_000).to_s
|
63
64
|
dummy_api_user.name = "Dummy API user created by gds-sso"
|
64
65
|
end
|
65
66
|
|
data/lib/gds-sso/config.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/cache/null_store"
|
2
2
|
|
3
3
|
module GDS
|
4
4
|
module SSO
|
5
5
|
module Config
|
6
|
+
# rubocop:disable Style/ClassVars
|
7
|
+
|
6
8
|
# Name of the User class
|
7
9
|
mattr_accessor :user_model
|
8
10
|
@@user_model = "User"
|
@@ -27,8 +29,15 @@ module GDS
|
|
27
29
|
|
28
30
|
mattr_accessor :additional_mock_permissions_required
|
29
31
|
|
32
|
+
mattr_accessor :connection_opts
|
33
|
+
@@connection_opts = {
|
34
|
+
request: {
|
35
|
+
open_timeout: 5,
|
36
|
+
},
|
37
|
+
}
|
38
|
+
|
30
39
|
def self.permissions_for_dummy_api_user
|
31
|
-
[
|
40
|
+
%w[signin].push(*additional_mock_permissions_required)
|
32
41
|
end
|
33
42
|
|
34
43
|
def self.user_klass
|
@@ -50,6 +59,8 @@ module GDS
|
|
50
59
|
default = config.respond_to?(:api_only) ? config.api_only : false
|
51
60
|
@@api_only.nil? ? default : @@api_only
|
52
61
|
end
|
62
|
+
|
63
|
+
# rubocop:enable Style/ClassVars
|
53
64
|
end
|
54
65
|
end
|
55
66
|
end
|
@@ -19,7 +19,6 @@ module GDS
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
22
|
def authorise_user!(permissions)
|
24
23
|
# Ensure that we're authenticated (and by extension that current_user is set).
|
25
24
|
# Otherwise current_user might be nil, and we'd error out
|
@@ -52,7 +51,7 @@ module GDS
|
|
52
51
|
end
|
53
52
|
|
54
53
|
def user_signed_in?
|
55
|
-
warden && warden.authenticated? && !
|
54
|
+
warden && warden.authenticated? && !warden.user.remotely_signed_out?
|
56
55
|
end
|
57
56
|
|
58
57
|
def current_user
|
@@ -64,22 +63,22 @@ module GDS
|
|
64
63
|
end
|
65
64
|
|
66
65
|
def warden
|
67
|
-
request.env[
|
66
|
+
request.env["warden"]
|
68
67
|
end
|
69
68
|
|
70
|
-
|
69
|
+
private
|
71
70
|
|
72
71
|
def authorise_user_with_at_least_one_of_permissions!(permissions)
|
73
72
|
if permissions.none? { |permission| current_user.has_permission?(permission) }
|
74
73
|
raise PermissionDeniedException,
|
75
|
-
|
74
|
+
"Sorry, you don't seem to have any of the permissions: #{permissions.to_sentence} for this app."
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
79
78
|
def authorise_user_with_all_permissions!(permissions)
|
80
79
|
unless permissions.all? { |permission| current_user.has_permission?(permission) }
|
81
80
|
raise PermissionDeniedException,
|
82
|
-
|
81
|
+
"Sorry, you don't seem to have all of the permissions: #{permissions.to_sentence} for this app."
|
83
82
|
end
|
84
83
|
end
|
85
84
|
end
|
data/lib/gds-sso/failure_app.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "action_controller/metal"
|
2
|
-
require
|
2
|
+
require "rails"
|
3
3
|
|
4
4
|
# Failure application that will be called every time :warden is thrown from
|
5
5
|
# any strategy or hook.
|
@@ -27,15 +27,15 @@ module GDS
|
|
27
27
|
|
28
28
|
def redirect
|
29
29
|
store_location!
|
30
|
-
redirect_to
|
30
|
+
redirect_to "/auth/gds"
|
31
31
|
end
|
32
32
|
|
33
33
|
def api_invalid_token
|
34
|
-
api_unauthorized(
|
34
|
+
api_unauthorized("Bearer token does not appear to be valid", "invalid_token")
|
35
35
|
end
|
36
36
|
|
37
37
|
def api_missing_token
|
38
|
-
api_unauthorized(
|
38
|
+
api_unauthorized("No bearer token was provided", "invalid_request")
|
39
39
|
end
|
40
40
|
|
41
41
|
# Stores requested uri to redirect the user after signing in. We cannot use
|
@@ -45,13 +45,13 @@ module GDS
|
|
45
45
|
|
46
46
|
# TOTALLY NOT DOING THE SCOPE THING. PROBABLY SHOULD.
|
47
47
|
def store_location!
|
48
|
-
session["return_to"] = request.env[
|
48
|
+
session["return_to"] = request.env["warden.options"][:attempted_path] if request.get?
|
49
49
|
end
|
50
50
|
|
51
|
-
|
51
|
+
private
|
52
52
|
|
53
53
|
def api_unauthorized(message, bearer_error)
|
54
|
-
headers[
|
54
|
+
headers["WWW-Authenticate"] = %(Bearer error="#{bearer_error}")
|
55
55
|
render json: { message: message }, status: :unauthorized
|
56
56
|
end
|
57
57
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
RSpec.shared_examples "a gds-sso user class" do
|
2
|
-
subject { described_class.new(:
|
2
|
+
subject { described_class.new(uid: "12345") }
|
3
3
|
|
4
4
|
it "implements #where" do
|
5
5
|
expect(described_class).to respond_to(:where)
|
6
6
|
|
7
|
-
result = described_class.where(uid:
|
7
|
+
result = described_class.where(uid: "123")
|
8
8
|
expect(result).to respond_to(:first)
|
9
9
|
end
|
10
10
|
|
@@ -15,8 +15,8 @@ RSpec.shared_examples "a gds-sso user class" do
|
|
15
15
|
expect(subject).to be_remotely_signed_out
|
16
16
|
end
|
17
17
|
|
18
|
-
it "implements #
|
19
|
-
subject.
|
18
|
+
it "implements #update!" do
|
19
|
+
subject.update!(email: "ab@c.com")
|
20
20
|
expect(subject.email).to eq("ab@c.com")
|
21
21
|
end
|
22
22
|
|
@@ -30,50 +30,49 @@ RSpec.shared_examples "a gds-sso user class" do
|
|
30
30
|
|
31
31
|
describe "#has_all_permissions?" do
|
32
32
|
it "is false when there are no permissions" do
|
33
|
-
subject.
|
34
|
-
required_permissions = [
|
33
|
+
subject.update!(permissions: nil)
|
34
|
+
required_permissions = %w[signin]
|
35
35
|
expect(subject.has_all_permissions?(required_permissions)).to be_falsy
|
36
36
|
end
|
37
37
|
|
38
38
|
it "is false when it does not have all required permissions" do
|
39
|
-
subject.
|
40
|
-
required_permissions = [
|
39
|
+
subject.update!(permissions: %w[signin])
|
40
|
+
required_permissions = %w[signin not_granted_permission_one not_granted_permission_two]
|
41
41
|
expect(subject.has_all_permissions?(required_permissions)).to be false
|
42
42
|
end
|
43
43
|
|
44
44
|
it "is true when it has all required permissions" do
|
45
|
-
subject.
|
46
|
-
required_permissions = [
|
45
|
+
subject.update!(permissions: %w[signin internal_app])
|
46
|
+
required_permissions = %w[signin internal_app]
|
47
47
|
expect(subject.has_all_permissions?(required_permissions)).to be true
|
48
48
|
end
|
49
|
-
|
50
49
|
end
|
51
50
|
|
52
51
|
specify "the User class and GDS::SSO::User mixin work together" do
|
53
52
|
auth_hash = {
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
"uid" => "12345",
|
54
|
+
"info" => {
|
55
|
+
"name" => "Joe Smith",
|
56
|
+
"email" => "joe.smith@example.com",
|
57
|
+
},
|
58
|
+
"extra" => {
|
59
|
+
"user" => {
|
60
|
+
"disabled" => false,
|
61
|
+
"permissions" => %w[signin],
|
62
|
+
"organisation_slug" => "cabinet-office",
|
63
|
+
"organisation_content_id" => "91e57ad9-29a3-4f94-9ab4-5e9ae6d13588",
|
64
|
+
},
|
58
65
|
},
|
59
|
-
'extra' => {
|
60
|
-
'user' => {
|
61
|
-
'disabled' => false,
|
62
|
-
'permissions' => ['signin'],
|
63
|
-
'organisation_slug' => 'cabinet-office',
|
64
|
-
'organisation_content_id' => '91e57ad9-29a3-4f94-9ab4-5e9ae6d13588'
|
65
|
-
}
|
66
|
-
}
|
67
66
|
}
|
68
67
|
|
69
68
|
user = described_class.find_for_gds_oauth(auth_hash)
|
70
69
|
expect(user).to be_an_instance_of(described_class)
|
71
|
-
expect(user.uid).to eq(
|
70
|
+
expect(user.uid).to eq("12345")
|
72
71
|
expect(user.name).to eq("Joe Smith")
|
73
|
-
expect(user.email).to eq(
|
72
|
+
expect(user.email).to eq("joe.smith@example.com")
|
74
73
|
expect(user).not_to be_disabled
|
75
|
-
expect(user.permissions).to eq([
|
76
|
-
expect(user.organisation_slug).to eq(
|
77
|
-
expect(user.organisation_content_id).to eq(
|
74
|
+
expect(user.permissions).to eq(%w[signin])
|
75
|
+
expect(user.organisation_slug).to eq("cabinet-office")
|
76
|
+
expect(user.organisation_content_id).to eq("91e57ad9-29a3-4f94-9ab4-5e9ae6d13588")
|
78
77
|
end
|
79
78
|
end
|