descope 1.0.4
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/workflows/ci.yaml +54 -0
- data/.gitignore +59 -0
- data/.release-please-manifest.json +3 -0
- data/.rubocop.yml +10 -0
- data/.rubocop_todo.yml +10 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +90 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +204 -0
- data/LICENSE +21 -0
- data/README.md +1171 -0
- data/Rakefile +31 -0
- data/descope.gemspec +34 -0
- data/examples/ruby/Gemfile +4 -0
- data/examples/ruby/Gemfile.lock +41 -0
- data/examples/ruby/access_key_app.rb +45 -0
- data/examples/ruby/enchantedlink_app.rb +65 -0
- data/examples/ruby/magiclink_app.rb +81 -0
- data/examples/ruby/management/Gemfile +5 -0
- data/examples/ruby/management/Gemfile.lock +38 -0
- data/examples/ruby/management/access_key_app.rb +71 -0
- data/examples/ruby/management/audit_app.rb +25 -0
- data/examples/ruby/management/authz_app.rb +135 -0
- data/examples/ruby/management/authz_files.json +229 -0
- data/examples/ruby/management/flow_app.rb +57 -0
- data/examples/ruby/management/permission_app.rb +56 -0
- data/examples/ruby/management/role_app.rb +58 -0
- data/examples/ruby/management/tenant_app.rb +60 -0
- data/examples/ruby/management/user_app.rb +60 -0
- data/examples/ruby/oauth_app.rb +39 -0
- data/examples/ruby/otp_app.rb +50 -0
- data/examples/ruby/password_app.rb +76 -0
- data/examples/ruby/saml_app.rb +38 -0
- data/examples/ruby-on-rails-api/descope/.dockerignore +37 -0
- data/examples/ruby-on-rails-api/descope/.gitattributes +9 -0
- data/examples/ruby-on-rails-api/descope/.gitignore +40 -0
- data/examples/ruby-on-rails-api/descope/.node-version +1 -0
- data/examples/ruby-on-rails-api/descope/.ruby-version +1 -0
- data/examples/ruby-on-rails-api/descope/Dockerfile +75 -0
- data/examples/ruby-on-rails-api/descope/Gemfile +67 -0
- data/examples/ruby-on-rails-api/descope/Gemfile.lock +284 -0
- data/examples/ruby-on-rails-api/descope/Procfile.dev +3 -0
- data/examples/ruby-on-rails-api/descope/README.md +54 -0
- data/examples/ruby-on-rails-api/descope/Rakefile +6 -0
- data/examples/ruby-on-rails-api/descope/app/assets/builds/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/app/assets/config/manifest.js +3 -0
- data/examples/ruby-on-rails-api/descope/app/assets/images/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/app/assets/images/descope.jpeg +0 -0
- data/examples/ruby-on-rails-api/descope/app/assets/images/favicon.ico +0 -0
- data/examples/ruby-on-rails-api/descope/app/assets/images/logo192.png +0 -0
- data/examples/ruby-on-rails-api/descope/app/assets/images/logo512.png +0 -0
- data/examples/ruby-on-rails-api/descope/app/assets/stylesheets/application.bootstrap.scss +67 -0
- data/examples/ruby-on-rails-api/descope/app/channels/application_cable/channel.rb +4 -0
- data/examples/ruby-on-rails-api/descope/app/channels/application_cable/connection.rb +4 -0
- data/examples/ruby-on-rails-api/descope/app/controllers/application_controller.rb +2 -0
- data/examples/ruby-on-rails-api/descope/app/controllers/concerns/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/app/controllers/homepage_controller.rb +4 -0
- data/examples/ruby-on-rails-api/descope/app/controllers/session_controller.rb +66 -0
- data/examples/ruby-on-rails-api/descope/app/helpers/application_helper.rb +2 -0
- data/examples/ruby-on-rails-api/descope/app/helpers/homepage_helper.rb +2 -0
- data/examples/ruby-on-rails-api/descope/app/helpers/session_helper.rb +2 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/App.css +53 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/application.js +5 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/components/App.jsx +4 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/components/Dashboard.jsx +60 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/components/Home.jsx +27 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/components/Login.jsx +45 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/components/Profile.jsx +81 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/components/index.html +11 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/components/index.jsx +24 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/controllers/application.js +9 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/controllers/index.js +5 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/reportWebVitals.js +13 -0
- data/examples/ruby-on-rails-api/descope/app/javascript/routes/index.jsx +17 -0
- data/examples/ruby-on-rails-api/descope/app/jobs/application_job.rb +7 -0
- data/examples/ruby-on-rails-api/descope/app/mailers/application_mailer.rb +4 -0
- data/examples/ruby-on-rails-api/descope/app/models/application_record.rb +3 -0
- data/examples/ruby-on-rails-api/descope/app/models/concerns/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/app/views/homepage/index.html.erb +2 -0
- data/examples/ruby-on-rails-api/descope/app/views/layouts/application.html.erb +16 -0
- data/examples/ruby-on-rails-api/descope/app/views/layouts/mailer.html.erb +13 -0
- data/examples/ruby-on-rails-api/descope/app/views/layouts/mailer.text.erb +1 -0
- data/examples/ruby-on-rails-api/descope/app/views/session/index.html.erb +2 -0
- data/examples/ruby-on-rails-api/descope/bin/bundle +109 -0
- data/examples/ruby-on-rails-api/descope/bin/dev +11 -0
- data/examples/ruby-on-rails-api/descope/bin/docker-entrypoint +8 -0
- data/examples/ruby-on-rails-api/descope/bin/rails +4 -0
- data/examples/ruby-on-rails-api/descope/bin/rake +4 -0
- data/examples/ruby-on-rails-api/descope/bin/setup +36 -0
- data/examples/ruby-on-rails-api/descope/build.js +30 -0
- data/examples/ruby-on-rails-api/descope/config/application.rb +42 -0
- data/examples/ruby-on-rails-api/descope/config/boot.rb +4 -0
- data/examples/ruby-on-rails-api/descope/config/cable.yml +10 -0
- data/examples/ruby-on-rails-api/descope/config/config.yml +9 -0
- data/examples/ruby-on-rails-api/descope/config/credentials.yml.enc +1 -0
- data/examples/ruby-on-rails-api/descope/config/database.yml +25 -0
- data/examples/ruby-on-rails-api/descope/config/environment.rb +5 -0
- data/examples/ruby-on-rails-api/descope/config/environments/development.rb +76 -0
- data/examples/ruby-on-rails-api/descope/config/environments/production.rb +97 -0
- data/examples/ruby-on-rails-api/descope/config/environments/test.rb +64 -0
- data/examples/ruby-on-rails-api/descope/config/initializers/assets.rb +13 -0
- data/examples/ruby-on-rails-api/descope/config/initializers/content_security_policy.rb +25 -0
- data/examples/ruby-on-rails-api/descope/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/ruby-on-rails-api/descope/config/initializers/inflections.rb +16 -0
- data/examples/ruby-on-rails-api/descope/config/initializers/load_config.rb +12 -0
- data/examples/ruby-on-rails-api/descope/config/initializers/permissions_policy.rb +13 -0
- data/examples/ruby-on-rails-api/descope/config/locales/en.yml +31 -0
- data/examples/ruby-on-rails-api/descope/config/puma.rb +35 -0
- data/examples/ruby-on-rails-api/descope/config/routes.rb +18 -0
- data/examples/ruby-on-rails-api/descope/config/storage.yml +34 -0
- data/examples/ruby-on-rails-api/descope/config.ru +6 -0
- data/examples/ruby-on-rails-api/descope/db/seeds.rb +9 -0
- data/examples/ruby-on-rails-api/descope/lib/assets/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/lib/tasks/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/log/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/package-lock.json +19680 -0
- data/examples/ruby-on-rails-api/descope/package.json +51 -0
- data/examples/ruby-on-rails-api/descope/public/404.html +67 -0
- data/examples/ruby-on-rails-api/descope/public/422.html +67 -0
- data/examples/ruby-on-rails-api/descope/public/500.html +66 -0
- data/examples/ruby-on-rails-api/descope/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/ruby-on-rails-api/descope/public/apple-touch-icon.png +0 -0
- data/examples/ruby-on-rails-api/descope/public/favicon.ico +0 -0
- data/examples/ruby-on-rails-api/descope/public/robots.txt +1 -0
- data/examples/ruby-on-rails-api/descope/storage/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/tmp/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/tmp/pids/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/tmp/storage/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/vendor/.keep +0 -0
- data/examples/ruby-on-rails-api/descope/yarn.lock +10780 -0
- data/lib/descope/api/v1/auth/enchantedlink.rb +156 -0
- data/lib/descope/api/v1/auth/magiclink.rb +170 -0
- data/lib/descope/api/v1/auth/oauth.rb +72 -0
- data/lib/descope/api/v1/auth/otp.rb +186 -0
- data/lib/descope/api/v1/auth/password.rb +100 -0
- data/lib/descope/api/v1/auth/saml.rb +48 -0
- data/lib/descope/api/v1/auth/totp.rb +72 -0
- data/lib/descope/api/v1/auth.rb +452 -0
- data/lib/descope/api/v1/management/access_key.rb +81 -0
- data/lib/descope/api/v1/management/audit.rb +82 -0
- data/lib/descope/api/v1/management/authz.rb +165 -0
- data/lib/descope/api/v1/management/common.rb +147 -0
- data/lib/descope/api/v1/management/flow.rb +55 -0
- data/lib/descope/api/v1/management/password.rb +58 -0
- data/lib/descope/api/v1/management/permission.rb +48 -0
- data/lib/descope/api/v1/management/project.rb +53 -0
- data/lib/descope/api/v1/management/role.rb +48 -0
- data/lib/descope/api/v1/management/scim.rb +206 -0
- data/lib/descope/api/v1/management/sso_settings.rb +153 -0
- data/lib/descope/api/v1/management/tenant.rb +71 -0
- data/lib/descope/api/v1/management/user.rb +619 -0
- data/lib/descope/api/v1/management.rb +38 -0
- data/lib/descope/api/v1/session.rb +84 -0
- data/lib/descope/api/v1.rb +13 -0
- data/lib/descope/client.rb +6 -0
- data/lib/descope/exception.rb +50 -0
- data/lib/descope/mixins/common.rb +129 -0
- data/lib/descope/mixins/headers.rb +15 -0
- data/lib/descope/mixins/http.rb +133 -0
- data/lib/descope/mixins/initializer.rb +80 -0
- data/lib/descope/mixins/logging.rb +30 -0
- data/lib/descope/mixins/validation.rb +79 -0
- data/lib/descope/mixins.rb +22 -0
- data/lib/descope/version.rb +7 -0
- data/lib/descope.rb +9 -0
- data/lib/descope_client.rb +5 -0
- data/release-please-config.json +18 -0
- data/renovate.json +6 -0
- data/spec/factories/user.rb +16 -0
- data/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb +159 -0
- data/spec/lib.descope/api/v1/auth/magiclink_spec.rb +282 -0
- data/spec/lib.descope/api/v1/auth/oauth_spec.rb +117 -0
- data/spec/lib.descope/api/v1/auth/otp_spec.rb +285 -0
- data/spec/lib.descope/api/v1/auth/password_spec.rb +124 -0
- data/spec/lib.descope/api/v1/auth/saml_spec.rb +55 -0
- data/spec/lib.descope/api/v1/auth/totp_spec.rb +70 -0
- data/spec/lib.descope/api/v1/auth_spec.rb +372 -0
- data/spec/lib.descope/api/v1/management/access_key_spec.rb +118 -0
- data/spec/lib.descope/api/v1/management/audit_spec.rb +78 -0
- data/spec/lib.descope/api/v1/management/authz_spec.rb +336 -0
- data/spec/lib.descope/api/v1/management/flow_spec.rb +78 -0
- data/spec/lib.descope/api/v1/management/password_spec.rb +25 -0
- data/spec/lib.descope/api/v1/management/permission_spec.rb +81 -0
- data/spec/lib.descope/api/v1/management/project_spec.rb +63 -0
- data/spec/lib.descope/api/v1/management/role_spec.rb +85 -0
- data/spec/lib.descope/api/v1/management/scim_spec.rb +312 -0
- data/spec/lib.descope/api/v1/management/sso_settings_spec.rb +172 -0
- data/spec/lib.descope/api/v1/management/tenant_spec.rb +141 -0
- data/spec/lib.descope/api/v1/management/user_spec.rb +667 -0
- data/spec/lib.descope/api/v1/session_spec.rb +117 -0
- data/spec/lib.descope/client_spec.rb +40 -0
- data/spec/spec_helper.rb +72 -0
- data/spec/support/client_config.rb +14 -0
- data/spec/support/dummy_class.rb +36 -0
- data/spec/support/utils.rb +32 -0
- metadata +420 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Descope
|
|
4
|
+
module Api
|
|
5
|
+
module V1
|
|
6
|
+
module Management
|
|
7
|
+
# Management API calls
|
|
8
|
+
module SCIM
|
|
9
|
+
include Descope::Api::V1::Management::Common
|
|
10
|
+
|
|
11
|
+
def scim_search_groups(filter: nil, start_index: nil, count: nil, excluded_attributes: nil)
|
|
12
|
+
# Search SCIM Groups
|
|
13
|
+
url = compose_scim_search_groups_url(filter, start_index, count, excluded_attributes)
|
|
14
|
+
get(url)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def scim_create_group(group_id: nil, display_name: nil, members: nil, external_id: nil,
|
|
18
|
+
excluded_attributes: nil)
|
|
19
|
+
# Create SCIM Group
|
|
20
|
+
body = compose_scim_create_group_body(group_id, display_name, members, external_id, excluded_attributes)
|
|
21
|
+
post(SCIM_GROUPS_PATH, body)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def scim_load_group(group_id: nil, display_name: nil, external_id: nil, excluded_attributes: nil)
|
|
25
|
+
# Load SCIM Group, using a valid access key.
|
|
26
|
+
validate_scim_group_id(group_id)
|
|
27
|
+
url = compose_scim_create_group_url(group_id, display_name, external_id, excluded_attributes)
|
|
28
|
+
get(url)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def scim_update_group(group_id: nil, display_name: nil, members: nil, external_id: nil,
|
|
32
|
+
excluded_attributes: nil)
|
|
33
|
+
# Update SCIM Group, using a valid access key.
|
|
34
|
+
validate_scim_group_id(group_id)
|
|
35
|
+
body = compose_scim_update_group_body(group_id, display_name, members, external_id, excluded_attributes)
|
|
36
|
+
patch("#{SCIM_GROUPS_PATH}/#{group_id}", body)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def scim_delete_group(group_id)
|
|
40
|
+
# Delete SCIM Group, using a valid access key.
|
|
41
|
+
validate_scim_group_id(group_id)
|
|
42
|
+
url = "#{SCIM_GROUPS_PATH}/#{group_id}"
|
|
43
|
+
delete(url)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def scim_patch_group(group_id: nil, user_id: nil, operations: nil)
|
|
47
|
+
# Patch SCIM Group, using a valid access key.
|
|
48
|
+
validate_scim_group_id(group_id)
|
|
49
|
+
url = compose_scim_patch_group_url(group_id, user_id, operations)
|
|
50
|
+
patch(url)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# SCIM Users
|
|
54
|
+
def scim_load_resource_types
|
|
55
|
+
# Load SCIM Resource Types, using a valid access key.
|
|
56
|
+
get(SCIM_RESOURCE_TYPES_PATH)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def scim_load_service_provider_config
|
|
60
|
+
# Load SCIM Service Provider Config, using a valid access key.
|
|
61
|
+
get(SCIM_SERVICE_PROVIDER_CONFIG_PATH)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def scim_search_users(filter: nil, start_index: nil, count: nil)
|
|
65
|
+
# Search SCIM Users, using a valid access key.
|
|
66
|
+
url = compose_scim_search_users_url(filter, start_index, count)
|
|
67
|
+
get(url)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def scim_create_user(user_id: nil, display_name: nil, emails: nil,
|
|
71
|
+
phone_numbers: nil, active: nil, name: nil, user_name: nil)
|
|
72
|
+
# Create SCIM User, using a valid access key.
|
|
73
|
+
validate_user_id(user_id)
|
|
74
|
+
body = compose_scim_create_user_body(user_id, display_name, emails, phone_numbers, active, name, user_name)
|
|
75
|
+
post(SCIM_USERS_PATH, body)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def scim_load_user(user_id)
|
|
79
|
+
# Load SCIM User, using a valid access key.
|
|
80
|
+
validate_user_id(user_id)
|
|
81
|
+
url = "#{SCIM_USERS_PATH}/#{user_id}"
|
|
82
|
+
get(url)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def scim_update_user(user_id)
|
|
86
|
+
# Update SCIM User, using a valid access key.
|
|
87
|
+
validate_user_id(user_id)
|
|
88
|
+
url = "#{SCIM_USERS_PATH}/#{user_id}"
|
|
89
|
+
patch(url)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def scim_delete_user(user_id)
|
|
93
|
+
# Delete SCIM User, using a valid access key.
|
|
94
|
+
validate_user_id(user_id)
|
|
95
|
+
url = "#{SCIM_USERS_PATH}/#{user_id}"
|
|
96
|
+
delete(url)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def scim_patch_user(user_id: nil, group_id: nil, operations: nil)
|
|
100
|
+
# Patch SCIM User, using a valid access key.
|
|
101
|
+
validate_user_id(user_id)
|
|
102
|
+
validate_scim_group_id(group_id)
|
|
103
|
+
body = compose_scim_patch_user_body(user_id, group_id, operations)
|
|
104
|
+
patch(SCIM_USERS_PATH, body)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def compose_scim_search_groups_url(filter, start_index, count, excluded_attributes)
|
|
110
|
+
url = "#{SCIM_GROUPS_PATH}?"
|
|
111
|
+
url += "filter=#{filter}&" unless filter.nil?
|
|
112
|
+
url += "startIndex=#{start_index}&" unless start_index.nil?
|
|
113
|
+
url += "count=#{count}&" unless count.nil?
|
|
114
|
+
url += "excludedAttributes=#{excluded_attributes}&" unless excluded_attributes.nil?
|
|
115
|
+
url
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def compose_scim_create_group_body(group_id, display_name, members, external_id, excluded_attributes)
|
|
119
|
+
body = {}
|
|
120
|
+
body['id'] = group_id unless group_id.nil?
|
|
121
|
+
body['displayName'] = display_name unless display_name.nil?
|
|
122
|
+
body['members'] = members unless members.nil?
|
|
123
|
+
body['externalId'] = external_id unless external_id.nil?
|
|
124
|
+
body['excludedAttributes'] = excluded_attributes unless excluded_attributes.nil?
|
|
125
|
+
body
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def compose_scim_create_group_url(group_id, display_name, external_id, excluded_attributes)
|
|
129
|
+
display_name = CGI.escape(display_name) unless display_name.nil?
|
|
130
|
+
url = "#{SCIM_GROUPS_PATH}/#{group_id}?"
|
|
131
|
+
url += "displayName=#{display_name}&" unless display_name.nil?
|
|
132
|
+
url += "externalId=#{external_id}&" unless external_id.nil?
|
|
133
|
+
url += "excludedAttributes=#{excluded_attributes}" unless excluded_attributes.nil?
|
|
134
|
+
url
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def compose_scim_update_group_body(group_id, display_name, members, external_id, excluded_attributes)
|
|
138
|
+
body = {}
|
|
139
|
+
body[:groupId] = group_id unless group_id.nil?
|
|
140
|
+
body[:displayName] = display_name unless display_name.nil?
|
|
141
|
+
body[:members] = members unless members.nil?
|
|
142
|
+
body[:externalId] = external_id unless external_id.nil?
|
|
143
|
+
body[:excludedAttributes] = excluded_attributes unless excluded_attributes.nil?
|
|
144
|
+
body
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def compose_scim_patch_group_url(group_id, user_id, operations)
|
|
148
|
+
url = "#{SCIM_GROUPS_PATH}/#{group_id}&"
|
|
149
|
+
url += "userId=#{user_id}&" unless user_id.nil?
|
|
150
|
+
url += "operations=#{compose_operations_param(operations)}&" unless operations.nil?
|
|
151
|
+
url
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def compose_scim_search_users_url(filter, start_index, count)
|
|
155
|
+
url = "#{SCIM_USERS_PATH}?"
|
|
156
|
+
url += "filter=#{filter}&" unless filter.nil?
|
|
157
|
+
url += "startIndex=#{start_index}&" unless start_index.nil?
|
|
158
|
+
url += "count=#{count}&" unless count.nil?
|
|
159
|
+
url
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def compose_scim_create_user_body(user_id, display_name, emails, phone_numbers, active, name, user_name)
|
|
163
|
+
raise AuthException.new('name must be a hash of these fields: given_name, family_name, last_name') if !name.nil? && !name.is_a?(Hash)
|
|
164
|
+
|
|
165
|
+
body = {}
|
|
166
|
+
body[:userId] = user_id unless user_id.nil?
|
|
167
|
+
body[:displayName] = display_name unless display_name.nil?
|
|
168
|
+
body[:emails] = emails unless emails.nil?
|
|
169
|
+
body[:phoneNumbers] = phone_numbers unless phone_numbers.nil?
|
|
170
|
+
body[:active] = active unless active.nil?
|
|
171
|
+
body[:name] = {} unless name.nil?
|
|
172
|
+
body[:name][:givenName] = name[:given_name] unless name[:given_name].nil?
|
|
173
|
+
body[:name][:familyName] = name[:family_name] unless name[:family_name].nil?
|
|
174
|
+
body[:name][:middleName] = name[:middle_name] unless name[:middle_name].nil?
|
|
175
|
+
body[:userName] = user_name unless user_name.nil?
|
|
176
|
+
body
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def compose_operations_param(operations)
|
|
180
|
+
operations_params = []
|
|
181
|
+
if operations.is_a?(Array)
|
|
182
|
+
operations.each do |op|
|
|
183
|
+
operations_params << {
|
|
184
|
+
op: op[:op],
|
|
185
|
+
path: op[:path],
|
|
186
|
+
valueString: op[:value_string],
|
|
187
|
+
valueBoolean: op[:value_boolean],
|
|
188
|
+
valueArray: op[:value_array]
|
|
189
|
+
}
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
operations_params
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def compose_scim_patch_user_body(user_id, group_id, operations)
|
|
196
|
+
body = {}
|
|
197
|
+
body[:userId] = user_id unless user_id.nil?
|
|
198
|
+
body[:groupId] = group_id unless group_id.nil?
|
|
199
|
+
body[:operations] = operations unless operations.nil?
|
|
200
|
+
body
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Descope
|
|
4
|
+
module Api
|
|
5
|
+
module V1
|
|
6
|
+
module Management
|
|
7
|
+
# Management API calls
|
|
8
|
+
module SSOSettings
|
|
9
|
+
include Descope::Api::V1::Management::Common
|
|
10
|
+
|
|
11
|
+
def get_sso_settings(tenant_id)
|
|
12
|
+
# Get SSO settings for the provided tenant id.
|
|
13
|
+
get(SSO_SETTINGS_PATH, { tenantId: tenant_id })
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def delete_sso_settings(tenant_id)
|
|
17
|
+
# Delete SSO settings for the provided tenant id.
|
|
18
|
+
delete(SSO_SETTINGS_PATH, { tenantId: tenant_id })
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create_sso_oidc_app(id: nil, name: nil, description: nil, enabled: nil, logo: nil, login_page_url: nil)
|
|
22
|
+
body = {}
|
|
23
|
+
body[:id] = id if id
|
|
24
|
+
body[:name] = name if name
|
|
25
|
+
body[:description] = description if description
|
|
26
|
+
body[:enabled] = enabled if enabled
|
|
27
|
+
body[:logo] = logo if logo
|
|
28
|
+
body[:loginPageUrl] = login_page_url if login_page_url
|
|
29
|
+
post(SSO_OIDC_CREATE_APP_PATH, body)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def update_sso_oidc_app(id: nil, name: nil, description: nil, enabled: nil, logo: nil, login_page_url: nil)
|
|
33
|
+
body = {}
|
|
34
|
+
body[:id] = id if id
|
|
35
|
+
body[:name] = name if name
|
|
36
|
+
body[:description] = description if description
|
|
37
|
+
body[:enabled] = enabled if enabled
|
|
38
|
+
body[:logo] = logo if logo
|
|
39
|
+
body[:loginPageUrl] = login_page_url if login_page_url
|
|
40
|
+
put(SSO_OIDC_UPDATE_APP_PATH, body)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def configure_sso_oidc(tenant_id: nil, settings: nil, redirect_url: nil, domain: nil)
|
|
44
|
+
raise Descope::ArgumentException.new('SSO settings must be a Hash', code: 400) unless settings.is_a?(Hash)
|
|
45
|
+
|
|
46
|
+
# Configure tenant SSO OIDC Settings, using a valid management key.
|
|
47
|
+
request_params = {
|
|
48
|
+
tenantId: tenant_id,
|
|
49
|
+
settings: compose_settings_body(settings),
|
|
50
|
+
redirectUrl: redirect_url,
|
|
51
|
+
domain:
|
|
52
|
+
}
|
|
53
|
+
post(SSO_OIDC_PATH, request_params)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def configure_sso_saml(tenant_id: nil, settings: nil, redirect_url: nil, domain: nil)
|
|
57
|
+
raise Descope::ArgumentException.new('SSO SAML settings must be a Hash', code: 400) unless settings.is_a?(Hash)
|
|
58
|
+
|
|
59
|
+
# Configure tenant SSO SAML Settings, using a valid management key.
|
|
60
|
+
request_params = {
|
|
61
|
+
tenantId: tenant_id,
|
|
62
|
+
settings: compose_settings_body(settings),
|
|
63
|
+
redirectUrl: redirect_url,
|
|
64
|
+
domain:
|
|
65
|
+
}
|
|
66
|
+
post(SSO_SAML_PATH, request_params)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def configure_sso_saml_metadata(tenant_id: nil, settings: nil, redirect_url: nil, domain: nil)
|
|
70
|
+
# Configure tenant SSO SAML Metadata, using a valid management key.
|
|
71
|
+
post(SSO_SAML_METADATA_PATH, compose_metadata_body(tenant_id, settings, redirect_url, domain))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
77
|
+
def compose_settings_body(settings)
|
|
78
|
+
|
|
79
|
+
body = {}
|
|
80
|
+
body[:name] = settings[:name] if settings.key?(:name)
|
|
81
|
+
body[:clientId] = settings[:client_id] if settings.key?(:client_id)
|
|
82
|
+
body[:clientSecret] = settings[:client_secret] if settings.key?(:client_secret)
|
|
83
|
+
body[:redirectUrl] = settings[:redirect_url] if settings.key?(:redirect_url)
|
|
84
|
+
body[:authUrl] = settings[:auth_url] if settings.key?(:auth_url)
|
|
85
|
+
body[:tokenUrl] = settings[:token_url] if settings.key?(:token_url)
|
|
86
|
+
body[:userDataUrl] = settings[:user_data_url] if settings.key?(:user_data_url)
|
|
87
|
+
body[:scope] = settings[:scope] if settings.key?(:scope)
|
|
88
|
+
body[:JWKsUrl] = settings[:jwks_url] if settings.key?(:jwks_url)
|
|
89
|
+
user_mappings = settings[:user_attr_mapping] if settings.key?(:user_attr_mapping)
|
|
90
|
+
|
|
91
|
+
# rubocop:disable Metrics/LineLength
|
|
92
|
+
unless user_mappings.nil? || user_mappings.empty?
|
|
93
|
+
body[:userAttrMapping] = {}
|
|
94
|
+
body[:userAttrMapping][:loginId] = user_mappings[:login_id] if settings[:user_attr_mapping].key?(:login_id)
|
|
95
|
+
body[:userAttrMapping][:username] = user_mappings[:username] if settings[:user_attr_mapping].key?(:username)
|
|
96
|
+
body[:userAttrMapping][:name] = user_mappings[:name] if settings[:user_attr_mapping].key?(:name)
|
|
97
|
+
body[:userAttrMapping][:email] = user_mappings[:email] if settings[:user_attr_mapping].key?(:email)
|
|
98
|
+
body[:userAttrMapping][:phoneNumber] = user_mappings[:phone_number] if settings[:user_attr_mapping].key?(:phone_number)
|
|
99
|
+
body[:userAttrMapping][:verifiedEmail] = user_mappings[:verified_email] if settings[:user_attr_mapping].key?(:verified_email)
|
|
100
|
+
body[:userAttrMapping][:verifiedPhone] = user_mappings[:verified_phone] if settings[:user_attr_mapping].key?(:verified_phone)
|
|
101
|
+
body[:userAttrMapping][:picture] = user_mappings[:picture] if settings[:user_attr_mapping].key?(:picture)
|
|
102
|
+
body[:userAttrMapping][:givenName] = user_mappings[:given_name] if settings[:user_attr_mapping].key?(:given_name)
|
|
103
|
+
body[:userAttrMapping][:middleName] = user_mappings[:middle_name] if settings[:user_attr_mapping].key?(:middle_name)
|
|
104
|
+
body[:userAttrMapping][:familyName] = user_mappings[:family_name] if settings[:user_attr_mapping].key?(:family_name)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
body[:manageProviderTokens] = settings[:manage_provider_tokens] if settings.key?(:manage_provider_tokens)
|
|
108
|
+
body[:callbackDomain] = settings[:callback_domain] if settings.key?(:callback_domain)
|
|
109
|
+
body[:prompt] = settings[:prompt] if settings.key?(:prompt)
|
|
110
|
+
body[:grantType] = settings[:grant_type] if settings.key?(:grant_type)
|
|
111
|
+
body[:issuer] = settings[:issuer] if settings.key?(:issuer)
|
|
112
|
+
|
|
113
|
+
body
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def compose_metadata_body(tenant_id, settings, redirect_url, domain)
|
|
117
|
+
{
|
|
118
|
+
tenantId: tenant_id,
|
|
119
|
+
settings: compose_settings_body(settings),
|
|
120
|
+
redirectUrl: redirect_url,
|
|
121
|
+
domain:
|
|
122
|
+
}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def role_mapping_to_hash(role_mapping)
|
|
126
|
+
role_mapping ||= []
|
|
127
|
+
role_mapping_list = []
|
|
128
|
+
role_mapping.each do |mapping|
|
|
129
|
+
role_mapping_list << {
|
|
130
|
+
groups: mapping['groups'],
|
|
131
|
+
roleName: mapping['role_name']
|
|
132
|
+
}
|
|
133
|
+
end
|
|
134
|
+
role_mapping_list
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def attribute_mapping_to_hash(attribute_mapping)
|
|
138
|
+
if attribute_mapping.nil?
|
|
139
|
+
raise Descope::ArgumentException.new('SSO Attribute mapping cannot be None', code: 400)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
{
|
|
143
|
+
name: attribute_mapping['name'],
|
|
144
|
+
email: attribute_mapping['email'],
|
|
145
|
+
phoneNumber: attribute_mapping['phone_number'],
|
|
146
|
+
groups: attribute_mapping['groups']
|
|
147
|
+
}
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Descope
|
|
4
|
+
module Api
|
|
5
|
+
module V1
|
|
6
|
+
module Management
|
|
7
|
+
# Management API calls
|
|
8
|
+
module Tenant
|
|
9
|
+
include Descope::Mixins::Validation
|
|
10
|
+
include Descope::Api::V1::Management::Common
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def create_tenant(name: nil, id: nil, self_provisioning_domains: nil, custom_attributes: nil)
|
|
14
|
+
# Create a new tenant with the given name. Tenant IDs are provisioned automatically, but can be provided
|
|
15
|
+
# explicitly if needed. Both the name and ID must be unique per project.
|
|
16
|
+
# @see https://docs.descope.com/api/openapi/tenantmanagement/operation/CreateTenant/
|
|
17
|
+
|
|
18
|
+
self_provisioning_domains ||= []
|
|
19
|
+
custom_attributes ||= {}
|
|
20
|
+
post(TENANT_CREATE_PATH, compose_tenant_create_update_body(name, id, self_provisioning_domains, custom_attributes))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def update_tenant(name: nil, id: nil, self_provisioning_domains: nil, custom_attributes: nil)
|
|
24
|
+
# Update an existing tenant with the given name and domains. IMPORTANT: All parameters are used as overrides
|
|
25
|
+
# to the existing tenant. Empty fields will override populated fields. Use carefully.
|
|
26
|
+
# @see https://docs.descope.com/api/openapi/tenantmanagement/operation/UpdateTenant/
|
|
27
|
+
self_provisioning_domains ||= []
|
|
28
|
+
custom_attributes ||= {}
|
|
29
|
+
post(TENANT_UPDATE_PATH, compose_tenant_create_update_body(name, id, self_provisioning_domains, custom_attributes))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def delete_tenant(id = nil)
|
|
33
|
+
# Delete an existing tenant. IMPORTANT: This action is irreversible. Use carefully.
|
|
34
|
+
post(TENANT_DELETE_PATH, { id: })
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def load_tenant(id = nil)
|
|
38
|
+
# Load tenant by id.
|
|
39
|
+
get(TENANT_LOAD_PATH, { id: })
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def load_all_tenants
|
|
43
|
+
# Load all tenants.
|
|
44
|
+
get(TENANT_LOAD_ALL_PATH)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def search_all_tenants(ids: nil, names: nil, self_provisioning_domains: nil, custom_attributes: nil)
|
|
48
|
+
# Search all tenants.
|
|
49
|
+
request_params = {
|
|
50
|
+
ids:,
|
|
51
|
+
names:,
|
|
52
|
+
selfProvisioningDomains: self_provisioning_domains,
|
|
53
|
+
customAttributes: custom_attributes
|
|
54
|
+
}
|
|
55
|
+
post(TENANT_SEARCH_ALL_PATH, request_params)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def compose_tenant_create_update_body(name, id, self_provisioning_domains, custom_attributes)
|
|
61
|
+
body = { name:, id: }
|
|
62
|
+
body[:selfProvisioningDomains] = self_provisioning_domains unless self_provisioning_domains.empty?
|
|
63
|
+
body[:customAttributes] = custom_attributes unless custom_attributes.empty?
|
|
64
|
+
|
|
65
|
+
body
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|