omniauth-auth0 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
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.