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.
- checksums.yaml +7 -0
- data/.github/CODEOWNERS +5 -0
- data/.github/pull_request_template.md +11 -0
- data/.github/renovate.json +5 -0
- data/.gitignore +49 -0
- data/.rspec +1 -0
- data/.rubocop.yml +24 -0
- data/.ruby-version +1 -0
- data/.semaphore/rubygems.yml +24 -0
- data/.semaphore/semaphore.yml +51 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +126 -0
- data/Gemfile.lock.old +127 -0
- data/LICENSE +21 -0
- data/README.md +53 -0
- data/bin/build +3 -0
- data/bin/console +3 -0
- data/bin/docs +5 -0
- data/bin/publish +3 -0
- data/bin/tapioca +29 -0
- data/codecov.yml +12 -0
- data/docs/WorkOS/APIError.html +160 -0
- data/docs/WorkOS/AuditLog.html +235 -0
- data/docs/WorkOS/AuditTrail.html +235 -0
- data/docs/WorkOS/AuthenticationError.html +160 -0
- data/docs/WorkOS/Base.html +287 -0
- data/docs/WorkOS/Client.html +504 -0
- data/docs/WorkOS/InvalidRequestError.html +160 -0
- data/docs/WorkOS/Profile.html +788 -0
- data/docs/WorkOS/RequestError.html +135 -0
- data/docs/WorkOS/SSO.html +691 -0
- data/docs/WorkOS/Types/ProfileStruct.html +135 -0
- data/docs/WorkOS/Types/Provider.html +135 -0
- data/docs/WorkOS/Types.html +128 -0
- data/docs/WorkOS/WorkOSError.html +447 -0
- data/docs/WorkOS.html +324 -0
- data/docs/class_list.html +51 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +496 -0
- data/docs/file.README.html +252 -0
- data/docs/file_list.html +56 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +250 -0
- data/docs/js/app.js +314 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +267 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/workosv2/audit_log_export.rb +55 -0
- data/lib/workosv2/audit_logs.rb +114 -0
- data/lib/workosv2/audit_trail.rb +111 -0
- data/lib/workosv2/challenge.rb +55 -0
- data/lib/workosv2/client.rb +186 -0
- data/lib/workosv2/configuration.rb +17 -0
- data/lib/workosv2/connection.rb +66 -0
- data/lib/workosv2/deprecated_hash_wrapper.rb +76 -0
- data/lib/workosv2/directory.rb +65 -0
- data/lib/workosv2/directory_group.rb +68 -0
- data/lib/workosv2/directory_sync.rb +218 -0
- data/lib/workosv2/directory_user.rb +97 -0
- data/lib/workosv2/errors.rb +81 -0
- data/lib/workosv2/event.rb +51 -0
- data/lib/workosv2/events.rb +52 -0
- data/lib/workosv2/factor.rb +54 -0
- data/lib/workosv2/hash_provider.rb +19 -0
- data/lib/workosv2/mfa.rb +178 -0
- data/lib/workosv2/organization.rb +57 -0
- data/lib/workosv2/organizations.rb +188 -0
- data/lib/workosv2/passwordless.rb +85 -0
- data/lib/workosv2/portal.rb +66 -0
- data/lib/workosv2/profile.rb +76 -0
- data/lib/workosv2/profile_and_token.rb +29 -0
- data/lib/workosv2/sso.rb +297 -0
- data/lib/workosv2/types/audit_log_export_struct.rb +17 -0
- data/lib/workosv2/types/challenge_struct.rb +18 -0
- data/lib/workosv2/types/connection_struct.rb +20 -0
- data/lib/workosv2/types/directory_group_struct.rb +19 -0
- data/lib/workosv2/types/directory_struct.rb +19 -0
- data/lib/workosv2/types/directory_user_struct.rb +26 -0
- data/lib/workosv2/types/event_struct.rb +15 -0
- data/lib/workosv2/types/factor_struct.rb +18 -0
- data/lib/workosv2/types/intent_enum.rb +17 -0
- data/lib/workosv2/types/list_struct.rb +13 -0
- data/lib/workosv2/types/organization_struct.rb +17 -0
- data/lib/workosv2/types/passwordless_session_struct.rb +17 -0
- data/lib/workosv2/types/profile_struct.rb +21 -0
- data/lib/workosv2/types/provider_enum.rb +15 -0
- data/lib/workosv2/types/verify_challenge_struct.rb +13 -0
- data/lib/workosv2/types/webhook_struct.rb +15 -0
- data/lib/workosv2/types.rb +25 -0
- data/lib/workosv2/verify_challenge.rb +39 -0
- data/lib/workosv2/version.rb +6 -0
- data/lib/workosv2/webhook.rb +51 -0
- data/lib/workosv2/webhooks.rb +217 -0
- data/lib/workosv2.rb +79 -0
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/addressable@2.8.0.rbi +290 -0
- data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
- data/sorbet/rbi/gems/codecov@0.2.12.rbi +55 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
- data/sorbet/rbi/gems/crack@0.4.5.rbi +57 -0
- data/sorbet/rbi/gems/diff-lcs@1.4.4.rbi +185 -0
- data/sorbet/rbi/gems/docile@1.3.5.rbi +54 -0
- data/sorbet/rbi/gems/hashdiff@1.0.1.rbi +82 -0
- data/sorbet/rbi/gems/json@2.5.1.rbi +109 -0
- data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
- data/sorbet/rbi/gems/parallel@1.20.1.rbi +113 -0
- data/sorbet/rbi/gems/parser@3.0.1.0.rbi +1187 -0
- data/sorbet/rbi/gems/pry@0.14.2.rbi +8 -0
- data/sorbet/rbi/gems/public_suffix@4.0.6.rbi +146 -0
- data/sorbet/rbi/gems/rainbow@3.0.0.rbi +153 -0
- data/sorbet/rbi/gems/rake@13.0.3.rbi +807 -0
- data/sorbet/rbi/gems/rbi@0.0.16.rbi +2118 -0
- data/sorbet/rbi/gems/regexp_parser@2.1.1.rbi +1117 -0
- data/sorbet/rbi/gems/rexml@3.2.5.rbi +709 -0
- data/sorbet/rbi/gems/rspec-core@3.9.3.rbi +2467 -0
- data/sorbet/rbi/gems/rspec-expectations@3.9.4.rbi +1569 -0
- data/sorbet/rbi/gems/rspec-mocks@3.9.1.rbi +1493 -0
- data/sorbet/rbi/gems/rspec-support@3.9.4.rbi +511 -0
- data/sorbet/rbi/gems/rspec@3.9.0.rbi +38 -0
- data/sorbet/rbi/gems/rubocop-ast@1.4.1.rbi +1881 -0
- data/sorbet/rbi/gems/rubocop@0.93.1.rbi +11497 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +405 -0
- data/sorbet/rbi/gems/simplecov-html@0.12.3.rbi +89 -0
- data/sorbet/rbi/gems/simplecov@0.21.2.rbi +577 -0
- data/sorbet/rbi/gems/simplecov_json_formatter@0.1.2.rbi +8 -0
- data/sorbet/rbi/gems/spoom@1.1.15.rbi +1549 -0
- data/sorbet/rbi/gems/tapioca@0.7.3.rbi +1718 -0
- data/sorbet/rbi/gems/thor@1.2.1.rbi +844 -0
- data/sorbet/rbi/gems/unicode-display_width@1.7.0.rbi +22 -0
- data/sorbet/rbi/gems/unparser@0.6.2.rbi +8 -0
- data/sorbet/rbi/gems/vcr@5.0.0.rbi +699 -0
- data/sorbet/rbi/gems/webmock@3.12.2.rbi +662 -0
- data/sorbet/rbi/gems/yard-sorbet@0.8.0.rbi +268 -0
- data/sorbet/rbi/gems/yard@0.9.26.rbi +4048 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +4 -0
- data/spec/lib/workos/audit_logs_spec.rb +151 -0
- data/spec/lib/workos/audit_trail_spec.rb +146 -0
- data/spec/lib/workos/configuration_spec.rb +61 -0
- data/spec/lib/workos/directory_sync_spec.rb +492 -0
- data/spec/lib/workos/directory_user_spec.rb +36 -0
- data/spec/lib/workos/event_spec.rb +88 -0
- data/spec/lib/workos/mfa_spec.rb +281 -0
- data/spec/lib/workos/organizations_spec.rb +257 -0
- data/spec/lib/workos/passwordless_spec.rb +77 -0
- data/spec/lib/workos/portal_spec.rb +87 -0
- data/spec/lib/workos/sso_spec.rb +650 -0
- data/spec/lib/workos/webhooks_spec.rb +236 -0
- data/spec/spec_helper.rb +56 -0
- 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 +77 -0
- data/spec/support/fixtures/vcr_cassettes/audit_logs/get_export.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event.yml +65 -0
- data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event_custom_idempotency_key.yml +67 -0
- data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event_invalid.yml +68 -0
- data/spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_and_payload.yml +131 -0
- data/spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_different_payload.yml +134 -0
- data/spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml +61 -0
- data/spec/support/fixtures/vcr_cassettes/base/execute_request_unauthenticated.yml +66 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/delete_directory.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/get_directory_with_invalid_id.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/get_directory_with_valid_id.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group.yml +80 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group_with_invalid_id.yml +62 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user_with_invalid_id.yml +62 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_after.yml +87 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_before.yml +89 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_domain.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_limit.yml +85 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_no_options.yml +93 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_search.yml +85 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_after.yml +90 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_before.yml +90 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_directory.yml +90 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_limit.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_no_options.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_user.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_after.yml +186 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_before.yml +88 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_directory.yml +194 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_group.yml +186 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_limit.yml +189 -0
- data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_no_options.yml +74 -0
- data/spec/support/fixtures/vcr_cassettes/events/list_events_with_after.yml +80 -0
- data/spec/support/fixtures/vcr_cassettes/events/list_events_with_event.yml +80 -0
- data/spec/support/fixtures/vcr_cassettes/events/list_events_with_no_options.yml +80 -0
- data/spec/support/fixtures/vcr_cassettes/events/list_events_with_range.yml +80 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_generic_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_sms_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_totp_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/delete_factor.yml +80 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_generic_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_sms_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_invalid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_expired.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_invalid.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid_is_false.yml +82 -0
- data/spec/support/fixtures/vcr_cassettes/organization/create.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml +72 -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/organization/delete.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/organization/delete_invalid.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/organization/get.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/organization/get_invalid.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/organization/list.yml +87 -0
- data/spec/support/fixtures/vcr_cassettes/organization/update.yml +84 -0
- data/spec/support/fixtures/vcr_cassettes/passwordless/create_session.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/passwordless/create_session_invalid.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/passwordless/send_session.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/passwordless/send_session_invalid.yml +73 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_audit_logs.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_dsync.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_invalid.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/portal/generate_link_sso.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_invalid_id.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_valid_id.yml +70 -0
- data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_invalid_id.yml +72 -0
- data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_valid_id.yml +86 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_after.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_before.yml +86 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_connection_type.yml +90 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_domain.yml +86 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_limit.yml +83 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_no_options.yml +89 -0
- data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_organization_id.yml +86 -0
- data/spec/support/fixtures/vcr_cassettes/sso/profile.yml +74 -0
- data/spec/support/profile.txt +1 -0
- data/spec/support/shared_examples/client_spec.rb +30 -0
- data/spec/support/webhook_payload.txt +1 -0
- data/workosv2.gemspec +38 -0
- metadata +531 -0
data/lib/workosv2/sso.rb
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module WorkOSV2
|
8
|
+
# The SSO module provides convenience methods for working with the WorkOSV2
|
9
|
+
# SSO platform. You'll need a valid API key, a client ID, and to have
|
10
|
+
# created an SSO connection on your WorkOSV2 dashboard.
|
11
|
+
#
|
12
|
+
# @see https://docs.workos.com/sso/overview
|
13
|
+
module SSO
|
14
|
+
class << self
|
15
|
+
extend T::Sig
|
16
|
+
include Client
|
17
|
+
|
18
|
+
PROVIDERS = WorkOSV2::Types::Provider.values.map(&:serialize).freeze
|
19
|
+
|
20
|
+
# Generate an Oauth2 authorization URL where your users will
|
21
|
+
# authenticate using the configured SSO Identity Provider.
|
22
|
+
#
|
23
|
+
# @param [String] redirect_uri The URI where users are directed
|
24
|
+
# after completing the authentication step. Must match a
|
25
|
+
# configured redirect URI on your WorkOSV2 dashboard.
|
26
|
+
# @param [String] client_id The WorkOSV2 client ID for the environment
|
27
|
+
# where you've configured your SSO connection.
|
28
|
+
# @param [String] domain The domain for the relevant SSO Connection
|
29
|
+
# configured on your WorkOSV2 dashboard. One of provider, domain,
|
30
|
+
# connection, or organization is required.
|
31
|
+
# The domain is deprecated.
|
32
|
+
# @param [String] provider A provider name for an Identity Provider
|
33
|
+
# configured on your WorkOSV2 dashboard. Only 'GoogleOAuth' and
|
34
|
+
# 'MicrosoftOAuth' are supported.
|
35
|
+
# @param [String] connection The ID for a Connection configured on
|
36
|
+
# WorkOSV2.
|
37
|
+
# @param [String] organization The ID for an Organization configured
|
38
|
+
# on WorkOSV2.
|
39
|
+
# @param [String] state An arbitrary state object
|
40
|
+
# that is preserved and available to the client in the response.
|
41
|
+
# @example
|
42
|
+
# WorkOSV2::SSO.authorization_url(
|
43
|
+
# connection: 'conn_123',
|
44
|
+
# client_id: 'project_01DG5TGK363GRVXP3ZS40WNGEZ',
|
45
|
+
# redirect_uri: 'https://workos.com/callback',
|
46
|
+
# state: {
|
47
|
+
# next_page: '/docs'
|
48
|
+
# }.to_s
|
49
|
+
# )
|
50
|
+
#
|
51
|
+
# => "https://api.workos.com/sso/authorize?connection=conn_123" \
|
52
|
+
# "&client_id=project_01DG5TGK363GRVXP3ZS40WNGEZ" \
|
53
|
+
# "&redirect_uri=https%3A%2F%2Fworkos.com%2Fcallback&" \
|
54
|
+
# "response_type=code&state=%7B%3Anext_page%3D%3E%22%2Fdocs%22%7D"
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
# rubocop:disable Metrics/ParameterLists
|
58
|
+
sig do
|
59
|
+
params(
|
60
|
+
redirect_uri: String,
|
61
|
+
client_id: T.nilable(String),
|
62
|
+
domain: T.nilable(String),
|
63
|
+
domain_hint: T.nilable(String),
|
64
|
+
login_hint: T.nilable(String),
|
65
|
+
provider: T.nilable(String),
|
66
|
+
connection: T.nilable(String),
|
67
|
+
organization: T.nilable(String),
|
68
|
+
state: T.nilable(String),
|
69
|
+
).returns(String)
|
70
|
+
end
|
71
|
+
def authorization_url(
|
72
|
+
redirect_uri:,
|
73
|
+
client_id: nil,
|
74
|
+
domain: nil,
|
75
|
+
domain_hint: nil,
|
76
|
+
login_hint: nil,
|
77
|
+
provider: nil,
|
78
|
+
connection: nil,
|
79
|
+
organization: nil,
|
80
|
+
state: ''
|
81
|
+
)
|
82
|
+
if domain
|
83
|
+
warn '[DEPRECATION] `domain` is deprecated.
|
84
|
+
Please use `organization` instead.'
|
85
|
+
end
|
86
|
+
|
87
|
+
validate_authorization_url_arguments(
|
88
|
+
provider: provider,
|
89
|
+
domain: domain,
|
90
|
+
connection: connection,
|
91
|
+
organization: organization,
|
92
|
+
)
|
93
|
+
|
94
|
+
query = URI.encode_www_form({
|
95
|
+
client_id: client_id,
|
96
|
+
redirect_uri: redirect_uri,
|
97
|
+
response_type: 'code',
|
98
|
+
state: state,
|
99
|
+
domain: domain,
|
100
|
+
domain_hint: domain_hint,
|
101
|
+
login_hint: login_hint,
|
102
|
+
provider: provider,
|
103
|
+
connection: connection,
|
104
|
+
organization: organization,
|
105
|
+
}.compact)
|
106
|
+
|
107
|
+
"https://#{WorkOSV2::API_HOSTNAME}/sso/authorize?#{query}"
|
108
|
+
end
|
109
|
+
# rubocop:enable Metrics/ParameterLists
|
110
|
+
|
111
|
+
sig do
|
112
|
+
params(
|
113
|
+
access_token: String,
|
114
|
+
).returns(WorkOSV2::Profile)
|
115
|
+
end
|
116
|
+
def get_profile(access_token:)
|
117
|
+
response = execute_request(
|
118
|
+
request: get_request(
|
119
|
+
path: '/sso/profile',
|
120
|
+
auth: true,
|
121
|
+
access_token: access_token,
|
122
|
+
),
|
123
|
+
)
|
124
|
+
|
125
|
+
WorkOSV2::Profile.new(response.body)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Fetch the profile details for the authenticated SSO user.
|
129
|
+
#
|
130
|
+
# @param [String] code The authorization code provided in the callback URL
|
131
|
+
# @param [String] client_id The WorkOSV2 client ID for the environment
|
132
|
+
# where you've configured your SSO connection
|
133
|
+
#
|
134
|
+
# @return [WorkOSV2::ProfileAndToken]
|
135
|
+
sig do
|
136
|
+
params(
|
137
|
+
code: String,
|
138
|
+
client_id: T.nilable(String),
|
139
|
+
).returns(WorkOSV2::ProfileAndToken)
|
140
|
+
end
|
141
|
+
def profile_and_token(code:, client_id: nil)
|
142
|
+
body = {
|
143
|
+
client_id: client_id,
|
144
|
+
client_secret: WorkOSV2.config.key!,
|
145
|
+
grant_type: 'authorization_code',
|
146
|
+
code: code,
|
147
|
+
}
|
148
|
+
|
149
|
+
response = client.request(post_request(path: '/sso/token', body: body))
|
150
|
+
check_and_raise_profile_and_token_error(response: response)
|
151
|
+
|
152
|
+
WorkOSV2::ProfileAndToken.new(response.body)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Retrieve connections.
|
156
|
+
#
|
157
|
+
# @param [Hash] options An options hash
|
158
|
+
# @option options [String] connection_type Authentication service
|
159
|
+
# provider descriptor.
|
160
|
+
# @option options [String] domain The domain of the connection to be
|
161
|
+
# retrieved.
|
162
|
+
# @option options [String] organization_id The id of the organization
|
163
|
+
# of the connections to be retrieved.
|
164
|
+
# @option options [String] limit Maximum number of records to return.
|
165
|
+
# @option options [String] order The order in which to paginate records
|
166
|
+
# @option options [String] before Pagination cursor to receive records
|
167
|
+
# before a provided Connection ID.
|
168
|
+
# @option options [String] after Pagination cursor to receive records
|
169
|
+
# before a provided Connection ID.
|
170
|
+
#
|
171
|
+
# @return [Hash]
|
172
|
+
sig do
|
173
|
+
params(
|
174
|
+
options: T::Hash[Symbol, String],
|
175
|
+
).returns(WorkOSV2::Types::ListStruct)
|
176
|
+
end
|
177
|
+
def list_connections(options = {})
|
178
|
+
response = execute_request(
|
179
|
+
request: get_request(
|
180
|
+
path: '/connections',
|
181
|
+
auth: true,
|
182
|
+
params: options,
|
183
|
+
),
|
184
|
+
)
|
185
|
+
|
186
|
+
parsed_response = JSON.parse(response.body)
|
187
|
+
connections = parsed_response['data'].map do |connection|
|
188
|
+
::WorkOSV2::Connection.new(connection.to_json)
|
189
|
+
end
|
190
|
+
|
191
|
+
WorkOSV2::Types::ListStruct.new(
|
192
|
+
data: connections,
|
193
|
+
list_metadata: parsed_response['listMetadata'],
|
194
|
+
)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Get a Connection
|
198
|
+
#
|
199
|
+
# @param [String] id Connection unique identifier
|
200
|
+
#
|
201
|
+
# @example
|
202
|
+
# WorkOSV2::SSO.get_connection(id: 'conn_02DRA1XNSJDZ19A31F183ECQW9')
|
203
|
+
# => #<WorkOSV2::Connection:0x00007fb6e4193d20
|
204
|
+
# @id="conn_02DRA1XNSJDZ19A31F183ECQW9",
|
205
|
+
# @name="Foo Corp",
|
206
|
+
# @connection_type="OktaSAML",
|
207
|
+
# @domains=
|
208
|
+
# [{:object=>"connection_domain",
|
209
|
+
# :id=>"domain_01E6PK9N3XMD8RHWF7S66380AR",
|
210
|
+
# :domain=>"example.com"}]>
|
211
|
+
#
|
212
|
+
# @return [WorkOSV2::Connection]
|
213
|
+
sig { params(id: String).returns(WorkOSV2::Connection) }
|
214
|
+
def get_connection(id:)
|
215
|
+
request = get_request(
|
216
|
+
auth: true,
|
217
|
+
path: "/connections/#{id}",
|
218
|
+
)
|
219
|
+
|
220
|
+
response = execute_request(request: request)
|
221
|
+
|
222
|
+
WorkOSV2::Connection.new(response.body)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Delete a Connection
|
226
|
+
#
|
227
|
+
# @param [String] id Connection unique identifier
|
228
|
+
#
|
229
|
+
# @example
|
230
|
+
# WorkOSV2::SSO.delete_connection(id: 'conn_02DRA1XNSJDZ19A31F183ECQW9')
|
231
|
+
# => true
|
232
|
+
#
|
233
|
+
# @return [Bool] - returns `true` if successful
|
234
|
+
sig { params(id: String).returns(T::Boolean) }
|
235
|
+
def delete_connection(id:)
|
236
|
+
request = delete_request(
|
237
|
+
auth: true,
|
238
|
+
path: "/connections/#{id}",
|
239
|
+
)
|
240
|
+
|
241
|
+
response = execute_request(request: request)
|
242
|
+
|
243
|
+
response.is_a? Net::HTTPSuccess
|
244
|
+
end
|
245
|
+
|
246
|
+
private
|
247
|
+
|
248
|
+
sig do
|
249
|
+
params(
|
250
|
+
domain: T.nilable(String),
|
251
|
+
provider: T.nilable(String),
|
252
|
+
connection: T.nilable(String),
|
253
|
+
organization: T.nilable(String),
|
254
|
+
).void
|
255
|
+
end
|
256
|
+
def validate_authorization_url_arguments(
|
257
|
+
domain:,
|
258
|
+
provider:,
|
259
|
+
connection:,
|
260
|
+
organization:
|
261
|
+
)
|
262
|
+
if [domain, provider, connection, organization].all?(&:nil?)
|
263
|
+
raise ArgumentError, 'Either connection, domain, ' \
|
264
|
+
'provider, or organization is required.'
|
265
|
+
end
|
266
|
+
|
267
|
+
return unless provider && !PROVIDERS.include?(provider)
|
268
|
+
|
269
|
+
raise ArgumentError, "#{provider} is not a valid value." \
|
270
|
+
" `provider` must be in #{PROVIDERS}"
|
271
|
+
end
|
272
|
+
|
273
|
+
sig { params(response: Net::HTTPResponse).void }
|
274
|
+
def check_and_raise_profile_and_token_error(response:)
|
275
|
+
begin
|
276
|
+
body = JSON.parse(response.body)
|
277
|
+
return if body['access_token'] && body['profile']
|
278
|
+
|
279
|
+
message = body['message']
|
280
|
+
error = body['error']
|
281
|
+
error_description = body['error_description']
|
282
|
+
request_id = response['x-request-id']
|
283
|
+
rescue StandardError
|
284
|
+
message = 'Something went wrong'
|
285
|
+
end
|
286
|
+
|
287
|
+
raise APIError.new(
|
288
|
+
message: message,
|
289
|
+
error: error,
|
290
|
+
error_description: error_description,
|
291
|
+
http_status: nil,
|
292
|
+
request_id: request_id,
|
293
|
+
)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
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
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# This ChallgengeStruct acts as a typed interface
|
7
|
+
# for the Factor class
|
8
|
+
class ChallengeStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :object, String
|
11
|
+
const :expires_at, String
|
12
|
+
const :code, T.nilable(String)
|
13
|
+
const :authentication_factor_id, String
|
14
|
+
const :created_at, String
|
15
|
+
const :updated_at, String
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# This ConnectionStruct acts as a typed interface
|
7
|
+
# for the Connection class
|
8
|
+
class ConnectionStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :name, String
|
11
|
+
const :connection_type, String
|
12
|
+
const :domains, T::Array[T.untyped]
|
13
|
+
const :organization_id, T.nilable(String)
|
14
|
+
const :state, String
|
15
|
+
const :status, String
|
16
|
+
const :created_at, String
|
17
|
+
const :updated_at, String
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# This DirectoryGroupStruct acts as a typed interface
|
7
|
+
# for the DirectoryGroup class
|
8
|
+
class DirectoryGroupStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :directory_id, String
|
11
|
+
const :organization_id, T.nilable(String)
|
12
|
+
const :idp_id, String
|
13
|
+
const :name, String
|
14
|
+
const :created_at, String
|
15
|
+
const :updated_at, String
|
16
|
+
const :raw_attributes, T::Hash[Symbol, Object]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# This DirectoryStruct acts as a typed interface
|
7
|
+
# for the Directory class
|
8
|
+
class DirectoryStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :name, String
|
11
|
+
const :domain, T.nilable(String)
|
12
|
+
const :type, String
|
13
|
+
const :state, String
|
14
|
+
const :organization_id, T.nilable(String)
|
15
|
+
const :created_at, String
|
16
|
+
const :updated_at, String
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# The DirectoryUserStruct acts as a typed interface
|
7
|
+
# for the DirectoryUser class
|
8
|
+
class DirectoryUserStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :directory_id, String
|
11
|
+
const :organization_id, T.nilable(String)
|
12
|
+
const :idp_id, String
|
13
|
+
const :emails, T::Array[T.untyped]
|
14
|
+
const :first_name, T.nilable(String)
|
15
|
+
const :last_name, T.nilable(String)
|
16
|
+
const :job_title, T.nilable(String)
|
17
|
+
const :username, T.nilable(String)
|
18
|
+
const :state, T.nilable(String)
|
19
|
+
const :groups, T::Array[T.untyped]
|
20
|
+
const :custom_attributes, T::Hash[Symbol, T.untyped]
|
21
|
+
const :raw_attributes, T::Hash[Symbol, Object]
|
22
|
+
const :created_at, String
|
23
|
+
const :updated_at, String
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# The EventStruct acts as a typed interface
|
7
|
+
# for the Event class
|
8
|
+
class EventStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :event, String
|
11
|
+
const :data, T::Hash[Symbol, Object]
|
12
|
+
const :created_at, String
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# This FactorStruct acts as a typed interface
|
7
|
+
# for the Factor class
|
8
|
+
class FactorStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :object, String
|
11
|
+
const :type, String
|
12
|
+
const :totp, T.nilable(T::Hash[Symbol, Object])
|
13
|
+
const :sms, T.nilable(T::Hash[Symbol, Object])
|
14
|
+
const :created_at, String
|
15
|
+
const :updated_at, String
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
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
|
+
AUDIT_LOGS = new('audit_logs')
|
11
|
+
DSYNC = new('dsync')
|
12
|
+
LOG_STREAMS = new('log_streams')
|
13
|
+
SSO = new('sso')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
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,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
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 :allow_profiles_outside_organization, T::Boolean
|
12
|
+
const :domains, T::Array[T.untyped]
|
13
|
+
const :created_at, String
|
14
|
+
const :updated_at, String
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module WorkOSV2
|
7
|
+
module Types
|
8
|
+
# This PasswordlessSessionStruct acts as a typed interface
|
9
|
+
# for the Passwordless class
|
10
|
+
class PasswordlessSessionStruct < T::Struct
|
11
|
+
const :id, String
|
12
|
+
const :email, String
|
13
|
+
const :expires_at, Date
|
14
|
+
const :link, String
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# The ProfileStruct acts as a typed interface
|
7
|
+
# for the Profile class
|
8
|
+
class ProfileStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :email, String
|
11
|
+
const :first_name, T.nilable(String)
|
12
|
+
const :last_name, T.nilable(String)
|
13
|
+
const :groups, T.nilable(T::Array[String])
|
14
|
+
const :organization_id, T.nilable(String)
|
15
|
+
const :connection_id, String
|
16
|
+
const :connection_type, String
|
17
|
+
const :idp_id, T.nilable(String)
|
18
|
+
const :raw_attributes, T::Hash[Symbol, Object]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# The ProviderEnum is type-safe declarations of a
|
7
|
+
# fixed set of values for SSO Providers.
|
8
|
+
class Provider < T::Enum
|
9
|
+
enums do
|
10
|
+
Google = new('GoogleOAuth')
|
11
|
+
Microsoft = new('MicrosoftOAuth')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# This VerifyChallengeStruct acts as a typed interface
|
7
|
+
# for the VerifyChallenge class
|
8
|
+
class VerifyChallengeStruct < T::Struct
|
9
|
+
const :challenge, T.nilable(T::Hash[Symbol, Object])
|
10
|
+
const :valid, T::Boolean
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
module Types
|
6
|
+
# This WebhookStruct acts as a typed interface
|
7
|
+
# for the Webhook class
|
8
|
+
class WebhookStruct < T::Struct
|
9
|
+
const :id, String
|
10
|
+
const :event, String
|
11
|
+
const :data, T::Hash[Symbol, Object]
|
12
|
+
const :created_at, String
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strong
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
# WorkOSV2 believes strongly in typed languages,
|
6
|
+
# so we're using Sorbet throughout this Ruby gem.
|
7
|
+
module Types
|
8
|
+
require_relative 'types/audit_log_export_struct'
|
9
|
+
require_relative 'types/connection_struct'
|
10
|
+
require_relative 'types/directory_struct'
|
11
|
+
require_relative 'types/directory_group_struct'
|
12
|
+
require_relative 'types/event_struct'
|
13
|
+
require_relative 'types/intent_enum'
|
14
|
+
require_relative 'types/list_struct'
|
15
|
+
require_relative 'types/organization_struct'
|
16
|
+
require_relative 'types/passwordless_session_struct'
|
17
|
+
require_relative 'types/profile_struct'
|
18
|
+
require_relative 'types/provider_enum'
|
19
|
+
require_relative 'types/directory_user_struct'
|
20
|
+
require_relative 'types/webhook_struct'
|
21
|
+
require_relative 'types/factor_struct'
|
22
|
+
require_relative 'types/challenge_struct'
|
23
|
+
require_relative 'types/verify_challenge_struct'
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: false
|
3
|
+
|
4
|
+
module WorkOSV2
|
5
|
+
# The VerifyChallenge class provides a lightweight wrapper around
|
6
|
+
# a WorkOSV2 Authentication Challenge resource.
|
7
|
+
class VerifyChallenge
|
8
|
+
include HashProvider
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
attr_accessor :challenge, :valid
|
12
|
+
|
13
|
+
sig { params(json: String).void }
|
14
|
+
def initialize(json)
|
15
|
+
raw = parse_json(json)
|
16
|
+
@challenge = T.let(raw.challenge, Hash)
|
17
|
+
@valid = raw.valid
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_json(*)
|
21
|
+
{
|
22
|
+
challenge: challenge,
|
23
|
+
valid: valid,
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
sig { params(json_string: String).returns(WorkOSV2::Types::VerifyChallengeStruct) }
|
30
|
+
def parse_json(json_string)
|
31
|
+
hash = JSON.parse(json_string, symbolize_names: true)
|
32
|
+
|
33
|
+
WorkOSV2::Types::VerifyChallengeStruct.new(
|
34
|
+
challenge: hash[:challenge],
|
35
|
+
valid: hash[:valid],
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|