gds-sso 21.1.0 → 22.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72938e39cf2466b8a2dc2d22aca03d64ff33ab2a8c5d11c0c57f3710a2935205
4
- data.tar.gz: 042b5c966919ab345d9ea3dc9e47197947fdd75e51ad263b0f0f038397c09fa9
3
+ metadata.gz: 69935efadb057e8b8f85cdd7549ff1c07a94d2b50ba25086e64c3f17dc8730c6
4
+ data.tar.gz: 28bc82620af28be973c62ef9c2020e072f9971aabfe7f6bce1b17c66d12fa8fd
5
5
  SHA512:
6
- metadata.gz: fdca3de72981e79aa420da0b3d6c4d689fba034d3d3cda4874082efe58bcf056128242ab09a4266b8d11f91da500d47b665e434ccb805a3f6a799d6d29f765f4
7
- data.tar.gz: ad252eb2aeaf3986b68b54a15f7f4622f4d56e730d509690e1e80c77be6411201ebf618ba68efebaff825fe731a111de186b439b6834a4c1de91782745658335
6
+ metadata.gz: a57f468d6a7bed0783851e1364112cbaaeea9ae41ea82b53b90e8231f0b2d9ec8280e69527c19dd79b04c1c127fb83d8f77ad80d69cad9763189abfc04a2a674
7
+ data.tar.gz: a6c38c8f82b5006ff4e69a505f7ce1c26a7e5469c816148c930a44225ed048f209ea8891666e9f7eb7d8f0a243a49cfc8f52ae8874037fe3a79b9e7d28ec36aa
@@ -6,6 +6,8 @@ require "rails"
6
6
  module GDS
7
7
  module SSO
8
8
  class FailureApp < ActionController::Metal
9
+ MAX_RETURN_TO_PATH_SIZE = 2048
10
+
9
11
  include ActionController::Redirecting
10
12
  include AbstractController::Rendering
11
13
  include ActionController::Rendering
@@ -37,14 +39,13 @@ module GDS
37
39
  api_unauthorized("No bearer token was provided", "invalid_request")
38
40
  end
39
41
 
40
- # Stores requested uri to redirect the user after signing in. We cannot use
41
- # scoped session provided by warden here, since the user is not authenticated
42
- # yet, but we still need to store the uri based on scope, so different scopes
43
- # would never use the same uri to redirect.
44
-
45
- # TOTALLY NOT DOING THE SCOPE THING. PROBABLY SHOULD.
46
42
  def store_location!
47
- session["return_to"] = request.env["warden.options"][:attempted_path] if request.get?
43
+ return unless request.get?
44
+
45
+ attempted_path = request.env["warden.options"][:attempted_path]
46
+ return if attempted_path.bytesize > MAX_RETURN_TO_PATH_SIZE
47
+
48
+ session["return_to"] = attempted_path
48
49
  end
49
50
 
50
51
  private
@@ -49,30 +49,33 @@ RSpec.shared_examples "a gds-sso user class" do
49
49
  end
50
50
 
51
51
  specify "the User class and GDS::SSO::User mixin work together" do
52
- auth_hash = {
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",
52
+ ClimateControl.modify ANONYMOUS_USER_ID_SECRET: "some-anonymous-user-id-secret" do
53
+ auth_hash = {
54
+ "uid" => "12345",
55
+ "info" => {
56
+ "name" => "Joe Smith",
57
+ "email" => "joe.smith@example.com",
64
58
  },
65
- },
66
- }
59
+ "extra" => {
60
+ "user" => {
61
+ "disabled" => false,
62
+ "permissions" => %w[signin],
63
+ "organisation_slug" => "cabinet-office",
64
+ "organisation_content_id" => "91e57ad9-29a3-4f94-9ab4-5e9ae6d13588",
65
+ },
66
+ },
67
+ }
67
68
 
68
- user = described_class.find_for_gds_oauth(auth_hash)
69
- expect(user).to be_an_instance_of(described_class)
70
- expect(user.uid).to eq("12345")
71
- expect(user.name).to eq("Joe Smith")
72
- expect(user.email).to eq("joe.smith@example.com")
73
- expect(user).not_to be_disabled
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")
69
+ user = described_class.find_for_gds_oauth(auth_hash)
70
+ expect(user).to be_an_instance_of(described_class)
71
+ expect(user.uid).to eq("12345")
72
+ expect(user.anonymous_user_id).to eq("91f4d86cd48c6d0cf")
73
+ expect(user.name).to eq("Joe Smith")
74
+ expect(user.email).to eq("joe.smith@example.com")
75
+ expect(user).not_to be_disabled
76
+ expect(user.permissions).to eq(%w[signin])
77
+ expect(user.organisation_slug).to eq("cabinet-office")
78
+ expect(user.organisation_content_id).to eq("91e57ad9-29a3-4f94-9ab4-5e9ae6d13588")
79
+ end
77
80
  end
78
81
  end
data/lib/gds-sso/user.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "active_support/concern"
2
+ require "json"
2
3
 
3
4
  module GDS
4
5
  module SSO
@@ -39,6 +40,13 @@ module GDS
39
40
  update_attribute(:remotely_signed_out, true)
40
41
  end
41
42
 
43
+ def anonymous_user_id
44
+ secret = ENV["ANONYMOUS_USER_ID_SECRET"]
45
+ return if secret.nil?
46
+
47
+ @anonymous_user_id ||= Digest::SHA2.hexdigest(JSON.dump([uid, secret]))[..16]
48
+ end
49
+
42
50
  module ClassMethods
43
51
  def find_for_gds_oauth(auth_hash)
44
52
  user_params = GDS::SSO::User.user_params_from_auth_hash(auth_hash.to_hash)
@@ -1,5 +1,5 @@
1
1
  module GDS
2
2
  module SSO
3
- VERSION = "21.1.0".freeze
3
+ VERSION = "22.1.0".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe GDS::SSO::FailureApp, type: :request do
4
+ describe "#redirect" do
5
+ before do
6
+ Rails.application.routes.draw do
7
+ get "redirect", to: GDS::SSO::FailureApp.action(:redirect)
8
+ end
9
+ end
10
+
11
+ after { Rails.application.reload_routes! }
12
+
13
+ it "should store the return_to path in session when it is reasonably short" do
14
+ attempted_path = "some-reasonably-short-path"
15
+
16
+ get "/redirect", env: { "warden.options" => { attempted_path: } }
17
+
18
+ expect(response).to redirect_to("/auth/gds")
19
+ expect(session["return_to"]).to eq(attempted_path)
20
+ end
21
+
22
+ it "should not attempt to store the return_to path in session when it is very long" do
23
+ attempted_path = "some-#{'very-' * 1000}-long-path"
24
+
25
+ get "/redirect", env: { "warden.options" => { attempted_path: } }
26
+
27
+ expect(response).to redirect_to("/auth/gds")
28
+ expect(session["return_to"]).to be_nil
29
+ end
30
+ end
31
+ end
@@ -30,6 +30,26 @@ describe GDS::SSO::User do
30
30
  expect(GDS::SSO::User.user_params_from_auth_hash(@auth_hash)).to eq(expected)
31
31
  end
32
32
 
33
+ describe "#anonymous_user_id" do
34
+ it "should be nil if ANONYMOUS_USER_ID_SECRET is unset" do
35
+ ClimateControl.modify ANONYMOUS_USER_ID_SECRET: nil do
36
+ expect(TestUser.new.anonymous_user_id).to be_nil
37
+ end
38
+ end
39
+
40
+ it "should be computed based on the uid and ANONYMOUS_USER_ID_SECRET" do
41
+ ClimateControl.modify ANONYMOUS_USER_ID_SECRET: "some-anonymous-user-id-secret" do
42
+ expect("8724f603978a3adc0").to eq(TestUser.new(uid: "some-user-id").anonymous_user_id)
43
+ expect("69d0cf995988be2e1").to eq(TestUser.new(uid: "some-other-user-id").anonymous_user_id)
44
+ end
45
+
46
+ ClimateControl.modify ANONYMOUS_USER_ID_SECRET: "other-anonymous-user-id-secret" do
47
+ expect("297069f42a9251c64").to eq(TestUser.new(uid: "some-user-id").anonymous_user_id)
48
+ expect("4a3c66e26f5ec4229").to eq(TestUser.new(uid: "other-user-id").anonymous_user_id)
49
+ end
50
+ end
51
+ end
52
+
33
53
  context "making sure that the lint spec is valid" do
34
54
  let(:described_class) { TestUser }
35
55
  it_behaves_like "a gds-sso user class"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gds-sso
3
3
  version: !ruby/object:Gem::Version
4
- version: 21.1.0
4
+ version: 22.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
@@ -169,28 +169,28 @@ dependencies:
169
169
  requirements:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
- version: '6'
172
+ version: '8'
173
173
  type: :development
174
174
  prerelease: false
175
175
  version_requirements: !ruby/object:Gem::Requirement
176
176
  requirements:
177
177
  - - "~>"
178
178
  - !ruby/object:Gem::Version
179
- version: '6'
179
+ version: '8'
180
180
  - !ruby/object:Gem::Dependency
181
181
  name: rubocop-govuk
182
182
  requirement: !ruby/object:Gem::Requirement
183
183
  requirements:
184
184
  - - '='
185
185
  - !ruby/object:Gem::Version
186
- version: 5.1.18
186
+ version: 5.1.20
187
187
  type: :development
188
188
  prerelease: false
189
189
  version_requirements: !ruby/object:Gem::Requirement
190
190
  requirements:
191
191
  - - '='
192
192
  - !ruby/object:Gem::Version
193
- version: 5.1.18
193
+ version: 5.1.20
194
194
  - !ruby/object:Gem::Dependency
195
195
  name: sqlite3
196
196
  requirement: !ruby/object:Gem::Requirement
@@ -272,6 +272,7 @@ files:
272
272
  - spec/unit/bearer_token_spec.rb
273
273
  - spec/unit/config_spec.rb
274
274
  - spec/unit/controller_methods_spec.rb
275
+ - spec/unit/failure_app_spec.rb
275
276
  - spec/unit/gds_sso_spec.rb
276
277
  - spec/unit/mock_bearer_token_spec.rb
277
278
  - spec/unit/railtie_spec.rb
@@ -321,6 +322,7 @@ test_files:
321
322
  - spec/unit/bearer_token_spec.rb
322
323
  - spec/unit/config_spec.rb
323
324
  - spec/unit/controller_methods_spec.rb
325
+ - spec/unit/failure_app_spec.rb
324
326
  - spec/unit/gds_sso_spec.rb
325
327
  - spec/unit/mock_bearer_token_spec.rb
326
328
  - spec/unit/railtie_spec.rb