workosv2 2.15.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.
Files changed (242) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CODEOWNERS +5 -0
  3. data/.github/pull_request_template.md +11 -0
  4. data/.github/renovate.json +5 -0
  5. data/.gitignore +49 -0
  6. data/.rspec +1 -0
  7. data/.rubocop.yml +24 -0
  8. data/.ruby-version +1 -0
  9. data/.semaphore/rubygems.yml +24 -0
  10. data/.semaphore/semaphore.yml +51 -0
  11. data/Gemfile +5 -0
  12. data/Gemfile.lock +126 -0
  13. data/Gemfile.lock.old +127 -0
  14. data/LICENSE +21 -0
  15. data/README.md +53 -0
  16. data/bin/build +3 -0
  17. data/bin/console +3 -0
  18. data/bin/docs +5 -0
  19. data/bin/publish +3 -0
  20. data/bin/tapioca +29 -0
  21. data/codecov.yml +12 -0
  22. data/docs/WorkOS/APIError.html +160 -0
  23. data/docs/WorkOS/AuditLog.html +235 -0
  24. data/docs/WorkOS/AuditTrail.html +235 -0
  25. data/docs/WorkOS/AuthenticationError.html +160 -0
  26. data/docs/WorkOS/Base.html +287 -0
  27. data/docs/WorkOS/Client.html +504 -0
  28. data/docs/WorkOS/InvalidRequestError.html +160 -0
  29. data/docs/WorkOS/Profile.html +788 -0
  30. data/docs/WorkOS/RequestError.html +135 -0
  31. data/docs/WorkOS/SSO.html +691 -0
  32. data/docs/WorkOS/Types/ProfileStruct.html +135 -0
  33. data/docs/WorkOS/Types/Provider.html +135 -0
  34. data/docs/WorkOS/Types.html +128 -0
  35. data/docs/WorkOS/WorkOSError.html +447 -0
  36. data/docs/WorkOS.html +324 -0
  37. data/docs/class_list.html +51 -0
  38. data/docs/css/common.css +1 -0
  39. data/docs/css/full_list.css +58 -0
  40. data/docs/css/style.css +496 -0
  41. data/docs/file.README.html +252 -0
  42. data/docs/file_list.html +56 -0
  43. data/docs/frames.html +17 -0
  44. data/docs/index.html +250 -0
  45. data/docs/js/app.js +314 -0
  46. data/docs/js/full_list.js +216 -0
  47. data/docs/js/jquery.js +4 -0
  48. data/docs/method_list.html +267 -0
  49. data/docs/top-level-namespace.html +110 -0
  50. data/lib/workosv2/audit_log_export.rb +55 -0
  51. data/lib/workosv2/audit_logs.rb +114 -0
  52. data/lib/workosv2/audit_trail.rb +111 -0
  53. data/lib/workosv2/challenge.rb +55 -0
  54. data/lib/workosv2/client.rb +186 -0
  55. data/lib/workosv2/configuration.rb +17 -0
  56. data/lib/workosv2/connection.rb +66 -0
  57. data/lib/workosv2/deprecated_hash_wrapper.rb +76 -0
  58. data/lib/workosv2/directory.rb +65 -0
  59. data/lib/workosv2/directory_group.rb +68 -0
  60. data/lib/workosv2/directory_sync.rb +218 -0
  61. data/lib/workosv2/directory_user.rb +97 -0
  62. data/lib/workosv2/errors.rb +81 -0
  63. data/lib/workosv2/event.rb +51 -0
  64. data/lib/workosv2/events.rb +52 -0
  65. data/lib/workosv2/factor.rb +54 -0
  66. data/lib/workosv2/hash_provider.rb +19 -0
  67. data/lib/workosv2/mfa.rb +178 -0
  68. data/lib/workosv2/organization.rb +57 -0
  69. data/lib/workosv2/organizations.rb +188 -0
  70. data/lib/workosv2/passwordless.rb +85 -0
  71. data/lib/workosv2/portal.rb +66 -0
  72. data/lib/workosv2/profile.rb +76 -0
  73. data/lib/workosv2/profile_and_token.rb +29 -0
  74. data/lib/workosv2/sso.rb +297 -0
  75. data/lib/workosv2/types/audit_log_export_struct.rb +17 -0
  76. data/lib/workosv2/types/challenge_struct.rb +18 -0
  77. data/lib/workosv2/types/connection_struct.rb +20 -0
  78. data/lib/workosv2/types/directory_group_struct.rb +19 -0
  79. data/lib/workosv2/types/directory_struct.rb +19 -0
  80. data/lib/workosv2/types/directory_user_struct.rb +26 -0
  81. data/lib/workosv2/types/event_struct.rb +15 -0
  82. data/lib/workosv2/types/factor_struct.rb +18 -0
  83. data/lib/workosv2/types/intent_enum.rb +17 -0
  84. data/lib/workosv2/types/list_struct.rb +13 -0
  85. data/lib/workosv2/types/organization_struct.rb +17 -0
  86. data/lib/workosv2/types/passwordless_session_struct.rb +17 -0
  87. data/lib/workosv2/types/profile_struct.rb +21 -0
  88. data/lib/workosv2/types/provider_enum.rb +15 -0
  89. data/lib/workosv2/types/verify_challenge_struct.rb +13 -0
  90. data/lib/workosv2/types/webhook_struct.rb +15 -0
  91. data/lib/workosv2/types.rb +25 -0
  92. data/lib/workosv2/verify_challenge.rb +39 -0
  93. data/lib/workosv2/version.rb +6 -0
  94. data/lib/workosv2/webhook.rb +51 -0
  95. data/lib/workosv2/webhooks.rb +217 -0
  96. data/lib/workosv2.rb +79 -0
  97. data/sorbet/config +2 -0
  98. data/sorbet/rbi/gems/addressable@2.8.0.rbi +290 -0
  99. data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
  100. data/sorbet/rbi/gems/codecov@0.2.12.rbi +55 -0
  101. data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
  102. data/sorbet/rbi/gems/crack@0.4.5.rbi +57 -0
  103. data/sorbet/rbi/gems/diff-lcs@1.4.4.rbi +185 -0
  104. data/sorbet/rbi/gems/docile@1.3.5.rbi +54 -0
  105. data/sorbet/rbi/gems/hashdiff@1.0.1.rbi +82 -0
  106. data/sorbet/rbi/gems/json@2.5.1.rbi +109 -0
  107. data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
  108. data/sorbet/rbi/gems/parallel@1.20.1.rbi +113 -0
  109. data/sorbet/rbi/gems/parser@3.0.1.0.rbi +1187 -0
  110. data/sorbet/rbi/gems/pry@0.14.2.rbi +8 -0
  111. data/sorbet/rbi/gems/public_suffix@4.0.6.rbi +146 -0
  112. data/sorbet/rbi/gems/rainbow@3.0.0.rbi +153 -0
  113. data/sorbet/rbi/gems/rake@13.0.3.rbi +807 -0
  114. data/sorbet/rbi/gems/rbi@0.0.16.rbi +2118 -0
  115. data/sorbet/rbi/gems/regexp_parser@2.1.1.rbi +1117 -0
  116. data/sorbet/rbi/gems/rexml@3.2.5.rbi +709 -0
  117. data/sorbet/rbi/gems/rspec-core@3.9.3.rbi +2467 -0
  118. data/sorbet/rbi/gems/rspec-expectations@3.9.4.rbi +1569 -0
  119. data/sorbet/rbi/gems/rspec-mocks@3.9.1.rbi +1493 -0
  120. data/sorbet/rbi/gems/rspec-support@3.9.4.rbi +511 -0
  121. data/sorbet/rbi/gems/rspec@3.9.0.rbi +38 -0
  122. data/sorbet/rbi/gems/rubocop-ast@1.4.1.rbi +1881 -0
  123. data/sorbet/rbi/gems/rubocop@0.93.1.rbi +11497 -0
  124. data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +405 -0
  125. data/sorbet/rbi/gems/simplecov-html@0.12.3.rbi +89 -0
  126. data/sorbet/rbi/gems/simplecov@0.21.2.rbi +577 -0
  127. data/sorbet/rbi/gems/simplecov_json_formatter@0.1.2.rbi +8 -0
  128. data/sorbet/rbi/gems/spoom@1.1.15.rbi +1549 -0
  129. data/sorbet/rbi/gems/tapioca@0.7.3.rbi +1718 -0
  130. data/sorbet/rbi/gems/thor@1.2.1.rbi +844 -0
  131. data/sorbet/rbi/gems/unicode-display_width@1.7.0.rbi +22 -0
  132. data/sorbet/rbi/gems/unparser@0.6.2.rbi +8 -0
  133. data/sorbet/rbi/gems/vcr@5.0.0.rbi +699 -0
  134. data/sorbet/rbi/gems/webmock@3.12.2.rbi +662 -0
  135. data/sorbet/rbi/gems/yard-sorbet@0.8.0.rbi +268 -0
  136. data/sorbet/rbi/gems/yard@0.9.26.rbi +4048 -0
  137. data/sorbet/tapioca/config.yml +13 -0
  138. data/sorbet/tapioca/require.rb +4 -0
  139. data/spec/lib/workos/audit_logs_spec.rb +151 -0
  140. data/spec/lib/workos/audit_trail_spec.rb +146 -0
  141. data/spec/lib/workos/configuration_spec.rb +61 -0
  142. data/spec/lib/workos/directory_sync_spec.rb +492 -0
  143. data/spec/lib/workos/directory_user_spec.rb +36 -0
  144. data/spec/lib/workos/event_spec.rb +88 -0
  145. data/spec/lib/workos/mfa_spec.rb +281 -0
  146. data/spec/lib/workos/organizations_spec.rb +257 -0
  147. data/spec/lib/workos/passwordless_spec.rb +77 -0
  148. data/spec/lib/workos/portal_spec.rb +87 -0
  149. data/spec/lib/workos/sso_spec.rb +650 -0
  150. data/spec/lib/workos/webhooks_spec.rb +236 -0
  151. data/spec/spec_helper.rb +56 -0
  152. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event.yml +59 -0
  153. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event_custom_idempotency_key.yml +60 -0
  154. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event_invalid.yml +59 -0
  155. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_export.yml +76 -0
  156. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_export_with_filters.yml +77 -0
  157. data/spec/support/fixtures/vcr_cassettes/audit_logs/get_export.yml +73 -0
  158. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event.yml +65 -0
  159. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event_custom_idempotency_key.yml +67 -0
  160. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event_invalid.yml +68 -0
  161. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_and_payload.yml +131 -0
  162. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_different_payload.yml +134 -0
  163. data/spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml +61 -0
  164. data/spec/support/fixtures/vcr_cassettes/base/execute_request_unauthenticated.yml +66 -0
  165. data/spec/support/fixtures/vcr_cassettes/directory_sync/delete_directory.yml +72 -0
  166. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_directory_with_invalid_id.yml +83 -0
  167. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_directory_with_valid_id.yml +84 -0
  168. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group.yml +80 -0
  169. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group_with_invalid_id.yml +62 -0
  170. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml +83 -0
  171. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user_with_invalid_id.yml +62 -0
  172. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_after.yml +87 -0
  173. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_before.yml +89 -0
  174. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_domain.yml +84 -0
  175. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_limit.yml +85 -0
  176. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_no_options.yml +93 -0
  177. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_search.yml +85 -0
  178. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_after.yml +90 -0
  179. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_before.yml +90 -0
  180. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_directory.yml +90 -0
  181. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_limit.yml +84 -0
  182. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_no_options.yml +84 -0
  183. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_user.yml +82 -0
  184. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_after.yml +186 -0
  185. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_before.yml +88 -0
  186. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_directory.yml +194 -0
  187. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_group.yml +186 -0
  188. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_limit.yml +189 -0
  189. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_no_options.yml +74 -0
  190. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_after.yml +80 -0
  191. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_event.yml +80 -0
  192. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_no_options.yml +80 -0
  193. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_range.yml +80 -0
  194. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_generic_valid.yml +82 -0
  195. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_sms_valid.yml +82 -0
  196. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_totp_valid.yml +82 -0
  197. data/spec/support/fixtures/vcr_cassettes/mfa/delete_factor.yml +80 -0
  198. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_generic_valid.yml +82 -0
  199. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_sms_valid.yml +82 -0
  200. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml +82 -0
  201. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_invalid.yml +82 -0
  202. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml +82 -0
  203. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_expired.yml +84 -0
  204. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_invalid.yml +84 -0
  205. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid.yml +82 -0
  206. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid_is_false.yml +82 -0
  207. data/spec/support/fixtures/vcr_cassettes/organization/create.yml +84 -0
  208. data/spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml +72 -0
  209. data/spec/support/fixtures/vcr_cassettes/organization/create_with_duplicate_idempotency_key_and_different_payload.yml +155 -0
  210. data/spec/support/fixtures/vcr_cassettes/organization/create_with_duplicate_idempotency_key_and_payload.yml +154 -0
  211. data/spec/support/fixtures/vcr_cassettes/organization/create_with_idempotency_key.yml +79 -0
  212. data/spec/support/fixtures/vcr_cassettes/organization/delete.yml +72 -0
  213. data/spec/support/fixtures/vcr_cassettes/organization/delete_invalid.yml +72 -0
  214. data/spec/support/fixtures/vcr_cassettes/organization/get.yml +84 -0
  215. data/spec/support/fixtures/vcr_cassettes/organization/get_invalid.yml +72 -0
  216. data/spec/support/fixtures/vcr_cassettes/organization/list.yml +87 -0
  217. data/spec/support/fixtures/vcr_cassettes/organization/update.yml +84 -0
  218. data/spec/support/fixtures/vcr_cassettes/passwordless/create_session.yml +72 -0
  219. data/spec/support/fixtures/vcr_cassettes/passwordless/create_session_invalid.yml +73 -0
  220. data/spec/support/fixtures/vcr_cassettes/passwordless/send_session.yml +72 -0
  221. data/spec/support/fixtures/vcr_cassettes/passwordless/send_session_invalid.yml +73 -0
  222. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_audit_logs.yml +72 -0
  223. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_dsync.yml +72 -0
  224. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_invalid.yml +72 -0
  225. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_sso.yml +72 -0
  226. data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_invalid_id.yml +72 -0
  227. data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_valid_id.yml +70 -0
  228. data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_invalid_id.yml +72 -0
  229. data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_valid_id.yml +86 -0
  230. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_after.yml +83 -0
  231. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_before.yml +86 -0
  232. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_connection_type.yml +90 -0
  233. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_domain.yml +86 -0
  234. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_limit.yml +83 -0
  235. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_no_options.yml +89 -0
  236. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_organization_id.yml +86 -0
  237. data/spec/support/fixtures/vcr_cassettes/sso/profile.yml +74 -0
  238. data/spec/support/profile.txt +1 -0
  239. data/spec/support/shared_examples/client_spec.rb +30 -0
  240. data/spec/support/webhook_payload.txt +1 -0
  241. data/workosv2.gemspec +38 -0
  242. metadata +531 -0
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module WorkOSV2
5
+ # The AuditLogExport class represents the WorkOSV2 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(WorkOSV2::Types::AuditLogExportStruct)
41
+ end
42
+ def parse_json(json_string)
43
+ hash = JSON.parse(json_string, symbolize_names: true)
44
+
45
+ WorkOSV2::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,114 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module WorkOSV2
8
+ # The Audit Logs module provides convenience methods for working with the
9
+ # WorkOSV2 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>] @deprecated use `actor_names` instead
50
+ # @param [Array<String>] actor_names A list of actor names to filter by
51
+ # @param [Array<String>] actor_ids A list of actor ids to filter by
52
+ # @param [Array<String>] targets A list of target types to filter by
53
+ #
54
+ # @return [WorkOSV2::AuditLogExport]
55
+ sig do
56
+ params(
57
+ organization: String,
58
+ range_start: String,
59
+ range_end: String,
60
+ actions: T.nilable(T::Array[String]),
61
+ actors: T.nilable(T::Array[String]),
62
+ targets: T.nilable(T::Array[String]),
63
+ actor_names: T.nilable(T::Array[String]),
64
+ actor_ids: T.nilable(T::Array[String]),
65
+ ).returns(WorkOSV2::AuditLogExport)
66
+ end
67
+ def create_export(organization:, range_start:, range_end:, actions: nil, # rubocop:disable Metrics/ParameterLists
68
+ actors: nil, targets: nil, actor_names: nil, actor_ids: nil)
69
+ body = {
70
+ organization_id: organization,
71
+ range_start: range_start,
72
+ range_end: range_end,
73
+ }
74
+
75
+ body['actions'] = actions unless actions.nil?
76
+ body['actors'] = actors unless actors.nil?
77
+ body['actor_names'] = actor_names unless actor_names.nil?
78
+ body['actor_ids'] = actor_ids unless actor_ids.nil?
79
+ body['targets'] = targets unless targets.nil?
80
+
81
+ request = post_request(
82
+ path: '/audit_logs/exports',
83
+ auth: true,
84
+ body: body,
85
+ )
86
+
87
+ response = execute_request(request: request)
88
+
89
+ WorkOSV2::AuditLogExport.new(response.body)
90
+ end
91
+
92
+ # Retrieves an Export of Audit Log Events
93
+ #
94
+ # @param [String] id An Audit Log Export ID
95
+ #
96
+ # @return [WorkOSV2::AuditLogExport]
97
+ sig do
98
+ params(
99
+ id: String,
100
+ ).returns(WorkOSV2::AuditLogExport)
101
+ end
102
+ def get_export(id:)
103
+ request = get_request(
104
+ auth: true,
105
+ path: "/audit_logs/exports/#{id}",
106
+ )
107
+
108
+ response = execute_request(request: request)
109
+
110
+ WorkOSV2::AuditLogExport.new(response.body)
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module WorkOSV2
8
+ # The Audit Trail module provides convenience methods for working with the
9
+ # WorkOSV2 Audit Trail platform. You'll need a valid API key.
10
+ #
11
+ # @see https://docs.workos.com/audit-trail/overview
12
+ module AuditTrail
13
+ class << self
14
+ extend T::Sig
15
+ include Client
16
+
17
+ # Create an Audit Trail event.
18
+ #
19
+ # @param [Hash] event An event hash
20
+ # @option event [String] group A single organization containing related
21
+ # members. This will normally be the customer of a vendor's application.
22
+ # @option event [String] location Identifier for where the event
23
+ # originated. This will be an IP address (IPv4 or IPv6), hostname, or
24
+ # device ID.
25
+ # @option event [String] action Specific activity performed by the actor.
26
+ # @option event [String] action_type Corresponding CRUD category of the
27
+ # event. Can be one of C, R, U, or D.
28
+ # @option event [String] actor_name Display name of the entity performing
29
+ # the action.
30
+ # @option event [String] actor_id Unique identifier of the entity
31
+ # performing the action.
32
+ # @option event [String] target_name Display name of the object or
33
+ # resource that is being acted upon.
34
+ # @option event [String] target_id Unique identifier of the object or
35
+ # resource being acted upon.
36
+ # @option event [String] occurred_at ISO-8601 datetime at which the event
37
+ # happened, with millisecond precision.
38
+ # @option event [Hash] metadata Arbitrary key-value data containing
39
+ # information associated with the event. Note: There is a limit of 50
40
+ # keys. Key names can be up to 40 characters long, and values can be up
41
+ # to 500 characters long.
42
+ # @param [String] idempotency_key An idempotency key
43
+ sig do
44
+ params(
45
+ event: Hash,
46
+ idempotency_key: T.nilable(String),
47
+ ).returns(::T.untyped)
48
+ end
49
+
50
+ def create_event(event:, idempotency_key: nil)
51
+ request = post_request(
52
+ path: '/events',
53
+ auth: true,
54
+ idempotency_key: idempotency_key,
55
+ body: event,
56
+ )
57
+
58
+ execute_request(request: request)
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 [String] order The order in which to paginate records
68
+ # @option options [Array<String>] group List of Groups to filter for
69
+ # @option options [Array<String>] action List of Actions to filter for
70
+ # @option options [Array<String>] action_type List of Action Types to
71
+ # filter for
72
+ # @option options [Array<String>] actor_name List of Actor Name to filter
73
+ # for
74
+ # @option options [Array<String>] actor_id List of Actor IDs to filter for
75
+ # @option options [Array<String>] target_name List of Target Names to
76
+ # filter for
77
+ # @option options [Array<String>] target_id List of Target IDs to filter
78
+ # for
79
+ # @option options [String] occurred_at ISO-8601 datetime of when an event
80
+ # occurred
81
+ # @option options [String] occurred_at_gt ISO-8601 datetime of when an
82
+ # event occurred after
83
+ # @option options [String] occurred_at_gte ISO-8601 datetime of when an
84
+ # event occurred at or after
85
+ # @option options [String] occurred_at_lt ISO-8601 datetime of when an
86
+ # event occurred before
87
+ # @option options [String] occurred_at_lte ISO-8601 datetime of when an
88
+ # event occured at or before
89
+ # @option options [String] search Keyword search
90
+ #
91
+ # @return [Array<Hash>]
92
+ sig do
93
+ params(
94
+ options: T::Hash[Symbol, String],
95
+ ).returns(T::Array[T::Hash[String, T.nilable(String)]])
96
+ end
97
+
98
+ def get_events(options = {})
99
+ response = execute_request(
100
+ request: get_request(
101
+ path: '/events',
102
+ auth: true,
103
+ params: options,
104
+ ),
105
+ )
106
+
107
+ JSON.parse(response.body)['data']
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+ # typed: false
3
+
4
+ module WorkOSV2
5
+ # The Challnge class provides a lightweight wrapper around
6
+ # a WorkOSV2 DirectoryUser resource. This class is not meant to be instantiated
7
+ # in DirectoryUser space, and is instantiated internally but exposed.
8
+ class Challenge
9
+ include HashProvider
10
+ extend T::Sig
11
+
12
+ attr_accessor :id, :object, :expires_at, :code, :authentication_factor_id, :updated_at, :created_at
13
+
14
+ sig { params(json: String).void }
15
+ def initialize(json)
16
+ raw = parse_json(json)
17
+ @id = T.let(raw.id, String)
18
+ @object = T.let(raw.object, String)
19
+ @expires_at = T.let(raw.expires_at, String)
20
+ @code = raw.code
21
+ @authentication_factor_id = T.let(raw.authentication_factor_id, String)
22
+ @created_at = T.let(raw.created_at, String)
23
+ @updated_at = T.let(raw.updated_at, String)
24
+ end
25
+
26
+ def to_json(*)
27
+ {
28
+ id: id,
29
+ object: object,
30
+ expires_at: expires_at,
31
+ code: code,
32
+ authentication_factor_id: authentication_factor_id,
33
+ created_at: created_at,
34
+ updated_at: updated_at,
35
+ }
36
+ end
37
+
38
+ private
39
+
40
+ sig { params(json_string: String).returns(WorkOSV2::Types::ChallengeStruct) }
41
+ def parse_json(json_string)
42
+ hash = JSON.parse(json_string, symbolize_names: true)
43
+
44
+ WorkOSV2::Types::ChallengeStruct.new(
45
+ id: hash[:id],
46
+ object: hash[:object],
47
+ expires_at: hash[:expires_at],
48
+ code: hash[:code],
49
+ authentication_factor_id: hash[:authentication_factor_id],
50
+ created_at: hash[:created_at],
51
+ updated_at: hash[:updated_at],
52
+ )
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+ # typed: false
3
+
4
+ module WorkOSV2
5
+ # A Net::HTTP based API client for interacting with the WorkOSV2 API
6
+ module Client
7
+ extend T::Sig
8
+ include Kernel
9
+
10
+ sig { returns(Net::HTTP) }
11
+ def client
12
+ Net::HTTP.new(WorkOSV2::API_HOSTNAME, 443).tap do |http_client|
13
+ http_client.use_ssl = true
14
+ http_client.open_timeout = WorkOSV2.config.timeout
15
+ http_client.read_timeout = WorkOSV2.config.timeout
16
+ http_client.write_timeout = WorkOSV2.config.timeout if RUBY_VERSION >= '2.6.0'
17
+ end
18
+ end
19
+
20
+ sig do
21
+ params(
22
+ request: T.any(Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Delete, Net::HTTP::Put),
23
+ ).returns(::T.untyped)
24
+ end
25
+ def execute_request(request:)
26
+ begin
27
+ response = client.request(request)
28
+ rescue Net::OpenTimeout, Net::ReadTimeout, Net::WriteTimeout
29
+ raise TimeoutError.new(
30
+ message: 'API Timeout Error',
31
+ )
32
+ end
33
+
34
+ http_status = response.code.to_i
35
+ handle_error_response(response: response) if http_status >= 400
36
+
37
+ response
38
+ end
39
+
40
+ sig do
41
+ params(
42
+ path: String,
43
+ auth: T.nilable(T::Boolean),
44
+ params: T.nilable(Hash),
45
+ access_token: T.nilable(String),
46
+ ).returns(Net::HTTP::Get)
47
+ end
48
+ def get_request(path:, auth: false, params: {}, access_token: nil)
49
+ uri = URI(path)
50
+ uri.query = URI.encode_www_form(params) if params
51
+
52
+ request = Net::HTTP::Get.new(
53
+ uri.to_s,
54
+ 'Content-Type' => 'application/json',
55
+ )
56
+
57
+ request['Authorization'] = "Bearer #{access_token || WorkOSV2.config.key!}" if auth
58
+ request['User-Agent'] = user_agent
59
+ request
60
+ end
61
+
62
+ sig do
63
+ params(
64
+ path: String,
65
+ auth: T.nilable(T::Boolean),
66
+ idempotency_key: T.nilable(String),
67
+ body: T.nilable(Hash),
68
+ ).returns(Net::HTTP::Post)
69
+ end
70
+ def post_request(path:, auth: false, idempotency_key: nil, body: nil)
71
+ request = Net::HTTP::Post.new(path, 'Content-Type' => 'application/json')
72
+ request.body = body.to_json if body
73
+ request['Authorization'] = "Bearer #{WorkOSV2.config.key!}" if auth
74
+ request['Idempotency-Key'] = idempotency_key if idempotency_key
75
+ request['User-Agent'] = user_agent
76
+ request
77
+ end
78
+
79
+ sig do
80
+ params(
81
+ path: String,
82
+ auth: T.nilable(T::Boolean),
83
+ params: T.nilable(Hash),
84
+ ).returns(Net::HTTP::Delete)
85
+ end
86
+ def delete_request(path:, auth: false, params: {})
87
+ uri = URI(path)
88
+ uri.query = URI.encode_www_form(params) if params
89
+
90
+ request = Net::HTTP::Delete.new(
91
+ uri.to_s,
92
+ 'Content-Type' => 'application/json',
93
+ )
94
+
95
+ request['Authorization'] = "Bearer #{WorkOSV2.config.key!}" if auth
96
+ request['User-Agent'] = user_agent
97
+ request
98
+ end
99
+
100
+ sig do
101
+ params(
102
+ path: String,
103
+ auth: T.nilable(T::Boolean),
104
+ idempotency_key: T.nilable(String),
105
+ body: T.nilable(Hash),
106
+ ).returns(Net::HTTP::Put)
107
+ end
108
+ def put_request(path:, auth: false, idempotency_key: nil, body: nil)
109
+ request = Net::HTTP::Put.new(path, 'Content-Type' => 'application/json')
110
+ request.body = body.to_json if body
111
+ request['Authorization'] = "Bearer #{WorkOSV2.config.key!}" if auth
112
+ request['Idempotency-Key'] = idempotency_key if idempotency_key
113
+ request['User-Agent'] = user_agent
114
+ request
115
+ end
116
+
117
+ sig { returns(String) }
118
+ def user_agent
119
+ engine = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : 'Ruby'
120
+
121
+ [
122
+ 'WorkOSV2',
123
+ "#{engine}/#{RUBY_VERSION}",
124
+ RUBY_PLATFORM,
125
+ "v#{WorkOSV2::VERSION}"
126
+ ].join('; ')
127
+ end
128
+
129
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
130
+ sig { params(response: ::T.untyped).void }
131
+ def handle_error_response(response:)
132
+ http_status = response.code.to_i
133
+ json = JSON.parse(response.body)
134
+
135
+ case http_status
136
+ when 400
137
+ raise InvalidRequestError.new(
138
+ message: json['message'],
139
+ http_status: http_status,
140
+ request_id: response['x-request-id'],
141
+ code: json['code'],
142
+ errors: json['errors'],
143
+ )
144
+ when 401
145
+ raise AuthenticationError.new(
146
+ message: json['message'],
147
+ http_status: http_status,
148
+ request_id: response['x-request-id'],
149
+ )
150
+ when 404
151
+ raise APIError.new(
152
+ message: json['message'],
153
+ http_status: http_status,
154
+ request_id: response['x-request-id'],
155
+ )
156
+ when 422
157
+ message = json['message']
158
+ code = json['code']
159
+ errors = extract_error(json['errors']) if json['errors']
160
+ message += " (#{errors})" if errors
161
+
162
+ raise InvalidRequestError.new(
163
+ message: message,
164
+ http_status: http_status,
165
+ request_id: response['x-request-id'],
166
+ code: code,
167
+ )
168
+ else
169
+ raise APIError.new(
170
+ message: json['message'],
171
+ http_status: http_status,
172
+ request_id: response['x-request-id'],
173
+ )
174
+ end
175
+ end
176
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
177
+
178
+ private
179
+
180
+ def extract_error(errors)
181
+ errors.map do |error|
182
+ "#{error['field']}: #{error['code']}"
183
+ end.join('; ')
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module WorkOSV2
5
+ # Configuration class sets config initializer
6
+ class Configuration
7
+ attr_accessor :timeout, :key
8
+
9
+ def initialize
10
+ @timeout = 60
11
+ end
12
+
13
+ def key!
14
+ key or raise '`WorkOSV2.config.key` not set'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module WorkOSV2
5
+ # The Connection class provides a lightweight wrapper around
6
+ # a WorkOSV2 Connection resource. This class is not meant to be instantiated
7
+ # in user space, and is instantiated internally but exposed.
8
+ # Note: status is deprecated - use state instead
9
+ class Connection
10
+ include HashProvider
11
+ extend T::Sig
12
+
13
+ attr_accessor :id, :name, :connection_type, :domains, :organization_id,
14
+ :state, :status, :created_at, :updated_at
15
+
16
+ # rubocop:disable Metrics/AbcSize
17
+ sig { params(json: String).void }
18
+ def initialize(json)
19
+ raw = parse_json(json)
20
+
21
+ @id = T.let(raw.id, String)
22
+ @name = T.let(raw.name, String)
23
+ @connection_type = T.let(raw.connection_type, String)
24
+ @domains = T.let(raw.domains, Array)
25
+ @organization_id = raw.organization_id
26
+ @state = T.let(raw.state, String)
27
+ @status = T.let(raw.status, String)
28
+ @created_at = T.let(raw.created_at, String)
29
+ @updated_at = T.let(raw.updated_at, String)
30
+ end
31
+ # rubocop:enable Metrics/AbcSize
32
+
33
+ def to_json(*)
34
+ {
35
+ id: id,
36
+ name: name,
37
+ connection_type: connection_type,
38
+ domains: domains,
39
+ organization_id: organization_id,
40
+ state: state,
41
+ status: status,
42
+ created_at: created_at,
43
+ updated_at: updated_at,
44
+ }
45
+ end
46
+
47
+ private
48
+
49
+ sig { params(json_string: String).returns(WorkOSV2::Types::ConnectionStruct) }
50
+ def parse_json(json_string)
51
+ hash = JSON.parse(json_string, symbolize_names: true)
52
+
53
+ WorkOSV2::Types::ConnectionStruct.new(
54
+ id: hash[:id],
55
+ name: hash[:name],
56
+ connection_type: hash[:connection_type],
57
+ domains: hash[:domains],
58
+ organization_id: hash[:organization_id],
59
+ state: hash[:state],
60
+ status: hash[:status],
61
+ created_at: hash[:created_at],
62
+ updated_at: hash[:updated_at],
63
+ )
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkOSV2
4
+ # A Temporary wrapper class for a Hash, currently the base class for
5
+ # WorOS::DirectoryGroup and WorkOSV2::DirectoryUser. Makes all the Hash
6
+ # methods available to those classes, but will also emit a deprecation
7
+ # warning whenever any of them are used.
8
+ #
9
+ # Once we deprecate Hash compatibility, this model can be deleted.
10
+ class DeprecatedHashWrapper < Hash
11
+ (public_instance_methods - Object.methods).each do |method_name|
12
+ define_method method_name do |*args, &block|
13
+ print_deprecation_warning(method_name)
14
+ super(*args, &block)
15
+ end
16
+ end
17
+
18
+ # call the original implementation of :replace in Hash,
19
+ # so we don't show the deprecation warning
20
+ def replace_without_warning(new_hash)
21
+ method(:replace).super_method&.call(new_hash)
22
+ end
23
+
24
+ def [](attribute_name)
25
+ usage = "#{object_name}.#{attribute_name}"
26
+ warning_message = "WARNING: The Hash style access for #{class_name} attributes is deprecated
27
+ and will be removed in a future version. Please use `#{usage}` or equivalent accessor.\n"
28
+
29
+ print_deprecation_warning('[]', warning_message)
30
+
31
+ super(attribute_name.to_sym)
32
+ end
33
+
34
+ private
35
+
36
+ def deprecation_warning(method_name)
37
+ usage = "#{object_name}.to_h.#{method_name}"
38
+
39
+ "WARNING: Hash compatibility for #{class_name} is deprecated and will be removed
40
+ in a future version. Please use `#{usage}` to access methods on the attribute Hash object.\n"
41
+ end
42
+
43
+ def print_deprecation_warning(method_name, warning_message = deprecation_warning(method_name))
44
+ if RUBY_VERSION > '3'
45
+ warn warning_message, category: :deprecated
46
+ else
47
+ warn warning_message
48
+ end
49
+ end
50
+
51
+ def class_name
52
+ self.class.name
53
+ end
54
+
55
+ # We want to do class_name.demodulize.underscore here, but that's not available in Ruby 1.9, so
56
+ # implementing the demodulize and underscore methods here.
57
+ def object_name
58
+ i = class_name.rindex('::')
59
+ object_name = i ? class_name[(i + 2)..-1] : class_name
60
+ underscore(object_name)
61
+ end
62
+
63
+ def underscore(camel_cased_word)
64
+ return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
65
+
66
+ word = camel_cased_word.to_s.gsub('::', '/')
67
+ word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)((?=a)b)(?=\b|[^a-z])/) do
68
+ "#{Regexp.last_match(1) && '_'}#{Regexp.last_match(2).downcase}"
69
+ end
70
+ word.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { (Regexp.last_match(1) || Regexp.last_match(2)) << '_' }
71
+ word.tr!('-', '_')
72
+ word.downcase!
73
+ word
74
+ end
75
+ end
76
+ end