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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -1
  3. data/Gemfile.lock +2 -2
  4. data/README.md +15 -15
  5. data/docs/WorkOS/SSO.html +235 -235
  6. data/docs/file.README.html +20 -20
  7. data/lib/workos.rb +1 -0
  8. data/lib/workos/audit_trail.rb +1 -0
  9. data/lib/workos/client.rb +22 -1
  10. data/lib/workos/connection.rb +0 -2
  11. data/lib/workos/organization.rb +0 -2
  12. data/lib/workos/passwordless.rb +0 -2
  13. data/lib/workos/portal.rb +1 -7
  14. data/lib/workos/profile.rb +2 -4
  15. data/lib/workos/sso.rb +142 -17
  16. data/lib/workos/types/intent_enum.rb +1 -0
  17. data/lib/workos/version.rb +1 -1
  18. data/spec/lib/workos/audit_trail_spec.rb +0 -8
  19. data/spec/lib/workos/directory_sync_spec.rb +0 -8
  20. data/spec/lib/workos/passwordless_spec.rb +0 -8
  21. data/spec/lib/workos/portal_spec.rb +18 -11
  22. data/spec/lib/workos/sso_spec.rb +224 -29
  23. data/spec/spec_helper.rb +1 -0
  24. data/spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml +2 -2
  25. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories.yml +1 -1
  26. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories_with_domain_param.yml +1 -1
  27. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_dsync.yml +72 -0
  28. data/spec/support/fixtures/vcr_cassettes/portal/{generate_link.yml → generate_link_sso.yml} +1 -1
  29. data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_invalid_id.yml +72 -0
  30. data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_valid_id.yml +70 -0
  31. data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_invalid_id.yml +72 -0
  32. data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_valid_id.yml +74 -0
  33. data/spec/support/fixtures/vcr_cassettes/sso/list_connections.yml +72 -0
  34. data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_after_param.yml +72 -0
  35. data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_before_param.yml +73 -0
  36. data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_connection_type_param.yml +72 -0
  37. data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_domain_param.yml +72 -0
  38. data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_limit_param.yml +72 -0
  39. data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_organization_id_param.yml +72 -0
  40. metadata +29 -5
@@ -8,6 +8,7 @@ module WorkOS
8
8
  class Intent < T::Enum
9
9
  enums do
10
10
  SSO = new('sso')
11
+ DSYNC = new('dsync')
11
12
  end
12
13
  end
13
14
  end
@@ -2,5 +2,5 @@
2
2
  # typed: strong
3
3
 
4
4
  module WorkOS
5
- VERSION = '0.9.1'
5
+ VERSION = '0.10.3'
6
6
  end
@@ -2,14 +2,6 @@
2
2
  # typed: false
3
3
 
4
4
  describe WorkOS::AuditTrail do
5
- before(:all) do
6
- WorkOS.key = 'key'
7
- end
8
-
9
- after(:all) do
10
- WorkOS.key = nil
11
- end
12
-
13
5
  describe '.create_event' do
14
6
  context 'with valid event payload' do
15
7
  let(:valid_event) do
@@ -2,14 +2,6 @@
2
2
  # typed: false
3
3
 
4
4
  describe WorkOS::DirectorySync do
5
- before(:all) do
6
- WorkOS.key = 'key'
7
- end
8
-
9
- after(:all) do
10
- WorkOS.key = nil
11
- end
12
-
13
5
  describe '.list_directories' do
14
6
  context 'with no options' do
15
7
  it 'returns directories' do
@@ -2,14 +2,6 @@
2
2
  # typed: false
3
3
 
4
4
  describe WorkOS::Passwordless do
5
- before(:all) do
6
- WorkOS.key = 'key'
7
- end
8
-
9
- after(:all) do
10
- WorkOS.key = nil
11
- end
12
-
13
5
  describe '.create_session' do
14
6
  context 'with valid options payload' do
15
7
  let(:valid_options) do
@@ -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
- describe 'with the minimal params' do
42
+ context 'with the sso intent' do
51
43
  it 'returns an Admin Portal link' do
52
- VCR.use_cassette 'portal/generate_link' do
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
- 'bogus-intent is not a valid value. `intent` must be in ["sso"]',
98
+ /bogus-intent is not a valid value/,
92
99
  )
93
100
  end
94
101
  end
@@ -9,7 +9,7 @@ describe WorkOS::SSO do
9
9
  let(:args) do
10
10
  {
11
11
  domain: 'foo.com',
12
- project_id: 'workos-proj-123',
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
- project_id: 'workos-proj-123',
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 neither domain or provider' do
76
+ context 'with a connection' do
77
77
  let(:args) do
78
78
  {
79
- project_id: 'workos-proj-123',
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
- project_id: 'workos-proj-123',
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
- describe '.profile' do
119
- before do
120
- WorkOS.key = 'api-key'
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
- project_id: 'workos-proj-123',
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[:project_id],
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(:project_id) { 'proj_0239u590h' }
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
data/spec/spec_helper.rb CHANGED
@@ -48,5 +48,6 @@ RSpec.configure do |config|
48
48
  end
49
49
  end)
50
50
 
51
+ config.before(:all) { WorkOS.key ||= '' }
51
52
  config.before(:each) { VCR.turn_on! }
52
53
  end