workos 2.5.1 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +13 -11
- data/lib/workos/audit_log_export.rb +55 -0
- data/lib/workos/audit_logs.rb +107 -0
- data/lib/workos/client.rb +2 -0
- data/lib/workos/errors.rb +15 -1
- data/lib/workos/organizations.rb +4 -1
- data/lib/workos/types/audit_log_export_struct.rb +17 -0
- data/lib/workos/types.rb +1 -0
- data/lib/workos/version.rb +1 -1
- data/lib/workos/webhooks.rb +49 -2
- data/lib/workos.rb +2 -0
- data/sorbet/rbi/sorbet-typed/lib/rainbow/all/rainbow.rbi +5 -5
- data/spec/lib/workos/audit_logs_spec.rb +149 -0
- data/spec/lib/workos/organizations_spec.rb +73 -9
- data/spec/lib/workos/webhooks_spec.rb +130 -84
- data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event.yml +59 -0
- data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event_custom_idempotency_key.yml +60 -0
- data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event_invalid.yml +59 -0
- data/spec/support/fixtures/vcr_cassettes/audit_logs/create_export.yml +76 -0
- data/spec/support/fixtures/vcr_cassettes/audit_logs/create_export_with_filters.yml +78 -0
- data/spec/support/fixtures/vcr_cassettes/audit_logs/get_export.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/organization/create_with_duplicate_idempotency_key_and_different_payload.yml +155 -0
- data/spec/support/fixtures/vcr_cassettes/organization/create_with_duplicate_idempotency_key_and_payload.yml +154 -0
- data/spec/support/fixtures/vcr_cassettes/organization/create_with_idempotency_key.yml +79 -0
- data/spec/support/webhook_payload.txt +1 -1
- metadata +26 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dc7e2ff5b758d6a8f65679a0947d94c6278551d68285ee366e062821e4c1544
|
4
|
+
data.tar.gz: 15d849b4fcf07f8c7741e36abbc4a6cec29d496e43dd5b5f428a150fb02a8ca0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8d8cdd3e0c5414e116f183af145206505d710c16a8372226b10c45595750c779a4c639bbe62c8410b79f130de689fa48376eeba76b5fc7fbfb3a0c87b6977d0
|
7
|
+
data.tar.gz: a0451a8ee3c4ffb30271dc7687817454b3e9ebd95db08cdbb7ba7b53aacb460b9bef54ad864261c29363910a1cbd9b6d8e8a057518ade44fdf8c82c83bb31c1f
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
workos (2.
|
4
|
+
workos (2.6.0)
|
5
5
|
sorbet-runtime (~> 0.5)
|
6
6
|
|
7
7
|
GEM
|
@@ -58,17 +58,19 @@ GEM
|
|
58
58
|
simplecov_json_formatter (~> 0.1)
|
59
59
|
simplecov-html (0.12.3)
|
60
60
|
simplecov_json_formatter (0.1.2)
|
61
|
-
sorbet (0.5.
|
62
|
-
sorbet-static (= 0.5.
|
61
|
+
sorbet (0.5.10346)
|
62
|
+
sorbet-static (= 0.5.10346)
|
63
63
|
sorbet-runtime (0.5.10323)
|
64
|
-
sorbet-static (0.5.
|
65
|
-
sorbet-static (0.5.
|
66
|
-
sorbet-static (0.5.
|
67
|
-
sorbet-static (0.5.
|
68
|
-
sorbet-static (0.5.
|
69
|
-
sorbet-static (0.5.
|
70
|
-
sorbet-static (0.5.
|
71
|
-
sorbet-static (0.5.
|
64
|
+
sorbet-static (0.5.10346-universal-darwin-14)
|
65
|
+
sorbet-static (0.5.10346-universal-darwin-15)
|
66
|
+
sorbet-static (0.5.10346-universal-darwin-16)
|
67
|
+
sorbet-static (0.5.10346-universal-darwin-17)
|
68
|
+
sorbet-static (0.5.10346-universal-darwin-18)
|
69
|
+
sorbet-static (0.5.10346-universal-darwin-19)
|
70
|
+
sorbet-static (0.5.10346-universal-darwin-20)
|
71
|
+
sorbet-static (0.5.10346-universal-darwin-21)
|
72
|
+
sorbet-static (0.5.10346-universal-darwin-22)
|
73
|
+
sorbet-static (0.5.10346-x86_64-linux)
|
72
74
|
unicode-display_width (1.7.0)
|
73
75
|
vcr (5.0.0)
|
74
76
|
webmock (3.12.2)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
module WorkOS
|
5
|
+
# The AuditLogExport class represents the WorkOS entity created when exporting Audit Log Events.
|
6
|
+
class AuditLogExport
|
7
|
+
include HashProvider
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
attr_accessor :object, :id, :state, :url, :created_at, :updated_at
|
11
|
+
|
12
|
+
sig { params(json: String).void }
|
13
|
+
def initialize(json)
|
14
|
+
raw = parse_json(json)
|
15
|
+
|
16
|
+
@object = T.let(raw.object, String)
|
17
|
+
@id = T.let(raw.id, String)
|
18
|
+
@state = T.let(raw.state, String)
|
19
|
+
@url = raw.url
|
20
|
+
@created_at = T.let(raw.created_at, String)
|
21
|
+
@updated_at = T.let(raw.updated_at, String)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_json(*)
|
25
|
+
{
|
26
|
+
object: object,
|
27
|
+
id: id,
|
28
|
+
state: state,
|
29
|
+
url: url,
|
30
|
+
created_at: created_at,
|
31
|
+
updated_at: updated_at,
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
sig do
|
38
|
+
params(
|
39
|
+
json_string: String,
|
40
|
+
).returns(WorkOS::Types::AuditLogExportStruct)
|
41
|
+
end
|
42
|
+
def parse_json(json_string)
|
43
|
+
hash = JSON.parse(json_string, symbolize_names: true)
|
44
|
+
|
45
|
+
WorkOS::Types::AuditLogExportStruct.new(
|
46
|
+
object: hash[:object],
|
47
|
+
id: hash[:id],
|
48
|
+
state: hash[:state],
|
49
|
+
url: hash[:url],
|
50
|
+
created_at: hash[:created_at],
|
51
|
+
updated_at: hash[:updated_at],
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module WorkOS
|
8
|
+
# The Audit Logs module provides convenience methods for working with the
|
9
|
+
# WorkOS Audit Logs platform. You'll need a valid API key.
|
10
|
+
module AuditLogs
|
11
|
+
class << self
|
12
|
+
extend T::Sig
|
13
|
+
include Client
|
14
|
+
|
15
|
+
# Create an Audit Log Event.
|
16
|
+
#
|
17
|
+
# @param [String] organization An Organization ID
|
18
|
+
# @param [Hash] event An Audit Log Event
|
19
|
+
# @param [String] idempotency_key An idempotency key
|
20
|
+
#
|
21
|
+
# @return [nil]
|
22
|
+
sig do
|
23
|
+
params(
|
24
|
+
organization: String,
|
25
|
+
event: Hash,
|
26
|
+
idempotency_key: T.nilable(String),
|
27
|
+
).void
|
28
|
+
end
|
29
|
+
def create_event(organization:, event:, idempotency_key: nil)
|
30
|
+
request = post_request(
|
31
|
+
path: '/audit_logs/events',
|
32
|
+
auth: true,
|
33
|
+
idempotency_key: idempotency_key,
|
34
|
+
body: {
|
35
|
+
organization_id: organization,
|
36
|
+
event: event,
|
37
|
+
},
|
38
|
+
)
|
39
|
+
|
40
|
+
execute_request(request: request)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Create an Export of Audit Log Events.
|
44
|
+
#
|
45
|
+
# @param [String] organization An Organization ID
|
46
|
+
# @param [String] range_start ISO-8601 datetime
|
47
|
+
# @param [String] range_end ISO-8601 datetime
|
48
|
+
# @param [Array<String>] actions A list of actions to filter by
|
49
|
+
# @param [Array<String>] actors A list of actor names to filter by
|
50
|
+
# @param [Array<String>] targets A list of target types to filter by
|
51
|
+
#
|
52
|
+
# @return [WorkOS::AuditLogExport]
|
53
|
+
sig do
|
54
|
+
params(
|
55
|
+
organization: String,
|
56
|
+
range_start: String,
|
57
|
+
range_end: String,
|
58
|
+
actions: T.nilable(T::Array[String]),
|
59
|
+
actors: T.nilable(T::Array[String]),
|
60
|
+
targets: T.nilable(T::Array[String]),
|
61
|
+
).returns(WorkOS::AuditLogExport)
|
62
|
+
end
|
63
|
+
def create_export(organization:, range_start:, range_end:, actions: nil, actors: nil, targets: nil)
|
64
|
+
body = {
|
65
|
+
organization_id: organization,
|
66
|
+
range_start: range_start,
|
67
|
+
range_end: range_end,
|
68
|
+
}
|
69
|
+
|
70
|
+
body['actions'] = actions unless actions.nil?
|
71
|
+
body['actors'] = actors unless actors.nil?
|
72
|
+
body['targets'] = targets unless targets.nil?
|
73
|
+
|
74
|
+
request = post_request(
|
75
|
+
path: '/audit_logs/exports',
|
76
|
+
auth: true,
|
77
|
+
body: body,
|
78
|
+
)
|
79
|
+
|
80
|
+
response = execute_request(request: request)
|
81
|
+
|
82
|
+
WorkOS::AuditLogExport.new(response.body)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Retrieves an Export of Audit Log Events
|
86
|
+
#
|
87
|
+
# @param [String] id An Audit Log Export ID
|
88
|
+
#
|
89
|
+
# @return [WorkOS::AuditLogExport]
|
90
|
+
sig do
|
91
|
+
params(
|
92
|
+
id: String,
|
93
|
+
).returns(WorkOS::AuditLogExport)
|
94
|
+
end
|
95
|
+
def get_export(id:)
|
96
|
+
request = get_request(
|
97
|
+
auth: true,
|
98
|
+
path: "/audit_logs/exports/#{id}",
|
99
|
+
)
|
100
|
+
|
101
|
+
response = execute_request(request: request)
|
102
|
+
|
103
|
+
WorkOS::AuditLogExport.new(response.body)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/workos/client.rb
CHANGED
data/lib/workos/errors.rb
CHANGED
@@ -9,7 +9,10 @@ module WorkOS
|
|
9
9
|
|
10
10
|
attr_reader :http_status
|
11
11
|
attr_reader :request_id
|
12
|
+
attr_reader :code
|
13
|
+
attr_reader :errors
|
12
14
|
|
15
|
+
# rubocop:disable Metrics/ParameterLists
|
13
16
|
sig do
|
14
17
|
params(
|
15
18
|
message: T.nilable(String),
|
@@ -18,16 +21,27 @@ module WorkOS
|
|
18
21
|
http_status: T.nilable(Integer),
|
19
22
|
request_id: T.nilable(String),
|
20
23
|
code: T.nilable(String),
|
24
|
+
errors: T.nilable(T::Array[T::Hash[T.untyped, T.untyped]]),
|
21
25
|
).void
|
22
26
|
end
|
23
|
-
def initialize(
|
27
|
+
def initialize(
|
28
|
+
message: nil,
|
29
|
+
error: nil,
|
30
|
+
error_description: nil,
|
31
|
+
http_status: nil,
|
32
|
+
request_id: nil,
|
33
|
+
code: nil,
|
34
|
+
errors: nil
|
35
|
+
)
|
24
36
|
@message = message
|
25
37
|
@error = error
|
26
38
|
@error_description = error_description
|
27
39
|
@http_status = http_status
|
28
40
|
@request_id = request_id
|
29
41
|
@code = code
|
42
|
+
@errors = errors
|
30
43
|
end
|
44
|
+
# rubocop:enable Metrics/ParameterLists
|
31
45
|
|
32
46
|
sig { returns(String) }
|
33
47
|
def to_s
|
data/lib/workos/organizations.rb
CHANGED
@@ -82,14 +82,16 @@ module WorkOS
|
|
82
82
|
# @param [String] name A unique, descriptive name for the organization
|
83
83
|
# @param [Boolean, nil] allow_profiles_outside_organization Whether Connections
|
84
84
|
# within the Organization allow profiles that are outside of the Organization's configured User Email Domains.
|
85
|
+
# @param [String] idempotency_key An idempotency key
|
85
86
|
sig do
|
86
87
|
params(
|
87
88
|
domains: T::Array[String],
|
88
89
|
name: String,
|
89
90
|
allow_profiles_outside_organization: T.nilable(T::Boolean),
|
91
|
+
idempotency_key: T.nilable(String),
|
90
92
|
).returns(WorkOS::Organization)
|
91
93
|
end
|
92
|
-
def create_organization(domains:, name:, allow_profiles_outside_organization: nil)
|
94
|
+
def create_organization(domains:, name:, allow_profiles_outside_organization: nil, idempotency_key: nil)
|
93
95
|
request = post_request(
|
94
96
|
auth: true,
|
95
97
|
body: {
|
@@ -98,6 +100,7 @@ module WorkOS
|
|
98
100
|
allow_profiles_outside_organization: allow_profiles_outside_organization,
|
99
101
|
},
|
100
102
|
path: '/organizations',
|
103
|
+
idempotency_key: idempotency_key,
|
101
104
|
)
|
102
105
|
|
103
106
|
response = execute_request(request: request)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOS
|
5
|
+
module Types
|
6
|
+
# This AuditLogExportStruct acts as a typed interface
|
7
|
+
# for the AuditLogExport class
|
8
|
+
class AuditLogExportStruct < T::Struct
|
9
|
+
const :object, String
|
10
|
+
const :id, String
|
11
|
+
const :state, String
|
12
|
+
const :url, T.nilable(String)
|
13
|
+
const :created_at, String
|
14
|
+
const :updated_at, String
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/workos/types.rb
CHANGED
@@ -5,6 +5,7 @@ module WorkOS
|
|
5
5
|
# WorkOS believes strongly in typed languages,
|
6
6
|
# so we're using Sorbet throughout this Ruby gem.
|
7
7
|
module Types
|
8
|
+
require_relative 'types/audit_log_export_struct'
|
8
9
|
require_relative 'types/connection_struct'
|
9
10
|
require_relative 'types/directory_struct'
|
10
11
|
require_relative 'types/directory_group_struct'
|
data/lib/workos/version.rb
CHANGED
data/lib/workos/webhooks.rb
CHANGED
@@ -55,8 +55,25 @@ module WorkOS
|
|
55
55
|
WorkOS::Webhook.new(payload)
|
56
56
|
end
|
57
57
|
|
58
|
-
|
59
|
-
|
58
|
+
# Verifies WorkOS-Signature header from request
|
59
|
+
# rubocop:disable Layout/LineLength
|
60
|
+
#
|
61
|
+
# @param [String] payload The payload from the webhook sent by WorkOS. This is the RAW_POST_DATA of the request.
|
62
|
+
# @param [String] sig_header The signature from the webhook sent by WorkOS.
|
63
|
+
# @param [String] secret The webhook secret from the WorkOS dashboard.
|
64
|
+
# @param [Integer] tolerance The time tolerance in seconds for the webhook.
|
65
|
+
#
|
66
|
+
# @example
|
67
|
+
# WorkOS::Webhooks.verify_header(
|
68
|
+
# payload: "{"id": "wh_123","data":{"id":"directory_user_01FAEAJCR3ZBZ30D8BD1924TVG","state":"active","emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"idp_id":"00u1e8mutl6wlH3lL4x7","object":"directory_user","username":"blair@foo-corp.com","last_name":"Lunchford","first_name":"Blair","directory_id":"directory_01F9M7F68PZP8QXP8G7X5QRHS7","raw_attributes":{"name":{"givenName":"Blair","familyName":"Lunchford","middleName":"Elizabeth","honorificPrefix":"Ms."},"title":"Developer Success Engineer","active":true,"emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"groups":[],"locale":"en-US","schemas":["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],"userName":"blair@foo-corp.com","addresses":[{"region":"CA","primary":true,"locality":"San Francisco","postalCode":"94016"}],"externalId":"00u1e8mutl6wlH3lL4x7","displayName":"Blair Lunchford","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User":{"manager":{"value":"2","displayName":"Kate Chapman"},"division":"Engineering","department":"Customer Success"}}},"event":"dsync.user.created"}",
|
69
|
+
# sig_header: 't=1626125972272, v1=80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928',
|
70
|
+
# secret: 'LJlTiC19GmCKWs8AE0IaOQcos',
|
71
|
+
# )
|
72
|
+
#
|
73
|
+
# => true
|
74
|
+
#
|
75
|
+
# @return Boolean
|
76
|
+
# rubocop:enable Layout/LineLength
|
60
77
|
sig do
|
61
78
|
params(
|
62
79
|
payload: String,
|
@@ -105,6 +122,18 @@ module WorkOS
|
|
105
122
|
end
|
106
123
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
107
124
|
|
125
|
+
# Extracts timestamp and signature hash from WorkOS-Signature header
|
126
|
+
#
|
127
|
+
# @param [String] sig_header The signature from the webhook sent by WorkOS.
|
128
|
+
#
|
129
|
+
# @example
|
130
|
+
# WorkOS::Webhooks.get_timestamp_and_signature_hash(
|
131
|
+
# sig_header: 't=1626125972272, v1=80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928',
|
132
|
+
# )
|
133
|
+
#
|
134
|
+
# => ['1626125972272', '80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928']
|
135
|
+
#
|
136
|
+
# @return Array
|
108
137
|
sig do
|
109
138
|
params(
|
110
139
|
sig_header: String,
|
@@ -127,6 +156,24 @@ module WorkOS
|
|
127
156
|
[timestamp, signature_hash]
|
128
157
|
end
|
129
158
|
|
159
|
+
# Computes expected signature
|
160
|
+
# rubocop:disable Layout/LineLength
|
161
|
+
#
|
162
|
+
# @param [String] timestamp The timestamp from the webhook signature.
|
163
|
+
# @param [String] payload The payload from the webhook sent by WorkOS. This is the RAW_POST_DATA of the request.
|
164
|
+
# @param [String] secret The webhook secret from the WorkOS dashboard.
|
165
|
+
#
|
166
|
+
# @example
|
167
|
+
# WorkOS::Webhooks.compute_signature(
|
168
|
+
# timestamp: '1626125972272',
|
169
|
+
# payload: "{"id": "wh_123","data":{"id":"directory_user_01FAEAJCR3ZBZ30D8BD1924TVG","state":"active","emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"idp_id":"00u1e8mutl6wlH3lL4x7","object":"directory_user","username":"blair@foo-corp.com","last_name":"Lunchford","first_name":"Blair","directory_id":"directory_01F9M7F68PZP8QXP8G7X5QRHS7","raw_attributes":{"name":{"givenName":"Blair","familyName":"Lunchford","middleName":"Elizabeth","honorificPrefix":"Ms."},"title":"Developer Success Engineer","active":true,"emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"groups":[],"locale":"en-US","schemas":["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],"userName":"blair@foo-corp.com","addresses":[{"region":"CA","primary":true,"locality":"San Francisco","postalCode":"94016"}],"externalId":"00u1e8mutl6wlH3lL4x7","displayName":"Blair Lunchford","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User":{"manager":{"value":"2","displayName":"Kate Chapman"},"division":"Engineering","department":"Customer Success"}}},"event":"dsync.user.created"}",
|
170
|
+
# secret: 'LJlTiC19GmCKWs8AE0IaOQcos',
|
171
|
+
# )
|
172
|
+
#
|
173
|
+
# => '80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928'
|
174
|
+
#
|
175
|
+
# @return String
|
176
|
+
# rubocop:enable Layout/LineLength
|
130
177
|
sig do
|
131
178
|
params(
|
132
179
|
timestamp: String,
|
data/lib/workos.rb
CHANGED
@@ -39,6 +39,8 @@ module WorkOS
|
|
39
39
|
autoload :Types, 'workos/types'
|
40
40
|
autoload :Client, 'workos/client'
|
41
41
|
autoload :Configuration, 'workos/configuration'
|
42
|
+
autoload :AuditLogExport, 'workos/audit_log_export'
|
43
|
+
autoload :AuditLogs, 'workos/audit_logs'
|
42
44
|
autoload :AuditTrail, 'workos/audit_trail'
|
43
45
|
autoload :Connection, 'workos/connection'
|
44
46
|
autoload :DirectorySync, 'workos/directory_sync'
|
@@ -30,7 +30,7 @@ module Rainbow
|
|
30
30
|
sig { returns(Integer) }
|
31
31
|
attr_reader :num
|
32
32
|
|
33
|
-
sig { params(ground: Symbol, num: Integer).
|
33
|
+
sig { params(ground: Symbol, num: Integer).void }
|
34
34
|
def initialize(ground, num); end
|
35
35
|
|
36
36
|
sig { returns(T::Array[Integer]) }
|
@@ -46,7 +46,7 @@ module Rainbow
|
|
46
46
|
sig { returns(String) }
|
47
47
|
def self.valid_names; end
|
48
48
|
|
49
|
-
sig { params(ground: Symbol, name: Symbol).
|
49
|
+
sig { params(ground: Symbol, name: Symbol).void }
|
50
50
|
def initialize(ground, name); end
|
51
51
|
end
|
52
52
|
|
@@ -57,7 +57,7 @@ module Rainbow
|
|
57
57
|
sig { params(value: Numeric).returns(Integer) }
|
58
58
|
def to_ansi_domain(value); end
|
59
59
|
|
60
|
-
sig { params(ground: Symbol, values: Integer).
|
60
|
+
sig { params(ground: Symbol, values: Integer).void }
|
61
61
|
def initialize(ground, *values); end
|
62
62
|
|
63
63
|
sig { returns(T::Array[Integer]) }
|
@@ -73,7 +73,7 @@ module Rainbow
|
|
73
73
|
sig { returns(String) }
|
74
74
|
def self.valid_names; end
|
75
75
|
|
76
|
-
sig { params(ground: Symbol, name: Symbol).
|
76
|
+
sig { params(ground: Symbol, name: Symbol).void }
|
77
77
|
def initialize(ground, name); end
|
78
78
|
end
|
79
79
|
end
|
@@ -260,7 +260,7 @@ module Rainbow
|
|
260
260
|
sig { returns(T::Boolean) }
|
261
261
|
attr_accessor :enabled
|
262
262
|
|
263
|
-
sig { params(enabled: T::Boolean).
|
263
|
+
sig { params(enabled: T::Boolean).void }
|
264
264
|
def initialize(enabled = true); end
|
265
265
|
|
266
266
|
sig { params(string: String).returns(T.any(Rainbow::Presenter, Rainbow::NullPresenter)) }
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: false
|
3
|
+
|
4
|
+
describe WorkOS::AuditLogs do
|
5
|
+
it_behaves_like 'client'
|
6
|
+
|
7
|
+
before do
|
8
|
+
WorkOS.configure do |config|
|
9
|
+
config.key = 'example_api_key'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '.create_event' do
|
14
|
+
context 'with valid event payload' do
|
15
|
+
let(:valid_event) do
|
16
|
+
{
|
17
|
+
action: 'user.signed_in',
|
18
|
+
occurred_at: '2022-08-22T15:04:19.704Z',
|
19
|
+
actor: {
|
20
|
+
id: 'user_123',
|
21
|
+
type: 'user',
|
22
|
+
name: 'User',
|
23
|
+
metadata: {
|
24
|
+
foo: 'bar',
|
25
|
+
},
|
26
|
+
},
|
27
|
+
targets: [{
|
28
|
+
id: 'team_123',
|
29
|
+
type: 'team',
|
30
|
+
name: 'Team',
|
31
|
+
metadata: {
|
32
|
+
foo: 'bar',
|
33
|
+
},
|
34
|
+
}],
|
35
|
+
context: {
|
36
|
+
location: '1.1.1.1',
|
37
|
+
user_agent: 'Mozilla',
|
38
|
+
},
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with idempotency key' do
|
43
|
+
it 'creates an event' do
|
44
|
+
VCR.use_cassette 'audit_logs/create_event_custom_idempotency_key', match_requests_on: %i[path body] do
|
45
|
+
response = described_class.create_event(
|
46
|
+
organization: 'org_123',
|
47
|
+
event: valid_event,
|
48
|
+
idempotency_key: 'idempotency_key',
|
49
|
+
)
|
50
|
+
|
51
|
+
expect(response).to eq T::Private::Types::Void::VOID
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'without idempotency key' do
|
57
|
+
it 'creates an event' do
|
58
|
+
VCR.use_cassette 'audit_logs/create_event', match_requests_on: %i[path body] do
|
59
|
+
response = described_class.create_event(
|
60
|
+
organization: 'org_123',
|
61
|
+
event: valid_event,
|
62
|
+
)
|
63
|
+
|
64
|
+
expect(response).to eq T::Private::Types::Void::VOID
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with invalid event' do
|
70
|
+
it 'returns error' do
|
71
|
+
VCR.use_cassette 'audit_logs/create_event_invalid', match_requests_on: %i[path body] do
|
72
|
+
described_class.create_event(
|
73
|
+
organization: 'org_123',
|
74
|
+
event: valid_event,
|
75
|
+
)
|
76
|
+
rescue WorkOS::InvalidRequestError => e
|
77
|
+
expect(
|
78
|
+
e.message,
|
79
|
+
).to eq 'Status 400, Invalid Audit Log event - request ID: 1cf9b8e7-5910-4a6d-a333-46bcf841422e'
|
80
|
+
expect(e.code).to eq 'invalid_audit_log'
|
81
|
+
expect(e.errors.count).to eq 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '.create_export' do
|
89
|
+
context 'without filters applied' do
|
90
|
+
it 'creates an event' do
|
91
|
+
VCR.use_cassette 'audit_logs/create_export', match_requests_on: %i[path body] do
|
92
|
+
audit_log_export = described_class.create_export(
|
93
|
+
organization: 'org_123',
|
94
|
+
range_start: '2022-06-22T15:04:19.704Z',
|
95
|
+
range_end: '2022-08-22T15:04:19.704Z',
|
96
|
+
)
|
97
|
+
|
98
|
+
expect(audit_log_export).to have_attributes(
|
99
|
+
object: 'audit_log_export',
|
100
|
+
id: 'audit_log_export_123',
|
101
|
+
state: 'pending',
|
102
|
+
url: nil,
|
103
|
+
created_at: '2022-08-22T15:04:19.704Z',
|
104
|
+
updated_at: '2022-08-22T15:04:19.704Z',
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with filters applied' do
|
111
|
+
it 'creates an export' do
|
112
|
+
VCR.use_cassette 'audit_logs/create_export_with_filters', match_requests_on: %i[path body] do
|
113
|
+
audit_log_export = described_class.create_export(
|
114
|
+
organization: 'org_123',
|
115
|
+
range_start: '2022-06-22T15:04:19.704Z',
|
116
|
+
range_end: '2022-08-22T15:04:19.704Z',
|
117
|
+
actions: ['user.signed_in'],
|
118
|
+
actors: ['Jon Smith'],
|
119
|
+
targets: %w[user team],
|
120
|
+
)
|
121
|
+
|
122
|
+
expect(audit_log_export.object).to eq 'audit_log_export'
|
123
|
+
expect(audit_log_export.id).to eq 'audit_log_export_123'
|
124
|
+
expect(audit_log_export.state).to eq 'pending'
|
125
|
+
expect(audit_log_export.url).to eq nil
|
126
|
+
expect(audit_log_export.created_at).to eq '2022-08-22T15:04:19.704Z'
|
127
|
+
expect(audit_log_export.updated_at).to eq '2022-08-22T15:04:19.704Z'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '.get_export' do
|
134
|
+
it 'returns an export' do
|
135
|
+
VCR.use_cassette 'audit_logs/get_export', match_requests_on: %i[path] do
|
136
|
+
audit_log_export = described_class.get_export(
|
137
|
+
id: 'audit_log_export_123',
|
138
|
+
)
|
139
|
+
|
140
|
+
expect(audit_log_export.object).to eq 'audit_log_export'
|
141
|
+
expect(audit_log_export.id).to eq 'audit_log_export_123'
|
142
|
+
expect(audit_log_export.state).to eq 'ready'
|
143
|
+
expect(audit_log_export.url).to eq 'https://audit-logs.com/download.csv'
|
144
|
+
expect(audit_log_export.created_at).to eq '2022-08-22T15:04:19.704Z'
|
145
|
+
expect(audit_log_export.updated_at).to eq '2022-08-22T15:04:19.704Z'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|