aws-cognito-srp 0.4.0 → 0.5.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: 6000777b1471345bf83ef454e2147786b46c8960218729c0ef9b33d05bc08634
4
- data.tar.gz: 5b28a08b3614d6dbe6f05a1bc25fd54200a8c90bb6fe8e3a24f97e4afc1bbe80
3
+ metadata.gz: 929d703154eb252230b0ec365cf85bb59e632e62a335bcf63d81c0168f6fe3d3
4
+ data.tar.gz: 2b857f9bcf58f8363eae7ad056de998758bfaf6458ca478d41e4398b57d34a11
5
5
  SHA512:
6
- metadata.gz: d1e507ab4e5a8ce39647a2699ad1bac52a62352c6b2a04d2eb47b12954ae8c8a1f86f26c457583c13f84200064620cbf938381894d302a457b7a2c0468f5f26e
7
- data.tar.gz: 3714f171b5527ed457d2c05e0ff5aece5f96d572e9f48e4fa6412b9cedad85d69ac54432b7e719f7afe0406aa7d135562b0f7446d705d0a4a494f22c48a45bd4
6
+ metadata.gz: 5763f4fac8412527c21ecfb3ae0e283e4cf7be33fc5eadbc94325c83b1b0aa91d34cfc86ebad7895c9f1e1fad93e8c7f8f0f08180f4219d4f78e1ff63d9cf0c1
7
+ data.tar.gz: 13e4d566a91689460b4aca21d48b73a3655d336dfc3e07e0e8c505b107606489581b720d045c72e0ebc2aea27d59a79c76eeba5cb3be77965818b69cb259f10d
@@ -7,14 +7,15 @@ jobs:
7
7
  strategy:
8
8
  fail-fast: false
9
9
  matrix:
10
- ruby: [2.3, 2.4, 2.5, 2.6, 2.7, '3.0']
10
+ os: [ubuntu-latest, macos-latest]
11
+ ruby: [2.4, 2.5, 2.6, 2.7, '3.0', 3.1, 3.2, jruby, truffleruby]
11
12
 
12
- runs-on: ubuntu-latest
13
+ runs-on: ${{ matrix.os }}
13
14
 
14
- name: Test against Ruby ${{ matrix.ruby }}
15
+ name: Test against ${{ matrix.ruby }} on ${{ matrix.os }}
15
16
 
16
17
  steps:
17
- - uses: actions/checkout@v2
18
+ - uses: actions/checkout@v3
18
19
  - name: Set up Ruby
19
20
  uses: ruby/setup-ruby@v1
20
21
  with:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## Changelog for aws-cognito-srp-ruby
2
2
 
3
+ ### 0.5.0 (February 14❤︎, 2023)
4
+
5
+ * Added support for `client_secret`
6
+
3
7
  ### 0.4.0 (October 1, 2021)
4
8
 
5
9
  * Added `refresh_tokens` method
data/README.md CHANGED
@@ -25,11 +25,12 @@ gem 'aws-cognito-srp'
25
25
  require "aws-cognito-srp"
26
26
 
27
27
  aws_srp = Aws::CognitoSrp.new(
28
- username: "username",
29
- password: "password",
30
- pool_id: "pool-id",
31
- client_id: "client-id",
32
- aws_client: Aws::CognitoIdentityProvider::Client.new(region: "aws-region")
28
+ username: "username",
29
+ password: "password",
30
+ pool_id: "pool-id",
31
+ client_id: "client-id",
32
+ client_secret: "client-secret", # Optional
33
+ aws_client: Aws::CognitoIdentityProvider::Client.new(region: "aws-region")
33
34
  )
34
35
 
35
36
  resp = aws_srp.authenticate
@@ -44,9 +45,23 @@ resp.refresh_token
44
45
  new_tokens = aws_srp.refresh_tokens(resp.refresh_token)
45
46
  ```
46
47
 
48
+ In case you need access to the `USER_ID_FOR_SRP` value from the auth response,
49
+ you can do so by calling `aws_srp.user_id_for_srp` *after* the initial auth
50
+ (`aws_srp` being the same as in the code example above).
51
+
52
+ If you're using a `client_secret` and calling `#refresh_tokens` in a different
53
+ instance than the one that performed the initial call to `#authenticate` you
54
+ will have to pass the `USER_ID_FOR_SRP` value as a keyword argument:
55
+
56
+ ```ruby
57
+ new_tokens = aws_srp.refresh_token(resp.refresh_token,
58
+ user_id_for_srp: your_user_id_for_srp)
59
+ ```
60
+
47
61
  ## Supported rubies
48
62
 
49
- This gem is tested against and supports Ruby 2.3, 2.4, 2.5, 2.6, 2.7 and 3.0.
63
+ This gem is tested against and supports Ruby 2.4 through 3.2, JRuby and
64
+ TruffleRuby.
50
65
 
51
66
  ## Development
52
67
 
@@ -20,11 +20,13 @@ Gem::Specification.new do |spec|
20
20
  end
21
21
  spec.require_paths = ["lib"]
22
22
 
23
+ spec.required_ruby_version = '>= 2.4.0'
24
+
23
25
  spec.add_dependency "aws-sdk-cognitoidentityprovider"
24
26
 
25
- spec.add_development_dependency "bundler", "~> 2.2.0"
27
+ spec.add_development_dependency "bundler", "~> 2.2"
26
28
  spec.add_development_dependency "rake", "~> 13.0"
27
- spec.add_development_dependency "ox", "~> 2.14.0"
29
+ spec.add_development_dependency "nokogiri", "~> 1.9"
28
30
  spec.add_development_dependency "rspec", "~> 3.0"
29
31
  spec.add_development_dependency "pry"
30
32
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aws
4
4
  class CognitoSrp
5
- VERSION = "0.4.0"
5
+ VERSION = "0.5.0"
6
6
  end
7
7
  end
@@ -24,19 +24,6 @@ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5")
24
24
  using IntegerWithPow
25
25
  end
26
26
 
27
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
28
- module StringWithUnpack1
29
- refine String do
30
- # String#unpack1 was introduced in Ruby 2.4
31
- def unpack1(fmt)
32
- unpack(fmt)[0]
33
- end
34
- end
35
- end
36
-
37
- using StringWithUnpack1
38
- end
39
-
40
27
  module Aws
41
28
  # Client for AWS Cognito Identity Provider using Secure Remote Password (SRP).
42
29
  #
@@ -85,12 +72,15 @@ module Aws
85
72
 
86
73
  INFO_BITS = 'Caldera Derived Key'
87
74
 
88
- def initialize(username:, password:, pool_id:, client_id:, aws_client:)
75
+ attr_reader :user_id_for_srp
76
+
77
+ def initialize(username:, password:, pool_id:, client_id:, aws_client:, client_secret: nil)
89
78
  @username = username
90
79
  @password = password
91
80
  @pool_id = pool_id
92
81
  @client_id = client_id
93
82
  @aws_client = aws_client
83
+ @client_secret = client_secret
94
84
 
95
85
  @big_n = hex_to_long(N_HEX)
96
86
  @g = hex_to_long(G_HEX)
@@ -100,13 +90,16 @@ module Aws
100
90
  end
101
91
 
102
92
  def authenticate
93
+ auth_parameters = {
94
+ USERNAME: @username,
95
+ SRP_A: long_to_hex(@large_a_value),
96
+ SECRET_HASH: @client_secret && secret_hash(@username)
97
+ }.compact
98
+
103
99
  init_auth_response = @aws_client.initiate_auth(
104
100
  client_id: @client_id,
105
101
  auth_flow: USER_SRP_AUTH,
106
- auth_parameters: {
107
- USERNAME: @username,
108
- SRP_A: long_to_hex(@large_a_value)
109
- }
102
+ auth_parameters: auth_parameters
110
103
  )
111
104
 
112
105
  unless init_auth_response.challenge_name == PASSWORD_VERIFIER
@@ -114,12 +107,15 @@ module Aws
114
107
  end
115
108
 
116
109
  challenge_response = process_challenge(init_auth_response.challenge_parameters)
110
+ hash = @client_secret && secret_hash(@user_id_for_srp)
117
111
 
118
- auth_response = @aws_client.respond_to_auth_challenge(
112
+ params = {
119
113
  client_id: @client_id,
120
114
  challenge_name: PASSWORD_VERIFIER,
121
- challenge_responses: challenge_response
122
- )
115
+ challenge_responses: challenge_response.merge(SECRET_HASH: hash).compact
116
+ }
117
+
118
+ auth_response = @aws_client.respond_to_auth_challenge(params)
123
119
 
124
120
  if auth_response.challenge_name == NEW_PASSWORD_REQUIRED
125
121
  raise NewPasswordRequired, "Cognito responded to password verifier with a #{NEW_PASSWORD_REQUIRED} challenge"
@@ -128,13 +124,16 @@ module Aws
128
124
  auth_response.authentication_result
129
125
  end
130
126
 
131
- def refresh_tokens(refresh_token)
127
+ def refresh_tokens(refresh_token, user_id_for_srp: @user_id_for_srp)
128
+ auth_parameters = {
129
+ REFRESH_TOKEN: refresh_token,
130
+ SECRET_HASH: @client_secret && secret_hash(user_id_for_srp)
131
+ }.compact
132
+
132
133
  resp = @aws_client.initiate_auth(
133
134
  client_id: @client_id,
134
135
  auth_flow: REFRESH_TOKEN,
135
- auth_parameters: {
136
- REFRESH_TOKEN: refresh_token
137
- }
136
+ auth_parameters: auth_parameters
138
137
  )
139
138
 
140
139
  resp.authentication_result
@@ -170,22 +169,22 @@ module Aws
170
169
  end
171
170
 
172
171
  def process_challenge(challenge_parameters)
173
- user_id_for_srp = challenge_parameters.fetch("USER_ID_FOR_SRP")
172
+ @user_id_for_srp = challenge_parameters.fetch("USER_ID_FOR_SRP")
174
173
  salt_hex = challenge_parameters.fetch("SALT")
175
174
  srp_b_hex = challenge_parameters.fetch("SRP_B")
176
175
  secret_block_b64 = challenge_parameters.fetch("SECRET_BLOCK")
177
176
 
178
177
  timestamp = ::Time.now.utc.strftime("%a %b %-d %H:%M:%S %Z %Y")
179
178
 
180
- hkdf = get_password_authentication_key(user_id_for_srp, @password, srp_b_hex.to_i(16), salt_hex)
179
+ hkdf = get_password_authentication_key(@user_id_for_srp, @password, srp_b_hex.to_i(16), salt_hex)
181
180
  secret_block_bytes = ::Base64.strict_decode64(secret_block_b64)
182
- msg = @pool_id.split("_")[1] + user_id_for_srp + secret_block_bytes + timestamp
181
+ msg = @pool_id.split("_")[1] + @user_id_for_srp + secret_block_bytes + timestamp
183
182
  hmac_digest = ::OpenSSL::HMAC.digest(::OpenSSL::Digest::SHA256.new, hkdf, msg)
184
183
  signature_string = ::Base64.strict_encode64(hmac_digest).force_encoding('utf-8')
185
184
 
186
185
  {
187
186
  TIMESTAMP: timestamp,
188
- USERNAME: user_id_for_srp,
187
+ USERNAME: @user_id_for_srp,
189
188
  PASSWORD_CLAIM_SECRET_BLOCK: secret_block_b64,
190
189
  PASSWORD_CLAIM_SIGNATURE: signature_string
191
190
  }
@@ -242,5 +241,9 @@ module Aws
242
241
  u_hex_hash = hex_hash(pad_hex(big_a) + pad_hex(big_b))
243
242
  hex_to_long(u_hex_hash)
244
243
  end
244
+
245
+ def secret_hash(username)
246
+ Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', @client_secret, username + @client_id))
247
+ end
245
248
  end
246
249
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-cognito-srp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Viney
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-10-01 00:00:00.000000000 Z
13
+ date: 2023-02-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws-sdk-cognitoidentityprovider
@@ -32,14 +32,14 @@ dependencies:
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: 2.2.0
35
+ version: '2.2'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: 2.2.0
42
+ version: '2.2'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: rake
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -55,19 +55,19 @@ dependencies:
55
55
  - !ruby/object:Gem::Version
56
56
  version: '13.0'
57
57
  - !ruby/object:Gem::Dependency
58
- name: ox
58
+ name: nokogiri
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - "~>"
62
62
  - !ruby/object:Gem::Version
63
- version: 2.14.0
63
+ version: '1.9'
64
64
  type: :development
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
68
  - - "~>"
69
69
  - !ruby/object:Gem::Version
70
- version: 2.14.0
70
+ version: '1.9'
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: rspec
73
73
  requirement: !ruby/object:Gem::Requirement
@@ -132,14 +132,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
132
  requirements:
133
133
  - - ">="
134
134
  - !ruby/object:Gem::Version
135
- version: '0'
135
+ version: 2.4.0
136
136
  required_rubygems_version: !ruby/object:Gem::Requirement
137
137
  requirements:
138
138
  - - ">="
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
141
  requirements: []
142
- rubygems_version: 3.0.6
142
+ rubygems_version: 3.3.3
143
143
  signing_key:
144
144
  specification_version: 4
145
145
  summary: AWS Cognito SRP auth for Ruby