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.
Files changed (197) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yaml +54 -0
  3. data/.gitignore +59 -0
  4. data/.release-please-manifest.json +3 -0
  5. data/.rubocop.yml +10 -0
  6. data/.rubocop_todo.yml +10 -0
  7. data/.ruby-version +1 -0
  8. data/CHANGELOG.md +90 -0
  9. data/Gemfile +22 -0
  10. data/Gemfile.lock +204 -0
  11. data/LICENSE +21 -0
  12. data/README.md +1171 -0
  13. data/Rakefile +31 -0
  14. data/descope.gemspec +34 -0
  15. data/examples/ruby/Gemfile +4 -0
  16. data/examples/ruby/Gemfile.lock +41 -0
  17. data/examples/ruby/access_key_app.rb +45 -0
  18. data/examples/ruby/enchantedlink_app.rb +65 -0
  19. data/examples/ruby/magiclink_app.rb +81 -0
  20. data/examples/ruby/management/Gemfile +5 -0
  21. data/examples/ruby/management/Gemfile.lock +38 -0
  22. data/examples/ruby/management/access_key_app.rb +71 -0
  23. data/examples/ruby/management/audit_app.rb +25 -0
  24. data/examples/ruby/management/authz_app.rb +135 -0
  25. data/examples/ruby/management/authz_files.json +229 -0
  26. data/examples/ruby/management/flow_app.rb +57 -0
  27. data/examples/ruby/management/permission_app.rb +56 -0
  28. data/examples/ruby/management/role_app.rb +58 -0
  29. data/examples/ruby/management/tenant_app.rb +60 -0
  30. data/examples/ruby/management/user_app.rb +60 -0
  31. data/examples/ruby/oauth_app.rb +39 -0
  32. data/examples/ruby/otp_app.rb +50 -0
  33. data/examples/ruby/password_app.rb +76 -0
  34. data/examples/ruby/saml_app.rb +38 -0
  35. data/examples/ruby-on-rails-api/descope/.dockerignore +37 -0
  36. data/examples/ruby-on-rails-api/descope/.gitattributes +9 -0
  37. data/examples/ruby-on-rails-api/descope/.gitignore +40 -0
  38. data/examples/ruby-on-rails-api/descope/.node-version +1 -0
  39. data/examples/ruby-on-rails-api/descope/.ruby-version +1 -0
  40. data/examples/ruby-on-rails-api/descope/Dockerfile +75 -0
  41. data/examples/ruby-on-rails-api/descope/Gemfile +67 -0
  42. data/examples/ruby-on-rails-api/descope/Gemfile.lock +284 -0
  43. data/examples/ruby-on-rails-api/descope/Procfile.dev +3 -0
  44. data/examples/ruby-on-rails-api/descope/README.md +54 -0
  45. data/examples/ruby-on-rails-api/descope/Rakefile +6 -0
  46. data/examples/ruby-on-rails-api/descope/app/assets/builds/.keep +0 -0
  47. data/examples/ruby-on-rails-api/descope/app/assets/config/manifest.js +3 -0
  48. data/examples/ruby-on-rails-api/descope/app/assets/images/.keep +0 -0
  49. data/examples/ruby-on-rails-api/descope/app/assets/images/descope.jpeg +0 -0
  50. data/examples/ruby-on-rails-api/descope/app/assets/images/favicon.ico +0 -0
  51. data/examples/ruby-on-rails-api/descope/app/assets/images/logo192.png +0 -0
  52. data/examples/ruby-on-rails-api/descope/app/assets/images/logo512.png +0 -0
  53. data/examples/ruby-on-rails-api/descope/app/assets/stylesheets/application.bootstrap.scss +67 -0
  54. data/examples/ruby-on-rails-api/descope/app/channels/application_cable/channel.rb +4 -0
  55. data/examples/ruby-on-rails-api/descope/app/channels/application_cable/connection.rb +4 -0
  56. data/examples/ruby-on-rails-api/descope/app/controllers/application_controller.rb +2 -0
  57. data/examples/ruby-on-rails-api/descope/app/controllers/concerns/.keep +0 -0
  58. data/examples/ruby-on-rails-api/descope/app/controllers/homepage_controller.rb +4 -0
  59. data/examples/ruby-on-rails-api/descope/app/controllers/session_controller.rb +66 -0
  60. data/examples/ruby-on-rails-api/descope/app/helpers/application_helper.rb +2 -0
  61. data/examples/ruby-on-rails-api/descope/app/helpers/homepage_helper.rb +2 -0
  62. data/examples/ruby-on-rails-api/descope/app/helpers/session_helper.rb +2 -0
  63. data/examples/ruby-on-rails-api/descope/app/javascript/App.css +53 -0
  64. data/examples/ruby-on-rails-api/descope/app/javascript/application.js +5 -0
  65. data/examples/ruby-on-rails-api/descope/app/javascript/components/App.jsx +4 -0
  66. data/examples/ruby-on-rails-api/descope/app/javascript/components/Dashboard.jsx +60 -0
  67. data/examples/ruby-on-rails-api/descope/app/javascript/components/Home.jsx +27 -0
  68. data/examples/ruby-on-rails-api/descope/app/javascript/components/Login.jsx +45 -0
  69. data/examples/ruby-on-rails-api/descope/app/javascript/components/Profile.jsx +81 -0
  70. data/examples/ruby-on-rails-api/descope/app/javascript/components/index.html +11 -0
  71. data/examples/ruby-on-rails-api/descope/app/javascript/components/index.jsx +24 -0
  72. data/examples/ruby-on-rails-api/descope/app/javascript/controllers/application.js +9 -0
  73. data/examples/ruby-on-rails-api/descope/app/javascript/controllers/index.js +5 -0
  74. data/examples/ruby-on-rails-api/descope/app/javascript/reportWebVitals.js +13 -0
  75. data/examples/ruby-on-rails-api/descope/app/javascript/routes/index.jsx +17 -0
  76. data/examples/ruby-on-rails-api/descope/app/jobs/application_job.rb +7 -0
  77. data/examples/ruby-on-rails-api/descope/app/mailers/application_mailer.rb +4 -0
  78. data/examples/ruby-on-rails-api/descope/app/models/application_record.rb +3 -0
  79. data/examples/ruby-on-rails-api/descope/app/models/concerns/.keep +0 -0
  80. data/examples/ruby-on-rails-api/descope/app/views/homepage/index.html.erb +2 -0
  81. data/examples/ruby-on-rails-api/descope/app/views/layouts/application.html.erb +16 -0
  82. data/examples/ruby-on-rails-api/descope/app/views/layouts/mailer.html.erb +13 -0
  83. data/examples/ruby-on-rails-api/descope/app/views/layouts/mailer.text.erb +1 -0
  84. data/examples/ruby-on-rails-api/descope/app/views/session/index.html.erb +2 -0
  85. data/examples/ruby-on-rails-api/descope/bin/bundle +109 -0
  86. data/examples/ruby-on-rails-api/descope/bin/dev +11 -0
  87. data/examples/ruby-on-rails-api/descope/bin/docker-entrypoint +8 -0
  88. data/examples/ruby-on-rails-api/descope/bin/rails +4 -0
  89. data/examples/ruby-on-rails-api/descope/bin/rake +4 -0
  90. data/examples/ruby-on-rails-api/descope/bin/setup +36 -0
  91. data/examples/ruby-on-rails-api/descope/build.js +30 -0
  92. data/examples/ruby-on-rails-api/descope/config/application.rb +42 -0
  93. data/examples/ruby-on-rails-api/descope/config/boot.rb +4 -0
  94. data/examples/ruby-on-rails-api/descope/config/cable.yml +10 -0
  95. data/examples/ruby-on-rails-api/descope/config/config.yml +9 -0
  96. data/examples/ruby-on-rails-api/descope/config/credentials.yml.enc +1 -0
  97. data/examples/ruby-on-rails-api/descope/config/database.yml +25 -0
  98. data/examples/ruby-on-rails-api/descope/config/environment.rb +5 -0
  99. data/examples/ruby-on-rails-api/descope/config/environments/development.rb +76 -0
  100. data/examples/ruby-on-rails-api/descope/config/environments/production.rb +97 -0
  101. data/examples/ruby-on-rails-api/descope/config/environments/test.rb +64 -0
  102. data/examples/ruby-on-rails-api/descope/config/initializers/assets.rb +13 -0
  103. data/examples/ruby-on-rails-api/descope/config/initializers/content_security_policy.rb +25 -0
  104. data/examples/ruby-on-rails-api/descope/config/initializers/filter_parameter_logging.rb +8 -0
  105. data/examples/ruby-on-rails-api/descope/config/initializers/inflections.rb +16 -0
  106. data/examples/ruby-on-rails-api/descope/config/initializers/load_config.rb +12 -0
  107. data/examples/ruby-on-rails-api/descope/config/initializers/permissions_policy.rb +13 -0
  108. data/examples/ruby-on-rails-api/descope/config/locales/en.yml +31 -0
  109. data/examples/ruby-on-rails-api/descope/config/puma.rb +35 -0
  110. data/examples/ruby-on-rails-api/descope/config/routes.rb +18 -0
  111. data/examples/ruby-on-rails-api/descope/config/storage.yml +34 -0
  112. data/examples/ruby-on-rails-api/descope/config.ru +6 -0
  113. data/examples/ruby-on-rails-api/descope/db/seeds.rb +9 -0
  114. data/examples/ruby-on-rails-api/descope/lib/assets/.keep +0 -0
  115. data/examples/ruby-on-rails-api/descope/lib/tasks/.keep +0 -0
  116. data/examples/ruby-on-rails-api/descope/log/.keep +0 -0
  117. data/examples/ruby-on-rails-api/descope/package-lock.json +19680 -0
  118. data/examples/ruby-on-rails-api/descope/package.json +51 -0
  119. data/examples/ruby-on-rails-api/descope/public/404.html +67 -0
  120. data/examples/ruby-on-rails-api/descope/public/422.html +67 -0
  121. data/examples/ruby-on-rails-api/descope/public/500.html +66 -0
  122. data/examples/ruby-on-rails-api/descope/public/apple-touch-icon-precomposed.png +0 -0
  123. data/examples/ruby-on-rails-api/descope/public/apple-touch-icon.png +0 -0
  124. data/examples/ruby-on-rails-api/descope/public/favicon.ico +0 -0
  125. data/examples/ruby-on-rails-api/descope/public/robots.txt +1 -0
  126. data/examples/ruby-on-rails-api/descope/storage/.keep +0 -0
  127. data/examples/ruby-on-rails-api/descope/tmp/.keep +0 -0
  128. data/examples/ruby-on-rails-api/descope/tmp/pids/.keep +0 -0
  129. data/examples/ruby-on-rails-api/descope/tmp/storage/.keep +0 -0
  130. data/examples/ruby-on-rails-api/descope/vendor/.keep +0 -0
  131. data/examples/ruby-on-rails-api/descope/yarn.lock +10780 -0
  132. data/lib/descope/api/v1/auth/enchantedlink.rb +156 -0
  133. data/lib/descope/api/v1/auth/magiclink.rb +170 -0
  134. data/lib/descope/api/v1/auth/oauth.rb +72 -0
  135. data/lib/descope/api/v1/auth/otp.rb +186 -0
  136. data/lib/descope/api/v1/auth/password.rb +100 -0
  137. data/lib/descope/api/v1/auth/saml.rb +48 -0
  138. data/lib/descope/api/v1/auth/totp.rb +72 -0
  139. data/lib/descope/api/v1/auth.rb +452 -0
  140. data/lib/descope/api/v1/management/access_key.rb +81 -0
  141. data/lib/descope/api/v1/management/audit.rb +82 -0
  142. data/lib/descope/api/v1/management/authz.rb +165 -0
  143. data/lib/descope/api/v1/management/common.rb +147 -0
  144. data/lib/descope/api/v1/management/flow.rb +55 -0
  145. data/lib/descope/api/v1/management/password.rb +58 -0
  146. data/lib/descope/api/v1/management/permission.rb +48 -0
  147. data/lib/descope/api/v1/management/project.rb +53 -0
  148. data/lib/descope/api/v1/management/role.rb +48 -0
  149. data/lib/descope/api/v1/management/scim.rb +206 -0
  150. data/lib/descope/api/v1/management/sso_settings.rb +153 -0
  151. data/lib/descope/api/v1/management/tenant.rb +71 -0
  152. data/lib/descope/api/v1/management/user.rb +619 -0
  153. data/lib/descope/api/v1/management.rb +38 -0
  154. data/lib/descope/api/v1/session.rb +84 -0
  155. data/lib/descope/api/v1.rb +13 -0
  156. data/lib/descope/client.rb +6 -0
  157. data/lib/descope/exception.rb +50 -0
  158. data/lib/descope/mixins/common.rb +129 -0
  159. data/lib/descope/mixins/headers.rb +15 -0
  160. data/lib/descope/mixins/http.rb +133 -0
  161. data/lib/descope/mixins/initializer.rb +80 -0
  162. data/lib/descope/mixins/logging.rb +30 -0
  163. data/lib/descope/mixins/validation.rb +79 -0
  164. data/lib/descope/mixins.rb +22 -0
  165. data/lib/descope/version.rb +7 -0
  166. data/lib/descope.rb +9 -0
  167. data/lib/descope_client.rb +5 -0
  168. data/release-please-config.json +18 -0
  169. data/renovate.json +6 -0
  170. data/spec/factories/user.rb +16 -0
  171. data/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb +159 -0
  172. data/spec/lib.descope/api/v1/auth/magiclink_spec.rb +282 -0
  173. data/spec/lib.descope/api/v1/auth/oauth_spec.rb +117 -0
  174. data/spec/lib.descope/api/v1/auth/otp_spec.rb +285 -0
  175. data/spec/lib.descope/api/v1/auth/password_spec.rb +124 -0
  176. data/spec/lib.descope/api/v1/auth/saml_spec.rb +55 -0
  177. data/spec/lib.descope/api/v1/auth/totp_spec.rb +70 -0
  178. data/spec/lib.descope/api/v1/auth_spec.rb +372 -0
  179. data/spec/lib.descope/api/v1/management/access_key_spec.rb +118 -0
  180. data/spec/lib.descope/api/v1/management/audit_spec.rb +78 -0
  181. data/spec/lib.descope/api/v1/management/authz_spec.rb +336 -0
  182. data/spec/lib.descope/api/v1/management/flow_spec.rb +78 -0
  183. data/spec/lib.descope/api/v1/management/password_spec.rb +25 -0
  184. data/spec/lib.descope/api/v1/management/permission_spec.rb +81 -0
  185. data/spec/lib.descope/api/v1/management/project_spec.rb +63 -0
  186. data/spec/lib.descope/api/v1/management/role_spec.rb +85 -0
  187. data/spec/lib.descope/api/v1/management/scim_spec.rb +312 -0
  188. data/spec/lib.descope/api/v1/management/sso_settings_spec.rb +172 -0
  189. data/spec/lib.descope/api/v1/management/tenant_spec.rb +141 -0
  190. data/spec/lib.descope/api/v1/management/user_spec.rb +667 -0
  191. data/spec/lib.descope/api/v1/session_spec.rb +117 -0
  192. data/spec/lib.descope/client_spec.rb +40 -0
  193. data/spec/spec_helper.rb +72 -0
  194. data/spec/support/client_config.rb +14 -0
  195. data/spec/support/dummy_class.rb +36 -0
  196. data/spec/support/utils.rb +32 -0
  197. metadata +420 -0
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Descope
4
+ module Api
5
+ module V1
6
+ module Management
7
+ # Management API calls
8
+ module Audit
9
+ include Descope::Api::V1::Management::Common
10
+
11
+ def audit_search(
12
+ user_ids: nil,
13
+ actions: nil,
14
+ exclude_actions: nil,
15
+ devices: nil,
16
+ methods: nil,
17
+ geos: nil,
18
+ remote_addresses: nil,
19
+ login_ids: nil,
20
+ tenants: nil,
21
+ no_tenants: false,
22
+ text: nil,
23
+ from_ts: nil,
24
+ to_ts: nil
25
+ )
26
+ # Search the audit trail up to last 30 days based on given parameters
27
+ # user_ids (Array): Optional list of user IDs to filter by
28
+ # actions (Array): Optional list of actions to filter by
29
+ # excluded_actions (Array): Optional list of actions to exclude
30
+ # devices (Array): Optional list of devices to filter by. Current devices supported are "Bot"/"Mobile"/"Desktop"/"Tablet"/"Unknown"
31
+ # methods (Array): Optional list of methods to filter by. Current auth methods are "otp"/"totp"/"magiclink"/"oauth"/"saml"/"password"
32
+ # geos (Array): Optional list of geos to filter by. Geo is currently country code like "US", "IL", etc.
33
+ # remote_addresses (Array): Optional list of remote addresses to filter by
34
+ # login_ids (Array): Optional list of login IDs to filter by
35
+ # tenants (Array): Optional list of tenants to filter by
36
+ # no_tenants (bool): Should audits without any tenants always be included
37
+ # text (str): Free text search across all fields
38
+ # from_ts (datetime): Retrieve records newer than given time but not older than 30 days
39
+ # to_ts (datetime): Retrieve records older than given time
40
+ request_params = {
41
+ noTenants: no_tenants
42
+ }
43
+ request_params[:userIds] = user_ids unless user_ids.nil?
44
+ request_params[:actions] = actions unless actions.nil?
45
+ request_params[:excludeActions] = exclude_actions unless exclude_actions.nil?
46
+ request_params[:devices] = devices unless devices.nil?
47
+ request_params[:methods] = methods unless methods.nil?
48
+ request_params[:geos] = geos unless geos.nil?
49
+ request_params[:remoteAddresses] = remote_addresses unless remote_addresses.nil?
50
+ request_params[:externalIds] = login_ids unless login_ids.nil?
51
+ request_params[:tenants] = tenants unless tenants.nil?
52
+ request_params[:text] = text unless text.nil?
53
+ request_params[:from] = from_ts.to_i * 1000 unless from_ts.nil?
54
+ request_params[:to] = to_ts.to_i * 1000 unless to_ts.nil?
55
+ res = post(AUDIT_SEARCH, request_params)
56
+ raise Descope::AuthException, "could not get audits: #{res}" if res['audits'].nil?
57
+
58
+ { 'audits' => res['audits'].map { |audit| convert_audit_record(audit) } }
59
+ end
60
+
61
+ private
62
+
63
+ def convert_audit_record(audit)
64
+ {
65
+ 'projectId' => audit['projectId'] || '',
66
+ 'userId' => audit['userId'] || '',
67
+ 'action' => audit['action'] || '',
68
+ 'occurred' => audit['occurred'] || '',
69
+ 'device' => audit['device'] || '',
70
+ 'method' => audit['method'] || '',
71
+ 'geo' => audit['geo'] || '',
72
+ 'remoteAddress' => audit['remoteAddress'] || '',
73
+ 'loginIds' => audit['externalIds'] || '',
74
+ 'tenants' => audit['tenants'] || '',
75
+ 'data' => audit['data'] || ''
76
+ }
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Descope
4
+ module Api
5
+ module V1
6
+ module Management
7
+ # Management API calls
8
+ module Authz
9
+ include Descope::Api::V1::Management::Common
10
+
11
+ def authz_save_schema(schema: nil, upgrade: false)
12
+ # Create or update the ReBAC schema.
13
+ # In case of update, will update only given namespaces and will not delete namespaces unless upgrade flag is true.
14
+ # Args:
15
+ # schema (dict): the schema dict with format
16
+ # {
17
+ # "name": "name-of-schema",
18
+ # "namespaces": [
19
+ # {
20
+ # "name": "name-of-namespace",
21
+ # "relationDefinitions": [
22
+ # {
23
+ # "name": "name-of-relation-definition",
24
+ # "complexDefinition": {
25
+ # "nType": "one of child|union|intersect|sub",
26
+ # "children": "optional list of node children - same format as complexDefinition",
27
+ # "expression": {
28
+ # "neType": "one of self|targetSet|relationLeft|relationRight",
29
+ # "relationDefinition": "name of relation definition for relationLeft and relationRight",
30
+ # "relationDefinitionNamespace": "the namespace for the rd above",
31
+ # "targetRelationDefinition": "relation definition for targetSet and relationLeft/right",
32
+ # "targetRelationDefinitionNamespace": "the namespace for above"
33
+ # }
34
+ # }
35
+ # }
36
+ # ]
37
+ # }
38
+ # ]
39
+ # }
40
+ # Schema name can be used for projects to track versioning.
41
+ # @see https://docs.descope.com/api/openapi/authz/operation/SaveSchema/
42
+ request_params = { schema:, upgrade: }
43
+ post(AUTHZ_SCHEMA_SAVE, request_params)
44
+ end
45
+
46
+ def authz_delete_schema
47
+ # Delete the schema for the project which will also delete all relations.
48
+ post(AUTHZ_SCHEMA_DELETE)
49
+ end
50
+
51
+ def authz_load_schema
52
+ # Load the schema for the project.
53
+ post(AUTHZ_SCHEMA_LOAD)
54
+ end
55
+
56
+ def authz_save_namespace(namespace: nil, old_name: nil, schema_name: nil)
57
+ # Create or update the given namespace
58
+ # Will not delete relation definitions not mentioned in the namespace.
59
+ request_params = { namespace: namespace }
60
+ request_params[:oldName] = old_name unless old_name.nil?
61
+ request_params[:schemaName] = schema_name unless schema_name.nil?
62
+ post(AUTHZ_NS_SAVE, request_params)
63
+ end
64
+
65
+ def authz_delete_namespace(name: nil, schema_name: nil)
66
+ # Delete the given namespace
67
+ request_params = { name: name }
68
+ request_params[:schemaName] = schema_name unless schema_name.nil?
69
+ post(AUTHZ_NS_DELETE, request_params)
70
+ end
71
+
72
+ def authz_save_relation_definition(relation_definition: nil, namespace: nil, old_name: nil, schema_name: nil)
73
+ # Create or update the given relation definition
74
+ # Will not delete relation definitions not mentioned in the namespace.
75
+ request_params = {
76
+ relationDefinition: relation_definition,
77
+ namespace:
78
+ }
79
+ request_params[:old_name] = old_name unless old_name.nil?
80
+ request_params[:schemaName] = schema_name unless schema_name.nil?
81
+ post(AUTHZ_RD_SAVE, request_params)
82
+ end
83
+
84
+ def authz_delete_relation_definition(name: nil, namespace: nil, schema_name: nil)
85
+ # Delete the given relation definition
86
+ request_params = { name: , namespace: }
87
+ request_params[:schemaName] = schema_name unless schema_name.nil?
88
+ post(AUTHZ_RD_DELETE, request_params)
89
+ end
90
+
91
+ def authz_create_relations(relations = nil)
92
+ # Create the given relations based on the existing schema
93
+ # relations (Array[]): the relations to create. Each in the following format:
94
+ # {
95
+ # "resource": "id of the resource that has the relation",
96
+ # "relationDefinition": "the relation definition for the relation",
97
+ # "namespace": "namespace for the relation definition",
98
+ # "target": "the target that has the relation - usually users or other resources",
99
+ # "targetSetResource": "if the target is a group that has another relation",
100
+ # "targetSetRelationDefinition": "the relation definition for the targetSet group",
101
+ # "targetSetRelationDefinitionNamespace": "the namespace for the relation definition for the targetSet group",
102
+ # "query": {
103
+ # "tenants": ["t1", "t2"],
104
+ # "roles": ["r1", "r2"],
105
+ # "text": "full-text-search",
106
+ # "statuses": ["enabled|disabled|invited"],
107
+ # "ssoOnly": True|False,
108
+ # "withTestUser": True|False,
109
+ # "customAttributes": {
110
+ # "key": "value",
111
+ # ...
112
+ # }
113
+ # }
114
+ # }
115
+ # Each relation should have exactly one of: target, targetSet, query
116
+ # Regarding query above, it should be specified if the target is a set of users that matches the query - all fields are optional
117
+ post(AUTHZ_RE_CREATE, { relations: })
118
+ end
119
+
120
+ def authz_delete_relations(relations = nil)
121
+ # Delete the given relations based on the existing schema
122
+ post(AUTHZ_RE_DELETE, { relations: })
123
+ end
124
+
125
+ def authz_delete_relations_for_resources(resources = nil)
126
+ # Delete all relations for the given resources
127
+ post(AUTHZ_RE_DELETE_RESOURCES, { resources: })
128
+ end
129
+
130
+ def authz_has_relations?(relation_queries = nil)
131
+ # Queries the given relations to see if they exist returning true if they do
132
+ post(AUTHZ_RE_HAS_RELATIONS, { relationQueries: relation_queries })
133
+ end
134
+
135
+ def authz_who_can_access?(resource: nil, relation_definition: nil, namespace: nil)
136
+ # Finds the list of targets (usually users) who can access the given resource with the given RD
137
+ request_params = {
138
+ resource:,
139
+ relationDefinition: relation_definition,
140
+ namespace:
141
+ }
142
+ post(AUTHZ_RE_WHO, request_params)
143
+ end
144
+
145
+ def authz_resource_relations(resources: nil)
146
+ post(AUTHZ_RE_RESOURCE, { resources: })
147
+ end
148
+
149
+ def authz_target_relations(targets: nil)
150
+ # Returns the list of all defined relations (not recursive) for the given targets.
151
+ post(AUTHZ_RE_TARGETS, { targets: })
152
+ end
153
+
154
+ def authz_what_can_target_access?(target: nil)
155
+ # Returns the list of all relations for the given target including derived relations from the schema tree.
156
+ res = post(AUTHZ_RE_TARGET_ALL, { target: })
157
+ raise Descope::AuthException, "could not get relation for target: #{res}" if res['relations'].nil?
158
+
159
+ res['relations']
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Descope
4
+ module Api
5
+ module V1
6
+ module Management
7
+ # Common Management constants
8
+ module Common
9
+ # tenant
10
+ TENANT_CREATE_PATH = '/v1/mgmt/tenant/create'
11
+ TENANT_UPDATE_PATH = '/v1/mgmt/tenant/update'
12
+ TENANT_DELETE_PATH = '/v1/mgmt/tenant/delete'
13
+ TENANT_LOAD_PATH = '/v1/mgmt/tenant'
14
+ TENANT_LOAD_ALL_PATH = '/v1/mgmt/tenant/all'
15
+ TENANT_SEARCH_ALL_PATH = '/v1/mgmt/tenant/search'
16
+ PASSWORD_SETTINGS_PATH = '/v1/mgmt/password/settings'
17
+
18
+ # userUSER_CREATE_PATH
19
+ USER_CREATE_PATH = '/v1/mgmt/user/create'
20
+ USER_CREATE_BATCH_PATH = '/v1/mgmt/user/create/batch'
21
+ USER_UPDATE_PATH = '/v1/mgmt/user/update'
22
+ USER_DELETE_PATH = '/v1/mgmt/user/delete'
23
+ USER_LOGOUT_PATH = '/v1/mgmt/user/logout'
24
+ USER_DELETE_ALL_TEST_USERS_PATH = '/v1/mgmt/user/test/delete/all'
25
+ USER_LOAD_PATH = '/v1/mgmt/user'
26
+ USERS_SEARCH_PATH = '/v1/mgmt/user/search'
27
+ USER_GET_PROVIDER_TOKEN = '/v1/mgmt/user/provider/token'
28
+ USER_UPDATE_STATUS_PATH = '/v1/mgmt/user/update/status'
29
+ USER_UPDATE_LOGIN_ID_PATH = '/v1/mgmt/user/update/loginid'
30
+ USER_UPDATE_EMAIL_PATH = '/v1/mgmt/user/update/email'
31
+ USER_UPDATE_PHONE_PATH = '/v1/mgmt/user/update/phone'
32
+ USER_UPDATE_NAME_PATH = '/v1/mgmt/user/update/name'
33
+ USER_UPDATE_PICTURE_PATH = '/v1/mgmt/user/update/picture'
34
+ USER_UPDATE_CUSTOM_ATTRIBUTE_PATH = '/v1/mgmt/user/update/customAttribute'
35
+ USER_ADD_ROLE_PATH = '/v1/mgmt/user/update/role/add'
36
+ USER_REMOVE_ROLE_PATH = '/v1/mgmt/user/update/role/remove'
37
+ USER_SET_PASSWORD_PATH = '/v1/mgmt/user/password/set'
38
+ USER_EXPIRE_PASSWORD_PATH = '/v1/mgmt/user/password/expire'
39
+ USER_ADD_TENANT_PATH = '/v1/mgmt/user/update/tenant/add'
40
+ USER_REMOVE_TENANT_PATH = '/v1/mgmt/user/update/tenant/remove'
41
+ USER_GENERATE_OTP_FOR_TEST_PATH = '/v1/mgmt/tests/generate/otp'
42
+ USER_GENERATE_MAGIC_LINK_FOR_TEST_PATH = '/v1/mgmt/tests/generate/magiclink'
43
+ USER_GENERATE_ENCHANTED_LINK_FOR_TEST_PATH = '/v1/mgmt/tests/generate/enchantedlink'
44
+ USER_GENERATE_EMBEDDED_LINK_PATH = '/v1/mgmt/user/signin/embeddedlink'
45
+
46
+ # access key
47
+ ACCESS_KEY_CREATE_PATH = '/v1/mgmt/accesskey/create'
48
+ ACCESS_KEY_LOAD_PATH = '/v1/mgmt/accesskey'
49
+ ACCESS_KEYS_SEARCH_PATH = '/v1/mgmt/accesskey/search'
50
+ ACCESS_KEY_UPDATE_PATH = '/v1/mgmt/accesskey/update'
51
+ ACCESS_KEY_DEACTIVATE_PATH = '/v1/mgmt/accesskey/deactivate'
52
+ ACCESS_KEY_ACTIVATE_PATH = '/v1/mgmt/accesskey/activate'
53
+ ACCESS_KEY_DELETE_PATH = '/v1/mgmt/accesskey/delete'
54
+
55
+ # sso
56
+ SSO_SETTINGS_PATH = '/v2/mgmt/sso/settings'
57
+ SSO_OIDC_PATH = '/v1/mgmt/sso/oidc' # configure ssp settings via oidc
58
+ SSO_OIDC_CREATE_APP_PATH = '/v1/mgmt/sso/idp/app/oidc/create'
59
+ SSO_OIDC_UPDATE_APP_PATH = '/v1/mgmt/sso/idp/app/oidc/create'
60
+ SSO_SAML_PATH = '/v1/mgmt/sso/saml' # configure ssp settings via saml
61
+ SSO_SAML_METADATA_PATH = '/v1/mgmt/sso/saml/metadata' # configure ssp settings via saml metadata
62
+
63
+ # SCIM
64
+ SCIM_GROUPS_PATH = '/scim/v2/Groups'
65
+ SCIM_RESOURCE_TYPES_PATH = '/scim/v2/ResourceTypes'
66
+ SCIM_SERVICE_PROVIDER_CONFIG_PATH = '/scim/v2/ServiceProviderConfig'
67
+ SCIM_USERS_PATH = '/scim/v2/Users'
68
+
69
+ # jwt
70
+ UPDATE_JWT_PATH = '/v1/mgmt/jwt/update'
71
+
72
+ # permission
73
+ PERMISSION_CREATE_PATH = '/v1/mgmt/permission/create'
74
+ PERMISSION_UPDATE_PATH = '/v1/mgmt/permission/update'
75
+ PERMISSION_DELETE_PATH = '/v1/mgmt/permission/delete'
76
+ PERMISSION_LOAD_ALL_PATH = '/v1/mgmt/permission/all'
77
+
78
+ # role
79
+ ROLE_CREATE_PATH = '/v1/mgmt/role/create'
80
+ ROLE_UPDATE_PATH = '/v1/mgmt/role/update'
81
+ ROLE_DELETE_PATH = '/v1/mgmt/role/delete'
82
+ ROLE_LOAD_ALL_PATH = '/v1/mgmt/role/all'
83
+
84
+ # flow
85
+ FLOW_LIST_PATH = '/v1/mgmt/flow/list'
86
+ FLOW_IMPORT_PATH = '/v1/mgmt/flow/import'
87
+ FLOW_EXPORT_PATH = '/v1/mgmt/flow/export'
88
+
89
+ # theme
90
+ THEME_IMPORT_PATH = '/v1/mgmt/theme/import'
91
+ THEME_EXPORT_PATH = '/v1/mgmt/theme/export'
92
+
93
+ # group
94
+ GROUP_LOAD_ALL_PATH = '/v1/mgmt/group/all'
95
+ GROUP_LOAD_ALL_FOR_MEMBER_PATH = '/v1/mgmt/group/member/all'
96
+ GROUP_LOAD_ALL_GROUP_MEMBERS_PATH = '/v1/mgmt/group/members'
97
+
98
+ # Audit
99
+ AUDIT_SEARCH = '/v1/mgmt/audit/search'
100
+
101
+ # Authz ReBAC
102
+ AUTHZ_SCHEMA_SAVE = '/v1/mgmt/authz/schema/save'
103
+ AUTHZ_SCHEMA_DELETE = '/v1/mgmt/authz/schema/delete'
104
+ AUTHZ_SCHEMA_LOAD = '/v1/mgmt/authz/schema/load'
105
+ AUTHZ_NS_SAVE = '/v1/mgmt/authz/ns/save'
106
+ AUTHZ_NS_DELETE = '/v1/mgmt/authz/ns/delete'
107
+ AUTHZ_RD_SAVE = '/v1/mgmt/authz/rd/save'
108
+ AUTHZ_RD_DELETE = '/v1/mgmt/authz/rd/delete'
109
+ AUTHZ_RE_CREATE = '/v1/mgmt/authz/re/create'
110
+ AUTHZ_RE_DELETE = '/v1/mgmt/authz/re/delete'
111
+ AUTHZ_RE_DELETE_RESOURCES = '/v1/mgmt/authz/re/deleteresources'
112
+ AUTHZ_RE_HAS_RELATIONS = '/v1/mgmt/authz/re/has'
113
+ AUTHZ_RE_WHO = '/v1/mgmt/authz/re/who'
114
+ AUTHZ_RE_RESOURCE = '/v1/mgmt/authz/re/resource'
115
+ AUTHZ_RE_TARGETS = '/v1/mgmt/authz/re/targets'
116
+ AUTHZ_RE_TARGET_ALL = '/v1/mgmt/authz/re/targetall'
117
+
118
+ # Project
119
+ PROJECT_UPDATE_NAME = '/v1/mgmt/project/update/name'
120
+ PROJECT_CLONE = '/v1/mgmt/project/clone'
121
+ PROJECT_EXPORT_PATH = '/v1/mgmt/project/export'
122
+ PROJECT_IMPORT_PATH = '/v1/mgmt/project/import'
123
+ PROJECT_DELETE_PATH = '/v1/mgmt/project/delete'
124
+
125
+ def associated_tenants_to_hash_array(associated_tenants = [])
126
+ # Represents a tenant association for a User or Access Key. The tenant_id is required to denote
127
+ # which tenant the user or access key belongs to. The role_names array is an optional list of
128
+ # roles for the user or access key in this specific tenant.
129
+ # @param [Array] associated_tenants - list of associated tenants in the format of
130
+ # [{tenant_id: 'tenant_id', role_names: ['role_name1', 'role_name2']}]
131
+ associated_tenants = associated_tenants.nil? ? [] : associated_tenants
132
+ associated_tenant_list = []
133
+ associated_tenants.each do |tenant|
134
+ associated_tenant_list.append(
135
+ {
136
+ "tenantId": tenant[:tenant_id],
137
+ "roleNames": tenant[:role_names]
138
+ }
139
+ )
140
+ end
141
+ associated_tenant_list
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Descope
4
+ module Api
5
+ module V1
6
+ module Management
7
+ # Management API calls
8
+ module Flow
9
+ include Descope::Api::V1::Management::Common
10
+
11
+ # List all project flows
12
+ # @see https://docs.descope.com/api/openapi/flowmanagement/operation/ListFlows/
13
+ # To list all flows, send an empty body such as: { } or { "ids": [] }.
14
+ #
15
+ # To search for a flow or several flows, send a body with the flowIds you want to search such as { "ids": ["sign-in"] } or { "ids": ["sign-in", "sign-up"] }.
16
+ def list_or_search_flows(ids = [])
17
+ request_params = { ids: }
18
+ post(FLOW_LIST_PATH, request_params)
19
+ end
20
+
21
+ # Export the given flow id flow and screens.
22
+ # @see https://docs.descope.com/api/openapi/flowmanagement/operation/ExportFlow/
23
+ def export_flow(flow_id = nil)
24
+ request_params = { flowId: flow_id }
25
+ post(FLOW_EXPORT_PATH, request_params)
26
+ end
27
+
28
+ # Import the given flow and screens.
29
+ # @see https://docs.descope.com/api/openapi/flowmanagement/operation/ImportFlow/
30
+ def import_flow(flow_id: nil, flow: nil, screens: nil)
31
+ request_params = {
32
+ flowId: flow_id,
33
+ flow:,
34
+ screens:
35
+ }
36
+ post(FLOW_IMPORT_PATH, request_params)
37
+ end
38
+
39
+ # Export the current project theme.
40
+ # @see https://docs.descope.com/api/openapi/flowmanagement/operation/ExportTheme/
41
+ def export_theme
42
+ post(THEME_EXPORT_PATH)
43
+ end
44
+
45
+ # Import the current project theme.
46
+ # @see https://docs.descope.com/api/openapi/flowmanagement/operation/ImportTheme/
47
+ def import_theme(theme)
48
+ request_params = { theme: }
49
+ post(THEME_IMPORT_PATH, request_params)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Descope
4
+ module Api
5
+ module V1
6
+ module Management
7
+ # Management API calls
8
+ module Password
9
+ include Descope::Api::V1::Management::Common
10
+
11
+ def get_password_settings(tenant_id)
12
+ # Get password settings for the provided tenant id.
13
+ get(PASSWORD_SETTINGS_PATH, { tenantId: tenant_id })
14
+ end
15
+
16
+ def update_password_settings(settings)
17
+ unless settings.is_a?(Hash)
18
+ raise Descope::ArgumentException.new('Password settings must be a Hash', code: 400)
19
+ end
20
+
21
+ # Update password settings for the provided tenant id.
22
+ body = compose_settings_body(settings)
23
+ post(PASSWORD_SETTINGS_PATH, body)
24
+ end
25
+
26
+ private
27
+
28
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
29
+ def compose_settings_body(settings)
30
+ body = {}
31
+ body['minLength'] = settings[:min_length] if settings.key?(:min_length)
32
+ body['lowercase'] = settings[:lowercase] if settings.key?(:lowercase)
33
+ body['uppercase'] = settings[:uppercase] if settings.key?(:uppercase)
34
+ body['number'] = settings[:number] if settings.key?(:number)
35
+ body['nonAlphanumeric'] = settings[:non_alphanumeric] if settings.key?(:non_alphanumeric)
36
+ body['expiration'] = settings[:expiration] if settings.key?(:expiration)
37
+ body['expirationWeeks'] = settings[:expiration_weeks] if settings.key?(:expiration_weeks)
38
+ body['reuse'] = settings[:reuse] if settings.key?(:reuse)
39
+ body['reuseAmount'] = settings[:reuse_amount] if settings.key?(:reuse_amount)
40
+ body['lock'] = settings[:lock] if settings.key?(:lock)
41
+ body['lockAttempts'] = settings[:lock_attempts] if settings.key?(:lock_attempts)
42
+ body['emailServiceProvider'] = settings[:email_service_provider] if settings.key?(:email_service_provider)
43
+ body['emailSubject'] = settings[:email_subject] if settings.key?(:email_subject)
44
+ body['emailBody'] = settings[:email_body] if settings.key?(:email_body)
45
+ body['resetAuthMethod'] = settings[:reset_auth_method] if settings.key?(:reset_auth_method)
46
+ body['emailBodyPlainText'] = settings[:email_body_plain_text] if settings.key?(:email_body_plain_text)
47
+ if settings.key?(:use_email_body_plain_text)
48
+ body['useEmailBodyPlainText'] = settings[:use_email_body_plain_text]
49
+ end
50
+ body['tenantId'] = settings[:tenant_id] if settings.key?(:tenant_id)
51
+ body['enabled'] = settings[:enabled] if settings.key?(:enabled)
52
+ body
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Descope
4
+ module Api
5
+ module V1
6
+ module Management
7
+ # Management API calls
8
+ module Permission
9
+ include Descope::Mixins::Validation
10
+ include Descope::Api::V1::Management::Common
11
+
12
+
13
+ def create_permission(name:, description: nil)
14
+ # Create a new permission.
15
+ # @see https://docs.descope.com/api/openapi/permissionmanagement/operation/CreatePermission/
16
+ request_params = {
17
+ name:,
18
+ description:
19
+ }
20
+ post(PERMISSION_CREATE_PATH, request_params)
21
+ end
22
+
23
+ def update_permission(name: nil, new_name: nil, description: nil)
24
+ # Update an existing permission with the given various fields. IMPORTANT: All parameters are used as overrides
25
+ # to the existing permission. Empty fields will override populated fields. Use carefully.
26
+ # @see https://docs.descope.com/api/openapi/permissionmanagement/operation/UpdatePermission/
27
+ request_params = {
28
+ name:,
29
+ newName: new_name,
30
+ description:
31
+ }
32
+ post(PERMISSION_UPDATE_PATH, request_params)
33
+ end
34
+
35
+ def delete_permission(name = nil)
36
+ # Delete an existing permission. IMPORTANT: This action is irreversible. Use carefully.
37
+ post(PERMISSION_DELETE_PATH, { name: })
38
+ end
39
+
40
+ def load_all_permissions
41
+ # Load all permissions.
42
+ get(PERMISSION_LOAD_ALL_PATH)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Descope
4
+ module Api
5
+ module V1
6
+ module Management
7
+ # Management API calls
8
+ module Project
9
+ include Descope::Api::V1::Management::Common
10
+
11
+ def rename_project(name)
12
+ # Rename a project.
13
+ post(PROJECT_UPDATE_NAME, { name: })
14
+ end
15
+
16
+ def export_project
17
+ # Exports all settings and configurations for a project and returns the
18
+ # raw JSON files response as an object.
19
+ # - This action is supported only with a pro license or above.
20
+ # - Users, tenants and access keys are not cloned.
21
+ # - Secrets, keys and tokens are not stripped from the exported data.
22
+ # @returns a HASH containing the exported JSON files payload.
23
+ post(PROJECT_EXPORT_PATH)
24
+ end
25
+
26
+ def import_project(files: nil, excludes: nil)
27
+ # Import a project.
28
+ # The argument of files should be the output of the export project endpoint
29
+ body = { files: }
30
+ body[:excludes] = excludes unless excludes.nil?
31
+ post(PROJECT_IMPORT_PATH, body)
32
+ end
33
+
34
+ def delete_project
35
+ # Delete the current project. IMPORTANT: This action is irreversible. Use carefully.
36
+ post(PROJECT_DELETE_PATH)
37
+ end
38
+
39
+ def clone_project(name: nil, tag: nil)
40
+ # Clone the current project, including its settings and configurations.
41
+ # - This action is supported only with a pro license or above.
42
+ # - Users, tenants and access keys are not cloned.
43
+ request_params = {
44
+ name:,
45
+ tag:
46
+ }
47
+ post(PROJECT_CLONE, request_params)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Descope
4
+ module Api
5
+ module V1
6
+ module Management
7
+ # Management API calls
8
+ module Role
9
+ include Descope::Api::V1::Management::Common
10
+
11
+ def create_role(name: nil, description: nil, permission_names: nil)
12
+ # Create a new role.
13
+ permission_names ||= []
14
+ request_params = {
15
+ name:,
16
+ description:,
17
+ permissionNames: permission_names
18
+ }
19
+ post(ROLE_CREATE_PATH, request_params)
20
+ end
21
+
22
+ def update_role(name: nil, new_name: nil, description: nil, permission_names: nil)
23
+ # Update an existing role with the given various fields. IMPORTANT: All parameters are used as overrides
24
+ # to the existing role. Empty fields will override populated fields. Use carefully.
25
+ permission_names ||= []
26
+ request_params = {
27
+ name:,
28
+ newName: new_name,
29
+ description:,
30
+ permissionNames: permission_names
31
+ }
32
+ post(ROLE_UPDATE_PATH, request_params)
33
+ end
34
+
35
+ def delete_role(name)
36
+ # Delete an existing role. IMPORTANT: This action is irreversible. Use carefully.
37
+ post(ROLE_DELETE_PATH, { name: })
38
+ end
39
+
40
+ def load_all_roles
41
+ # Load all roles.
42
+ get(ROLE_LOAD_ALL_PATH)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end