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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +11 -6
  3. data/app/controllers/api/user_controller.rb +30 -28
  4. data/app/controllers/authentications_controller.rb +3 -5
  5. data/config/routes.rb +6 -5
  6. data/lib/gds-sso.rb +24 -23
  7. data/lib/gds-sso/api_access.rb +1 -1
  8. data/lib/gds-sso/bearer_token.rb +24 -24
  9. data/lib/gds-sso/config.rb +9 -5
  10. data/lib/gds-sso/controller_methods.rb +5 -6
  11. data/lib/gds-sso/failure_app.rb +7 -7
  12. data/lib/gds-sso/lint/user_spec.rb +24 -25
  13. data/lib/gds-sso/lint/user_test.rb +28 -28
  14. data/lib/gds-sso/user.rb +12 -12
  15. data/lib/gds-sso/version.rb +1 -1
  16. data/lib/gds-sso/warden_config.rb +21 -31
  17. data/spec/controller/api_user_controller_spec.rb +40 -37
  18. data/spec/controller/controller_methods_spec.rb +28 -28
  19. data/spec/internal/app/controllers/application_controller.rb +1 -1
  20. data/spec/internal/app/controllers/example_controller.rb +1 -2
  21. data/spec/internal/config/initializers/gds-sso.rb +2 -2
  22. data/spec/internal/config/routes.rb +2 -2
  23. data/spec/internal/db/combustion_test.sqlite +0 -0
  24. data/spec/internal/db/schema.rb +5 -5
  25. data/spec/internal/log/test.log +1079 -1079
  26. data/spec/requests/end_to_end_spec.rb +44 -45
  27. data/spec/spec_helper.rb +12 -13
  28. data/spec/support/signon_integration_helpers.rb +9 -7
  29. data/spec/support/timecop.rb +1 -1
  30. data/spec/unit/api_access_spec.rb +7 -7
  31. data/spec/unit/bearer_token_spec.rb +14 -15
  32. data/spec/unit/config_spec.rb +5 -5
  33. data/spec/unit/mock_bearer_token_spec.rb +4 -4
  34. data/spec/unit/session_serialisation_spec.rb +5 -5
  35. data/spec/unit/user_spec.rb +22 -23
  36. metadata +71 -57
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f6e8e343ed76d12863efbbaa32b8cad40f6f1c089e425a4e9fa3fdde95ee0c8
4
- data.tar.gz: c1556af8d9f7fb3a17708796e4ab5e63d00f57b1b05e67123eea37baacd77994
3
+ metadata.gz: a2435fe77d5992ffde6d0cb2aaf09ed4449c17c73908e4509e0a9a0ad6dc2763
4
+ data.tar.gz: fdeae2412f7a8a2f665b6d3ef8da833fc49737bab89336517b52c89bd3148cc5
5
5
  SHA512:
6
- metadata.gz: 7d6c7c78f8f04bbb7d19ed8dfb60427b0b16441206f14828f46edd46d4b94a0beab11c0b2697bc3677e0b711a9b8fcb80109b83eef7a272aca16d409be6fd831
7
- data.tar.gz: e22e4728bc10f3f4b0c0ba791566512c5b855f80666dbc76e9abea6cdf17eb52a8d77d1ab37a2e3e95042bd80f19cc3cd769e3018c6603538455602ea17a9394
6
+ metadata.gz: b5357aa5392b165604cda90222b0edd561dceff9ec8aa18da4bf40d4bf4818b65cc32b7df96f2ef8ae8a92b0e094a84e729448c4d5bd0a54a4ce1d62fbafde85
7
+ data.tar.gz: 8ad294caa8d1e2c09256f3e41e7cf380cd271d9b5c3504daef1e3e0651cba1130e9f29a92c1c66c183c373b156858d61755e998b99ab1ad125ed92906d28ce14
data/Rakefile CHANGED
@@ -1,19 +1,24 @@
1
- require 'bundler/setup'
2
- require 'bundler/gem_tasks'
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
3
 
4
4
  Bundler::GemHelper.install_tasks
5
5
 
6
- require 'rspec/core/rake_task'
6
+ require "rspec/core/rake_task"
7
7
  desc "Run all specs"
8
8
  RSpec::Core::RakeTask.new(:spec) do |task|
9
- task.pattern = 'spec/**/*_spec.rb'
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 = 'spec/integration/**/*_spec.rb'
15
+ task.pattern = "spec/integration/**/*_spec.rb"
16
16
  end
17
17
  end
18
18
 
19
- task :default => ["spec"]
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)['user']
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: 'text/plain'
12
+ head :ok, content_type: "text/plain"
13
13
  end
14
14
 
15
15
  def reauth
16
- user = GDS::SSO::Config.user_klass.where(:uid => params[:uid]).first
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: 'text/plain'
18
+ head :ok, content_type: "text/plain"
19
19
  else
20
- head 500, content_type: 'text/plain'
20
+ head 500, content_type: "text/plain"
21
21
  end
22
22
  end
23
23
 
24
- private
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
- def require_user_update_permission
46
- authorise_user!("user_update_permission")
47
- end
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!, :only => :callback
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
@@ -1,8 +1,9 @@
1
1
  Rails.application.routes.draw do
2
2
  next if GDS::SSO::Config.api_only?
3
- get '/auth/gds/callback', to: 'authentications#callback', as: :gds_sign_in
4
- get '/auth/gds/sign_out', to: 'authentications#sign_out', as: :gds_sign_out
5
- get '/auth/failure', to: 'authentications#failure', as: :auth_failure
6
- put '/auth/gds/api/users/:uid', to: "api/user#update"
7
- post '/auth/gds/api/users/:uid/reauth', to: "api/user#reauth"
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
@@ -1,17 +1,17 @@
1
- require 'rails'
1
+ require "rails"
2
2
 
3
- require 'gds-sso/config'
4
- require 'gds-sso/version'
5
- require 'gds-sso/warden_config'
6
- require 'omniauth'
7
- require 'omniauth-gds'
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, 'gds-sso/failure_app'
12
- autoload :ControllerMethods, 'gds-sso/controller_methods'
13
- autoload :User, 'gds-sso/user'
14
- autoload :ApiAccess, 'gds-sso/api_access'
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 { |app| app.reload_routes! }
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
- client_options: {
32
- site: GDS::SSO::Config.oauth_root_url,
33
- authorize_url: "#{GDS::SSO::Config.oauth_root_url}/oauth/authorize",
34
- token_url: "#{GDS::SSO::Config.oauth_root_url}/oauth/access_token",
35
- connection_opts: {
36
- headers: {
37
- user_agent: "gds-sso/#{GDS::SSO::VERSION} (#{ENV['GOVUK_APP_NAME']})"
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? ? [:mock_gds_sso, :gds_bearer_token] : [:gds_sso, :gds_bearer_token]
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 *self.default_strategies
49
+ config.default_strategies(*default_strategies)
49
50
  config.failure_app = GDS::SSO::FailureApp
50
51
  end
51
52
  end
@@ -2,7 +2,7 @@ module GDS
2
2
  module SSO
3
3
  class ApiAccess
4
4
  def self.api_call?(env)
5
- /\ABearer / === env['HTTP_AUTHORIZATION'].to_s
5
+ env["HTTP_AUTHORIZATION"].to_s =~ /\ABearer /
6
6
  end
7
7
  end
8
8
  end
@@ -1,12 +1,12 @@
1
- require 'multi_json'
2
- require 'oauth2'
3
- require 'gds-sso/version'
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(['api-user-cache', token_string], expires_in: 5.minutes) do
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
- :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)
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)['user']
38
+ input = MultiJson.decode(response_body)["user"]
39
39
 
40
40
  {
41
- 'uid' => input['uid'],
42
- 'info' => {
43
- 'email' => input['email'],
44
- 'name' => input['name']
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(token_string)
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 = "#{rand(10000)}"
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
 
@@ -1,8 +1,10 @@
1
- require 'active_support/cache/null_store'
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
- :request => {
33
- :open_timeout => 5,
34
- }
34
+ request: {
35
+ open_timeout: 5,
36
+ },
35
37
  }
36
38
 
37
39
  def self.permissions_for_dummy_api_user
38
- ["signin"].push(*additional_mock_permissions_required)
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? && ! warden.user.remotely_signed_out?
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['warden']
66
+ request.env["warden"]
68
67
  end
69
68
 
70
- private
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
- "Sorry, you don't seem to have any of the permissions: #{permissions.to_sentence} for this app."
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
- "Sorry, you don't seem to have all of the permissions: #{permissions.to_sentence} for this app."
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
@@ -1,5 +1,5 @@
1
1
  require "action_controller/metal"
2
- require 'rails'
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 '/auth/gds'
30
+ redirect_to "/auth/gds"
31
31
  end
32
32
 
33
33
  def api_invalid_token
34
- api_unauthorized('Bearer token does not appear to be valid', 'invalid_token')
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('No bearer token was provided', 'invalid_request')
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['warden.options'][:attempted_path] if request.get?
48
+ session["return_to"] = request.env["warden.options"][:attempted_path] if request.get?
49
49
  end
50
50
 
51
- private
51
+ private
52
52
 
53
53
  def api_unauthorized(message, bearer_error)
54
- headers['WWW-Authenticate'] = %(Bearer error="#{bearer_error}")
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(:uid => '12345') }
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: '123')
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 = ["signin"]
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: ["signin"])
40
- required_permissions = ["signin", "not_granted_permission_one", "not_granted_permission_two"]
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: ["signin", "internal_app"])
46
- required_permissions = ["signin", "internal_app"]
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
- 'uid' => '12345',
55
- 'info' => {
56
- 'name' => 'Joe Smith',
57
- 'email' => 'joe.smith@example.com',
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('12345')
70
+ expect(user.uid).to eq("12345")
72
71
  expect(user.name).to eq("Joe Smith")
73
- expect(user.email).to eq('joe.smith@example.com')
72
+ expect(user.email).to eq("joe.smith@example.com")
74
73
  expect(user).not_to be_disabled
75
- expect(user.permissions).to eq(['signin'])
76
- expect(user.organisation_slug).to eq('cabinet-office')
77
- expect(user.organisation_content_id).to eq('91e57ad9-29a3-4f94-9ab4-5e9ae6d13588')
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