workos 2.5.1 → 2.7.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 +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/intent_enum.rb +1 -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/portal_spec.rb +15 -0
- 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/fixtures/vcr_cassettes/portal/generate_link_audit_logs.yml +72 -0
- data/spec/support/webhook_payload.txt +1 -1
- metadata +28 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9c1d1a239604c91126acc4b7c4482abaf306abf129eb9c4260cd2af6eb832a8
|
4
|
+
data.tar.gz: e614d8659cac83f4f1d4aca7ac930b6f1a89aa14f09bb4905b44797b77ee41cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7ac7ebb757400aa6f4195776662347cc0763aab1170d5a3678fa96324d6fcd5f59a80e75cd3df2082d710beff957f97cb0de6c287a9ea1ebf7631dcdf41ad3c
|
7
|
+
data.tar.gz: c655246d047fd79f7ab963b44ab5ab37912c5b8e4a7663cb9597c505cdc99903c308dd74fa024968d45dd4aff624e8b379be3a162b5c7082d9aa99fbc0749ee6
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
workos (2.
|
4
|
+
workos (2.7.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
|