gds-sso 15.0.0 → 15.0.1
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/Rakefile +11 -6
- data/app/controllers/api/user_controller.rb +30 -28
- data/app/controllers/authentications_controller.rb +3 -5
- data/config/routes.rb +6 -5
- data/lib/gds-sso.rb +24 -23
- data/lib/gds-sso/api_access.rb +1 -1
- data/lib/gds-sso/bearer_token.rb +24 -24
- data/lib/gds-sso/config.rb +9 -5
- 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 +24 -25
- data/lib/gds-sso/lint/user_test.rb +28 -28
- data/lib/gds-sso/user.rb +12 -12
- 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/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 +2 -2
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +5 -5
- data/spec/internal/log/test.log +1079 -1079
- data/spec/requests/end_to_end_spec.rb +44 -45
- 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 +22 -23
- metadata +71 -57
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
|
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,17 +1,17 @@
|
|
1
|
-
require
|
1
|
+
require "rails"
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
3
|
+
require "gds-sso/config"
|
4
|
+
require "gds-sso/version"
|
5
|
+
require "gds-sso/warden_config"
|
6
|
+
require "omniauth"
|
7
|
+
require "omniauth-gds"
|
8
8
|
|
9
9
|
module GDS
|
10
10
|
module SSO
|
11
|
-
autoload :FailureApp,
|
12
|
-
autoload :ControllerMethods,
|
13
|
-
autoload :User,
|
14
|
-
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"
|
15
15
|
|
16
16
|
# User to return as logged in during tests
|
17
17
|
mattr_accessor :test_user
|
@@ -23,29 +23,30 @@ module GDS
|
|
23
23
|
class Engine < ::Rails::Engine
|
24
24
|
# Force routes to be loaded if we are doing any eager load.
|
25
25
|
# TODO - check this one - Stolen from Devise because it looked sensible...
|
26
|
-
config.before_eager_load
|
26
|
+
config.before_eager_load(&:reload_routes!)
|
27
27
|
|
28
28
|
config.app_middleware.use ::OmniAuth::Builder do
|
29
29
|
next if GDS::SSO::Config.api_only?
|
30
|
+
|
30
31
|
provider :gds, GDS::SSO::Config.oauth_id, GDS::SSO::Config.oauth_secret,
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
+
}
|
41
42
|
end
|
42
43
|
|
43
44
|
def self.default_strategies
|
44
|
-
Config.use_mock_strategies? ? [
|
45
|
+
Config.use_mock_strategies? ? %i[mock_gds_sso gds_bearer_token] : %i[gds_sso gds_bearer_token]
|
45
46
|
end
|
46
47
|
|
47
48
|
config.app_middleware.use Warden::Manager do |config|
|
48
|
-
config.default_strategies
|
49
|
+
config.default_strategies(*default_strategies)
|
49
50
|
config.failure_app = GDS::SSO::FailureApp
|
50
51
|
end
|
51
52
|
end
|
data/lib/gds-sso/api_access.rb
CHANGED
data/lib/gds-sso/bearer_token.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "multi_json"
|
2
|
+
require "oauth2"
|
3
|
+
require "gds-sso/version"
|
4
4
|
|
5
5
|
module GDS
|
6
6
|
module SSO
|
7
7
|
module BearerToken
|
8
8
|
def self.locate(token_string)
|
9
|
-
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
|
10
10
|
access_token = OAuth2::AccessToken.new(oauth_client, token_string)
|
11
11
|
response_body = access_token.get("/user.json?client_id=#{CGI.escape(GDS::SSO::Config.oauth_id)}").body
|
12
12
|
omniauth_style_response(response_body)
|
@@ -21,12 +21,12 @@ module GDS
|
|
21
21
|
@oauth_client ||= OAuth2::Client.new(
|
22
22
|
GDS::SSO::Config.oauth_id,
|
23
23
|
GDS::SSO::Config.oauth_secret,
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
}
|
29
|
-
}.merge(GDS::SSO::Config.connection_opts)
|
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),
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
@@ -35,32 +35,32 @@ module GDS
|
|
35
35
|
# structure. Here we're addressing signon directly so
|
36
36
|
# we need to transform the response ourselves.
|
37
37
|
def self.omniauth_style_response(response_body)
|
38
|
-
input = MultiJson.decode(response_body)[
|
38
|
+
input = MultiJson.decode(response_body)["user"]
|
39
39
|
|
40
40
|
{
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
+
},
|
45
52
|
},
|
46
|
-
'extra' => {
|
47
|
-
'user' => {
|
48
|
-
'permissions' => input['permissions'],
|
49
|
-
'organisation_slug' => input['organisation_slug'],
|
50
|
-
'organisation_content_id' => input['organisation_content_id'],
|
51
|
-
}
|
52
|
-
}
|
53
53
|
}
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
57
|
module MockBearerToken
|
58
|
-
def self.locate(
|
58
|
+
def self.locate(_token_string)
|
59
59
|
dummy_api_user = GDS::SSO.test_user || GDS::SSO::Config.user_klass.where(email: "dummyapiuser@domain.com").first
|
60
60
|
if dummy_api_user.nil?
|
61
61
|
dummy_api_user = GDS::SSO::Config.user_klass.new
|
62
62
|
dummy_api_user.email = "dummyapiuser@domain.com"
|
63
|
-
dummy_api_user.uid =
|
63
|
+
dummy_api_user.uid = rand(10_000).to_s
|
64
64
|
dummy_api_user.name = "Dummy API user created by gds-sso"
|
65
65
|
end
|
66
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"
|
@@ -29,13 +31,13 @@ module GDS
|
|
29
31
|
|
30
32
|
mattr_accessor :connection_opts
|
31
33
|
@@connection_opts = {
|
32
|
-
:
|
33
|
-
:
|
34
|
-
}
|
34
|
+
request: {
|
35
|
+
open_timeout: 5,
|
36
|
+
},
|
35
37
|
}
|
36
38
|
|
37
39
|
def self.permissions_for_dummy_api_user
|
38
|
-
[
|
40
|
+
%w[signin].push(*additional_mock_permissions_required)
|
39
41
|
end
|
40
42
|
|
41
43
|
def self.user_klass
|
@@ -57,6 +59,8 @@ module GDS
|
|
57
59
|
default = config.respond_to?(:api_only) ? config.api_only : false
|
58
60
|
@@api_only.nil? ? default : @@api_only
|
59
61
|
end
|
62
|
+
|
63
|
+
# rubocop:enable Style/ClassVars
|
60
64
|
end
|
61
65
|
end
|
62
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
|
|
@@ -31,49 +31,48 @@ RSpec.shared_examples "a gds-sso user class" do
|
|
31
31
|
describe "#has_all_permissions?" do
|
32
32
|
it "is false when there are no permissions" do
|
33
33
|
subject.update!(permissions: nil)
|
34
|
-
required_permissions = [
|
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.update!(permissions: [
|
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.update!(permissions: [
|
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
|