workos 0.9.1 → 0.10.3
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 +4 -4
- data/.rubocop.yml +5 -1
- data/Gemfile.lock +2 -2
- data/README.md +15 -15
- data/docs/WorkOS/SSO.html +235 -235
- data/docs/file.README.html +20 -20
- data/lib/workos.rb +1 -0
- data/lib/workos/audit_trail.rb +1 -0
- data/lib/workos/client.rb +22 -1
- data/lib/workos/connection.rb +0 -2
- data/lib/workos/organization.rb +0 -2
- data/lib/workos/passwordless.rb +0 -2
- data/lib/workos/portal.rb +1 -7
- data/lib/workos/profile.rb +2 -4
- data/lib/workos/sso.rb +142 -17
- data/lib/workos/types/intent_enum.rb +1 -0
- data/lib/workos/version.rb +1 -1
- data/spec/lib/workos/audit_trail_spec.rb +0 -8
- data/spec/lib/workos/directory_sync_spec.rb +0 -8
- data/spec/lib/workos/passwordless_spec.rb +0 -8
- data/spec/lib/workos/portal_spec.rb +18 -11
- data/spec/lib/workos/sso_spec.rb +224 -29
- data/spec/spec_helper.rb +1 -0
- data/spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml +2 -2
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories.yml +1 -1
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories_with_domain_param.yml +1 -1
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_dsync.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/portal/{generate_link.yml → generate_link_sso.yml} +1 -1
- data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_invalid_id.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_valid_id.yml +70 -0
- data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_invalid_id.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_valid_id.yml +74 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_after_param.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_before_param.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_connection_type_param.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_domain_param.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_limit_param.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_organization_id_param.yml +72 -0
- metadata +29 -5
data/lib/workos/version.rb
CHANGED
@@ -2,14 +2,6 @@
|
|
2
2
|
# typed: false
|
3
3
|
|
4
4
|
describe WorkOS::Portal do
|
5
|
-
before :all do
|
6
|
-
WorkOS.key = 'test'
|
7
|
-
end
|
8
|
-
|
9
|
-
after :all do
|
10
|
-
WorkOS.key = nil
|
11
|
-
end
|
12
|
-
|
13
5
|
describe '.create_organization' do
|
14
6
|
context 'with valid payload' do
|
15
7
|
it 'creates an organization' do
|
@@ -47,9 +39,9 @@ describe WorkOS::Portal do
|
|
47
39
|
let(:organization) { 'org_01EHQMYV6MBK39QC5PZXHY59C3' }
|
48
40
|
|
49
41
|
describe 'with a valid organization' do
|
50
|
-
|
42
|
+
context 'with the sso intent' do
|
51
43
|
it 'returns an Admin Portal link' do
|
52
|
-
VCR.use_cassette 'portal/
|
44
|
+
VCR.use_cassette 'portal/generate_link_sso' do
|
53
45
|
portal_link = described_class.generate_link(
|
54
46
|
intent: 'sso',
|
55
47
|
organization: organization,
|
@@ -61,6 +53,21 @@ describe WorkOS::Portal do
|
|
61
53
|
end
|
62
54
|
end
|
63
55
|
end
|
56
|
+
|
57
|
+
describe 'with the dsync intent' do
|
58
|
+
it 'returns an Admin Portal link' do
|
59
|
+
VCR.use_cassette 'portal/generate_link_dsync' do
|
60
|
+
portal_link = described_class.generate_link(
|
61
|
+
intent: 'dsync',
|
62
|
+
organization: organization,
|
63
|
+
)
|
64
|
+
|
65
|
+
expect(portal_link).to eq(
|
66
|
+
'https://id.workos.com/portal/launch?secret=secret',
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
64
71
|
end
|
65
72
|
|
66
73
|
describe 'with an invalid organization' do
|
@@ -88,7 +95,7 @@ describe WorkOS::Portal do
|
|
88
95
|
)
|
89
96
|
end.to raise_error(
|
90
97
|
ArgumentError,
|
91
|
-
|
98
|
+
/bogus-intent is not a valid value/,
|
92
99
|
)
|
93
100
|
end
|
94
101
|
end
|
data/spec/lib/workos/sso_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe WorkOS::SSO do
|
|
9
9
|
let(:args) do
|
10
10
|
{
|
11
11
|
domain: 'foo.com',
|
12
|
-
|
12
|
+
client_id: 'workos-proj-123',
|
13
13
|
redirect_uri: 'foo.com/auth/callback',
|
14
14
|
state: {
|
15
15
|
next_page: '/dashboard/edit',
|
@@ -43,7 +43,7 @@ describe WorkOS::SSO do
|
|
43
43
|
let(:args) do
|
44
44
|
{
|
45
45
|
provider: 'GoogleOAuth',
|
46
|
-
|
46
|
+
client_id: 'workos-proj-123',
|
47
47
|
redirect_uri: 'foo.com/auth/callback',
|
48
48
|
state: {
|
49
49
|
next_page: '/dashboard/edit',
|
@@ -73,10 +73,44 @@ describe WorkOS::SSO do
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
context 'with
|
76
|
+
context 'with a connection' do
|
77
77
|
let(:args) do
|
78
78
|
{
|
79
|
-
|
79
|
+
connection: 'connection_123',
|
80
|
+
client_id: 'workos-proj-123',
|
81
|
+
redirect_uri: 'foo.com/auth/callback',
|
82
|
+
state: {
|
83
|
+
next_page: '/dashboard/edit',
|
84
|
+
}.to_s,
|
85
|
+
}
|
86
|
+
end
|
87
|
+
it 'returns a valid URL' do
|
88
|
+
authorization_url = described_class.authorization_url(**args)
|
89
|
+
|
90
|
+
expect(URI.parse(authorization_url)).to be_a URI
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns the expected hostname' do
|
94
|
+
authorization_url = described_class.authorization_url(**args)
|
95
|
+
|
96
|
+
expect(URI.parse(authorization_url).host).to eq(WorkOS::API_HOSTNAME)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'returns the expected query string' do
|
100
|
+
authorization_url = described_class.authorization_url(**args)
|
101
|
+
|
102
|
+
expect(URI.parse(authorization_url).query).to eq(
|
103
|
+
'client_id=workos-proj-123&redirect_uri=foo.com%2Fauth%2Fcallback' \
|
104
|
+
'&response_type=code&state=%7B%3Anext_page%3D%3E%22%2Fdashboard%2F' \
|
105
|
+
'edit%22%7D&connection=connection_123',
|
106
|
+
)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with neither connection, domain, or provider' do
|
111
|
+
let(:args) do
|
112
|
+
{
|
113
|
+
client_id: 'workos-proj-123',
|
80
114
|
redirect_uri: 'foo.com/auth/callback',
|
81
115
|
state: {
|
82
116
|
next_page: '/dashboard/edit',
|
@@ -88,7 +122,7 @@ describe WorkOS::SSO do
|
|
88
122
|
described_class.authorization_url(**args)
|
89
123
|
end.to raise_error(
|
90
124
|
ArgumentError,
|
91
|
-
'Either domain or provider is required.',
|
125
|
+
'Either connection, domain, or provider is required.',
|
92
126
|
)
|
93
127
|
end
|
94
128
|
end
|
@@ -97,7 +131,7 @@ describe WorkOS::SSO do
|
|
97
131
|
let(:args) do
|
98
132
|
{
|
99
133
|
provider: 'Okta',
|
100
|
-
|
134
|
+
client_id: 'workos-proj-123',
|
101
135
|
redirect_uri: 'foo.com/auth/callback',
|
102
136
|
state: {
|
103
137
|
next_page: '/dashboard/edit',
|
@@ -113,23 +147,62 @@ describe WorkOS::SSO do
|
|
113
147
|
)
|
114
148
|
end
|
115
149
|
end
|
116
|
-
end
|
117
150
|
|
118
|
-
|
119
|
-
|
120
|
-
|
151
|
+
context 'passing the project_id' do
|
152
|
+
let(:args) do
|
153
|
+
{
|
154
|
+
domain: 'foo.com',
|
155
|
+
project_id: 'workos-proj-123',
|
156
|
+
redirect_uri: 'foo.com/auth/callback',
|
157
|
+
state: {
|
158
|
+
next_page: '/dashboard/edit',
|
159
|
+
}.to_s,
|
160
|
+
}
|
161
|
+
end
|
162
|
+
it 'raises a deprecation warning' do
|
163
|
+
expect do
|
164
|
+
described_class.authorization_url(**args)
|
165
|
+
end.to output(
|
166
|
+
"[DEPRECATION] `project_id` is deprecated.
|
167
|
+
Please use `client_id` instead.\n",
|
168
|
+
).to_stderr
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'returns a valid URL' do
|
172
|
+
authorization_url = described_class.authorization_url(**args)
|
173
|
+
|
174
|
+
expect(URI.parse(authorization_url)).to be_a URI
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'returns the expected hostname' do
|
178
|
+
authorization_url = described_class.authorization_url(**args)
|
179
|
+
|
180
|
+
expect(URI.parse(authorization_url).host).to eq(WorkOS::API_HOSTNAME)
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'returns the expected query string' do
|
184
|
+
authorization_url = described_class.authorization_url(**args)
|
185
|
+
|
186
|
+
expect(URI.parse(authorization_url).query).to eq(
|
187
|
+
'client_id=workos-proj-123&redirect_uri=foo.com%2Fauth%2Fcallback' \
|
188
|
+
'&response_type=code&state=%7B%3Anext_page%3D%3E%22%2Fdashboard%2F' \
|
189
|
+
'edit%22%7D&domain=foo.com',
|
190
|
+
)
|
191
|
+
end
|
121
192
|
end
|
193
|
+
end
|
122
194
|
|
195
|
+
describe '.profile' do
|
123
196
|
let(:args) do
|
124
197
|
{
|
125
198
|
code: SecureRandom.hex(10),
|
126
|
-
|
199
|
+
client_id: 'workos-proj-123',
|
127
200
|
}
|
128
201
|
end
|
129
202
|
|
130
203
|
let(:request_body) do
|
131
204
|
{
|
132
|
-
client_id: args[:
|
205
|
+
client_id: args[:client_id],
|
133
206
|
client_secret: WorkOS.key,
|
134
207
|
code: args[:code],
|
135
208
|
grant_type: 'authorization_code',
|
@@ -231,14 +304,6 @@ describe WorkOS::SSO do
|
|
231
304
|
end
|
232
305
|
|
233
306
|
describe '.create_connection' do
|
234
|
-
before(:all) do
|
235
|
-
WorkOS.key = 'key'
|
236
|
-
end
|
237
|
-
|
238
|
-
after(:all) do
|
239
|
-
WorkOS.key = nil
|
240
|
-
end
|
241
|
-
|
242
307
|
context 'with a valid source' do
|
243
308
|
it 'creates a connection' do
|
244
309
|
VCR.use_cassette('sso/create_connection_with_valid_source') do
|
@@ -269,16 +334,8 @@ describe WorkOS::SSO do
|
|
269
334
|
end
|
270
335
|
|
271
336
|
describe '.promote_draft_connection' do
|
272
|
-
before(:all) do
|
273
|
-
WorkOS.key = 'key'
|
274
|
-
end
|
275
|
-
|
276
|
-
after(:all) do
|
277
|
-
WorkOS.key = nil
|
278
|
-
end
|
279
|
-
|
280
337
|
let(:token) { 'draft_conn_id' }
|
281
|
-
let(:
|
338
|
+
let(:client_id) { 'proj_0239u590h' }
|
282
339
|
|
283
340
|
context 'with a valid request' do
|
284
341
|
before do
|
@@ -312,4 +369,142 @@ describe WorkOS::SSO do
|
|
312
369
|
end
|
313
370
|
end
|
314
371
|
end
|
372
|
+
|
373
|
+
describe '.list_connections' do
|
374
|
+
context 'with no options' do
|
375
|
+
it 'returns connections' do
|
376
|
+
VCR.use_cassette('sso/list_connections') do
|
377
|
+
connections = WorkOS::SSO.list_connections
|
378
|
+
expect(connections.size).to eq(1)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
context 'with connection_type option' do
|
384
|
+
it 'returns connections' do
|
385
|
+
VCR.use_cassette('sso/list_connections_with_connection_type_param') do
|
386
|
+
connections = WorkOS::SSO.list_connections(
|
387
|
+
connection_type: 'OktaSAML',
|
388
|
+
)
|
389
|
+
expect(connections.first['connection_type']).to eq('OktaSAML')
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
context 'with domain option' do
|
395
|
+
it 'returns connections' do
|
396
|
+
VCR.use_cassette('sso/list_connections_with_domain_param') do
|
397
|
+
connections = WorkOS::SSO.list_connections(
|
398
|
+
domain: 'foo-corp.com',
|
399
|
+
)
|
400
|
+
domains = connections.first['domains']
|
401
|
+
expect(domains.first['domain']).to eq('foo-corp.com')
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
context 'with organization_id option' do
|
407
|
+
it 'returns connections' do
|
408
|
+
VCR.use_cassette('sso/list_connections_with_organization_id_param') do
|
409
|
+
connections = WorkOS::SSO.list_connections(
|
410
|
+
organization_id: 'org_01EGS4P7QR31EZ4YWD1Z1XA176',
|
411
|
+
)
|
412
|
+
expect(connections.size).to eq(1)
|
413
|
+
expect(connections.first['organization_id']).to eq(
|
414
|
+
'org_01EGS4P7QR31EZ4YWD1Z1XA176',
|
415
|
+
)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
context 'with limit option' do
|
421
|
+
it 'returns connections' do
|
422
|
+
VCR.use_cassette('sso/list_connections_with_limit_param') do
|
423
|
+
connections = WorkOS::SSO.list_connections(
|
424
|
+
limit: 1,
|
425
|
+
)
|
426
|
+
expect(connections.size).to eq(1)
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
context 'with before option' do
|
432
|
+
it 'returns connections' do
|
433
|
+
VCR.use_cassette('sso/list_connections_with_before_param') do
|
434
|
+
connections = WorkOS::SSO.list_connections(
|
435
|
+
before: 'conn_01EQKPMQAPV02H270HKVNS4CTA',
|
436
|
+
)
|
437
|
+
expect(connections.size).to eq(1)
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
context 'with after option' do
|
443
|
+
it 'returns connections' do
|
444
|
+
VCR.use_cassette('sso/list_connections_with_after_param') do
|
445
|
+
connections = WorkOS::SSO.list_connections(
|
446
|
+
after: 'conn_01EQKPMQAPV02H270HKVNS4CTA',
|
447
|
+
)
|
448
|
+
expect(connections.size).to eq(1)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
describe '.get_connection' do
|
455
|
+
context 'with a valid id' do
|
456
|
+
it 'gets the connection details' do
|
457
|
+
VCR.use_cassette('sso/get_connection_with_valid_id') do
|
458
|
+
connection = WorkOS::SSO.get_connection(
|
459
|
+
id: 'conn_01EX00NB050H354WKGC7990AR2',
|
460
|
+
)
|
461
|
+
|
462
|
+
expect(connection.id).to eq('conn_01EX00NB050H354WKGC7990AR2')
|
463
|
+
expect(connection.connection_type).to eq('OktaSAML')
|
464
|
+
expect(connection.name).to eq('Foo Corp')
|
465
|
+
expect(connection.domains.first[:domain]).to eq('foo-corp.com')
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
context 'with an invalid id' do
|
471
|
+
it 'raises an error' do
|
472
|
+
VCR.use_cassette('sso/get_connection_with_invalid_id') do
|
473
|
+
expect do
|
474
|
+
WorkOS::SSO.get_connection(id: 'invalid')
|
475
|
+
end.to raise_error(
|
476
|
+
WorkOS::APIError,
|
477
|
+
'Status 404, Not Found - request ID: ',
|
478
|
+
)
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
describe '.delete_connection' do
|
485
|
+
context 'with a valid id' do
|
486
|
+
it 'returns true' do
|
487
|
+
VCR.use_cassette('sso/delete_connection_with_valid_id') do
|
488
|
+
response = WorkOS::SSO.delete_connection(
|
489
|
+
id: 'conn_01EX55FRVN1V2PCA9YWTMZQMMQ',
|
490
|
+
)
|
491
|
+
|
492
|
+
expect(response).to be(true)
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
context 'with an invalid id' do
|
498
|
+
it 'returns false' do
|
499
|
+
VCR.use_cassette('sso/delete_connection_with_invalid_id') do
|
500
|
+
expect do
|
501
|
+
WorkOS::SSO.delete_connection(id: 'invalid')
|
502
|
+
end.to raise_error(
|
503
|
+
WorkOS::APIError,
|
504
|
+
'Status 404, Not Found - request ID: ',
|
505
|
+
)
|
506
|
+
end
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end
|
315
510
|
end
|