descope 1.0.7 → 1.2.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/.github/workflows/ci.yaml +51 -12
- data/.github/workflows/publish-gem.yaml +6 -33
- data/.github/workflows/release-please.yaml +36 -0
- data/.gitignore +3 -2
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +31 -0
- data/Gemfile +7 -6
- data/Gemfile.lock +46 -45
- data/README.md +244 -1
- data/examples/ruby-on-rails-api/descope/package-lock.json +16 -10
- data/examples/ruby-on-rails-api/descope/yarn.lock +3 -3
- data/lib/descope/api/v1/auth/enchantedlink.rb +76 -9
- data/lib/descope/api/v1/management/access_key.rb +8 -7
- data/lib/descope/api/v1/management/analytics.rb +62 -0
- data/lib/descope/api/v1/management/audit.rb +2 -2
- data/lib/descope/api/v1/management/authz.rb +15 -15
- data/lib/descope/api/v1/management/common.rb +76 -0
- data/lib/descope/api/v1/management/descoper.rb +45 -0
- data/lib/descope/api/v1/management/engine.rb +44 -0
- data/lib/descope/api/v1/management/fga.rb +64 -0
- data/lib/descope/api/v1/management/flow.rb +5 -5
- data/lib/descope/api/v1/management/group.rb +42 -0
- data/lib/descope/api/v1/management/jwt_template.rb +49 -0
- data/lib/descope/api/v1/management/lists.rb +96 -0
- data/lib/descope/api/v1/management/management_key.rb +54 -0
- data/lib/descope/api/v1/management/outbound_app.rb +112 -0
- data/lib/descope/api/v1/management/password.rb +2 -2
- data/lib/descope/api/v1/management/permission.rb +4 -4
- data/lib/descope/api/v1/management/project.rb +5 -5
- data/lib/descope/api/v1/management/role.rb +5 -5
- data/lib/descope/api/v1/management/scim.rb +14 -14
- data/lib/descope/api/v1/management/scope_claim_mapping.rb +34 -0
- data/lib/descope/api/v1/management/sso_application.rb +7 -7
- data/lib/descope/api/v1/management/sso_settings.rb +5 -5
- data/lib/descope/api/v1/management/tenant.rb +8 -6
- data/lib/descope/api/v1/management/third_party_application.rb +190 -0
- data/lib/descope/api/v1/management/user.rb +36 -36
- data/lib/descope/api/v1/management.rb +22 -0
- data/lib/descope/http_client.rb +30 -0
- data/lib/descope/mixins/common.rb +1 -0
- data/lib/descope/mixins/http.rb +25 -18
- data/lib/descope/mixins/initializer.rb +23 -11
- data/lib/descope/mixins/requests.rb +24 -0
- data/lib/descope/mixins.rb +2 -1
- data/lib/descope/version.rb +1 -1
- data/spec/integration/lib.descope/api/v1/auth/enchantedlink_spec.rb +19 -21
- data/spec/integration/lib.descope/api/v1/auth/magiclink_spec.rb +5 -1
- data/spec/integration/lib.descope/api/v1/auth/otp_spec.rb +5 -1
- data/spec/integration/lib.descope/api/v1/auth/session_spec.rb +24 -5
- data/spec/integration/lib.descope/api/v1/auth/totp_spec.rb +5 -1
- data/spec/integration/lib.descope/api/v1/management/access_key_spec.rb +10 -2
- data/spec/integration/lib.descope/api/v1/management/authz_spec.rb +26 -5
- data/spec/integration/lib.descope/api/v1/management/permissions_spec.rb +20 -2
- data/spec/integration/lib.descope/api/v1/management/project_spec.rb +16 -2
- data/spec/integration/lib.descope/api/v1/management/roles_spec.rb +114 -36
- data/spec/integration/lib.descope/api/v1/management/user_spec.rb +21 -4
- data/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb +163 -1
- data/spec/lib.descope/api/v1/management/access_key_spec.rb +7 -7
- data/spec/lib.descope/api/v1/management/analytics_spec.rb +82 -0
- data/spec/lib.descope/api/v1/management/audit_spec.rb +2 -2
- data/spec/lib.descope/api/v1/management/authz_spec.rb +16 -16
- data/spec/lib.descope/api/v1/management/descoper_spec.rb +101 -0
- data/spec/lib.descope/api/v1/management/engine_spec.rb +115 -0
- data/spec/lib.descope/api/v1/management/fga_spec.rb +169 -0
- data/spec/lib.descope/api/v1/management/flow_spec.rb +5 -5
- data/spec/lib.descope/api/v1/management/group_spec.rb +72 -0
- data/spec/lib.descope/api/v1/management/jwt_template_spec.rb +103 -0
- data/spec/lib.descope/api/v1/management/lists_spec.rb +285 -0
- data/spec/lib.descope/api/v1/management/management_key_spec.rb +109 -0
- data/spec/lib.descope/api/v1/management/outbound_app_spec.rb +236 -0
- data/spec/lib.descope/api/v1/management/password_spec.rb +2 -2
- data/spec/lib.descope/api/v1/management/permission_spec.rb +4 -4
- data/spec/lib.descope/api/v1/management/project_spec.rb +4 -4
- data/spec/lib.descope/api/v1/management/role_spec.rb +5 -5
- data/spec/lib.descope/api/v1/management/scim_spec.rb +14 -14
- data/spec/lib.descope/api/v1/management/scope_claim_mapping_spec.rb +59 -0
- data/spec/lib.descope/api/v1/management/sso_application_spec.rb +6 -6
- data/spec/lib.descope/api/v1/management/sso_settings_spec.rb +5 -5
- data/spec/lib.descope/api/v1/management/tenant_spec.rb +6 -6
- data/spec/lib.descope/api/v1/management/third_party_application_spec.rb +171 -0
- data/spec/lib.descope/api/v1/management/user_spec.rb +36 -36
- data/spec/lib.descope/auth_management_key_spec.rb +151 -0
- data/spec/lib.descope/mixins/http_spec.rb +17 -6
- data/spec/support/client_config.rb +1 -0
- data/spec/support/dummy_class.rb +12 -9
- data/spec/support/utils.rb +15 -0
- metadata +29 -3
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Descope
|
|
4
|
+
module Api
|
|
5
|
+
module V1
|
|
6
|
+
module Management
|
|
7
|
+
# Management API calls for third party applications
|
|
8
|
+
module ThirdPartyApplication
|
|
9
|
+
include Descope::Api::V1::Management::Common
|
|
10
|
+
|
|
11
|
+
def create_application(
|
|
12
|
+
name: nil,
|
|
13
|
+
id: nil,
|
|
14
|
+
description: nil,
|
|
15
|
+
logo: nil,
|
|
16
|
+
login_page_url: nil,
|
|
17
|
+
approved_callback_urls: nil,
|
|
18
|
+
permissions_scopes: nil,
|
|
19
|
+
attributes_scopes: nil,
|
|
20
|
+
jwt_bearer_settings: nil,
|
|
21
|
+
custom_attributes: nil,
|
|
22
|
+
force_pkce: nil,
|
|
23
|
+
default_audience: nil
|
|
24
|
+
)
|
|
25
|
+
# Create a new third party application with the given name. Application IDs are provisioned automatically,
|
|
26
|
+
# but can be provided explicitly if needed. Both the name and ID must be unique per project.
|
|
27
|
+
body = compose_create_update_body(
|
|
28
|
+
name:,
|
|
29
|
+
id:,
|
|
30
|
+
description:,
|
|
31
|
+
logo:,
|
|
32
|
+
login_page_url:,
|
|
33
|
+
approved_callback_urls:,
|
|
34
|
+
permissions_scopes:,
|
|
35
|
+
attributes_scopes:,
|
|
36
|
+
jwt_bearer_settings:,
|
|
37
|
+
custom_attributes:,
|
|
38
|
+
force_pkce:,
|
|
39
|
+
default_audience:
|
|
40
|
+
)
|
|
41
|
+
mgmt_post(THIRD_PARTY_APP_CREATE_PATH, body)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def update_application(
|
|
45
|
+
id: nil,
|
|
46
|
+
name: nil,
|
|
47
|
+
description: nil,
|
|
48
|
+
logo: nil,
|
|
49
|
+
login_page_url: nil,
|
|
50
|
+
approved_callback_urls: nil,
|
|
51
|
+
permissions_scopes: nil,
|
|
52
|
+
attributes_scopes: nil,
|
|
53
|
+
jwt_bearer_settings: nil,
|
|
54
|
+
custom_attributes: nil,
|
|
55
|
+
force_pkce: nil,
|
|
56
|
+
default_audience: nil
|
|
57
|
+
)
|
|
58
|
+
# Update an existing third party application with the given parameters. IMPORTANT: All parameters are used as
|
|
59
|
+
# overrides to the existing application. Empty fields will override populated fields. Use carefully.
|
|
60
|
+
body = compose_create_update_body(
|
|
61
|
+
name:,
|
|
62
|
+
id:,
|
|
63
|
+
description:,
|
|
64
|
+
logo:,
|
|
65
|
+
login_page_url:,
|
|
66
|
+
approved_callback_urls:,
|
|
67
|
+
permissions_scopes:,
|
|
68
|
+
attributes_scopes:,
|
|
69
|
+
jwt_bearer_settings:,
|
|
70
|
+
custom_attributes:,
|
|
71
|
+
force_pkce:,
|
|
72
|
+
default_audience:
|
|
73
|
+
)
|
|
74
|
+
mgmt_post(THIRD_PARTY_APP_UPDATE_PATH, body)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def patch_application(
|
|
78
|
+
id: nil,
|
|
79
|
+
name: nil,
|
|
80
|
+
description: nil,
|
|
81
|
+
logo: nil,
|
|
82
|
+
login_page_url: nil,
|
|
83
|
+
approved_callback_urls: nil,
|
|
84
|
+
permissions_scopes: nil,
|
|
85
|
+
attributes_scopes: nil,
|
|
86
|
+
jwt_bearer_settings: nil,
|
|
87
|
+
custom_attributes: nil,
|
|
88
|
+
force_pkce: nil,
|
|
89
|
+
default_audience: nil
|
|
90
|
+
)
|
|
91
|
+
# Patch an existing third party application. Only the provided fields will be updated.
|
|
92
|
+
body = compose_create_update_body(
|
|
93
|
+
name:,
|
|
94
|
+
id:,
|
|
95
|
+
description:,
|
|
96
|
+
logo:,
|
|
97
|
+
login_page_url:,
|
|
98
|
+
approved_callback_urls:,
|
|
99
|
+
permissions_scopes:,
|
|
100
|
+
attributes_scopes:,
|
|
101
|
+
jwt_bearer_settings:,
|
|
102
|
+
custom_attributes:,
|
|
103
|
+
force_pkce:,
|
|
104
|
+
default_audience:
|
|
105
|
+
)
|
|
106
|
+
mgmt_post(THIRD_PARTY_APP_PATCH_PATH, body)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def delete_application(id)
|
|
110
|
+
# Delete an existing third party application. IMPORTANT: This operation is irreversible. Use carefully.
|
|
111
|
+
mgmt_post(THIRD_PARTY_APP_DELETE_PATH, { id: })
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def load_application(id)
|
|
115
|
+
# Load an existing third party application.
|
|
116
|
+
mgmt_get(THIRD_PARTY_APP_LOAD_PATH, { id: })
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def load_all_applications
|
|
120
|
+
# Load all third party applications.
|
|
121
|
+
mgmt_get(THIRD_PARTY_APP_LOAD_ALL_PATH, {})
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def get_application_secret(id)
|
|
125
|
+
# Get the cleartext secret of an existing third party application.
|
|
126
|
+
mgmt_get(THIRD_PARTY_APP_SECRET_PATH, { id: })
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def rotate_application_secret(id)
|
|
130
|
+
# Rotate the secret of an existing third party application, returning the new cleartext secret.
|
|
131
|
+
mgmt_post(THIRD_PARTY_APP_ROTATE_PATH, { id: })
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def delete_consents(app_id: nil, consent_ids: nil, user_ids: nil, tenant_id: nil)
|
|
135
|
+
# Delete consents of a third party application.
|
|
136
|
+
body = {}
|
|
137
|
+
body[:consentIds] = consent_ids if consent_ids
|
|
138
|
+
body[:appId] = app_id if app_id
|
|
139
|
+
body[:userIds] = user_ids if user_ids
|
|
140
|
+
body[:tenantId] = tenant_id if tenant_id
|
|
141
|
+
mgmt_post(THIRD_PARTY_APP_DELETE_CONSENTS_PATH, body)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def delete_tenant_consents(app_id: nil, consent_ids: nil, tenant_id: nil)
|
|
145
|
+
# Delete consents of a third party application for a specific tenant.
|
|
146
|
+
body = {}
|
|
147
|
+
body[:consentIds] = consent_ids if consent_ids
|
|
148
|
+
body[:appId] = app_id if app_id
|
|
149
|
+
body[:tenantId] = tenant_id if tenant_id
|
|
150
|
+
mgmt_post(THIRD_PARTY_APP_DELETE_TENANT_CONSENTS_PATH, body)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
private
|
|
154
|
+
|
|
155
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
156
|
+
def compose_create_update_body(
|
|
157
|
+
name: nil,
|
|
158
|
+
id: nil,
|
|
159
|
+
description: nil,
|
|
160
|
+
logo: nil,
|
|
161
|
+
login_page_url: nil,
|
|
162
|
+
approved_callback_urls: nil,
|
|
163
|
+
permissions_scopes: nil,
|
|
164
|
+
attributes_scopes: nil,
|
|
165
|
+
jwt_bearer_settings: nil,
|
|
166
|
+
custom_attributes: nil,
|
|
167
|
+
force_pkce: nil,
|
|
168
|
+
default_audience: nil
|
|
169
|
+
)
|
|
170
|
+
body = {}
|
|
171
|
+
body[:id] = id if id
|
|
172
|
+
body[:name] = name if name
|
|
173
|
+
body[:description] = description if description
|
|
174
|
+
body[:logo] = logo if logo
|
|
175
|
+
body[:loginPageUrl] = login_page_url if login_page_url
|
|
176
|
+
body[:approvedCallbackUrls] = approved_callback_urls if approved_callback_urls
|
|
177
|
+
body[:permissionsScopes] = permissions_scopes if permissions_scopes
|
|
178
|
+
body[:attributesScopes] = attributes_scopes if attributes_scopes
|
|
179
|
+
body[:jwtBearerSettings] = jwt_bearer_settings if jwt_bearer_settings
|
|
180
|
+
body[:customAttributes] = custom_attributes if custom_attributes
|
|
181
|
+
body[:forcePkce] = force_pkce unless force_pkce.nil?
|
|
182
|
+
body[:defaultAudience] = default_audience if default_audience
|
|
183
|
+
body
|
|
184
|
+
end
|
|
185
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -27,7 +27,7 @@ module Descope
|
|
|
27
27
|
request_params = {
|
|
28
28
|
users: users_params
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
mgmt_post(path, request_params)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# Create a new test user.
|
|
@@ -102,7 +102,7 @@ module Descope
|
|
|
102
102
|
hashed_password:,
|
|
103
103
|
sso_app_ids:
|
|
104
104
|
)
|
|
105
|
-
|
|
105
|
+
mgmt_post(path, request_params)
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
# Delete a user, using a valid management key.
|
|
@@ -113,12 +113,12 @@ module Descope
|
|
|
113
113
|
request_params = {
|
|
114
114
|
loginId: login_id
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
mgmt_post(path, request_params)
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
def delete_all_test_users
|
|
120
120
|
path = Common::USER_DELETE_ALL_TEST_USERS_PATH
|
|
121
|
-
|
|
121
|
+
mgmt_delete(path)
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
# Load a user's data, using a valid management key.
|
|
@@ -132,7 +132,7 @@ module Descope
|
|
|
132
132
|
loginId: login_id
|
|
133
133
|
}
|
|
134
134
|
path = Common::USER_LOAD_PATH
|
|
135
|
-
|
|
135
|
+
mgmt_get(path, request_params)
|
|
136
136
|
end
|
|
137
137
|
|
|
138
138
|
# Load a user's data, using a valid management key by user id.
|
|
@@ -146,7 +146,7 @@ module Descope
|
|
|
146
146
|
request_params = {
|
|
147
147
|
userId: user_id
|
|
148
148
|
}
|
|
149
|
-
|
|
149
|
+
mgmt_get(path, request_params)
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
# Log a user out of all sessions, using a valid management key.
|
|
@@ -157,7 +157,7 @@ module Descope
|
|
|
157
157
|
request_params = {
|
|
158
158
|
loginId: login_id
|
|
159
159
|
}
|
|
160
|
-
|
|
160
|
+
mgmt_post(path, request_params)
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
def logout_user_by_id(user_id)
|
|
@@ -166,7 +166,7 @@ module Descope
|
|
|
166
166
|
request_params = {
|
|
167
167
|
userId: user_id
|
|
168
168
|
}
|
|
169
|
-
|
|
169
|
+
mgmt_post(path, request_params)
|
|
170
170
|
end
|
|
171
171
|
|
|
172
172
|
# Search for users, using a valid management key.
|
|
@@ -216,7 +216,7 @@ module Descope
|
|
|
216
216
|
body[:roleNames] = role_names unless role_names.empty?
|
|
217
217
|
body[:tenantRoleIds] = map_to_values_object(tenant_role_ids) unless tenant_role_ids.nil? || tenant_role_ids.empty?
|
|
218
218
|
body[:tenantRoleNames] = map_to_values_object(tenant_role_names) unless tenant_role_names.nil? || tenant_role_names.empty?
|
|
219
|
-
|
|
219
|
+
mgmt_post(Common::USERS_SEARCH_PATH, body)
|
|
220
220
|
end
|
|
221
221
|
|
|
222
222
|
def map_to_values_object(input_map)
|
|
@@ -234,7 +234,7 @@ module Descope
|
|
|
234
234
|
loginId: login_id,
|
|
235
235
|
provider: provider
|
|
236
236
|
}
|
|
237
|
-
|
|
237
|
+
mgmt_get(path, request_params)
|
|
238
238
|
end
|
|
239
239
|
|
|
240
240
|
# Updates an existing user's status, using a valid management key.
|
|
@@ -246,7 +246,7 @@ module Descope
|
|
|
246
246
|
loginId: login_id,
|
|
247
247
|
status: 'enabled'
|
|
248
248
|
}
|
|
249
|
-
|
|
249
|
+
mgmt_post(path, request_params)
|
|
250
250
|
end
|
|
251
251
|
|
|
252
252
|
def deactivate(login_id)
|
|
@@ -256,7 +256,7 @@ module Descope
|
|
|
256
256
|
loginId: login_id,
|
|
257
257
|
status: 'disabled'
|
|
258
258
|
}
|
|
259
|
-
|
|
259
|
+
mgmt_post(path, request_params)
|
|
260
260
|
end
|
|
261
261
|
|
|
262
262
|
# Updates an existing user's login ID, using a valid management key.
|
|
@@ -268,7 +268,7 @@ module Descope
|
|
|
268
268
|
loginId: login_id,
|
|
269
269
|
newLoginId: new_login_id
|
|
270
270
|
}
|
|
271
|
-
|
|
271
|
+
mgmt_post(path, request_params)
|
|
272
272
|
end
|
|
273
273
|
|
|
274
274
|
# Updates an existing user's email, using a valid management key.
|
|
@@ -281,7 +281,7 @@ module Descope
|
|
|
281
281
|
email:,
|
|
282
282
|
verified:
|
|
283
283
|
}
|
|
284
|
-
|
|
284
|
+
mgmt_post(path, request_params)
|
|
285
285
|
end
|
|
286
286
|
|
|
287
287
|
# Updates an existing user's phone number, using a valid management key.
|
|
@@ -293,7 +293,7 @@ module Descope
|
|
|
293
293
|
phone:,
|
|
294
294
|
verified:
|
|
295
295
|
}
|
|
296
|
-
|
|
296
|
+
mgmt_post(path, request_params)
|
|
297
297
|
end
|
|
298
298
|
|
|
299
299
|
# Updates an existing user's display name, using a valid management key.
|
|
@@ -310,7 +310,7 @@ module Descope
|
|
|
310
310
|
body[:givenName] = given_name unless given_name.nil?
|
|
311
311
|
body[:middleName] = middle_name unless middle_name.nil?
|
|
312
312
|
body[:familyName] = family_name unless family_name.nil?
|
|
313
|
-
|
|
313
|
+
mgmt_post(Common::USER_UPDATE_NAME_PATH, body)
|
|
314
314
|
end
|
|
315
315
|
|
|
316
316
|
# Update an existing user's profile picture, using a valid management key.
|
|
@@ -320,7 +320,7 @@ module Descope
|
|
|
320
320
|
loginId: login_id,
|
|
321
321
|
picture: picture
|
|
322
322
|
}
|
|
323
|
-
|
|
323
|
+
mgmt_post(Common::USER_UPDATE_PICTURE_PATH, body)
|
|
324
324
|
end
|
|
325
325
|
|
|
326
326
|
# Update an existing user's custom attributes, using a valid management key.
|
|
@@ -332,7 +332,7 @@ module Descope
|
|
|
332
332
|
attributeKey: attribute_key,
|
|
333
333
|
attributeValue: attribute_value
|
|
334
334
|
}
|
|
335
|
-
|
|
335
|
+
mgmt_post(Common::USER_UPDATE_CUSTOM_ATTRIBUTE_PATH, body)
|
|
336
336
|
end
|
|
337
337
|
|
|
338
338
|
def patch_user(
|
|
@@ -377,7 +377,7 @@ module Descope
|
|
|
377
377
|
hashed_password:,
|
|
378
378
|
sso_app_ids:
|
|
379
379
|
)
|
|
380
|
-
|
|
380
|
+
mgmt_patch(path, request_params)
|
|
381
381
|
end
|
|
382
382
|
|
|
383
383
|
def update_jwt(jwt: nil, custom_claims: nil)
|
|
@@ -385,7 +385,7 @@ module Descope
|
|
|
385
385
|
jwt:,
|
|
386
386
|
customClaims: custom_claims,
|
|
387
387
|
}
|
|
388
|
-
|
|
388
|
+
mgmt_post(Common::UPDATE_JWT_PATH, body)
|
|
389
389
|
end
|
|
390
390
|
|
|
391
391
|
#
|
|
@@ -395,7 +395,7 @@ module Descope
|
|
|
395
395
|
roleNames: role_names,
|
|
396
396
|
tenantId: tenant_id
|
|
397
397
|
}
|
|
398
|
-
|
|
398
|
+
mgmt_post(Common::USER_ADD_ROLE_PATH, body)
|
|
399
399
|
end
|
|
400
400
|
|
|
401
401
|
def user_remove_roles(login_id: nil, tenant_id:nil, role_names: [])
|
|
@@ -404,7 +404,7 @@ module Descope
|
|
|
404
404
|
roleNames: role_names,
|
|
405
405
|
tenantId: tenant_id
|
|
406
406
|
}
|
|
407
|
-
|
|
407
|
+
mgmt_post(Common::USER_REMOVE_ROLE_PATH, body)
|
|
408
408
|
end
|
|
409
409
|
|
|
410
410
|
def user_add_tenant(login_id: nil, tenant_id: nil)
|
|
@@ -412,7 +412,7 @@ module Descope
|
|
|
412
412
|
loginId: login_id,
|
|
413
413
|
tenantId: tenant_id
|
|
414
414
|
}
|
|
415
|
-
|
|
415
|
+
mgmt_post(Common::USER_ADD_TENANT_PATH, body)
|
|
416
416
|
end
|
|
417
417
|
|
|
418
418
|
def user_remove_tenant(login_id: nil, tenant_id: nil)
|
|
@@ -420,7 +420,7 @@ module Descope
|
|
|
420
420
|
loginId: login_id,
|
|
421
421
|
tenantId: tenant_id
|
|
422
422
|
}
|
|
423
|
-
|
|
423
|
+
mgmt_post(Common::USER_REMOVE_TENANT_PATH, body)
|
|
424
424
|
end
|
|
425
425
|
|
|
426
426
|
def add_tenant_role(login_id: nil, tenant_id: nil, role_names: [])
|
|
@@ -429,7 +429,7 @@ module Descope
|
|
|
429
429
|
tenantId: tenant_id,
|
|
430
430
|
roleNames: role_names
|
|
431
431
|
}
|
|
432
|
-
|
|
432
|
+
mgmt_post(Common::USER_ADD_TENANT_PATH, body)
|
|
433
433
|
end
|
|
434
434
|
|
|
435
435
|
def user_remove_tenant_roles(login_id: nil, tenant_id: nil, role_names: [])
|
|
@@ -438,7 +438,7 @@ module Descope
|
|
|
438
438
|
tenantId: tenant_id,
|
|
439
439
|
roleNames: role_names
|
|
440
440
|
}
|
|
441
|
-
|
|
441
|
+
mgmt_post(Common::USER_REMOVE_TENANT_PATH, body)
|
|
442
442
|
end
|
|
443
443
|
|
|
444
444
|
def set_temporary_password(login_id: nil, password: nil)
|
|
@@ -446,7 +446,7 @@ module Descope
|
|
|
446
446
|
loginId: login_id,
|
|
447
447
|
password:
|
|
448
448
|
}
|
|
449
|
-
|
|
449
|
+
mgmt_post(Common::USER_SET_TEMPORARY_PASSWORD_PATH, body)
|
|
450
450
|
end
|
|
451
451
|
|
|
452
452
|
def set_active_password(login_id: nil, password: nil)
|
|
@@ -454,7 +454,7 @@ module Descope
|
|
|
454
454
|
loginId: login_id,
|
|
455
455
|
password:
|
|
456
456
|
}
|
|
457
|
-
|
|
457
|
+
mgmt_post(Common::USER_SET_ACTIVE_PASSWORD_PATH, body)
|
|
458
458
|
end
|
|
459
459
|
|
|
460
460
|
# Deprecated (use set_temporary_password(..) instead)
|
|
@@ -463,7 +463,7 @@ module Descope
|
|
|
463
463
|
loginId: login_id,
|
|
464
464
|
password:
|
|
465
465
|
}
|
|
466
|
-
|
|
466
|
+
mgmt_post(Common::USER_SET_PASSWORD_PATH, body)
|
|
467
467
|
end
|
|
468
468
|
|
|
469
469
|
def expire_password(login_id)
|
|
@@ -471,7 +471,7 @@ module Descope
|
|
|
471
471
|
body = {
|
|
472
472
|
loginId: login_id
|
|
473
473
|
}
|
|
474
|
-
|
|
474
|
+
mgmt_post(Common::USER_EXPIRE_PASSWORD_PATH, body)
|
|
475
475
|
end
|
|
476
476
|
|
|
477
477
|
def generate_otp_for_test_user(method: nil, login_id: nil)
|
|
@@ -479,7 +479,7 @@ module Descope
|
|
|
479
479
|
loginId: login_id,
|
|
480
480
|
deliveryMethod: get_method_string(method)
|
|
481
481
|
}
|
|
482
|
-
|
|
482
|
+
mgmt_post(Common::USER_GENERATE_OTP_FOR_TEST_PATH, body)
|
|
483
483
|
end
|
|
484
484
|
|
|
485
485
|
def generate_magic_link_for_test_user(method: nil, login_id: nil, uri: nil)
|
|
@@ -488,7 +488,7 @@ module Descope
|
|
|
488
488
|
deliveryMethod: get_method_string(method),
|
|
489
489
|
URI: uri
|
|
490
490
|
}
|
|
491
|
-
|
|
491
|
+
mgmt_post(Common::USER_GENERATE_MAGIC_LINK_FOR_TEST_PATH, body)
|
|
492
492
|
end
|
|
493
493
|
|
|
494
494
|
def generate_enchanted_link_for_test_user(login_id: nil, uri: nil)
|
|
@@ -496,7 +496,7 @@ module Descope
|
|
|
496
496
|
loginId: login_id,
|
|
497
497
|
URI: uri
|
|
498
498
|
}
|
|
499
|
-
|
|
499
|
+
mgmt_post(Common::USER_GENERATE_ENCHANTED_LINK_FOR_TEST_PATH, body)
|
|
500
500
|
end
|
|
501
501
|
|
|
502
502
|
def generate_embedded_link(login_id: nil, custom_claims: nil)
|
|
@@ -513,7 +513,7 @@ module Descope
|
|
|
513
513
|
loginId: login_id,
|
|
514
514
|
customClaims: custom_claims.to_h
|
|
515
515
|
}
|
|
516
|
-
|
|
516
|
+
mgmt_post(USER_GENERATE_EMBEDDED_LINK_PATH, request_params)
|
|
517
517
|
end
|
|
518
518
|
|
|
519
519
|
# Search for all test users.
|
|
@@ -582,7 +582,7 @@ module Descope
|
|
|
582
582
|
body[:tenantRoleIds] = map_to_values_object(tenant_role_ids) unless tenant_role_ids.nil? || tenant_role_ids.empty?
|
|
583
583
|
body[:tenantRoleNames] = map_to_values_object(tenant_role_names) unless tenant_role_names.nil? || tenant_role_names.empty?
|
|
584
584
|
|
|
585
|
-
|
|
585
|
+
mgmt_post(Common::TEST_USERS_SEARCH_PATH, body)
|
|
586
586
|
end
|
|
587
587
|
|
|
588
588
|
|
|
@@ -647,7 +647,7 @@ module Descope
|
|
|
647
647
|
)
|
|
648
648
|
return request_params if skip_create
|
|
649
649
|
|
|
650
|
-
|
|
650
|
+
mgmt_post(path, request_params)
|
|
651
651
|
end
|
|
652
652
|
|
|
653
653
|
def user_compose_create_body(
|
|
@@ -14,6 +14,17 @@ require 'descope/api/v1/management/sso_application'
|
|
|
14
14
|
require 'descope/api/v1/management/sso_settings'
|
|
15
15
|
require 'descope/api/v1/management/scim'
|
|
16
16
|
require 'descope/api/v1/management/password'
|
|
17
|
+
require 'descope/api/v1/management/outbound_app'
|
|
18
|
+
require 'descope/api/v1/management/group'
|
|
19
|
+
require 'descope/api/v1/management/fga'
|
|
20
|
+
require 'descope/api/v1/management/third_party_application'
|
|
21
|
+
require 'descope/api/v1/management/management_key'
|
|
22
|
+
require 'descope/api/v1/management/analytics'
|
|
23
|
+
require 'descope/api/v1/management/descoper'
|
|
24
|
+
require 'descope/api/v1/management/engine'
|
|
25
|
+
require 'descope/api/v1/management/lists'
|
|
26
|
+
require 'descope/api/v1/management/jwt_template'
|
|
27
|
+
require 'descope/api/v1/management/scope_claim_mapping'
|
|
17
28
|
|
|
18
29
|
module Descope
|
|
19
30
|
module Api
|
|
@@ -34,6 +45,17 @@ module Descope
|
|
|
34
45
|
include Descope::Api::V1::Management::SSOSettings
|
|
35
46
|
include Descope::Api::V1::Management::SCIM
|
|
36
47
|
include Descope::Api::V1::Management::Password
|
|
48
|
+
include Descope::Api::V1::Management::OutboundApp
|
|
49
|
+
include Descope::Api::V1::Management::Group
|
|
50
|
+
include Descope::Api::V1::Management::FGA
|
|
51
|
+
include Descope::Api::V1::Management::ThirdPartyApplication
|
|
52
|
+
include Descope::Api::V1::Management::ManagementKey
|
|
53
|
+
include Descope::Api::V1::Management::Analytics
|
|
54
|
+
include Descope::Api::V1::Management::Descoper
|
|
55
|
+
include Descope::Api::V1::Management::Engine
|
|
56
|
+
include Descope::Api::V1::Management::Lists
|
|
57
|
+
include Descope::Api::V1::Management::JWTTemplate
|
|
58
|
+
include Descope::Api::V1::Management::ScopeClaimMapping
|
|
37
59
|
end
|
|
38
60
|
end
|
|
39
61
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'descope/mixins/http'
|
|
4
|
+
|
|
5
|
+
module Descope
|
|
6
|
+
# Performs the SDK's HTTP calls. One instance is created per kind of request so that the two
|
|
7
|
+
# management keys are never sent together: the management client carries the management key, the
|
|
8
|
+
# authentication client carries the auth management key.
|
|
9
|
+
class HttpClient
|
|
10
|
+
include Descope::Mixins::HTTP
|
|
11
|
+
|
|
12
|
+
def initialize(base_uri:, project_id:, headers:, logger:, key: nil, timeout: nil, retry_count: nil)
|
|
13
|
+
@base_uri = base_uri
|
|
14
|
+
@project_id = project_id
|
|
15
|
+
@key = key
|
|
16
|
+
@headers = headers.dup
|
|
17
|
+
@logger = logger
|
|
18
|
+
@timeout = timeout
|
|
19
|
+
@retry_count = retry_count
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Bearer <project_id>[:<pswd>][:<key>] where pswd is a refresh token or access key presented by
|
|
23
|
+
# the caller and key is this client's management key. Blank parts are skipped, so callers do
|
|
24
|
+
# not have to branch on what happens to be configured.
|
|
25
|
+
def authorization_header(pswd = nil)
|
|
26
|
+
bearer = [@project_id, pswd, @key].reject { |part| part.nil? || part.to_s.empty? }.join(':')
|
|
27
|
+
{ 'Authorization' => "Bearer #{bearer}" }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -81,6 +81,7 @@ module Descope
|
|
|
81
81
|
VERIFY_ENCHANTEDLINK_AUTH_PATH = '/v1/auth/enchantedlink/verify'
|
|
82
82
|
GET_SESSION_ENCHANTEDLINK_AUTH_PATH = '/v1/auth/enchantedlink/pending-session'
|
|
83
83
|
UPDATE_USER_EMAIL_ENCHANTEDLINK_PATH = '/v1/auth/enchantedlink/update/email'
|
|
84
|
+
UPDATE_USER_PHONE_ENCHANTEDLINK_PATH = '/v1/auth/enchantedlink/update/phone'
|
|
84
85
|
|
|
85
86
|
# oauth
|
|
86
87
|
OAUTH_START_PATH = '/v1/auth/oauth/authorize'
|
data/lib/descope/mixins/http.rb
CHANGED
|
@@ -18,13 +18,18 @@ module Descope
|
|
|
18
18
|
MIN_REQUEST_RETRY_DELAY = 250
|
|
19
19
|
BASE_DELAY = 100
|
|
20
20
|
|
|
21
|
-
%i[get post
|
|
21
|
+
HTTP_METHODS = %i[get post put patch delete].freeze
|
|
22
|
+
|
|
23
|
+
HTTP_METHODS.each do |method|
|
|
22
24
|
define_method(method) do |uri, body = {}, extra_headers = {}, pswd = nil|
|
|
23
25
|
body = body.delete_if { |_, v| v.nil? }
|
|
24
|
-
|
|
26
|
+
|
|
27
|
+
# The Authorization header travels with the request rather than being merged into the
|
|
28
|
+
# shared @headers, so concurrent requests cannot send each other's credentials.
|
|
29
|
+
headers = authorization_header(pswd).merge(extra_headers || {})
|
|
25
30
|
|
|
26
31
|
@logger.debug "request => method: #{method}, uri: #{uri}, body: #{body}, extra_headers: #{extra_headers}}"
|
|
27
|
-
request_with_retry(method, uri, body,
|
|
32
|
+
request_with_retry(method, uri, body, headers)
|
|
28
33
|
end
|
|
29
34
|
end
|
|
30
35
|
|
|
@@ -63,9 +68,9 @@ module Descope
|
|
|
63
68
|
# If no cookies found via RestClient, parse Set-Cookie headers directly
|
|
64
69
|
# This handles custom domain cookies that RestClient filters out
|
|
65
70
|
if extracted_cookies.empty? && headers.respond_to?(:[])
|
|
66
|
-
set_cookie_headers = headers['set-cookie'] || headers['Set-Cookie'] || []
|
|
71
|
+
set_cookie_headers = headers[:set_cookie] || headers['set-cookie'] || headers['Set-Cookie'] || []
|
|
67
72
|
set_cookie_headers = [set_cookie_headers] unless set_cookie_headers.is_a?(Array)
|
|
68
|
-
|
|
73
|
+
|
|
69
74
|
set_cookie_headers.each do |cookie_header|
|
|
70
75
|
next unless cookie_header.is_a?(String)
|
|
71
76
|
|
|
@@ -118,6 +123,15 @@ module Descope
|
|
|
118
123
|
@headers.merge!(h.to_hash)
|
|
119
124
|
end
|
|
120
125
|
|
|
126
|
+
# Everything after the project ID in the bearer is either a token or a management key, so
|
|
127
|
+
# none of it belongs in a log line.
|
|
128
|
+
def mask_authorization(headers)
|
|
129
|
+
authorization = headers['Authorization']
|
|
130
|
+
return headers if authorization.nil?
|
|
131
|
+
|
|
132
|
+
headers.merge('Authorization' => authorization.sub(/\A(Bearer [^:]*):.*\z/, '\1:***'))
|
|
133
|
+
end
|
|
134
|
+
|
|
121
135
|
def request_with_retry(method, uri, body = {}, extra_headers = {}, pswd = nil)
|
|
122
136
|
Retryable.retryable(retry_options) do
|
|
123
137
|
request(method, uri, body, extra_headers)
|
|
@@ -125,23 +139,16 @@ module Descope
|
|
|
125
139
|
end
|
|
126
140
|
|
|
127
141
|
def request(method, uri, body = {}, extra_headers = {})
|
|
128
|
-
|
|
129
|
-
headers_debug = @headers.dup
|
|
130
|
-
if headers_debug['Authorization']
|
|
131
|
-
headers_debug['Authorization'] = headers_debug['Authorization'].gsub(/(.{10})\z/, '***********')
|
|
132
|
-
end
|
|
142
|
+
request_headers = @headers.merge(extra_headers)
|
|
133
143
|
|
|
134
144
|
@logger.debug "base url: #{@base_uri}"
|
|
135
|
-
@logger.debug "request method: #{method}, uri: #{uri}, body: #{body},
|
|
145
|
+
@logger.debug "request method: #{method}, uri: #{uri}, body: #{body}, " \
|
|
146
|
+
"headers: #{mask_authorization(request_headers)}"
|
|
136
147
|
result = case method
|
|
137
|
-
when :get
|
|
138
|
-
|
|
139
|
-
call(:get, encode_uri(uri), timeout, get_headers)
|
|
140
|
-
when :delete
|
|
141
|
-
delete_headers = @headers.merge({ params: body })
|
|
142
|
-
call(:delete, encode_uri(uri), timeout, delete_headers)
|
|
148
|
+
when :get, :delete
|
|
149
|
+
call(method, encode_uri(uri), timeout, request_headers.merge({ params: body }))
|
|
143
150
|
else
|
|
144
|
-
call(method, encode_uri(uri), timeout,
|
|
151
|
+
call(method, encode_uri(uri), timeout, request_headers, body.to_json)
|
|
145
152
|
end
|
|
146
153
|
|
|
147
154
|
raise Descope::Unsupported.new('No response from server', code: 400) unless result.respond_to?(:code)
|