workos 0.3.3 → 0.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 +4 -4
- data/Gemfile.lock +8 -11
- data/README.md +7 -0
- data/lib/workos.rb +2 -0
- data/lib/workos/audit_trail.rb +48 -0
- data/lib/workos/directory_sync.rb +2 -0
- data/lib/workos/organization.rb +49 -0
- data/lib/workos/portal.rb +145 -0
- data/lib/workos/profile.rb +7 -2
- data/lib/workos/types.rb +3 -0
- data/lib/workos/types/intent_enum.rb +14 -0
- data/lib/workos/types/list_struct.rb +13 -0
- data/lib/workos/types/organization_struct.rb +14 -0
- data/lib/workos/types/profile_struct.rb +2 -1
- data/lib/workos/version.rb +1 -1
- data/spec/lib/workos/audit_trail_spec.rb +12 -0
- data/spec/lib/workos/portal_spec.rb +176 -0
- data/spec/lib/workos/sso_spec.rb +18 -0
- data/spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml +61 -0
- data/spec/support/fixtures/vcr_cassettes/organization/create.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/organization/list.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_invalid.yml +72 -0
- data/spec/support/profile.txt +1 -1
- data/workos.gemspec +1 -1
- metadata +23 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0fdd6aec096f0a3a3aa2f20c398515b1bf42d8e5b3d529e316bdce2327a0961
|
4
|
+
data.tar.gz: 269a70ac10a9aa6f7b49f7cefbde2b1af8e5bf559b429d202b5d5167bb8b83f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd67a590cefd06ae6fc83e45cd0cfe9243d8849e865e0b7f7eb342d0bb9a29b10cbb6693802d54bb25c045a2f90505f17217358c36ef196a2066ffab0ca6f2bc
|
7
|
+
data.tar.gz: e528ade9f4a33fff0a25d24fcdb94f6232a3fc00c8ef27233735520a71a7b8c207c2fb853040c96ce34a5a8b91c842d4b9dc485699101bcc58159743f9471934
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
workos (0.
|
4
|
+
workos (0.6.0)
|
5
5
|
sorbet-runtime (~> 0.5)
|
6
6
|
|
7
7
|
GEM
|
@@ -10,17 +10,16 @@ GEM
|
|
10
10
|
addressable (2.7.0)
|
11
11
|
public_suffix (>= 2.0.2, < 5.0)
|
12
12
|
ast (2.4.0)
|
13
|
-
codecov (0.
|
13
|
+
codecov (0.2.8)
|
14
14
|
json
|
15
15
|
simplecov
|
16
|
-
url
|
17
16
|
crack (0.4.3)
|
18
17
|
safe_yaml (~> 1.0.0)
|
19
18
|
diff-lcs (1.3)
|
20
19
|
docile (1.3.2)
|
21
20
|
hashdiff (1.0.0)
|
22
21
|
jaro_winkler (1.5.4)
|
23
|
-
json (2.3.
|
22
|
+
json (2.3.1)
|
24
23
|
parallel (1.19.1)
|
25
24
|
parser (2.7.0.0)
|
26
25
|
ast (~> 2.4.0)
|
@@ -49,17 +48,15 @@ GEM
|
|
49
48
|
unicode-display_width (>= 1.4.0, < 1.7)
|
50
49
|
ruby-progressbar (1.10.1)
|
51
50
|
safe_yaml (1.0.5)
|
52
|
-
simplecov (0.
|
51
|
+
simplecov (0.19.0)
|
53
52
|
docile (~> 1.1)
|
54
|
-
|
55
|
-
|
56
|
-
simplecov-html (0.10.2)
|
53
|
+
simplecov-html (~> 0.11)
|
54
|
+
simplecov-html (0.12.2)
|
57
55
|
sorbet (0.5.5560)
|
58
56
|
sorbet-static (= 0.5.5560)
|
59
|
-
sorbet-runtime (0.5.
|
57
|
+
sorbet-runtime (0.5.5909)
|
60
58
|
sorbet-static (0.5.5560-universal-darwin-14)
|
61
59
|
unicode-display_width (1.6.0)
|
62
|
-
url (0.3.2)
|
63
60
|
vcr (5.0.0)
|
64
61
|
webmock (3.7.6)
|
65
62
|
addressable (>= 2.3.6)
|
@@ -72,7 +69,7 @@ PLATFORMS
|
|
72
69
|
|
73
70
|
DEPENDENCIES
|
74
71
|
bundler (>= 2.0.1)
|
75
|
-
codecov (~> 0.
|
72
|
+
codecov (~> 0.2.8)
|
76
73
|
rake
|
77
74
|
rspec (~> 3.9.0)
|
78
75
|
rubocop (~> 0.77)
|
data/README.md
CHANGED
@@ -157,6 +157,13 @@ This method will return an instance of a `WorkOS::Profile` with the following at
|
|
157
157
|
@connection_type="OktaSAML",
|
158
158
|
@last_name="Demo",
|
159
159
|
@idp_id="00u1klkowm8EGah2H357",
|
160
|
+
@raw_attributes={
|
161
|
+
:id=>"prof_01DRA1XNSJDZ19A31F183ECQW5",
|
162
|
+
:email=>"demo@workos-okta.com",
|
163
|
+
:first_name=>"WorkOS",
|
164
|
+
:last_name=>"Demo",
|
165
|
+
:idp_id=>"00u1klkowm8EGah2H357"
|
166
|
+
},
|
160
167
|
>
|
161
168
|
```
|
162
169
|
|
data/lib/workos.rb
CHANGED
@@ -31,6 +31,8 @@ module WorkOS
|
|
31
31
|
autoload :AuditTrail, 'workos/audit_trail'
|
32
32
|
autoload :Connection, 'workos/connection'
|
33
33
|
autoload :DirectorySync, 'workos/directory_sync'
|
34
|
+
autoload :Organization, 'workos/organization'
|
35
|
+
autoload :Portal, 'workos/portal'
|
34
36
|
autoload :Profile, 'workos/profile'
|
35
37
|
autoload :SSO, 'workos/sso'
|
36
38
|
|
data/lib/workos/audit_trail.rb
CHANGED
@@ -57,6 +57,54 @@ module WorkOS
|
|
57
57
|
|
58
58
|
execute_request(request: request)
|
59
59
|
end
|
60
|
+
|
61
|
+
# Retrieve Audit Trail events.
|
62
|
+
#
|
63
|
+
# @param [Hash] options An options hash
|
64
|
+
# @option options [String] before Event ID to look before
|
65
|
+
# @option options [String] after Event ID to look after
|
66
|
+
# @option options [Integer] limit Number of Events to return
|
67
|
+
# @option options [Array<String>] group List of Groups to filter for
|
68
|
+
# @option options [Array<String>] action List of Actions to filter for
|
69
|
+
# @option options [Array<String>] action_type List of Action Types to
|
70
|
+
# filter for
|
71
|
+
# @option options [Array<String>] actor_name List of Actor Name to filter
|
72
|
+
# for
|
73
|
+
# @option options [Array<String>] actor_id List of Actor IDs to filter for
|
74
|
+
# @option options [Array<String>] target_name List of Target Names to
|
75
|
+
# filter for
|
76
|
+
# @option options [Array<String>] target_id List of Target IDs to filter
|
77
|
+
# for
|
78
|
+
# @option options [String] occurred_at ISO-8601 datetime of when an event
|
79
|
+
# occurred
|
80
|
+
# @option options [String] occurred_at_gt ISO-8601 datetime of when an
|
81
|
+
# event occurred after
|
82
|
+
# @option options [String] occurred_at_gte ISO-8601 datetime of when an
|
83
|
+
# event occurred at or after
|
84
|
+
# @option options [String] occurred_at_lt ISO-8601 datetime of when an
|
85
|
+
# event occurred before
|
86
|
+
# @option options [String] ISO-8601 datetime of when an event occured at
|
87
|
+
# or before
|
88
|
+
# @option options [String] search Keyword search
|
89
|
+
#
|
90
|
+
# @return [Array<Hash>]
|
91
|
+
sig do
|
92
|
+
params(
|
93
|
+
options: T::Hash[Symbol, String],
|
94
|
+
).returns(T::Array[T::Hash[String, T.nilable(String)]])
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_events(options = {})
|
98
|
+
response = execute_request(
|
99
|
+
request: get_request(
|
100
|
+
path: '/events',
|
101
|
+
auth: true,
|
102
|
+
params: options,
|
103
|
+
),
|
104
|
+
)
|
105
|
+
|
106
|
+
JSON.parse(response.body)['data']
|
107
|
+
end
|
60
108
|
end
|
61
109
|
end
|
62
110
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module WorkOS
|
7
|
+
# The Organization class provides a lightweight wrapper around
|
8
|
+
# a WorkOS Organization resource. This class is not meant to be instantiated
|
9
|
+
# in user space, and is instantiated internally but exposed.
|
10
|
+
class Organization
|
11
|
+
extend T::Sig
|
12
|
+
|
13
|
+
attr_accessor :id, :domains, :name
|
14
|
+
|
15
|
+
sig { params(json: String).void }
|
16
|
+
def initialize(json)
|
17
|
+
raw = parse_json(json)
|
18
|
+
|
19
|
+
@id = T.let(raw.id, String)
|
20
|
+
@name = T.let(raw.name, String)
|
21
|
+
@domains = T.let(raw.domains, Array)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_json(*)
|
25
|
+
{
|
26
|
+
id: id,
|
27
|
+
name: name,
|
28
|
+
domains: domains,
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
sig do
|
35
|
+
params(
|
36
|
+
json_string: String,
|
37
|
+
).returns(WorkOS::Types::OrganizationStruct)
|
38
|
+
end
|
39
|
+
def parse_json(json_string)
|
40
|
+
hash = JSON.parse(json_string, symbolize_names: true)
|
41
|
+
|
42
|
+
WorkOS::Types::OrganizationStruct.new(
|
43
|
+
id: hash[:id],
|
44
|
+
name: hash[:name],
|
45
|
+
domains: hash[:domains],
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
module WorkOS
|
7
|
+
# The Portal module provides resource methods for working with the Admin
|
8
|
+
# Portal product
|
9
|
+
module Portal
|
10
|
+
class << self
|
11
|
+
extend T::Sig
|
12
|
+
include Base
|
13
|
+
include Client
|
14
|
+
|
15
|
+
GENERATE_LINK_INTENTS = WorkOS::Types::Intent.values.map(&:serialize).
|
16
|
+
freeze
|
17
|
+
|
18
|
+
# Create an organization
|
19
|
+
#
|
20
|
+
# @param [Array<String>] domains List of domains that belong to the
|
21
|
+
# organization
|
22
|
+
# @param [String] name A unique, descriptive name for the organization
|
23
|
+
sig do
|
24
|
+
params(
|
25
|
+
domains: T::Array[String],
|
26
|
+
name: String,
|
27
|
+
).returns(WorkOS::Organization)
|
28
|
+
end
|
29
|
+
def create_organization(domains:, name:)
|
30
|
+
request = post_request(
|
31
|
+
auth: true,
|
32
|
+
body: { domains: domains, name: name },
|
33
|
+
path: '/organizations',
|
34
|
+
)
|
35
|
+
|
36
|
+
response = execute_request(request: request)
|
37
|
+
check_and_raise_organization_error(response: response)
|
38
|
+
|
39
|
+
WorkOS::Organization.new(response.body)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Generate a link to grant access to an organization's Admin Portal
|
43
|
+
#
|
44
|
+
# @param [String] intent The access scope for the generated Admin Portal
|
45
|
+
# link. Valid values are: ["sso"]
|
46
|
+
# @param [String] organization The ID of the organization the Admin
|
47
|
+
# Portal link will be generated for.
|
48
|
+
# @param [String] The URL that the end user will be redirected to upon
|
49
|
+
# exiting the generated Admin Portal. If none is provided, the default
|
50
|
+
# redirect link set in your WorkOS Dashboard will be used.
|
51
|
+
sig do
|
52
|
+
params(
|
53
|
+
intent: String,
|
54
|
+
organization: String,
|
55
|
+
return_url: T.nilable(String),
|
56
|
+
).returns(String)
|
57
|
+
end
|
58
|
+
# rubocop:disable Metrics/MethodLength
|
59
|
+
def generate_link(intent:, organization:, return_url: nil)
|
60
|
+
validate_intent(intent)
|
61
|
+
|
62
|
+
request = post_request(
|
63
|
+
auth: true,
|
64
|
+
body: {
|
65
|
+
intent: intent,
|
66
|
+
organization: organization,
|
67
|
+
return_url: return_url,
|
68
|
+
},
|
69
|
+
path: '/portal/generate_link',
|
70
|
+
)
|
71
|
+
|
72
|
+
response = execute_request(request: request)
|
73
|
+
|
74
|
+
JSON.parse(response.body)['link']
|
75
|
+
end
|
76
|
+
# rubocop:enable Metrics/MethodLength
|
77
|
+
|
78
|
+
# Retrieve a list of organizations that have connections configured
|
79
|
+
# within your WorkOS dashboard.
|
80
|
+
#
|
81
|
+
# @param [Array<String>] domains Filter organizations to only return those
|
82
|
+
# that are associated with the provided domains.
|
83
|
+
# @param [String] before A pagination argument used to request
|
84
|
+
# organizations before the provided Organization ID.
|
85
|
+
# @param [String] after A pagination argument used to request
|
86
|
+
# organizations after the provided Organization ID.
|
87
|
+
# @param [Integer] limit A pagination argument used to limit the number
|
88
|
+
# of listed Organizations that are returned.
|
89
|
+
sig do
|
90
|
+
params(
|
91
|
+
options: T::Hash[Symbol, String],
|
92
|
+
).returns(WorkOS::Types::ListStruct)
|
93
|
+
end
|
94
|
+
# rubocop:disable Metrics/MethodLength
|
95
|
+
def list_organizations(options = {})
|
96
|
+
response = execute_request(
|
97
|
+
request: get_request(
|
98
|
+
path: '/organizations',
|
99
|
+
auth: true,
|
100
|
+
params: options,
|
101
|
+
),
|
102
|
+
)
|
103
|
+
|
104
|
+
parsed_response = JSON.parse(response.body)
|
105
|
+
|
106
|
+
WorkOS::Types::ListStruct.new(
|
107
|
+
data: parsed_response['data'],
|
108
|
+
list_metadata: parsed_response['listMetadata'],
|
109
|
+
)
|
110
|
+
end
|
111
|
+
# rubocop:enable Metrics/MethodLength
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
sig { params(response: Net::HTTPResponse).void }
|
116
|
+
# rubocop:disable Metrics/MethodLength
|
117
|
+
def check_and_raise_organization_error(response:)
|
118
|
+
begin
|
119
|
+
body = JSON.parse(response.body)
|
120
|
+
return unless body['message']
|
121
|
+
|
122
|
+
message = body['message']
|
123
|
+
request_id = response['x-request-id']
|
124
|
+
rescue StandardError
|
125
|
+
message = 'Something went wrong'
|
126
|
+
end
|
127
|
+
|
128
|
+
raise APIError.new(
|
129
|
+
message: message,
|
130
|
+
http_status: nil,
|
131
|
+
request_id: request_id,
|
132
|
+
)
|
133
|
+
end
|
134
|
+
# rubocop:enable Metrics/MethodLength
|
135
|
+
|
136
|
+
sig { params(intent: String).void }
|
137
|
+
def validate_intent(intent)
|
138
|
+
return if GENERATE_LINK_INTENTS.include?(intent)
|
139
|
+
|
140
|
+
raise ArgumentError, "#{intent} is not a valid value." \
|
141
|
+
" `intent` must be in #{GENERATE_LINK_INTENTS}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/workos/profile.rb
CHANGED
@@ -14,7 +14,7 @@ module WorkOS
|
|
14
14
|
|
15
15
|
sig { returns(String) }
|
16
16
|
attr_accessor :id, :email, :first_name, :last_name,
|
17
|
-
:connection_type, :idp_id
|
17
|
+
:connection_type, :idp_id, :raw_attributes
|
18
18
|
|
19
19
|
sig { params(profile_json: String).void }
|
20
20
|
def initialize(profile_json)
|
@@ -25,7 +25,8 @@ module WorkOS
|
|
25
25
|
@first_name = raw.first_name
|
26
26
|
@last_name = raw.last_name
|
27
27
|
@connection_type = T.let(raw.connection_type, String)
|
28
|
-
@idp_id =
|
28
|
+
@idp_id = raw.idp_id
|
29
|
+
@raw_attributes = raw.raw_attributes
|
29
30
|
end
|
30
31
|
|
31
32
|
sig { returns(String) }
|
@@ -41,11 +42,13 @@ module WorkOS
|
|
41
42
|
last_name: last_name,
|
42
43
|
connection_type: connection_type,
|
43
44
|
idp_id: idp_id,
|
45
|
+
raw_attributes: raw_attributes,
|
44
46
|
}
|
45
47
|
end
|
46
48
|
|
47
49
|
private
|
48
50
|
|
51
|
+
# rubocop:disable Metrics/AbcSize
|
49
52
|
sig { params(json_string: String).returns(WorkOS::Types::ProfileStruct) }
|
50
53
|
def parse_json(json_string)
|
51
54
|
hash = JSON.parse(json_string, symbolize_names: true)
|
@@ -57,7 +60,9 @@ module WorkOS
|
|
57
60
|
last_name: hash[:profile][:last_name],
|
58
61
|
connection_type: hash[:profile][:connection_type],
|
59
62
|
idp_id: hash[:profile][:idp_id],
|
63
|
+
raw_attributes: hash[:profile][:raw_attributes],
|
60
64
|
)
|
61
65
|
end
|
66
|
+
# rubocop:enable Metrics/AbcSize
|
62
67
|
end
|
63
68
|
end
|
data/lib/workos/types.rb
CHANGED
@@ -6,6 +6,9 @@ module WorkOS
|
|
6
6
|
# so we're using Sorbet throughout this Ruby gem.
|
7
7
|
module Types
|
8
8
|
require_relative 'types/connection_struct'
|
9
|
+
require_relative 'types/intent_enum'
|
10
|
+
require_relative 'types/list_struct'
|
11
|
+
require_relative 'types/organization_struct'
|
9
12
|
require_relative 'types/profile_struct'
|
10
13
|
require_relative 'types/provider_enum'
|
11
14
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOS
|
5
|
+
module Types
|
6
|
+
# The IntentEnum is type-safe declarations of a fixed set of values for
|
7
|
+
# intents while generating an Admin Portal link.
|
8
|
+
class Intent < T::Enum
|
9
|
+
enums do
|
10
|
+
SSO = new('sso')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOS
|
5
|
+
module Types
|
6
|
+
# ListStruct acts as a typed interface to expose lists of data and related
|
7
|
+
# metadata
|
8
|
+
class ListStruct < T::Struct
|
9
|
+
const :data, T::Array[T.untyped]
|
10
|
+
const :list_metadata, T::Hash[String, T.nilable(String)]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOS
|
5
|
+
module Types
|
6
|
+
# This OrganizationStruct acts as a typed interface
|
7
|
+
# for the Organization class
|
8
|
+
class OrganizationStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :name, String
|
11
|
+
const :domains, T::Array[T.untyped]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -11,7 +11,8 @@ module WorkOS
|
|
11
11
|
const :first_name, T.nilable(String)
|
12
12
|
const :last_name, T.nilable(String)
|
13
13
|
const :connection_type, String
|
14
|
-
const :idp_id, String
|
14
|
+
const :idp_id, T.nilable(String)
|
15
|
+
const :raw_attributes, T::Hash[Symbol, Object]
|
15
16
|
end
|
16
17
|
end
|
17
18
|
end
|
data/lib/workos/version.rb
CHANGED
@@ -137,4 +137,16 @@ describe WorkOS::AuditTrail do
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
140
|
+
|
141
|
+
describe '.get_events' do
|
142
|
+
context 'with no options' do
|
143
|
+
it 'returns events' do
|
144
|
+
VCR.use_cassette('audit_trail/get_events') do
|
145
|
+
events = described_class.get_events
|
146
|
+
|
147
|
+
expect(events.size).to eq(2)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
140
152
|
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: false
|
3
|
+
|
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
|
+
describe '.create_organization' do
|
14
|
+
context 'with valid payload' do
|
15
|
+
it 'creates an organization' do
|
16
|
+
VCR.use_cassette 'organization/create' do
|
17
|
+
organization = described_class.create_organization(
|
18
|
+
domains: ['example.com'],
|
19
|
+
name: 'Test Organization',
|
20
|
+
)
|
21
|
+
|
22
|
+
expect(organization.id).to eq('org_01EHT88Z8J8795GZNQ4ZP1J81T')
|
23
|
+
expect(organization.name).to eq('Test Organization')
|
24
|
+
expect(organization.domains.first[:domain]).to eq('example.com')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with an invalid payload' do
|
30
|
+
it 'returns an error' do
|
31
|
+
VCR.use_cassette 'organization/create_invalid' do
|
32
|
+
expect do
|
33
|
+
described_class.create_organization(
|
34
|
+
domains: ['example.com'],
|
35
|
+
name: 'Test Organization 2',
|
36
|
+
)
|
37
|
+
end.to raise_error(
|
38
|
+
WorkOS::APIError,
|
39
|
+
/An Organization with the domain example.com already exists/,
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '.generate_link' do
|
47
|
+
let(:organization) { 'org_01EHQMYV6MBK39QC5PZXHY59C3' }
|
48
|
+
|
49
|
+
describe 'with a valid organization' do
|
50
|
+
describe 'with the minimal params' do
|
51
|
+
it 'returns an Admin Portal link' do
|
52
|
+
VCR.use_cassette 'portal/generate_link' do
|
53
|
+
portal_link = described_class.generate_link(
|
54
|
+
intent: 'sso',
|
55
|
+
organization: organization,
|
56
|
+
)
|
57
|
+
|
58
|
+
expect(portal_link).to eq(
|
59
|
+
'https://id.workos.com/portal/launch?secret=secret',
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'with an invalid organization' do
|
67
|
+
it 'raises an error' do
|
68
|
+
VCR.use_cassette 'portal/generate_link_invalid' do
|
69
|
+
expect do
|
70
|
+
described_class.generate_link(
|
71
|
+
intent: 'sso',
|
72
|
+
organization: 'bogus-id',
|
73
|
+
)
|
74
|
+
end.to raise_error(
|
75
|
+
WorkOS::InvalidRequestError,
|
76
|
+
/Could not find an organization with the id, bogus-id/,
|
77
|
+
)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'with an invalid intent' do
|
83
|
+
it 'raises an error' do
|
84
|
+
expect do
|
85
|
+
described_class.generate_link(
|
86
|
+
intent: 'bogus-intent',
|
87
|
+
organization: organization,
|
88
|
+
)
|
89
|
+
end.to raise_error(
|
90
|
+
ArgumentError,
|
91
|
+
'bogus-intent is not a valid value. `intent` must be in ["sso"]',
|
92
|
+
)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '.list_organizations' do
|
98
|
+
context 'with no options' do
|
99
|
+
it 'returns organizations and metadata' do
|
100
|
+
expected_metadata = {
|
101
|
+
'after' => nil,
|
102
|
+
'before' => 'before-id',
|
103
|
+
}
|
104
|
+
|
105
|
+
VCR.use_cassette 'organization/list' do
|
106
|
+
organizations = described_class.list_organizations
|
107
|
+
|
108
|
+
expect(organizations.data.size).to eq(7)
|
109
|
+
expect(organizations.list_metadata).to eq(expected_metadata)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'with the before option' do
|
115
|
+
it 'forms the proper request to the API' do
|
116
|
+
request_args = [
|
117
|
+
'/organizations?before=before-id',
|
118
|
+
'Content-Type' => 'application/json'
|
119
|
+
]
|
120
|
+
|
121
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
122
|
+
|
123
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
124
|
+
and_return(expected_request)
|
125
|
+
|
126
|
+
VCR.use_cassette 'organization/list', match_requests_on: [:path] do
|
127
|
+
organizations = described_class.list_organizations(
|
128
|
+
before: 'before-id',
|
129
|
+
)
|
130
|
+
|
131
|
+
expect(organizations.data.size).to eq(7)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with the after option' do
|
137
|
+
it 'forms the proper request to the API' do
|
138
|
+
request_args = [
|
139
|
+
'/organizations?after=after-id',
|
140
|
+
'Content-Type' => 'application/json'
|
141
|
+
]
|
142
|
+
|
143
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
144
|
+
|
145
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
146
|
+
and_return(expected_request)
|
147
|
+
|
148
|
+
VCR.use_cassette 'organization/list', match_requests_on: [:path] do
|
149
|
+
organizations = described_class.list_organizations(after: 'after-id')
|
150
|
+
|
151
|
+
expect(organizations.data.size).to eq(7)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'with the limit option' do
|
157
|
+
it 'forms the proper request to the API' do
|
158
|
+
request_args = [
|
159
|
+
'/organizations?limit=10',
|
160
|
+
'Content-Type' => 'application/json'
|
161
|
+
]
|
162
|
+
|
163
|
+
expected_request = Net::HTTP::Get.new(*request_args)
|
164
|
+
|
165
|
+
expect(Net::HTTP::Get).to receive(:new).with(*request_args).
|
166
|
+
and_return(expected_request)
|
167
|
+
|
168
|
+
VCR.use_cassette 'organization/list', match_requests_on: [:path] do
|
169
|
+
organizations = described_class.list_organizations(limit: 10)
|
170
|
+
|
171
|
+
expect(organizations.data.size).to eq(7)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
data/spec/lib/workos/sso_spec.rb
CHANGED
@@ -161,6 +161,24 @@ describe WorkOS::SSO do
|
|
161
161
|
it 'returns a WorkOS::Profile' do
|
162
162
|
profile = described_class.profile(**args)
|
163
163
|
expect(profile).to be_a(WorkOS::Profile)
|
164
|
+
|
165
|
+
expectation = {
|
166
|
+
connection_type: 'OktaSAML',
|
167
|
+
email: 'demo@workos-okta.com',
|
168
|
+
first_name: 'WorkOS',
|
169
|
+
id: 'prof_01DRA1XNSJDZ19A31F183ECQW5',
|
170
|
+
idp_id: '00u1klkowm8EGah2H357',
|
171
|
+
last_name: 'Demo',
|
172
|
+
raw_attributes: {
|
173
|
+
email: 'demo@workos-okta.com',
|
174
|
+
first_name: 'WorkOS',
|
175
|
+
id: 'prof_01DRA1XNSJDZ19A31F183ECQW5',
|
176
|
+
idp_id: '00u1klkowm8EGah2H357',
|
177
|
+
last_name: 'Demo',
|
178
|
+
},
|
179
|
+
}
|
180
|
+
|
181
|
+
expect(profile.to_json).to eq(expectation)
|
164
182
|
end
|
165
183
|
end
|
166
184
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://api.workos.com/events
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ""
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- "*/*"
|
16
|
+
User-Agent:
|
17
|
+
- WorkOS; ruby/2.7.1; x86_64-darwin19; v0.4.0
|
18
|
+
Authorization:
|
19
|
+
- Bearer <API_KEY>
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Vary:
|
26
|
+
- Origin, Accept-Encoding
|
27
|
+
Access-Control-Allow-Credentials:
|
28
|
+
- "true"
|
29
|
+
X-Dns-Prefetch-Control:
|
30
|
+
- "off"
|
31
|
+
X-Frame-Options:
|
32
|
+
- SAMEORIGIN
|
33
|
+
Strict-Transport-Security:
|
34
|
+
- max-age=15552000; includeSubDomains
|
35
|
+
X-Download-Options:
|
36
|
+
- noopen
|
37
|
+
X-Content-Type-Options:
|
38
|
+
- nosniff
|
39
|
+
X-Xss-Protection:
|
40
|
+
- 1; mode=block
|
41
|
+
X-Request-Id:
|
42
|
+
- ""
|
43
|
+
Content-Type:
|
44
|
+
- application/json; charset=utf-8
|
45
|
+
Etag:
|
46
|
+
- W/"1784-HtVN7X+AT30Dlt9nZrirP0nnyV8"
|
47
|
+
Date:
|
48
|
+
- Fri, 31 Jul 2020 14:41:12 GMT
|
49
|
+
Connection:
|
50
|
+
- keep-alive
|
51
|
+
Transfer-Encoding:
|
52
|
+
- chunked
|
53
|
+
body:
|
54
|
+
encoding: ASCII-8BIT
|
55
|
+
string:
|
56
|
+
'{"data":[{"object":"event","id":"evt_01EEJM9Q9SMC3W2SZDKA5VJ8XQ","group":"workos.com","location":"::1","latitude":null,"longitude":null,"type":"r","actor_name":"foo@example.com","actor_id":"user_01EEG9P7A1DA9VY9CX7GT47RPF","target_name":"api_key_query","target_id":"key_01EEG9MPHAYX46BBZKGK3BGQXJ","metadata":{"description":"User
|
57
|
+
viewed API key.","x_request_id":""},"occurred_at":"2020-07-31T14:27:00.384Z","action":{"object":"event_action","id":"evt_action_01EEGQXWAHB065P5JD0QDAAGDC","name":"user.viewed_api_key","project_id":"project_01DZB0E7HQMA6G85PQNHQJMZD0"}},{"object":"event","id":"evt_01EEJM9Q7GMR1VGT6VXN2N2JJQ","group":"workos.com","location":"::1","latitude":null,"longitude":null,"type":"r","actor_name":"foo@example.com","actor_id":"user_01EEG9P7A1DA9VY9CX7GT47RPF","target_name":"api_key_query","target_id":"key_01EEG9MPGM8KFT9VBQHJMV8YZB","metadata":{"description":"User
|
58
|
+
viewed API key.","x_request_id":""},"occurred_at":"2020-07-31T14:27:00.360Z","action":{"object":"event_action","id":"evt_action_01EEGQXWAHB065P5JD0QDAAGDC","name":"user.viewed_api_key","project_id":"project_01DZB0E7HQMA6G85PQNHQJMZD0"}}],"listMetadata":{"before":"evt_01EEJKZDAR6G4JHFQT4R3KSZDQ","after":null}}'
|
59
|
+
http_version:
|
60
|
+
recorded_at: Fri, 31 Jul 2020 14:41:12 GMT
|
61
|
+
recorded_with: VCR 5.0.0
|
@@ -0,0 +1,72 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.workos.com/organizations
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"domains":["example.com"],"name":"Test Organization"}'
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- "*/*"
|
16
|
+
User-Agent:
|
17
|
+
- WorkOS; ruby/2.7.1; x86_64-darwin19; v0.5.0
|
18
|
+
Authorization:
|
19
|
+
- Bearer <API_KEY>
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 201
|
23
|
+
message: Created
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- Cowboy
|
27
|
+
Connection:
|
28
|
+
- keep-alive
|
29
|
+
Vary:
|
30
|
+
- Origin, Accept-Encoding
|
31
|
+
Access-Control-Allow-Credentials:
|
32
|
+
- 'true'
|
33
|
+
Content-Security-Policy:
|
34
|
+
- 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self''
|
35
|
+
https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src
|
36
|
+
''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests'
|
37
|
+
X-Dns-Prefetch-Control:
|
38
|
+
- 'off'
|
39
|
+
Expect-Ct:
|
40
|
+
- max-age=0
|
41
|
+
X-Frame-Options:
|
42
|
+
- SAMEORIGIN
|
43
|
+
Strict-Transport-Security:
|
44
|
+
- max-age=15552000; includeSubDomains
|
45
|
+
X-Download-Options:
|
46
|
+
- noopen
|
47
|
+
X-Content-Type-Options:
|
48
|
+
- nosniff
|
49
|
+
X-Permitted-Cross-Domain-Policies:
|
50
|
+
- none
|
51
|
+
Referrer-Policy:
|
52
|
+
- no-referrer
|
53
|
+
X-Xss-Protection:
|
54
|
+
- '0'
|
55
|
+
X-Request-Id:
|
56
|
+
- bcddfa8b-3a12-4d48-b265-6094a26225a4
|
57
|
+
Content-Type:
|
58
|
+
- application/json; charset=utf-8
|
59
|
+
Content-Length:
|
60
|
+
- '203'
|
61
|
+
Etag:
|
62
|
+
- W/"cb-T4+GTGrJeuAmC0PAjcaSX5ZXL18"
|
63
|
+
Date:
|
64
|
+
- Wed, 09 Sep 2020 20:17:53 GMT
|
65
|
+
Via:
|
66
|
+
- 1.1 vegur
|
67
|
+
body:
|
68
|
+
encoding: UTF-8
|
69
|
+
string: '{"name":"Test Organization","object":"organization","id":"org_01EHT88Z8J8795GZNQ4ZP1J81T","domains":[{"domain":"example.com","object":"organization_domain","id":"org_domain_01EHT88Z8WZEFWYPM6EC9BX2R8"}]}'
|
70
|
+
http_version:
|
71
|
+
recorded_at: Wed, 09 Sep 2020 20:17:54 GMT
|
72
|
+
recorded_with: VCR 5.0.0
|
@@ -0,0 +1,72 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.workos.com/organizations
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"domains":["example.com"],"name":"Test Organization 2"}'
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- "*/*"
|
16
|
+
User-Agent:
|
17
|
+
- WorkOS; ruby/2.7.1; x86_64-darwin19; v0.5.0
|
18
|
+
Authorization:
|
19
|
+
- Bearer <API_KEY>
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 409
|
23
|
+
message: Conflict
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- Cowboy
|
27
|
+
Connection:
|
28
|
+
- keep-alive
|
29
|
+
Vary:
|
30
|
+
- Origin, Accept-Encoding
|
31
|
+
Access-Control-Allow-Credentials:
|
32
|
+
- 'true'
|
33
|
+
Content-Security-Policy:
|
34
|
+
- 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self''
|
35
|
+
https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src
|
36
|
+
''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests'
|
37
|
+
X-Dns-Prefetch-Control:
|
38
|
+
- 'off'
|
39
|
+
Expect-Ct:
|
40
|
+
- max-age=0
|
41
|
+
X-Frame-Options:
|
42
|
+
- SAMEORIGIN
|
43
|
+
Strict-Transport-Security:
|
44
|
+
- max-age=15552000; includeSubDomains
|
45
|
+
X-Download-Options:
|
46
|
+
- noopen
|
47
|
+
X-Content-Type-Options:
|
48
|
+
- nosniff
|
49
|
+
X-Permitted-Cross-Domain-Policies:
|
50
|
+
- none
|
51
|
+
Referrer-Policy:
|
52
|
+
- no-referrer
|
53
|
+
X-Xss-Protection:
|
54
|
+
- '0'
|
55
|
+
X-Request-Id:
|
56
|
+
- 929940d6-33dd-404c-9856-eca6cc606d28
|
57
|
+
Content-Type:
|
58
|
+
- application/json; charset=utf-8
|
59
|
+
Content-Length:
|
60
|
+
- '73'
|
61
|
+
Etag:
|
62
|
+
- W/"49-8i1S2EtfSciiA8rvGWbYFNlSlhw"
|
63
|
+
Date:
|
64
|
+
- Wed, 09 Sep 2020 21:26:03 GMT
|
65
|
+
Via:
|
66
|
+
- 1.1 vegur
|
67
|
+
body:
|
68
|
+
encoding: UTF-8
|
69
|
+
string: '{"message":"An Organization with the domain example.com already exists."}'
|
70
|
+
http_version:
|
71
|
+
recorded_at: Wed, 09 Sep 2020 21:26:03 GMT
|
72
|
+
recorded_with: VCR 5.0.0
|
@@ -0,0 +1,72 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://api.workos.com/organizations
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- "*/*"
|
16
|
+
User-Agent:
|
17
|
+
- WorkOS; ruby/2.7.1; x86_64-darwin19; v0.5.0
|
18
|
+
Authorization:
|
19
|
+
- Bearer <API_KEY>
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- Cowboy
|
27
|
+
Connection:
|
28
|
+
- keep-alive
|
29
|
+
Vary:
|
30
|
+
- Origin, Accept-Encoding
|
31
|
+
Access-Control-Allow-Credentials:
|
32
|
+
- 'true'
|
33
|
+
Content-Security-Policy:
|
34
|
+
- 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self''
|
35
|
+
https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src
|
36
|
+
''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests'
|
37
|
+
X-Dns-Prefetch-Control:
|
38
|
+
- 'off'
|
39
|
+
Expect-Ct:
|
40
|
+
- max-age=0
|
41
|
+
X-Frame-Options:
|
42
|
+
- SAMEORIGIN
|
43
|
+
Strict-Transport-Security:
|
44
|
+
- max-age=15552000; includeSubDomains
|
45
|
+
X-Download-Options:
|
46
|
+
- noopen
|
47
|
+
X-Content-Type-Options:
|
48
|
+
- nosniff
|
49
|
+
X-Permitted-Cross-Domain-Policies:
|
50
|
+
- none
|
51
|
+
Referrer-Policy:
|
52
|
+
- no-referrer
|
53
|
+
X-Xss-Protection:
|
54
|
+
- '0'
|
55
|
+
X-Request-Id:
|
56
|
+
- bac447a8-ba37-40d0-bd2e-c6b0d9e55cb4
|
57
|
+
Content-Type:
|
58
|
+
- application/json; charset=utf-8
|
59
|
+
Etag:
|
60
|
+
- W/"5e0-jXwzOfsEklDxV9I2vJyDWqYBnmU"
|
61
|
+
Date:
|
62
|
+
- Tue, 08 Sep 2020 23:05:22 GMT
|
63
|
+
Transfer-Encoding:
|
64
|
+
- chunked
|
65
|
+
Via:
|
66
|
+
- 1.1 vegur
|
67
|
+
body:
|
68
|
+
encoding: ASCII-8BIT
|
69
|
+
string: '{"object":"list","data":[{"object":"organization","id":"org_01EHQMYV6MBK39QC5PZXHY59C3","name":"example.com","domains":[{"object":"organization_domain","id":"org_domain_01EHQMYV71XT8H31WE5HF8YK4A","domain":"example.com"}]},{"object":"organization","id":"org_01EHQMVDTC2GRAHFCCRNTSKH46","name":"example2.com","domains":[{"object":"organization_domain","id":"org_domain_01EHQMVDTZVA27PK614ME4YK7V","domain":"example2.com"}]},{"object":"organization","id":"org_01EGS4P7QR31EZ4YWD1Z1XA176","name":"foo-corp.com","domains":[{"object":"organization_domain","id":"org_domain_01EGS4P7RNQPFQAQ7SKCC40KNE","domain":"foo-corp.com"}]},{"object":"organization","id":"org_01EGPYFYM0Y66AHNYQG9Z63DTN","name":"example3.com","domains":[{"object":"organization_domain","id":"org_domain_01EGPYFYMGTRR38Z109MCJ3HHA","domain":"example3.com"}]},{"object":"organization","id":"org_01EGPJWMT2EQMK7FMPR3TBC861","name":"workos.com","domains":[{"object":"organization_domain","id":"org_domain_01EGPJWMTHRB5FP6MKE14RZ9BQ","domain":"workos.com"}]},{"object":"organization","id":"org_01EGPJ5YY5P897573GJFGGY7ZF","name":"example4.com","domains":[{"object":"organization_domain","id":"org_domain_01EGPJ5YYE7V931BWYS1AJHHHC","domain":"example4.com"}]},{"object":"organization","id":"org_01EGP9Z6RY2J6YE0ZV57CGEXV2","name":"example5.com","domains":[{"object":"organization_domain","id":"org_domain_01EGP9Z6S6HVQ5CPD152GJBEA5","domain":"example5.com"}]}],"listMetadata":{"before":"before-id","after":null}}'
|
70
|
+
http_version:
|
71
|
+
recorded_at: Tue, 08 Sep 2020 23:05:22 GMT
|
72
|
+
recorded_with: VCR 5.0.0
|
@@ -0,0 +1,72 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.workos.com/portal/generate_link
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"intent":"sso","organization":"org_01EHQMYV6MBK39QC5PZXHY59C3","return_url":null}'
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- "*/*"
|
16
|
+
User-Agent:
|
17
|
+
- WorkOS; ruby/2.7.1; x86_64-darwin19; v0.5.0
|
18
|
+
Authorization:
|
19
|
+
- Bearer <API_KEY>
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 201
|
23
|
+
message: Created
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- Cowboy
|
27
|
+
Connection:
|
28
|
+
- keep-alive
|
29
|
+
Vary:
|
30
|
+
- Origin, Accept-Encoding
|
31
|
+
Access-Control-Allow-Credentials:
|
32
|
+
- 'true'
|
33
|
+
Content-Security-Policy:
|
34
|
+
- 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self''
|
35
|
+
https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src
|
36
|
+
''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests'
|
37
|
+
X-Dns-Prefetch-Control:
|
38
|
+
- 'off'
|
39
|
+
Expect-Ct:
|
40
|
+
- max-age=0
|
41
|
+
X-Frame-Options:
|
42
|
+
- SAMEORIGIN
|
43
|
+
Strict-Transport-Security:
|
44
|
+
- max-age=15552000; includeSubDomains
|
45
|
+
X-Download-Options:
|
46
|
+
- noopen
|
47
|
+
X-Content-Type-Options:
|
48
|
+
- nosniff
|
49
|
+
X-Permitted-Cross-Domain-Policies:
|
50
|
+
- none
|
51
|
+
Referrer-Policy:
|
52
|
+
- no-referrer
|
53
|
+
X-Xss-Protection:
|
54
|
+
- '0'
|
55
|
+
X-Request-Id:
|
56
|
+
- cb9ad5cf-243a-4084-a4f6-2d7d2b097b8b
|
57
|
+
Content-Type:
|
58
|
+
- application/json; charset=utf-8
|
59
|
+
Content-Length:
|
60
|
+
- '79'
|
61
|
+
Etag:
|
62
|
+
- W/"4f-NN86NUZRu/GQgPAYTexTS6/9DnM"
|
63
|
+
Date:
|
64
|
+
- Wed, 09 Sep 2020 23:43:07 GMT
|
65
|
+
Via:
|
66
|
+
- 1.1 vegur
|
67
|
+
body:
|
68
|
+
encoding: UTF-8
|
69
|
+
string: '{"link":"https://id.workos.com/portal/launch?secret=secret"}'
|
70
|
+
http_version:
|
71
|
+
recorded_at: Wed, 09 Sep 2020 23:43:07 GMT
|
72
|
+
recorded_with: VCR 5.0.0
|
@@ -0,0 +1,72 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.workos.com/portal/generate_link
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"intent":"sso","organization":"bogus-id","return_url":null}'
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
Accept:
|
15
|
+
- "*/*"
|
16
|
+
User-Agent:
|
17
|
+
- WorkOS; ruby/2.7.1; x86_64-darwin19; v0.5.0
|
18
|
+
Authorization:
|
19
|
+
- Bearer <API_KEY>
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 400
|
23
|
+
message: Bad Request
|
24
|
+
headers:
|
25
|
+
Server:
|
26
|
+
- Cowboy
|
27
|
+
Connection:
|
28
|
+
- keep-alive
|
29
|
+
Vary:
|
30
|
+
- Origin, Accept-Encoding
|
31
|
+
Access-Control-Allow-Credentials:
|
32
|
+
- 'true'
|
33
|
+
Content-Security-Policy:
|
34
|
+
- 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self''
|
35
|
+
https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src
|
36
|
+
''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests'
|
37
|
+
X-Dns-Prefetch-Control:
|
38
|
+
- 'off'
|
39
|
+
Expect-Ct:
|
40
|
+
- max-age=0
|
41
|
+
X-Frame-Options:
|
42
|
+
- SAMEORIGIN
|
43
|
+
Strict-Transport-Security:
|
44
|
+
- max-age=15552000; includeSubDomains
|
45
|
+
X-Download-Options:
|
46
|
+
- noopen
|
47
|
+
X-Content-Type-Options:
|
48
|
+
- nosniff
|
49
|
+
X-Permitted-Cross-Domain-Policies:
|
50
|
+
- none
|
51
|
+
Referrer-Policy:
|
52
|
+
- no-referrer
|
53
|
+
X-Xss-Protection:
|
54
|
+
- '0'
|
55
|
+
X-Request-Id:
|
56
|
+
- f1c46aa5-0d87-4d9a-b2ce-dc0505eb8f75
|
57
|
+
Content-Type:
|
58
|
+
- application/json; charset=utf-8
|
59
|
+
Content-Length:
|
60
|
+
- '67'
|
61
|
+
Etag:
|
62
|
+
- W/"43-kRRkij6uWMfZoSUJpiGbSXw7SNc"
|
63
|
+
Date:
|
64
|
+
- Thu, 10 Sep 2020 16:14:41 GMT
|
65
|
+
Via:
|
66
|
+
- 1.1 vegur
|
67
|
+
body:
|
68
|
+
encoding: UTF-8
|
69
|
+
string: '{"message":"Could not find an organization with the id, bogus-id."}'
|
70
|
+
http_version:
|
71
|
+
recorded_at: Thu, 10 Sep 2020 16:14:41 GMT
|
72
|
+
recorded_with: VCR 5.0.0
|
data/spec/support/profile.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"profile":{"object":"profile","id":"prof_01DRA1XNSJDZ19A31F183ECQW5","email":"demo@workos-okta.com","first_name":"WorkOS","connection_type":"OktaSAML","last_name":"Demo","idp_id":"00u1klkowm8EGah2H357"},"access_token":"01DVX6QBS3EG6FHY2ESAA5Q65X"}
|
1
|
+
{"profile":{"object":"profile","id":"prof_01DRA1XNSJDZ19A31F183ECQW5","email":"demo@workos-okta.com","first_name":"WorkOS","connection_type":"OktaSAML","last_name":"Demo","idp_id":"00u1klkowm8EGah2H357","raw_attributes":{"id":"prof_01DRA1XNSJDZ19A31F183ECQW5","email":"demo@workos-okta.com","first_name":"WorkOS","last_name":"Demo","idp_id":"00u1klkowm8EGah2H357"}},"access_token":"01DVX6QBS3EG6FHY2ESAA5Q65X"}
|
data/workos.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency 'sorbet-runtime', '~> 0.5'
|
26
26
|
|
27
27
|
spec.add_development_dependency 'bundler', '>= 2.0.1'
|
28
|
-
spec.add_development_dependency 'codecov', '~> 0.
|
28
|
+
spec.add_development_dependency 'codecov', '~> 0.2.8'
|
29
29
|
spec.add_development_dependency 'rake'
|
30
30
|
spec.add_development_dependency 'rspec', '~> 3.9.0'
|
31
31
|
spec.add_development_dependency 'rubocop', '~> 0.77'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: workos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- WorkOS
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sorbet-runtime
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 0.2.8
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 0.2.8
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -213,10 +213,15 @@ files:
|
|
213
213
|
- lib/workos/connection.rb
|
214
214
|
- lib/workos/directory_sync.rb
|
215
215
|
- lib/workos/errors.rb
|
216
|
+
- lib/workos/organization.rb
|
217
|
+
- lib/workos/portal.rb
|
216
218
|
- lib/workos/profile.rb
|
217
219
|
- lib/workos/sso.rb
|
218
220
|
- lib/workos/types.rb
|
219
221
|
- lib/workos/types/connection_struct.rb
|
222
|
+
- lib/workos/types/intent_enum.rb
|
223
|
+
- lib/workos/types/list_struct.rb
|
224
|
+
- lib/workos/types/organization_struct.rb
|
220
225
|
- lib/workos/types/profile_struct.rb
|
221
226
|
- lib/workos/types/provider_enum.rb
|
222
227
|
- lib/workos/version.rb
|
@@ -232,6 +237,7 @@ files:
|
|
232
237
|
- spec/lib/workos/audit_trail_spec.rb
|
233
238
|
- spec/lib/workos/base_spec.rb
|
234
239
|
- spec/lib/workos/directory_sync_spec.rb
|
240
|
+
- spec/lib/workos/portal_spec.rb
|
235
241
|
- spec/lib/workos/sso_spec.rb
|
236
242
|
- spec/spec_helper.rb
|
237
243
|
- spec/support/fixtures/vcr_cassettes/audit_trail/create_event.yml
|
@@ -239,6 +245,7 @@ files:
|
|
239
245
|
- spec/support/fixtures/vcr_cassettes/audit_trail/create_event_invalid.yml
|
240
246
|
- spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_and_payload.yml
|
241
247
|
- spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_different_payload.yml
|
248
|
+
- spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml
|
242
249
|
- spec/support/fixtures/vcr_cassettes/base/execute_request_unauthenticated.yml
|
243
250
|
- spec/support/fixtures/vcr_cassettes/directory_sync/get_group.yml
|
244
251
|
- spec/support/fixtures/vcr_cassettes/directory_sync/get_group_with_invalid_id.yml
|
@@ -250,6 +257,11 @@ files:
|
|
250
257
|
- spec/support/fixtures/vcr_cassettes/directory_sync/list_groups_with_directory_param.yml
|
251
258
|
- spec/support/fixtures/vcr_cassettes/directory_sync/list_users.yml
|
252
259
|
- spec/support/fixtures/vcr_cassettes/directory_sync/list_users_with_directory_param.yml
|
260
|
+
- spec/support/fixtures/vcr_cassettes/organization/create.yml
|
261
|
+
- spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml
|
262
|
+
- spec/support/fixtures/vcr_cassettes/organization/list.yml
|
263
|
+
- spec/support/fixtures/vcr_cassettes/portal/generate_link.yml
|
264
|
+
- spec/support/fixtures/vcr_cassettes/portal/generate_link_invalid.yml
|
253
265
|
- spec/support/fixtures/vcr_cassettes/sso/create_connection_with_invalid_source.yml
|
254
266
|
- spec/support/fixtures/vcr_cassettes/sso/create_connection_with_valid_source.yml
|
255
267
|
- spec/support/profile.txt
|
@@ -282,6 +294,7 @@ test_files:
|
|
282
294
|
- spec/lib/workos/audit_trail_spec.rb
|
283
295
|
- spec/lib/workos/base_spec.rb
|
284
296
|
- spec/lib/workos/directory_sync_spec.rb
|
297
|
+
- spec/lib/workos/portal_spec.rb
|
285
298
|
- spec/lib/workos/sso_spec.rb
|
286
299
|
- spec/spec_helper.rb
|
287
300
|
- spec/support/fixtures/vcr_cassettes/audit_trail/create_event.yml
|
@@ -289,6 +302,7 @@ test_files:
|
|
289
302
|
- spec/support/fixtures/vcr_cassettes/audit_trail/create_event_invalid.yml
|
290
303
|
- spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_and_payload.yml
|
291
304
|
- spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_different_payload.yml
|
305
|
+
- spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml
|
292
306
|
- spec/support/fixtures/vcr_cassettes/base/execute_request_unauthenticated.yml
|
293
307
|
- spec/support/fixtures/vcr_cassettes/directory_sync/get_group.yml
|
294
308
|
- spec/support/fixtures/vcr_cassettes/directory_sync/get_group_with_invalid_id.yml
|
@@ -300,6 +314,11 @@ test_files:
|
|
300
314
|
- spec/support/fixtures/vcr_cassettes/directory_sync/list_groups_with_directory_param.yml
|
301
315
|
- spec/support/fixtures/vcr_cassettes/directory_sync/list_users.yml
|
302
316
|
- spec/support/fixtures/vcr_cassettes/directory_sync/list_users_with_directory_param.yml
|
317
|
+
- spec/support/fixtures/vcr_cassettes/organization/create.yml
|
318
|
+
- spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml
|
319
|
+
- spec/support/fixtures/vcr_cassettes/organization/list.yml
|
320
|
+
- spec/support/fixtures/vcr_cassettes/portal/generate_link.yml
|
321
|
+
- spec/support/fixtures/vcr_cassettes/portal/generate_link_invalid.yml
|
303
322
|
- spec/support/fixtures/vcr_cassettes/sso/create_connection_with_invalid_source.yml
|
304
323
|
- spec/support/fixtures/vcr_cassettes/sso/create_connection_with_valid_source.yml
|
305
324
|
- spec/support/profile.txt
|