omniauth-auth0 2.5.0 → 2.6.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: 530b0c2ecfb26938944778585c034f1281b46f0c7e920f40b9d58c72fb892c52
4
- data.tar.gz: 0ca3365ce632a95272eabb1b1db1ed7fcc6faacdbdc1acaa3fa9889329886cef
3
+ metadata.gz: f45e6ee50254603367c7de482ce5537b48c5faf1bc7a4f2797cf461f21b37198
4
+ data.tar.gz: 88eb699d3cf59148df15728b42d517e010bebe29617f1f9e972dc9656e5a79a2
5
5
  SHA512:
6
- metadata.gz: f1ad9ad998942bd4b081c8873352bf54d0bc5900203baee151535324533b28954e7ab3e990ada83436189bd22a17b24d3a31d7552d45570fe356d00bfbb85fd6
7
- data.tar.gz: 60954e800d0a30ea948590cb89b90038185dfa7466bf301ef4e7b782a3b327265921cccf6ddbd4275789046a12c0e4d0956ce4a73ab35d1ea20e633432430e45
6
+ metadata.gz: 829fd68186ab4685d7628b6a7c3a0cce95b1008396e6b6588e72b30ff7b077c103109bafe8e3e480539a07d715550fed27b2d73f537e505498a8b434655a0776
7
+ data.tar.gz: 8d03a181ad81f1b08618f542d1971d298a9751ca5d02e949bcf8f60bbf4d6ba2ce3463e6f5ce5a01945a82f24ce7e6f67881192f3e4214a2d05bb556ba6ef66e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## [v2.6.0](https://github.com/auth0/omniauth-auth0/tree/v2.6.0) (2021-04-01)
4
+
5
+ [Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v2.5.0...v2.6.0)
6
+
7
+ **Added**
8
+ - Org Support [SDK-2395] [\#124](https://github.com/auth0/omniauth-auth0/pull/124) ([davidpatrick](https://github.com/davidpatrick))
9
+ - Add login_hint to permitted params [\#123](https://github.com/auth0/omniauth-auth0/pull/123) ([Roriz](https://github.com/Roriz))
10
+
3
11
  ## [v2.5.0](https://github.com/auth0/omniauth-auth0/tree/v2.5.0) (2021-01-21)
4
12
 
5
13
  [Full Changelog](https://github.com/auth0/omniauth-auth0/compare/v2.4.2...v2.5.0)
data/README.md CHANGED
@@ -131,9 +131,78 @@ In some scenarios, you may need to pass specific query parameters to `/authorize
131
131
  - `connection_scope`
132
132
  - `prompt`
133
133
  - `screen_hint` (only relevant to New Universal Login Experience)
134
+ - `organization`
135
+ - `invitation`
134
136
 
135
137
  Simply pass these query parameters to your OmniAuth redirect endpoint to enable their behavior.
136
138
 
139
+ ## Examples
140
+
141
+ ### Auth0 Organizations (Closed Beta)
142
+
143
+ Organizations is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications.
144
+
145
+ Using Organizations, you can:
146
+
147
+ - Represent teams, business customers, partner companies, or any logical grouping of users that should have different ways of accessing your applications, as organizations.
148
+ - Manage their membership in a variety of ways, including user invitation.
149
+ - Configure branded, federated login flows for each organization.
150
+ - Implement role-based access control, such that users can have different roles when authenticating in the context of different organizations.
151
+ - Build administration capabilities into your products, using Organizations APIs, so that those businesses can manage their own organizations.
152
+
153
+ Note that Organizations is currently only available to customers on our Enterprise and Startup subscription plans.
154
+
155
+ #### Logging in with an Organization
156
+
157
+ Logging in with an Organization is as easy as passing the parameters to the authorize endpoint. You can do this with
158
+
159
+ ```ruby
160
+ <%=
161
+ button_to 'Login', 'auth/auth0',
162
+ method: :post,
163
+ params: {
164
+ # Found in your Auth0 dashboard, under Organization settings:
165
+ organization: '{AUTH0_ORGANIZATION}'
166
+ }
167
+ %>
168
+ ```
169
+
170
+ Alternatively you can configure the organization when you register the provider:
171
+
172
+ ```ruby
173
+ provider
174
+ :auth0,
175
+ ENV['AUTH0_CLIENT_ID'],
176
+ ENV['AUTH0_CLIENT_SECRET'],
177
+ ENV['AUTH0_DOMAIN'],
178
+ {
179
+ authorize_params: {
180
+ scope: 'openid read:users',
181
+ audience: 'https://{AUTH0_DOMAIN}/api',
182
+ organization: '{AUTH0_ORGANIZATION}'
183
+ }
184
+ }
185
+ ```
186
+
187
+ #### Accepting user invitations
188
+
189
+ Auth0 Organizations allow users to be invited using emailed links, which will direct a user back to your application. The URL the user will arrive at is based on your configured `Application Login URI`, which you can change from your Application's settings inside the Auth0 dashboard.
190
+
191
+ When the user arrives at your application using an invite link, you can expect three query parameters to be provided: `invitation`, `organization`, and `organization_name`. These will always be delivered using a GET request.
192
+
193
+ You can then supply those parametrs to a `button_to` or `link_to` helper
194
+
195
+ ```ruby
196
+ <%=
197
+ button_to 'Login', 'auth/auth0',
198
+ method: :post,
199
+ params: {
200
+ organization: '{YOUR_ORGANIZATION_ID}',
201
+ invitation: '{INVITE_CODE}'
202
+ }
203
+ %>
204
+ ```
205
+
137
206
  ## Contribution
138
207
 
139
208
  We appreciate feedback and contribution to this repo! Before you get started, please see the following:
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module Auth0
3
- VERSION = '2.5.0'.freeze
3
+ VERSION = '2.6.0'.freeze
4
4
  end
5
5
  end
@@ -174,6 +174,7 @@ module OmniAuth
174
174
  leeway = authorize_params[:leeway] || 60
175
175
  max_age = authorize_params[:max_age]
176
176
  nonce = authorize_params[:nonce]
177
+ organization = authorize_params[:organization]
177
178
 
178
179
  verify_iss(id_token)
179
180
  verify_sub(id_token)
@@ -183,6 +184,7 @@ module OmniAuth
183
184
  verify_nonce(id_token, nonce)
184
185
  verify_azp(id_token)
185
186
  verify_auth_time(id_token, leeway, max_age)
187
+ verify_org(id_token, organization)
186
188
  end
187
189
 
188
190
  def verify_iss(id_token)
@@ -260,6 +262,17 @@ module OmniAuth
260
262
  end
261
263
  end
262
264
  end
265
+
266
+ def verify_org(id_token, organization)
267
+ if organization
268
+ org_id = id_token['org_id']
269
+ if !org_id || !org_id.is_a?(String)
270
+ raise OmniAuth::Auth0::TokenValidationError.new("Organization Id (org_id) claim must be a string present in the ID token")
271
+ elsif org_id != organization
272
+ raise OmniAuth::Auth0::TokenValidationError.new("Organization Id (org_id) claim value mismatch in the ID token; expected '#{organization}', found '#{org_id}'")
273
+ end
274
+ end
275
+ end
263
276
  end
264
277
  end
265
278
  end
@@ -84,7 +84,7 @@ module OmniAuth
84
84
  # Define the parameters used for the /authorize endpoint
85
85
  def authorize_params
86
86
  params = super
87
- %w[connection connection_scope prompt screen_hint].each do |key|
87
+ %w[connection connection_scope prompt screen_hint login_hint organization invitation].each do |key|
88
88
  params[key] = request.params[key] if request.params.key?(key)
89
89
  end
90
90
 
@@ -476,6 +476,41 @@ describe OmniAuth::Auth0::JWTValidator do
476
476
  expect(id_token['auth_time']).to eq(auth_time)
477
477
  end
478
478
 
479
+ it 'should fail when authorize params has organization but org_id is missing in the token', focus: true do
480
+ payload = {
481
+ iss: "https://#{domain}/",
482
+ sub: 'sub',
483
+ aud: client_id,
484
+ exp: future_timecode,
485
+ iat: past_timecode
486
+ }
487
+
488
+ token = make_hs256_token(payload)
489
+ expect do
490
+ jwt_validator.verify(token, { organization: 'Test Org' })
491
+ end.to raise_error(an_instance_of(OmniAuth::Auth0::TokenValidationError).and having_attributes({
492
+ message: "Organization Id (org_id) claim must be a string present in the ID token"
493
+ }))
494
+ end
495
+
496
+ it 'should fail when authorize params has organization but token org_id does not match', focus: true do
497
+ payload = {
498
+ iss: "https://#{domain}/",
499
+ sub: 'sub',
500
+ aud: client_id,
501
+ exp: future_timecode,
502
+ iat: past_timecode,
503
+ org_id: 'Wrong Org'
504
+ }
505
+
506
+ token = make_hs256_token(payload)
507
+ expect do
508
+ jwt_validator.verify(token, { organization: 'Test Org' })
509
+ end.to raise_error(an_instance_of(OmniAuth::Auth0::TokenValidationError).and having_attributes({
510
+ message: "Organization Id (org_id) claim value mismatch in the ID token; expected 'Test Org', found 'Wrong Org'"
511
+ }))
512
+ end
513
+
479
514
  it 'should fail for RS256 token when kid is incorrect' do
480
515
  domain = 'example.org'
481
516
  sub = 'abc123'
@@ -91,6 +91,9 @@ describe OmniAuth::Strategies::Auth0 do
91
91
  expect(redirect_url).not_to have_query('connection_scope')
92
92
  expect(redirect_url).not_to have_query('prompt')
93
93
  expect(redirect_url).not_to have_query('screen_hint')
94
+ expect(redirect_url).not_to have_query('login_hint')
95
+ expect(redirect_url).not_to have_query('organization')
96
+ expect(redirect_url).not_to have_query('invitation')
94
97
  end
95
98
 
96
99
  it 'redirects to hosted login page' do
@@ -107,6 +110,9 @@ describe OmniAuth::Strategies::Auth0 do
107
110
  expect(redirect_url).not_to have_query('connection_scope')
108
111
  expect(redirect_url).not_to have_query('prompt')
109
112
  expect(redirect_url).not_to have_query('screen_hint')
113
+ expect(redirect_url).not_to have_query('login_hint')
114
+ expect(redirect_url).not_to have_query('organization')
115
+ expect(redirect_url).not_to have_query('invitation')
110
116
  end
111
117
 
112
118
  it 'redirects to the hosted login page with connection_scope' do
@@ -130,6 +136,9 @@ describe OmniAuth::Strategies::Auth0 do
130
136
  expect(redirect_url).to have_query('prompt', 'login')
131
137
  expect(redirect_url).not_to have_query('auth0Client')
132
138
  expect(redirect_url).not_to have_query('connection')
139
+ expect(redirect_url).not_to have_query('login_hint')
140
+ expect(redirect_url).not_to have_query('organization')
141
+ expect(redirect_url).not_to have_query('invitation')
133
142
  end
134
143
 
135
144
  it 'redirects to hosted login page with screen_hint=signup' do
@@ -144,6 +153,47 @@ describe OmniAuth::Strategies::Auth0 do
144
153
  expect(redirect_url).to have_query('screen_hint', 'signup')
145
154
  expect(redirect_url).not_to have_query('auth0Client')
146
155
  expect(redirect_url).not_to have_query('connection')
156
+ expect(redirect_url).not_to have_query('login_hint')
157
+ expect(redirect_url).not_to have_query('organization')
158
+ expect(redirect_url).not_to have_query('invitation')
159
+ end
160
+
161
+ it 'redirects to hosted login page with organization=TestOrg and invitation=TestInvite' do
162
+ get 'auth/auth0?organization=TestOrg&invitation=TestInvite'
163
+ expect(last_response.status).to eq(302)
164
+ redirect_url = last_response.headers['Location']
165
+ expect(redirect_url).to start_with('https://samples.auth0.com/authorize')
166
+ expect(redirect_url).to have_query('response_type', 'code')
167
+ expect(redirect_url).to have_query('state')
168
+ expect(redirect_url).to have_query('client_id')
169
+ expect(redirect_url).to have_query('redirect_uri')
170
+ expect(redirect_url).to have_query('organization', 'TestOrg')
171
+ expect(redirect_url).to have_query('invitation', 'TestInvite')
172
+ expect(redirect_url).not_to have_query('auth0Client')
173
+ expect(redirect_url).not_to have_query('connection')
174
+ expect(redirect_url).not_to have_query('connection_scope')
175
+ expect(redirect_url).not_to have_query('prompt')
176
+ expect(redirect_url).not_to have_query('screen_hint')
177
+ expect(redirect_url).not_to have_query('login_hint')
178
+ end
179
+
180
+ it 'redirects to hosted login page with login_hint=example@mail.com' do
181
+ get 'auth/auth0?login_hint=example@mail.com'
182
+ expect(last_response.status).to eq(302)
183
+ redirect_url = last_response.headers['Location']
184
+ expect(redirect_url).to start_with('https://samples.auth0.com/authorize')
185
+ expect(redirect_url).to have_query('response_type', 'code')
186
+ expect(redirect_url).to have_query('state')
187
+ expect(redirect_url).to have_query('client_id')
188
+ expect(redirect_url).to have_query('redirect_uri')
189
+ expect(redirect_url).to have_query('login_hint', 'example@mail.com')
190
+ expect(redirect_url).not_to have_query('auth0Client')
191
+ expect(redirect_url).not_to have_query('connection')
192
+ expect(redirect_url).not_to have_query('connection_scope')
193
+ expect(redirect_url).not_to have_query('prompt')
194
+ expect(redirect_url).not_to have_query('screen_hint')
195
+ expect(redirect_url).not_to have_query('organization')
196
+ expect(redirect_url).not_to have_query('invitation')
147
197
  end
148
198
 
149
199
  describe 'callback' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-auth0
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Auth0
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-21 00:00:00.000000000 Z
11
+ date: 2021-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: omniauth
@@ -118,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  - !ruby/object:Gem::Version
119
119
  version: '0'
120
120
  requirements: []
121
- rubygems_version: 3.0.9
121
+ rubygems_version: 3.1.2
122
122
  signing_key:
123
123
  specification_version: 4
124
124
  summary: OmniAuth OAuth2 strategy for the Auth0 platform.