diff --git a/.rubocop.yml b/.rubocop.yml index b7ff052d..de306e1b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ inherit_from: .rubocop_todo.yml -require: +plugins: - rubocop-rails Rails: Enabled: False diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e155e35e..56515a47 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -2,7 +2,7 @@ Metrics/MethodLength: Enabled: false Metrics/BlockLength: Enabled: false -Metrics/LineLength: +Layout/LineLength: Max: 121 Metrics/ParameterLists: Enabled: false diff --git a/README.md b/README.md index 7dc3ce24..f9cc99ad 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,49 @@ descope_client = Descope::Client.new( ) ``` +### Auth Management Key + +Authentication methods whose public access has been disabled can still be used by providing an +auth management key. When set, it is sent along with every authentication request. + +Create one in the [Descope Console](https://app.descope.com/settings/company/managementkeys) with +either the `Authentication` or `Full Access` scope on the project or company. + +```ruby +# Initialized after setting the DESCOPE_PROJECT_ID and DESCOPE_AUTH_MANAGEMENT_KEY env vars +descope_client = Descope::Client.new({}) + +# ** Or directly ** +descope_client = Descope::Client.new( + { + project_id: '', + auth_management_key: ENV['AUTH_MGMT_KEY'] + } +) +``` + +**Note**: the auth management key can, and probably should, be a different management key than the +one provided for [management API usage](#setup-1). The auth management key is never sent on +management requests, and the management key is never sent on authentication requests. + +### Request timeout + +Every request is bounded by a 60 second timeout, matching the other Descope server SDKs. Raise it +for calls that legitimately take longer, such as `export_project` on a large project: + +```ruby +descope_client = Descope::Client.new( + { + project_id: '', + timeout_seconds: 180 + } +) +``` + ### Important Logging note You may pass `log_level: 'debug'` to the client config or use `DESCOPE_LOG_LEVEL` env var. -Be aware that only the management key is truncated, and the JWT responses are printed on debug +Be aware that everything after the project ID in the `Authorization` header is masked, but the JWT +responses are printed on debug Do not run with log level debug on Production! @@ -504,6 +544,8 @@ in nature. Please use responsibly. To use the management API you'll need a `Management Key` along with your `Project ID`. Create one in the [Descope Console](https://app.descope.com/settings/company/managementkeys). +This key is used only for management functions - to reach authentication methods whose public +access has been disabled, use the [Auth Management Key](#auth-management-key) instead. ```ruby require 'descope' @@ -1457,6 +1499,15 @@ You can find various usage examples in the [examples folder](https://github.com/ bundle install ``` +### Environment variables + +```bash +export DESCOPE_PROJECT_ID= +export DESCOPE_MANAGEMENT_KEY= +# Optional, only needed for authentication methods with disabled public access +export DESCOPE_AUTH_MANAGEMENT_KEY= +``` + ### Run tests Running all tests: diff --git a/lib/descope/api/v1/auth/enchantedlink.rb b/lib/descope/api/v1/auth/enchantedlink.rb index e000565b..04024ec3 100644 --- a/lib/descope/api/v1/auth/enchantedlink.rb +++ b/lib/descope/api/v1/auth/enchantedlink.rb @@ -17,7 +17,7 @@ def enchanted_link_sign_in(login_id: nil, uri: nil, login_options: nil, refresh_ validate_refresh_token_provided(login_options, refresh_token) body = enchanted_link_compose_signin_body(login_id, uri, login_options) uri = enchanted_link_compose_signin_url - post(uri, body, nil, refresh_token) + post(uri, body, {}, refresh_token) end def enchanted_link_sign_up(login_id: nil, uri: nil, user: {}) diff --git a/lib/descope/api/v1/management/access_key.rb b/lib/descope/api/v1/management/access_key.rb index 8006a910..ae8756fe 100644 --- a/lib/descope/api/v1/management/access_key.rb +++ b/lib/descope/api/v1/management/access_key.rb @@ -16,7 +16,8 @@ def create_access_key(name: nil, expire_time: nil, role_names: nil, key_tenants: role_names ||= [] key_tenants ||= [] validate_tenants(key_tenants) - post(ACCESS_KEY_CREATE_PATH, access_key_compose_create_body(name, expire_time, role_names, key_tenants, custom_claims)) + mgmt_post(ACCESS_KEY_CREATE_PATH, + access_key_compose_create_body(name, expire_time, role_names, key_tenants, custom_claims)) end def access_key_compose_create_body(name, expire_time, role_names, key_tenants, custom_claims) @@ -34,7 +35,7 @@ def load_access_key(id) # @param id [string] The access key id. # @see https://docs.descope.com/api/openapi/accesskeymanagement/operation/LoadAccessKey/ - get(ACCESS_KEY_LOAD_PATH, { id: }) + mgmt_get(ACCESS_KEY_LOAD_PATH, { id: }) end def search_all_access_keys(tenant_ids = nil) @@ -43,7 +44,7 @@ def search_all_access_keys(tenant_ids = nil) request_params = { tenantIds: tenant_ids } - post(ACCESS_KEYS_SEARCH_PATH, request_params) + mgmt_post(ACCESS_KEYS_SEARCH_PATH, request_params) end def update_access_key(id: nil, name: nil) @@ -53,27 +54,27 @@ def update_access_key(id: nil, name: nil) id:, name: } - post(ACCESS_KEY_UPDATE_PATH, request_params) + mgmt_post(ACCESS_KEY_UPDATE_PATH, request_params) end def deactivate_access_key(id) # Deactivate an existing access key. IMPORTANT: This deactivated key will not be usable from this stage. # It will, however, persist, and can be activated again if needed. # @see https://docs.descope.com/api/openapi/accesskeymanagement/operation/DeactivateAccessKey/ - post(ACCESS_KEY_DEACTIVATE_PATH, { id: }) + mgmt_post(ACCESS_KEY_DEACTIVATE_PATH, { id: }) end def activate_access_key(id) # Activate an existing access key. IMPORTANT: Only deactivated keys can be activated again, # and become usable once more. New access keys are active by default. # @see https://docs.descope.com/api/openapi/accesskeymanagement/operation/ActivateAccessKey/ - post(ACCESS_KEY_ACTIVATE_PATH, { id: }) + mgmt_post(ACCESS_KEY_ACTIVATE_PATH, { id: }) end def delete_access_key(id) # Delete an existing access key. IMPORTANT: This action is irreversible. Use carefully. # @see https://docs.descope.com/api/openapi/accesskeymanagement/operation/DeleteAccessKey/ - post(ACCESS_KEY_DELETE_PATH, { id: }) + mgmt_post(ACCESS_KEY_DELETE_PATH, { id: }) end end end diff --git a/lib/descope/api/v1/management/analytics.rb b/lib/descope/api/v1/management/analytics.rb index 7710fb0d..04a74ab2 100644 --- a/lib/descope/api/v1/management/analytics.rb +++ b/lib/descope/api/v1/management/analytics.rb @@ -53,7 +53,7 @@ def analytics_search( request_params[:geos] = geos unless geos.nil? request_params[:tenants] = tenants unless tenants.nil? - post(ANALYTICS_SEARCH_PATH, request_params) + mgmt_post(ANALYTICS_SEARCH_PATH, request_params) end end end diff --git a/lib/descope/api/v1/management/audit.rb b/lib/descope/api/v1/management/audit.rb index 49bdf386..49af0bc5 100644 --- a/lib/descope/api/v1/management/audit.rb +++ b/lib/descope/api/v1/management/audit.rb @@ -52,7 +52,7 @@ def audit_search( request_params[:text] = text unless text.nil? request_params[:from] = from_ts.to_i * 1000 unless from_ts.nil? request_params[:to] = to_ts.to_i * 1000 unless to_ts.nil? - res = post(AUDIT_SEARCH, request_params) + res = mgmt_post(AUDIT_SEARCH, request_params) raise Descope::AuthException, "could not get audits: #{res}" if res['audits'].nil? { 'audits' => res['audits'].map { |audit| convert_audit_record(audit) } } @@ -79,7 +79,7 @@ def audit_create_event(action: nil, type: nil, data: nil, user_id: nil, actor_id } request_params[:userId] = user_id unless user_id.nil? - post(AUDIT_CREATE_EVENT, request_params) + mgmt_post(AUDIT_CREATE_EVENT, request_params) end private diff --git a/lib/descope/api/v1/management/authz.rb b/lib/descope/api/v1/management/authz.rb index 9ca3cb29..4364ab02 100644 --- a/lib/descope/api/v1/management/authz.rb +++ b/lib/descope/api/v1/management/authz.rb @@ -40,17 +40,17 @@ def authz_save_schema(schema: nil, upgrade: false) # Schema name can be used for projects to track versioning. # @see https://docs.descope.com/api/openapi/authz/operation/SaveSchema/ request_params = { schema:, upgrade: } - post(AUTHZ_SCHEMA_SAVE, request_params) + mgmt_post(AUTHZ_SCHEMA_SAVE, request_params) end def authz_delete_schema # Delete the schema for the project which will also delete all relations. - post(AUTHZ_SCHEMA_DELETE) + mgmt_post(AUTHZ_SCHEMA_DELETE) end def authz_load_schema # Load the schema for the project. - post(AUTHZ_SCHEMA_LOAD) + mgmt_post(AUTHZ_SCHEMA_LOAD) end def authz_save_namespace(namespace: nil, old_name: nil, schema_name: nil) @@ -59,14 +59,14 @@ def authz_save_namespace(namespace: nil, old_name: nil, schema_name: nil) request_params = { namespace: namespace } request_params[:oldName] = old_name unless old_name.nil? request_params[:schemaName] = schema_name unless schema_name.nil? - post(AUTHZ_NS_SAVE, request_params) + mgmt_post(AUTHZ_NS_SAVE, request_params) end def authz_delete_namespace(name: nil, schema_name: nil) # Delete the given namespace request_params = { name: name } request_params[:schemaName] = schema_name unless schema_name.nil? - post(AUTHZ_NS_DELETE, request_params) + mgmt_post(AUTHZ_NS_DELETE, request_params) end def authz_save_relation_definition(relation_definition: nil, namespace: nil, old_name: nil, schema_name: nil) @@ -78,14 +78,14 @@ def authz_save_relation_definition(relation_definition: nil, namespace: nil, old } request_params[:old_name] = old_name unless old_name.nil? request_params[:schemaName] = schema_name unless schema_name.nil? - post(AUTHZ_RD_SAVE, request_params) + mgmt_post(AUTHZ_RD_SAVE, request_params) end def authz_delete_relation_definition(name: nil, namespace: nil, schema_name: nil) # Delete the given relation definition request_params = { name: , namespace: } request_params[:schemaName] = schema_name unless schema_name.nil? - post(AUTHZ_RD_DELETE, request_params) + mgmt_post(AUTHZ_RD_DELETE, request_params) end def authz_create_relations(relations = nil) @@ -114,22 +114,22 @@ def authz_create_relations(relations = nil) # } # Each relation should have exactly one of: target, targetSet, query # Regarding query above, it should be specified if the target is a set of users that matches the query - all fields are optional - post(AUTHZ_RE_CREATE, { relations: }) + mgmt_post(AUTHZ_RE_CREATE, { relations: }) end def authz_delete_relations(relations = nil) # Delete the given relations based on the existing schema - post(AUTHZ_RE_DELETE, { relations: }) + mgmt_post(AUTHZ_RE_DELETE, { relations: }) end def authz_delete_relations_for_resources(resources = nil) # Delete all relations for the given resources - post(AUTHZ_RE_DELETE_RESOURCES, { resources: }) + mgmt_post(AUTHZ_RE_DELETE_RESOURCES, { resources: }) end def authz_has_relations?(relation_queries = nil) # Queries the given relations to see if they exist returning true if they do - post(AUTHZ_RE_HAS_RELATIONS, { relationQueries: relation_queries }) + mgmt_post(AUTHZ_RE_HAS_RELATIONS, { relationQueries: relation_queries }) end def authz_who_can_access?(resource: nil, relation_definition: nil, namespace: nil) @@ -139,21 +139,21 @@ def authz_who_can_access?(resource: nil, relation_definition: nil, namespace: ni relationDefinition: relation_definition, namespace: } - post(AUTHZ_RE_WHO, request_params) + mgmt_post(AUTHZ_RE_WHO, request_params) end def authz_resource_relations(resources: nil) - post(AUTHZ_RE_RESOURCE, { resources: }) + mgmt_post(AUTHZ_RE_RESOURCE, { resources: }) end def authz_target_relations(targets: nil) # Returns the list of all defined relations (not recursive) for the given targets. - post(AUTHZ_RE_TARGETS, { targets: }) + mgmt_post(AUTHZ_RE_TARGETS, { targets: }) end def authz_what_can_target_access?(target: nil) # Returns the list of all relations for the given target including derived relations from the schema tree. - res = post(AUTHZ_RE_TARGET_ALL, { target: }) + res = mgmt_post(AUTHZ_RE_TARGET_ALL, { target: }) raise Descope::AuthException, "could not get relation for target: #{res}" if res['relations'].nil? res['relations'] diff --git a/lib/descope/api/v1/management/descoper.rb b/lib/descope/api/v1/management/descoper.rb index f7ed435f..eed49847 100644 --- a/lib/descope/api/v1/management/descoper.rb +++ b/lib/descope/api/v1/management/descoper.rb @@ -11,7 +11,7 @@ module Descoper def create_descoper(descopers = nil) # Create the given descopers. # descopers (Array): the descopers to create. - put(DESCOPER_CREATE_PATH, { descopers: descopers }) + mgmt_put(DESCOPER_CREATE_PATH, { descopers: descopers }) end def update_descoper(id: nil, attributes: nil, rbac: nil) @@ -21,22 +21,22 @@ def update_descoper(id: nil, attributes: nil, rbac: nil) attributes: attributes, rbac: rbac } - patch(DESCOPER_UPDATE_PATH, request_params) + mgmt_patch(DESCOPER_UPDATE_PATH, request_params) end def get_descoper(id: nil) # Get a descoper by id. - get(DESCOPER_GET_PATH, { id: id }) + mgmt_get(DESCOPER_GET_PATH, { id: id }) end def delete_descoper(id: nil) # Delete a descoper by id. - delete(DESCOPER_DELETE_PATH, { id: id }) + mgmt_delete(DESCOPER_DELETE_PATH, { id: id }) end def search_descopers # Search (list) all descopers. - post(DESCOPER_SEARCH_PATH, {}) + mgmt_post(DESCOPER_SEARCH_PATH, {}) end end end diff --git a/lib/descope/api/v1/management/engine.rb b/lib/descope/api/v1/management/engine.rb index 634e0003..1914d51f 100644 --- a/lib/descope/api/v1/management/engine.rb +++ b/lib/descope/api/v1/management/engine.rb @@ -10,32 +10,32 @@ module Engine def create_engine(name:) # Create a new engine with the given name. - post(ENGINE_CREATE_PATH, { name: }) + mgmt_post(ENGINE_CREATE_PATH, { name: }) end def update_engine(id:, name:) # Update an existing engine with the given id and name. - post(ENGINE_UPDATE_PATH, { id:, name: }) + mgmt_post(ENGINE_UPDATE_PATH, { id:, name: }) end def delete_engine(id:) # Delete an existing engine. IMPORTANT: This action is irreversible. Use carefully. - post(ENGINE_DELETE_PATH, { id: }) + mgmt_post(ENGINE_DELETE_PATH, { id: }) end def load_engine(id:) # Load engine by id. - get(ENGINE_LOAD_PATH, { id: }) + mgmt_get(ENGINE_LOAD_PATH, { id: }) end def load_all_engines # Load all engines. - get(ENGINE_LOAD_ALL_PATH) + mgmt_get(ENGINE_LOAD_ALL_PATH) end def rotate_engine_secret(id:) # Rotate the secret for the given engine. - post(ENGINE_ROTATE_SECRET_PATH, { id: }) + mgmt_post(ENGINE_ROTATE_SECRET_PATH, { id: }) end end end diff --git a/lib/descope/api/v1/management/fga.rb b/lib/descope/api/v1/management/fga.rb index e96563a0..c679991d 100644 --- a/lib/descope/api/v1/management/fga.rb +++ b/lib/descope/api/v1/management/fga.rb @@ -11,51 +11,51 @@ module FGA def fga_save_schema(schema: nil) # Create or update the FGA schema. # schema (String): the schema DSL string. - post(FGA_SAVE_SCHEMA_PATH, { dsl: schema }) + mgmt_post(FGA_SAVE_SCHEMA_PATH, { dsl: schema }) end def fga_load_schema # Load the FGA schema for the project. - get(FGA_LOAD_SCHEMA_PATH) + mgmt_get(FGA_LOAD_SCHEMA_PATH) end def fga_create_relations(tuples: nil) # Create the given relations (tuples) based on the existing schema. - post(FGA_CREATE_RELATIONS_PATH, { tuples: }) + mgmt_post(FGA_CREATE_RELATIONS_PATH, { tuples: }) end def fga_delete_relations(tuples: nil) # Delete the given relations (tuples) based on the existing schema. - post(FGA_DELETE_RELATIONS_PATH, { tuples: }) + mgmt_post(FGA_DELETE_RELATIONS_PATH, { tuples: }) end def fga_check(tuples: nil) # Check the given relations (tuples) to see if they are allowed. - post(FGA_CHECK_PATH, { tuples: }) + mgmt_post(FGA_CHECK_PATH, { tuples: }) end def fga_load_mappable_schema(tenant_id: nil, options: nil) # Load the mappable schema for the given tenant. request_params = { tenantId: tenant_id } request_params[:resourcesLimit] = options[:resourcesLimit] if options && options[:resourcesLimit] - get(FGA_LOAD_MAPPABLE_SCHEMA_PATH, request_params) + mgmt_get(FGA_LOAD_MAPPABLE_SCHEMA_PATH, request_params) end def fga_search_mappable_resources(tenant_id: nil, resources_queries: nil, options: nil) # Search for mappable resources for the given tenant. request_params = { tenantId: tenant_id, resourcesQueries: resources_queries } request_params[:resourcesLimit] = options[:resourcesLimit] if options && options[:resourcesLimit] - post(FGA_SEARCH_MAPPABLE_RESOURCES_PATH, request_params) + mgmt_post(FGA_SEARCH_MAPPABLE_RESOURCES_PATH, request_params) end def fga_load_resources_details(resource_identifiers: nil) # Load the details of the given resource identifiers. - post(FGA_RESOURCES_LOAD_PATH, { resourceIdentifiers: resource_identifiers }) + mgmt_post(FGA_RESOURCES_LOAD_PATH, { resourceIdentifiers: resource_identifiers }) end def fga_save_resources_details(resources_details: nil) # Save the details of the given resources. - post(FGA_RESOURCES_SAVE_PATH, { resourcesDetails: resources_details }) + mgmt_post(FGA_RESOURCES_SAVE_PATH, { resourcesDetails: resources_details }) end end end diff --git a/lib/descope/api/v1/management/flow.rb b/lib/descope/api/v1/management/flow.rb index c81576c9..81817610 100644 --- a/lib/descope/api/v1/management/flow.rb +++ b/lib/descope/api/v1/management/flow.rb @@ -15,14 +15,14 @@ module Flow # 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"] }. def list_or_search_flows(ids = []) request_params = { ids: } - post(FLOW_LIST_PATH, request_params) + mgmt_post(FLOW_LIST_PATH, request_params) end # Export the given flow id flow and screens. # @see https://docs.descope.com/api/openapi/flowmanagement/operation/ExportFlow/ def export_flow(flow_id = nil) request_params = { flowId: flow_id } - post(FLOW_EXPORT_PATH, request_params) + mgmt_post(FLOW_EXPORT_PATH, request_params) end # Import the given flow and screens. @@ -33,20 +33,20 @@ def import_flow(flow_id: nil, flow: nil, screens: nil) flow:, screens: } - post(FLOW_IMPORT_PATH, request_params) + mgmt_post(FLOW_IMPORT_PATH, request_params) end # Export the current project theme. # @see https://docs.descope.com/api/openapi/flowmanagement/operation/ExportTheme/ def export_theme - post(THEME_EXPORT_PATH) + mgmt_post(THEME_EXPORT_PATH) end # Import the current project theme. # @see https://docs.descope.com/api/openapi/flowmanagement/operation/ImportTheme/ def import_theme(theme) request_params = { theme: } - post(THEME_IMPORT_PATH, request_params) + mgmt_post(THEME_IMPORT_PATH, request_params) end end end diff --git a/lib/descope/api/v1/management/group.rb b/lib/descope/api/v1/management/group.rb index e5dad27c..48ac145b 100644 --- a/lib/descope/api/v1/management/group.rb +++ b/lib/descope/api/v1/management/group.rb @@ -10,12 +10,12 @@ module Group def load_all_groups(tenant_id:) # Load all groups for a given tenant id. - post(GROUP_LOAD_ALL_PATH, { tenantId: tenant_id }) + mgmt_post(GROUP_LOAD_ALL_PATH, { tenantId: tenant_id }) end def load_all_groups_for_members(tenant_id:, user_ids: nil, login_ids: nil) # Load all groups for the given user's or login IDs (can be given either). - post( + mgmt_post( GROUP_LOAD_ALL_FOR_MEMBER_PATH, { tenantId: tenant_id, @@ -27,7 +27,7 @@ def load_all_groups_for_members(tenant_id:, user_ids: nil, login_ids: nil) def load_all_group_members(tenant_id:, group_id:) # Load all members of the given group id. - post( + mgmt_post( GROUP_LOAD_ALL_GROUP_MEMBERS_PATH, { tenantId: tenant_id, diff --git a/lib/descope/api/v1/management/jwt_template.rb b/lib/descope/api/v1/management/jwt_template.rb index aedbb412..b5618a22 100644 --- a/lib/descope/api/v1/management/jwt_template.rb +++ b/lib/descope/api/v1/management/jwt_template.rb @@ -19,28 +19,28 @@ def create_jwt_template(template: nil) # "conformanceIssuer": True|False, # "authSchema": "one of default|tenantOnly|none" # } - post(JWT_TEMPLATE_CREATE_PATH, { template: }) + mgmt_post(JWT_TEMPLATE_CREATE_PATH, { template: }) end def update_jwt_template(template: nil) # Update an existing JWT template. # The given template must include an "id" field. - post(JWT_TEMPLATE_UPDATE_PATH, { template: }) + mgmt_post(JWT_TEMPLATE_UPDATE_PATH, { template: }) end def delete_jwt_template(id: nil) # Delete the JWT template with the given id. - post(JWT_TEMPLATE_DELETE_PATH, { id: }) + mgmt_post(JWT_TEMPLATE_DELETE_PATH, { id: }) end def list_jwt_templates # Load all JWT templates for the project. - post(JWT_TEMPLATE_LIST_PATH, {}) + mgmt_post(JWT_TEMPLATE_LIST_PATH, {}) end def load_jwt_template(id: nil) # Load the JWT template with the given id. - post(JWT_TEMPLATE_LOAD_PATH, { id: }) + mgmt_post(JWT_TEMPLATE_LOAD_PATH, { id: }) end end end diff --git a/lib/descope/api/v1/management/lists.rb b/lib/descope/api/v1/management/lists.rb index 6399f934..c7349159 100644 --- a/lib/descope/api/v1/management/lists.rb +++ b/lib/descope/api/v1/management/lists.rb @@ -13,7 +13,7 @@ def create_list(name: nil, type: nil, description: nil, data: nil) body = { name:, type: } body[:description] = description unless description.nil? body[:data] = data unless data.nil? - post(LIST_CREATE_PATH, body) + mgmt_post(LIST_CREATE_PATH, body) end def update_list(id: nil, name: nil, type: nil, description: nil, data: nil) @@ -21,67 +21,67 @@ def update_list(id: nil, name: nil, type: nil, description: nil, data: nil) body = { id:, name:, type: } body[:description] = description unless description.nil? body[:data] = data unless data.nil? - post(LIST_UPDATE_PATH, body) + mgmt_post(LIST_UPDATE_PATH, body) end def delete_list(id: nil) # Delete an existing list. IMPORTANT: This action is irreversible. Use carefully. - post(LIST_DELETE_PATH, { id: }) + mgmt_post(LIST_DELETE_PATH, { id: }) end def load_list(id: nil) # Load list by id. - get("#{LIST_LOAD_PATH}/#{id}") + mgmt_get("#{LIST_LOAD_PATH}/#{id}") end def load_list_by_name(name: nil) # Load list by name. - get("#{LIST_LOAD_BY_NAME_PATH}/#{name}") + mgmt_get("#{LIST_LOAD_BY_NAME_PATH}/#{name}") end def load_all_lists # Load all lists. - get(LIST_LOAD_ALL_PATH) + mgmt_get(LIST_LOAD_ALL_PATH) end def import_lists(lists: nil) # Import the given lists. - post(LIST_IMPORT_PATH, { lists: }) + mgmt_post(LIST_IMPORT_PATH, { lists: }) end def list_add_ips(id: nil, ips: nil) # Add the given IPs to the list with the given id. - post(LIST_ADD_IPS_PATH, { id:, ips: }) + mgmt_post(LIST_ADD_IPS_PATH, { id:, ips: }) end def list_remove_ips(id: nil, ips: nil) # Remove the given IPs from the list with the given id. - post(LIST_REMOVE_IPS_PATH, { id:, ips: }) + mgmt_post(LIST_REMOVE_IPS_PATH, { id:, ips: }) end def list_check_ip(id: nil, ip: nil) # Check whether the given IP exists in the list with the given id. - post(LIST_CHECK_IP_PATH, { id:, ip: }) + mgmt_post(LIST_CHECK_IP_PATH, { id:, ip: }) end def list_add_texts(id: nil, texts: nil) # Add the given texts to the list with the given id. - post(LIST_ADD_TEXTS_PATH, { id:, texts: }) + mgmt_post(LIST_ADD_TEXTS_PATH, { id:, texts: }) end def list_remove_texts(id: nil, texts: nil) # Remove the given texts from the list with the given id. - post(LIST_REMOVE_TEXTS_PATH, { id:, texts: }) + mgmt_post(LIST_REMOVE_TEXTS_PATH, { id:, texts: }) end def list_check_text(id: nil, text: nil) # Check whether the given text exists in the list with the given id. - post(LIST_CHECK_TEXT_PATH, { id:, text: }) + mgmt_post(LIST_CHECK_TEXT_PATH, { id:, text: }) end def clear_list(id: nil) # Clear all entries from the list with the given id. - post(LIST_CLEAR_PATH, { id: }) + mgmt_post(LIST_CLEAR_PATH, { id: }) end end end diff --git a/lib/descope/api/v1/management/management_key.rb b/lib/descope/api/v1/management/management_key.rb index 9fca93c0..7763343d 100644 --- a/lib/descope/api/v1/management/management_key.rb +++ b/lib/descope/api/v1/management/management_key.rb @@ -10,7 +10,7 @@ module ManagementKey def create_management_key(name:, description: nil, expires_in: 0, permitted_ips: nil, re_bac: nil) # Create a new management key. - put(MGMT_KEY_CREATE_PATH, { + mgmt_put(MGMT_KEY_CREATE_PATH, { name:, description:, expiresIn: expires_in, @@ -21,7 +21,7 @@ def create_management_key(name:, description: nil, expires_in: 0, permitted_ips: def update_management_key(id:, name:, description: nil, permitted_ips: nil, status: nil) # Update an existing management key. - patch(MGMT_KEY_UPDATE_PATH, { + mgmt_patch(MGMT_KEY_UPDATE_PATH, { id:, name:, description:, @@ -32,17 +32,17 @@ def update_management_key(id:, name:, description: nil, permitted_ips: nil, stat def get_management_key(id:) # Load an existing management key. - get(MGMT_KEY_GET_PATH, { id: }) + mgmt_get(MGMT_KEY_GET_PATH, { id: }) end def delete_management_key(id:) # Delete an existing management key. - post(MGMT_KEY_DELETE_PATH, { ids: [id] }) + mgmt_post(MGMT_KEY_DELETE_PATH, { ids: [id] }) end def search_management_keys(tenant_ids: nil, status: nil) # Search all management keys. - get(MGMT_KEY_SEARCH_PATH, { + mgmt_get(MGMT_KEY_SEARCH_PATH, { tenantIds: tenant_ids, status: }) diff --git a/lib/descope/api/v1/management/outbound_app.rb b/lib/descope/api/v1/management/outbound_app.rb index 0dbdcd49..52115e2b 100644 --- a/lib/descope/api/v1/management/outbound_app.rb +++ b/lib/descope/api/v1/management/outbound_app.rb @@ -47,7 +47,7 @@ def fetch_outbound_app_user_token(app_id:, user_id:, scopes: nil, with_refresh_t } end - post(OUTBOUND_APP_FETCH_USER_TOKEN_PATH, body) + mgmt_post(OUTBOUND_APP_FETCH_USER_TOKEN_PATH, body) end # Delete outbound application tokens by appId or userId. @@ -70,7 +70,7 @@ def delete_outbound_app_user_tokens(app_id: nil, user_id: nil) query_params[:appId] = app_id unless app_id.nil? || app_id.empty? query_params[:userId] = user_id unless user_id.nil? || user_id.empty? - delete(OUTBOUND_APP_DELETE_USER_TOKENS_PATH, query_params) + mgmt_delete(OUTBOUND_APP_DELETE_USER_TOKENS_PATH, query_params) end # Delete outbound application token by its ID. @@ -83,7 +83,7 @@ def delete_outbound_app_token_by_id(token_id:) validate_token_id(token_id) query_params = { id: token_id } - delete(OUTBOUND_APP_DELETE_TOKEN_BY_ID_PATH, query_params) + mgmt_delete(OUTBOUND_APP_DELETE_TOKEN_BY_ID_PATH, query_params) end private diff --git a/lib/descope/api/v1/management/password.rb b/lib/descope/api/v1/management/password.rb index a920a7a6..769aea90 100644 --- a/lib/descope/api/v1/management/password.rb +++ b/lib/descope/api/v1/management/password.rb @@ -10,7 +10,7 @@ module Password def get_password_settings(tenant_id) # Get password settings for the provided tenant id. - get(PASSWORD_SETTINGS_PATH, { tenantId: tenant_id }) + mgmt_get(PASSWORD_SETTINGS_PATH, { tenantId: tenant_id }) end def update_password_settings(settings) @@ -20,7 +20,7 @@ def update_password_settings(settings) # Update password settings for the provided tenant id. body = compose_settings_body(settings) - post(PASSWORD_SETTINGS_PATH, body) + mgmt_post(PASSWORD_SETTINGS_PATH, body) end private diff --git a/lib/descope/api/v1/management/permission.rb b/lib/descope/api/v1/management/permission.rb index 1b01257c..1d44d075 100644 --- a/lib/descope/api/v1/management/permission.rb +++ b/lib/descope/api/v1/management/permission.rb @@ -17,7 +17,7 @@ def create_permission(name:, description: nil) name:, description: } - post(PERMISSION_CREATE_PATH, request_params) + mgmt_post(PERMISSION_CREATE_PATH, request_params) end def update_permission(name: nil, new_name: nil, description: nil) @@ -29,17 +29,17 @@ def update_permission(name: nil, new_name: nil, description: nil) newName: new_name, description: } - post(PERMISSION_UPDATE_PATH, request_params) + mgmt_post(PERMISSION_UPDATE_PATH, request_params) end def delete_permission(name = nil) # Delete an existing permission. IMPORTANT: This action is irreversible. Use carefully. - post(PERMISSION_DELETE_PATH, { name: }) + mgmt_post(PERMISSION_DELETE_PATH, { name: }) end def load_all_permissions # Load all permissions. - get(PERMISSION_LOAD_ALL_PATH) + mgmt_get(PERMISSION_LOAD_ALL_PATH) end end end diff --git a/lib/descope/api/v1/management/project.rb b/lib/descope/api/v1/management/project.rb index 6362fba6..1ba74470 100644 --- a/lib/descope/api/v1/management/project.rb +++ b/lib/descope/api/v1/management/project.rb @@ -10,7 +10,7 @@ module Project def rename_project(name) # Rename a project. - post(PROJECT_UPDATE_NAME, { name: }) + mgmt_post(PROJECT_UPDATE_NAME, { name: }) end def export_project @@ -20,7 +20,7 @@ def export_project # - Users, tenants and access keys are not cloned. # - Secrets, keys and tokens are not stripped from the exported data. # @returns a HASH containing the exported JSON files payload. - post(PROJECT_EXPORT_PATH) + mgmt_post(PROJECT_EXPORT_PATH) end def import_project(files: nil, excludes: nil) @@ -28,12 +28,12 @@ def import_project(files: nil, excludes: nil) # The argument of files should be the output of the export project endpoint body = { files: } body[:excludes] = excludes unless excludes.nil? - post(PROJECT_IMPORT_PATH, body) + mgmt_post(PROJECT_IMPORT_PATH, body) end def delete_project # Delete the current project. IMPORTANT: This action is irreversible. Use carefully. - post(PROJECT_DELETE_PATH) + mgmt_post(PROJECT_DELETE_PATH) end def clone_project(name: nil, tag: nil) @@ -44,7 +44,7 @@ def clone_project(name: nil, tag: nil) name:, tag: } - post(PROJECT_CLONE, request_params) + mgmt_post(PROJECT_CLONE, request_params) end end end diff --git a/lib/descope/api/v1/management/role.rb b/lib/descope/api/v1/management/role.rb index 0e8a1471..7930227e 100644 --- a/lib/descope/api/v1/management/role.rb +++ b/lib/descope/api/v1/management/role.rb @@ -17,7 +17,7 @@ def create_role(name: nil, description: nil, permission_names: nil, tenant_id: n permissionNames: permission_names, tenantId: tenant_id } - post(ROLE_CREATE_PATH, request_params) + mgmt_post(ROLE_CREATE_PATH, request_params) end def update_role(name: nil, new_name: nil, description: nil, permission_names: nil, tenant_id: nil) @@ -31,7 +31,7 @@ def update_role(name: nil, new_name: nil, description: nil, permission_names: ni permissionNames: permission_names, tenantId: tenant_id } - post(ROLE_UPDATE_PATH, request_params) + mgmt_post(ROLE_UPDATE_PATH, request_params) end def delete_role(name: nil, tenant_id: nil) @@ -40,12 +40,12 @@ def delete_role(name: nil, tenant_id: nil) request_params = { name: } request_params[:tenantId] = tenant_id if tenant_id - post(ROLE_DELETE_PATH, request_params) + mgmt_post(ROLE_DELETE_PATH, request_params) end def load_all_roles # Load all roles. - get(ROLE_LOAD_ALL_PATH) + mgmt_get(ROLE_LOAD_ALL_PATH) end def search_roles(role_names: nil, tenant_ids: nil, role_name_like: nil, permission_names: nil) @@ -55,7 +55,7 @@ def search_roles(role_names: nil, tenant_ids: nil, role_name_like: nil, permissi request_params[:tenantIds] = tenant_ids if tenant_ids request_params[:roleNameLike] = role_name_like if role_name_like request_params[:permissionNames] = permission_names if permission_names - post(ROLE_SEARCH_PATH, request_params) + mgmt_post(ROLE_SEARCH_PATH, request_params) end end end diff --git a/lib/descope/api/v1/management/scim.rb b/lib/descope/api/v1/management/scim.rb index d00249cd..0a8a496e 100644 --- a/lib/descope/api/v1/management/scim.rb +++ b/lib/descope/api/v1/management/scim.rb @@ -11,21 +11,21 @@ module SCIM def scim_search_groups(filter: nil, start_index: nil, count: nil, excluded_attributes: nil) # Search SCIM Groups url = compose_scim_search_groups_url(filter, start_index, count, excluded_attributes) - get(url) + mgmt_get(url) end def scim_create_group(group_id: nil, display_name: nil, members: nil, external_id: nil, excluded_attributes: nil) # Create SCIM Group body = compose_scim_create_group_body(group_id, display_name, members, external_id, excluded_attributes) - post(SCIM_GROUPS_PATH, body) + mgmt_post(SCIM_GROUPS_PATH, body) end def scim_load_group(group_id: nil, display_name: nil, external_id: nil, excluded_attributes: nil) # Load SCIM Group, using a valid access key. validate_scim_group_id(group_id) url = compose_scim_create_group_url(group_id, display_name, external_id, excluded_attributes) - get(url) + mgmt_get(url) end def scim_update_group(group_id: nil, display_name: nil, members: nil, external_id: nil, @@ -33,38 +33,38 @@ def scim_update_group(group_id: nil, display_name: nil, members: nil, external_i # Update SCIM Group, using a valid access key. validate_scim_group_id(group_id) body = compose_scim_update_group_body(group_id, display_name, members, external_id, excluded_attributes) - patch("#{SCIM_GROUPS_PATH}/#{group_id}", body) + mgmt_patch("#{SCIM_GROUPS_PATH}/#{group_id}", body) end def scim_delete_group(group_id) # Delete SCIM Group, using a valid access key. validate_scim_group_id(group_id) url = "#{SCIM_GROUPS_PATH}/#{group_id}" - delete(url) + mgmt_delete(url) end def scim_patch_group(group_id: nil, user_id: nil, operations: nil) # Patch SCIM Group, using a valid access key. validate_scim_group_id(group_id) url = compose_scim_patch_group_url(group_id, user_id, operations) - patch(url) + mgmt_patch(url) end # SCIM Users def scim_load_resource_types # Load SCIM Resource Types, using a valid access key. - get(SCIM_RESOURCE_TYPES_PATH) + mgmt_get(SCIM_RESOURCE_TYPES_PATH) end def scim_load_service_provider_config # Load SCIM Service Provider Config, using a valid access key. - get(SCIM_SERVICE_PROVIDER_CONFIG_PATH) + mgmt_get(SCIM_SERVICE_PROVIDER_CONFIG_PATH) end def scim_search_users(filter: nil, start_index: nil, count: nil) # Search SCIM Users, using a valid access key. url = compose_scim_search_users_url(filter, start_index, count) - get(url) + mgmt_get(url) end def scim_create_user(user_id: nil, display_name: nil, emails: nil, @@ -72,28 +72,28 @@ def scim_create_user(user_id: nil, display_name: nil, emails: nil, # Create SCIM User, using a valid access key. validate_user_id(user_id) body = compose_scim_create_user_body(user_id, display_name, emails, phone_numbers, active, name, user_name) - post(SCIM_USERS_PATH, body) + mgmt_post(SCIM_USERS_PATH, body) end def scim_load_user(user_id) # Load SCIM User, using a valid access key. validate_user_id(user_id) url = "#{SCIM_USERS_PATH}/#{user_id}" - get(url) + mgmt_get(url) end def scim_update_user(user_id) # Update SCIM User, using a valid access key. validate_user_id(user_id) url = "#{SCIM_USERS_PATH}/#{user_id}" - patch(url) + mgmt_patch(url) end def scim_delete_user(user_id) # Delete SCIM User, using a valid access key. validate_user_id(user_id) url = "#{SCIM_USERS_PATH}/#{user_id}" - delete(url) + mgmt_delete(url) end def scim_patch_user(user_id: nil, group_id: nil, operations: nil) @@ -101,7 +101,7 @@ def scim_patch_user(user_id: nil, group_id: nil, operations: nil) validate_user_id(user_id) validate_scim_group_id(group_id) body = compose_scim_patch_user_body(user_id, group_id, operations) - patch(SCIM_USERS_PATH, body) + mgmt_patch(SCIM_USERS_PATH, body) end private diff --git a/lib/descope/api/v1/management/scope_claim_mapping.rb b/lib/descope/api/v1/management/scope_claim_mapping.rb index a00c4d13..8327ee1f 100644 --- a/lib/descope/api/v1/management/scope_claim_mapping.rb +++ b/lib/descope/api/v1/management/scope_claim_mapping.rb @@ -10,7 +10,7 @@ module ScopeClaimMapping def get_scope_claim_mapping # rubocop:disable Naming/AccessorMethodName # Get the project-wide OIDC scope-to-claim mappings. - post(SCOPE_CLAIM_MAPPING_GET_PATH) + mgmt_post(SCOPE_CLAIM_MAPPING_GET_PATH) end def set_scope_claim_mapping(mappings: nil) @@ -20,12 +20,12 @@ def set_scope_claim_mapping(mappings: nil) # "scope": "name of the OIDC scope", # "claims": ["list of claims mapped to the scope"] # } - post(SCOPE_CLAIM_MAPPING_SET_PATH, { mappings: }) + mgmt_post(SCOPE_CLAIM_MAPPING_SET_PATH, { mappings: }) end def delete_scope_claim_mapping # Delete the project-wide OIDC scope-to-claim mappings. - post(SCOPE_CLAIM_MAPPING_DELETE_PATH) + mgmt_post(SCOPE_CLAIM_MAPPING_DELETE_PATH) end end end diff --git a/lib/descope/api/v1/management/sso_application.rb b/lib/descope/api/v1/management/sso_application.rb index 61198567..6b3d52c7 100644 --- a/lib/descope/api/v1/management/sso_application.rb +++ b/lib/descope/api/v1/management/sso_application.rb @@ -18,7 +18,7 @@ def create_sso_oidc_app(id: nil, name: nil, description: nil, enabled: nil, logo body[:enabled] = enabled if enabled body[:logo] = logo if logo body[:loginPageUrl] = login_page_url if login_page_url - post(SSO_APPLICATION_OIDC_CREATE_PATH, body) + mgmt_post(SSO_APPLICATION_OIDC_CREATE_PATH, body) end # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity @@ -78,14 +78,14 @@ def create_saml_application( force_authentication:, logout_redirect_url: ) - post(SSO_APPLICATION_SAML_CREATE_PATH, body) + mgmt_post(SSO_APPLICATION_SAML_CREATE_PATH, body) end def update_sso_oidc_app(id: nil, name: nil, description: nil, enabled: nil, logo: nil, login_page_url: nil, force_authentication: nil) # Update an existing OIDC sso application with the given parameters. IMPORTANT: All parameters are used as overrides # to the existing sso application. Empty fields will override populated fields. Use carefully. body = compose_create_update_oidc_body(name, login_page_url, id, description, enabled, logo, force_authentication) - post(SSO_APPLICATION_OIDC_UPDATE_PATH, body) + mgmt_post(SSO_APPLICATION_OIDC_UPDATE_PATH, body) end def update_saml_application( @@ -143,17 +143,17 @@ def update_saml_application( force_authentication:, logout_redirect_url: ) - post(SSO_APPLICATION_SAML_UPDATE_PATH, body) + mgmt_post(SSO_APPLICATION_SAML_UPDATE_PATH, body) end def delete_sso_app(id) # Delete an existing sso application. IMPORTANT: This operation is irreversible. Use carefully. - delete(SSO_APPLICATION_DELETE_PATH, { id: }) + mgmt_delete(SSO_APPLICATION_DELETE_PATH, { id: }) end def load_sso_app(id) # Load an existing sso application. - get(SSO_APPLICATION_LOAD_PATH, { id: }) + mgmt_get(SSO_APPLICATION_LOAD_PATH, { id: }) end def load_all_sso_apps @@ -167,7 +167,7 @@ def load_all_sso_apps # ] # } # Containing the loaded sso applications information. - get(SSO_APPLICATION_LOAD_ALL_PATH, {}) + mgmt_get(SSO_APPLICATION_LOAD_ALL_PATH, {}) end private diff --git a/lib/descope/api/v1/management/sso_settings.rb b/lib/descope/api/v1/management/sso_settings.rb index 57f35491..6d2fa7ad 100644 --- a/lib/descope/api/v1/management/sso_settings.rb +++ b/lib/descope/api/v1/management/sso_settings.rb @@ -10,12 +10,12 @@ module SSOSettings def get_sso_settings(tenant_id) # Get SSO settings for the provided tenant id. - get(SSO_SETTINGS_PATH, { tenantId: tenant_id }) + mgmt_get(SSO_SETTINGS_PATH, { tenantId: tenant_id }) end def delete_sso_settings(tenant_id) # Delete SSO settings for the provided tenant id. - delete(SSO_SETTINGS_PATH, { tenantId: tenant_id }) + mgmt_delete(SSO_SETTINGS_PATH, { tenantId: tenant_id }) end def configure_sso_oidc(tenant_id: nil, settings: nil, redirect_url: nil, domain: nil) @@ -28,7 +28,7 @@ def configure_sso_oidc(tenant_id: nil, settings: nil, redirect_url: nil, domain: redirectUrl: redirect_url, domain: } - post(SSO_OIDC_PATH, request_params) + mgmt_post(SSO_OIDC_PATH, request_params) end def configure_sso_saml(tenant_id: nil, settings: nil, redirect_url: nil, domain: nil) @@ -41,12 +41,12 @@ def configure_sso_saml(tenant_id: nil, settings: nil, redirect_url: nil, domain: redirectUrl: redirect_url, domain: } - post(SSO_SETTINGS_PATH, request_params) + mgmt_post(SSO_SETTINGS_PATH, request_params) end def configure_sso_saml_metadata(tenant_id: nil, settings: nil, redirect_url: nil, domain: nil) # Configure tenant SSO SAML Metadata, using a valid management key. - post(SSO_METADATA_PATH, compose_metadata_body(tenant_id, settings, redirect_url, domain)) + mgmt_post(SSO_METADATA_PATH, compose_metadata_body(tenant_id, settings, redirect_url, domain)) end private diff --git a/lib/descope/api/v1/management/tenant.rb b/lib/descope/api/v1/management/tenant.rb index 200f3383..27d47461 100644 --- a/lib/descope/api/v1/management/tenant.rb +++ b/lib/descope/api/v1/management/tenant.rb @@ -17,7 +17,8 @@ def create_tenant(name: nil, id: nil, self_provisioning_domains: nil, custom_att self_provisioning_domains ||= [] custom_attributes ||= {} - post(TENANT_CREATE_PATH, compose_tenant_create_update_body(name, id, self_provisioning_domains, custom_attributes)) + mgmt_post(TENANT_CREATE_PATH, + compose_tenant_create_update_body(name, id, self_provisioning_domains, custom_attributes)) end def update_tenant(name: nil, id: nil, self_provisioning_domains: nil, custom_attributes: nil) @@ -26,22 +27,23 @@ def update_tenant(name: nil, id: nil, self_provisioning_domains: nil, custom_att # @see https://docs.descope.com/api/openapi/tenantmanagement/operation/UpdateTenant/ self_provisioning_domains ||= [] custom_attributes ||= {} - post(TENANT_UPDATE_PATH, compose_tenant_create_update_body(name, id, self_provisioning_domains, custom_attributes)) + mgmt_post(TENANT_UPDATE_PATH, + compose_tenant_create_update_body(name, id, self_provisioning_domains, custom_attributes)) end def delete_tenant(id = nil) # Delete an existing tenant. IMPORTANT: This action is irreversible. Use carefully. - post(TENANT_DELETE_PATH, { id: }) + mgmt_post(TENANT_DELETE_PATH, { id: }) end def load_tenant(id = nil) # Load tenant by id. - get(TENANT_LOAD_PATH, { id: }) + mgmt_get(TENANT_LOAD_PATH, { id: }) end def load_all_tenants # Load all tenants. - get(TENANT_LOAD_ALL_PATH) + mgmt_get(TENANT_LOAD_ALL_PATH) end def search_all_tenants(ids: nil, names: nil, self_provisioning_domains: nil, custom_attributes: nil) @@ -52,7 +54,7 @@ def search_all_tenants(ids: nil, names: nil, self_provisioning_domains: nil, cus selfProvisioningDomains: self_provisioning_domains, customAttributes: custom_attributes } - post(TENANT_SEARCH_ALL_PATH, request_params) + mgmt_post(TENANT_SEARCH_ALL_PATH, request_params) end private diff --git a/lib/descope/api/v1/management/third_party_application.rb b/lib/descope/api/v1/management/third_party_application.rb index d385c8ac..f08edb85 100644 --- a/lib/descope/api/v1/management/third_party_application.rb +++ b/lib/descope/api/v1/management/third_party_application.rb @@ -38,7 +38,7 @@ def create_application( force_pkce:, default_audience: ) - post(THIRD_PARTY_APP_CREATE_PATH, body) + mgmt_post(THIRD_PARTY_APP_CREATE_PATH, body) end def update_application( @@ -71,7 +71,7 @@ def update_application( force_pkce:, default_audience: ) - post(THIRD_PARTY_APP_UPDATE_PATH, body) + mgmt_post(THIRD_PARTY_APP_UPDATE_PATH, body) end def patch_application( @@ -103,32 +103,32 @@ def patch_application( force_pkce:, default_audience: ) - post(THIRD_PARTY_APP_PATCH_PATH, body) + mgmt_post(THIRD_PARTY_APP_PATCH_PATH, body) end def delete_application(id) # Delete an existing third party application. IMPORTANT: This operation is irreversible. Use carefully. - post(THIRD_PARTY_APP_DELETE_PATH, { id: }) + mgmt_post(THIRD_PARTY_APP_DELETE_PATH, { id: }) end def load_application(id) # Load an existing third party application. - get(THIRD_PARTY_APP_LOAD_PATH, { id: }) + mgmt_get(THIRD_PARTY_APP_LOAD_PATH, { id: }) end def load_all_applications # Load all third party applications. - get(THIRD_PARTY_APP_LOAD_ALL_PATH, {}) + mgmt_get(THIRD_PARTY_APP_LOAD_ALL_PATH, {}) end def get_application_secret(id) # Get the cleartext secret of an existing third party application. - get(THIRD_PARTY_APP_SECRET_PATH, { id: }) + mgmt_get(THIRD_PARTY_APP_SECRET_PATH, { id: }) end def rotate_application_secret(id) # Rotate the secret of an existing third party application, returning the new cleartext secret. - post(THIRD_PARTY_APP_ROTATE_PATH, { id: }) + mgmt_post(THIRD_PARTY_APP_ROTATE_PATH, { id: }) end def delete_consents(app_id: nil, consent_ids: nil, user_ids: nil, tenant_id: nil) @@ -138,7 +138,7 @@ def delete_consents(app_id: nil, consent_ids: nil, user_ids: nil, tenant_id: nil body[:appId] = app_id if app_id body[:userIds] = user_ids if user_ids body[:tenantId] = tenant_id if tenant_id - post(THIRD_PARTY_APP_DELETE_CONSENTS_PATH, body) + mgmt_post(THIRD_PARTY_APP_DELETE_CONSENTS_PATH, body) end def delete_tenant_consents(app_id: nil, consent_ids: nil, tenant_id: nil) @@ -147,7 +147,7 @@ def delete_tenant_consents(app_id: nil, consent_ids: nil, tenant_id: nil) body[:consentIds] = consent_ids if consent_ids body[:appId] = app_id if app_id body[:tenantId] = tenant_id if tenant_id - post(THIRD_PARTY_APP_DELETE_TENANT_CONSENTS_PATH, body) + mgmt_post(THIRD_PARTY_APP_DELETE_TENANT_CONSENTS_PATH, body) end private diff --git a/lib/descope/api/v1/management/user.rb b/lib/descope/api/v1/management/user.rb index 431059c1..bc6f46ae 100644 --- a/lib/descope/api/v1/management/user.rb +++ b/lib/descope/api/v1/management/user.rb @@ -27,7 +27,7 @@ def create_batch_users(users = []) request_params = { users: users_params } - post(path, request_params) + mgmt_post(path, request_params) end # Create a new test user. @@ -102,7 +102,7 @@ def update_user( hashed_password:, sso_app_ids: ) - post(path, request_params) + mgmt_post(path, request_params) end # Delete a user, using a valid management key. @@ -113,12 +113,12 @@ def delete_user(login_id = nil) request_params = { loginId: login_id } - post(path, request_params) + mgmt_post(path, request_params) end def delete_all_test_users path = Common::USER_DELETE_ALL_TEST_USERS_PATH - delete(path) + mgmt_delete(path) end # Load a user's data, using a valid management key. @@ -132,7 +132,7 @@ def load_user(login_id) loginId: login_id } path = Common::USER_LOAD_PATH - get(path, request_params) + mgmt_get(path, request_params) end # Load a user's data, using a valid management key by user id. @@ -146,7 +146,7 @@ def load_by_user_id(user_id) request_params = { userId: user_id } - get(path, request_params) + mgmt_get(path, request_params) end # Log a user out of all sessions, using a valid management key. @@ -157,7 +157,7 @@ def logout_user(login_id) request_params = { loginId: login_id } - post(path, request_params) + mgmt_post(path, request_params) end def logout_user_by_id(user_id) @@ -166,7 +166,7 @@ def logout_user_by_id(user_id) request_params = { userId: user_id } - post(path, request_params) + mgmt_post(path, request_params) end # Search for users, using a valid management key. @@ -216,7 +216,7 @@ def search_all_users( body[:roleNames] = role_names unless role_names.empty? body[:tenantRoleIds] = map_to_values_object(tenant_role_ids) unless tenant_role_ids.nil? || tenant_role_ids.empty? body[:tenantRoleNames] = map_to_values_object(tenant_role_names) unless tenant_role_names.nil? || tenant_role_names.empty? - post(Common::USERS_SEARCH_PATH, body) + mgmt_post(Common::USERS_SEARCH_PATH, body) end def map_to_values_object(input_map) @@ -234,7 +234,7 @@ def get_provider_token(login_id: nil, provider: nil) loginId: login_id, provider: provider } - get(path, request_params) + mgmt_get(path, request_params) end # Updates an existing user's status, using a valid management key. @@ -246,7 +246,7 @@ def activate(login_id) loginId: login_id, status: 'enabled' } - post(path, request_params) + mgmt_post(path, request_params) end def deactivate(login_id) @@ -256,7 +256,7 @@ def deactivate(login_id) loginId: login_id, status: 'disabled' } - post(path, request_params) + mgmt_post(path, request_params) end # Updates an existing user's login ID, using a valid management key. @@ -268,7 +268,7 @@ def update_login_id(login_id: nil, new_login_id: nil) loginId: login_id, newLoginId: new_login_id } - post(path, request_params) + mgmt_post(path, request_params) end # Updates an existing user's email, using a valid management key. @@ -281,7 +281,7 @@ def update_email(login_id: nil, email: nil, verified: true) email:, verified: } - post(path, request_params) + mgmt_post(path, request_params) end # Updates an existing user's phone number, using a valid management key. @@ -293,7 +293,7 @@ def update_phone(login_id: nil, phone: nil, verified: true) phone:, verified: } - post(path, request_params) + mgmt_post(path, request_params) end # Updates an existing user's display name, using a valid management key. @@ -310,7 +310,7 @@ def update_display_name( body[:givenName] = given_name unless given_name.nil? body[:middleName] = middle_name unless middle_name.nil? body[:familyName] = family_name unless family_name.nil? - post(Common::USER_UPDATE_NAME_PATH, body) + mgmt_post(Common::USER_UPDATE_NAME_PATH, body) end # Update an existing user's profile picture, using a valid management key. @@ -320,7 +320,7 @@ def update_picture(login_id: nil, picture: nil) loginId: login_id, picture: picture } - post(Common::USER_UPDATE_PICTURE_PATH, body) + mgmt_post(Common::USER_UPDATE_PICTURE_PATH, body) end # Update an existing user's custom attributes, using a valid management key. @@ -332,7 +332,7 @@ def update_custom_attribute(login_id: nil, attribute_key: nil, attribute_value: attributeKey: attribute_key, attributeValue: attribute_value } - post(Common::USER_UPDATE_CUSTOM_ATTRIBUTE_PATH, body) + mgmt_post(Common::USER_UPDATE_CUSTOM_ATTRIBUTE_PATH, body) end def patch_user( @@ -377,7 +377,7 @@ def patch_user( hashed_password:, sso_app_ids: ) - patch(path, request_params) + mgmt_patch(path, request_params) end def update_jwt(jwt: nil, custom_claims: nil) @@ -385,7 +385,7 @@ def update_jwt(jwt: nil, custom_claims: nil) jwt:, customClaims: custom_claims, } - post(Common::UPDATE_JWT_PATH, body) + mgmt_post(Common::UPDATE_JWT_PATH, body) end # @@ -395,7 +395,7 @@ def user_add_roles(login_id: nil, tenant_id: nil, role_names: []) roleNames: role_names, tenantId: tenant_id } - post(Common::USER_ADD_ROLE_PATH, body) + mgmt_post(Common::USER_ADD_ROLE_PATH, body) end def user_remove_roles(login_id: nil, tenant_id:nil, role_names: []) @@ -404,7 +404,7 @@ def user_remove_roles(login_id: nil, tenant_id:nil, role_names: []) roleNames: role_names, tenantId: tenant_id } - post(Common::USER_REMOVE_ROLE_PATH, body) + mgmt_post(Common::USER_REMOVE_ROLE_PATH, body) end def user_add_tenant(login_id: nil, tenant_id: nil) @@ -412,7 +412,7 @@ def user_add_tenant(login_id: nil, tenant_id: nil) loginId: login_id, tenantId: tenant_id } - post(Common::USER_ADD_TENANT_PATH, body) + mgmt_post(Common::USER_ADD_TENANT_PATH, body) end def user_remove_tenant(login_id: nil, tenant_id: nil) @@ -420,7 +420,7 @@ def user_remove_tenant(login_id: nil, tenant_id: nil) loginId: login_id, tenantId: tenant_id } - post(Common::USER_REMOVE_TENANT_PATH, body) + mgmt_post(Common::USER_REMOVE_TENANT_PATH, body) end def add_tenant_role(login_id: nil, tenant_id: nil, role_names: []) @@ -429,7 +429,7 @@ def add_tenant_role(login_id: nil, tenant_id: nil, role_names: []) tenantId: tenant_id, roleNames: role_names } - post(Common::USER_ADD_TENANT_PATH, body) + mgmt_post(Common::USER_ADD_TENANT_PATH, body) end def user_remove_tenant_roles(login_id: nil, tenant_id: nil, role_names: []) @@ -438,7 +438,7 @@ def user_remove_tenant_roles(login_id: nil, tenant_id: nil, role_names: []) tenantId: tenant_id, roleNames: role_names } - post(Common::USER_REMOVE_TENANT_PATH, body) + mgmt_post(Common::USER_REMOVE_TENANT_PATH, body) end def set_temporary_password(login_id: nil, password: nil) @@ -446,7 +446,7 @@ def set_temporary_password(login_id: nil, password: nil) loginId: login_id, password: } - post(Common::USER_SET_TEMPORARY_PASSWORD_PATH, body) + mgmt_post(Common::USER_SET_TEMPORARY_PASSWORD_PATH, body) end def set_active_password(login_id: nil, password: nil) @@ -454,7 +454,7 @@ def set_active_password(login_id: nil, password: nil) loginId: login_id, password: } - post(Common::USER_SET_ACTIVE_PASSWORD_PATH, body) + mgmt_post(Common::USER_SET_ACTIVE_PASSWORD_PATH, body) end # Deprecated (use set_temporary_password(..) instead) @@ -463,7 +463,7 @@ def set_password(login_id: nil, password: nil) loginId: login_id, password: } - post(Common::USER_SET_PASSWORD_PATH, body) + mgmt_post(Common::USER_SET_PASSWORD_PATH, body) end def expire_password(login_id) @@ -471,7 +471,7 @@ def expire_password(login_id) body = { loginId: login_id } - post(Common::USER_EXPIRE_PASSWORD_PATH, body) + mgmt_post(Common::USER_EXPIRE_PASSWORD_PATH, body) end def generate_otp_for_test_user(method: nil, login_id: nil) @@ -479,7 +479,7 @@ def generate_otp_for_test_user(method: nil, login_id: nil) loginId: login_id, deliveryMethod: get_method_string(method) } - post(Common::USER_GENERATE_OTP_FOR_TEST_PATH, body) + mgmt_post(Common::USER_GENERATE_OTP_FOR_TEST_PATH, body) end def generate_magic_link_for_test_user(method: nil, login_id: nil, uri: nil) @@ -488,7 +488,7 @@ def generate_magic_link_for_test_user(method: nil, login_id: nil, uri: nil) deliveryMethod: get_method_string(method), URI: uri } - post(Common::USER_GENERATE_MAGIC_LINK_FOR_TEST_PATH, body) + mgmt_post(Common::USER_GENERATE_MAGIC_LINK_FOR_TEST_PATH, body) end def generate_enchanted_link_for_test_user(login_id: nil, uri: nil) @@ -496,7 +496,7 @@ def generate_enchanted_link_for_test_user(login_id: nil, uri: nil) loginId: login_id, URI: uri } - post(Common::USER_GENERATE_ENCHANTED_LINK_FOR_TEST_PATH, body) + mgmt_post(Common::USER_GENERATE_ENCHANTED_LINK_FOR_TEST_PATH, body) end def generate_embedded_link(login_id: nil, custom_claims: nil) @@ -513,7 +513,7 @@ def generate_embedded_link(login_id: nil, custom_claims: nil) loginId: login_id, customClaims: custom_claims.to_h } - post(USER_GENERATE_EMBEDDED_LINK_PATH, request_params) + mgmt_post(USER_GENERATE_EMBEDDED_LINK_PATH, request_params) end # Search for all test users. @@ -582,7 +582,7 @@ def search_all_test_users( body[:tenantRoleIds] = map_to_values_object(tenant_role_ids) unless tenant_role_ids.nil? || tenant_role_ids.empty? body[:tenantRoleNames] = map_to_values_object(tenant_role_names) unless tenant_role_names.nil? || tenant_role_names.empty? - post(Common::TEST_USERS_SEARCH_PATH, body) + mgmt_post(Common::TEST_USERS_SEARCH_PATH, body) end @@ -647,7 +647,7 @@ def user_create( ) return request_params if skip_create - post(path, request_params) + mgmt_post(path, request_params) end def user_compose_create_body( diff --git a/lib/descope/http_client.rb b/lib/descope/http_client.rb new file mode 100644 index 00000000..d79cf813 --- /dev/null +++ b/lib/descope/http_client.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'descope/mixins/http' + +module Descope + # Performs the SDK's HTTP calls. One instance is created per kind of request so that the two + # management keys are never sent together: the management client carries the management key, the + # authentication client carries the auth management key. + class HttpClient + include Descope::Mixins::HTTP + + def initialize(base_uri:, project_id:, headers:, logger:, key: nil, timeout: nil, retry_count: nil) + @base_uri = base_uri + @project_id = project_id + @key = key + @headers = headers.dup + @logger = logger + @timeout = timeout + @retry_count = retry_count + end + + # Bearer [:][:] where pswd is a refresh token or access key presented by + # the caller and key is this client's management key. Blank parts are skipped, so callers do + # not have to branch on what happens to be configured. + def authorization_header(pswd = nil) + bearer = [@project_id, pswd, @key].reject { |part| part.nil? || part.to_s.empty? }.join(':') + { 'Authorization' => "Bearer #{bearer}" } + end + end +end diff --git a/lib/descope/mixins.rb b/lib/descope/mixins.rb index 466a3000..70150600 100644 --- a/lib/descope/mixins.rb +++ b/lib/descope/mixins.rb @@ -4,6 +4,7 @@ require 'jwt' require 'descope/mixins/headers' require 'descope/mixins/http' +require 'descope/mixins/requests' require 'descope/mixins/initializer' require 'descope/mixins/validation' require 'descope/mixins/logging' @@ -15,7 +16,7 @@ module Descope module Mixins include Descope::Mixins::Common include Descope::Mixins::Headers - include Descope::Mixins::HTTP + include Descope::Mixins::Requests include Descope::Mixins::Initializer include Descope::Mixins::Logging end diff --git a/lib/descope/mixins/http.rb b/lib/descope/mixins/http.rb index 85413f9e..42d1500d 100644 --- a/lib/descope/mixins/http.rb +++ b/lib/descope/mixins/http.rb @@ -18,13 +18,18 @@ module HTTP MIN_REQUEST_RETRY_DELAY = 250 BASE_DELAY = 100 - %i[get post post_file post_form put patch delete delete_with_body].each do |method| + HTTP_METHODS = %i[get post put patch delete].freeze + + HTTP_METHODS.each do |method| define_method(method) do |uri, body = {}, extra_headers = {}, pswd = nil| body = body.delete_if { |_, v| v.nil? } - authorization_header(pswd) # This will set the pswd if provided, else default to the @default_pswd + + # The Authorization header travels with the request rather than being merged into the + # shared @headers, so concurrent requests cannot send each other's credentials. + headers = authorization_header(pswd).merge(extra_headers || {}) @logger.debug "request => method: #{method}, uri: #{uri}, body: #{body}, extra_headers: #{extra_headers}}" - request_with_retry(method, uri, body, extra_headers) + request_with_retry(method, uri, body, headers) end end @@ -118,6 +123,15 @@ def add_headers(h = {}) @headers.merge!(h.to_hash) end + # Everything after the project ID in the bearer is either a token or a management key, so + # none of it belongs in a log line. + def mask_authorization(headers) + authorization = headers['Authorization'] + return headers if authorization.nil? + + headers.merge('Authorization' => authorization.sub(/\A(Bearer [^:]*):.*\z/, '\1:***')) + end + def request_with_retry(method, uri, body = {}, extra_headers = {}, pswd = nil) Retryable.retryable(retry_options) do request(method, uri, body, extra_headers) @@ -125,23 +139,16 @@ def request_with_retry(method, uri, body = {}, extra_headers = {}, pswd = nil) end def request(method, uri, body = {}, extra_headers = {}) - # @headers is getting the authorization header merged in initializer.rb - headers_debug = @headers.dup - if headers_debug['Authorization'] - headers_debug['Authorization'] = headers_debug['Authorization'].gsub(/(.{10})\z/, '***********') - end + request_headers = @headers.merge(extra_headers) @logger.debug "base url: #{@base_uri}" - @logger.debug "request method: #{method}, uri: #{uri}, body: #{body}, extra_headers: #{extra_headers}, headers: #{headers_debug}" + @logger.debug "request method: #{method}, uri: #{uri}, body: #{body}, " \ + "headers: #{mask_authorization(request_headers)}" result = case method - when :get - get_headers = @headers.merge({ params: body }).merge(extra_headers) - call(:get, encode_uri(uri), timeout, get_headers) - when :delete - delete_headers = @headers.merge({ params: body }) - call(:delete, encode_uri(uri), timeout, delete_headers) + when :get, :delete + call(method, encode_uri(uri), timeout, request_headers.merge({ params: body })) else - call(method, encode_uri(uri), timeout, @headers, body.to_json) + call(method, encode_uri(uri), timeout, request_headers, body.to_json) end raise Descope::Unsupported.new('No response from server', code: 400) unless result.respond_to?(:code) diff --git a/lib/descope/mixins/initializer.rb b/lib/descope/mixins/initializer.rb index 058de6a7..e737d239 100644 --- a/lib/descope/mixins/initializer.rb +++ b/lib/descope/mixins/initializer.rb @@ -1,12 +1,14 @@ # frozen_string_literal: true require 'json' +require 'descope/http_client' module Descope module Mixins # Helper class for initializing the Descope API module Initializer attr_accessor :public_keys, :mlock + attr_reader :base_uri, :headers def initialize(config) options = Hash[config.map { |(k, v)| [k.to_sym, v] }] @@ -33,7 +35,10 @@ def initialize(config) @skip_verify = options[:skip_verify] @secure = !@skip_verify @management_key = options[:management_key] || ENV['DESCOPE_MANAGEMENT_KEY'] - @logger.debug("Management Key ID: #{@management_key}") + # Sent with every authentication request so that methods whose public access has been + # disabled can still be used. Never sent on management requests, and can - and probably + # should - be a different management key than @management_key. + @auth_management_key = options[:auth_management_key] || ENV['DESCOPE_AUTH_MANAGEMENT_KEY'] @timeout_seconds = options[:timeout_seconds] || Common::DEFAULT_TIMEOUT_SECONDS @jwt_validation_leeway = options[:jwt_validation_leeway] || Common::DEFAULT_JWT_VALIDATION_LEEWAY @@ -60,16 +65,21 @@ def base_url(options) end - def authorization_header(pswd = nil) - pswd = @default_pswd if pswd.nil? || pswd.empty? - bearer = "#{@project_id}:#{pswd}" - add_headers('Authorization' => "Bearer #{bearer}") - end - def initialize_api(options) initialize_v1(options) - @default_pswd = options.fetch(:management_key, ENV['DESCOPE_MANAGEMENT_KEY']) - authorization_header + @auth_http = http_client(@auth_management_key) + @mgmt_http = http_client(@management_key) + end + + def http_client(key) + HttpClient.new( + base_uri: @base_uri, + project_id: @project_id, + key: key, + headers: @headers, + logger: @logger, + timeout: @timeout_seconds + ) end def initialize_v1(_options) diff --git a/lib/descope/mixins/requests.rb b/lib/descope/mixins/requests.rb new file mode 100644 index 00000000..6c6cb579 --- /dev/null +++ b/lib/descope/mixins/requests.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'descope/mixins/http' + +module Descope + module Mixins + # Routes an API call to the HTTP client that holds the right key: the bare verbs serve the + # authentication APIs and go out with the auth management key, the mgmt_ prefixed verbs serve + # the management APIs and go out with the management key. + module Requests + attr_reader :auth_http, :mgmt_http + + Descope::Mixins::HTTP::HTTP_METHODS.each do |method| + define_method(method) do |*args| + @auth_http.public_send(method, *args) + end + + define_method(:"mgmt_#{method}") do |*args| + @mgmt_http.public_send(method, *args) + end + end + end + end +end diff --git a/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb b/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb index 7a848c79..8c25747c 100644 --- a/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb +++ b/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb @@ -30,7 +30,7 @@ expect(@instance).to receive(:post).with( enchanted_link_compose_signin_url, request_params, - nil, + {}, 'refresh_token' ) diff --git a/spec/lib.descope/api/v1/management/access_key_spec.rb b/spec/lib.descope/api/v1/management/access_key_spec.rb index 397bebf7..c264368f 100644 --- a/spec/lib.descope/api/v1/management/access_key_spec.rb +++ b/spec/lib.descope/api/v1/management/access_key_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create access key' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ACCESS_KEY_CREATE_PATH, { name: 'test', expireTime: 0, @@ -46,7 +46,7 @@ end it 'is expected to load an access key' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( ACCESS_KEY_LOAD_PATH, { id: '123' } ) expect { @instance.load_access_key('123') }.not_to raise_error @@ -59,7 +59,7 @@ end it 'is expected to search all access keys' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ACCESS_KEYS_SEARCH_PATH, { tenantIds: %w[123 456] } ) expect { @instance.search_all_access_keys(%w[123 456]) }.not_to raise_error @@ -72,7 +72,7 @@ end it 'is expected to update an access keys' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ACCESS_KEY_UPDATE_PATH, { id: '123', name: 'test1' } ) expect { @instance.update_access_key(id: '123', name: 'test1') }.not_to raise_error @@ -85,7 +85,7 @@ end it 'is expected to deactivate an access keys' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ACCESS_KEY_DEACTIVATE_PATH, { id: '123' } ) expect { @instance.deactivate_access_key('123') }.not_to raise_error @@ -98,7 +98,7 @@ end it 'is expected to activate an access keys' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ACCESS_KEY_ACTIVATE_PATH, { id: '123' } ) expect { @instance.activate_access_key('123') }.not_to raise_error @@ -111,7 +111,7 @@ end it 'is expected to delete an access keys' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ACCESS_KEY_DELETE_PATH, { id: '123' } ) expect { @instance.delete_access_key('123') }.not_to raise_error diff --git a/spec/lib.descope/api/v1/management/analytics_spec.rb b/spec/lib.descope/api/v1/management/analytics_spec.rb index ce1b279e..2089529e 100644 --- a/spec/lib.descope/api/v1/management/analytics_spec.rb +++ b/spec/lib.descope/api/v1/management/analytics_spec.rb @@ -29,7 +29,7 @@ end before do - allow(@instance).to receive(:post).with( + allow(@instance).to receive(:mgmt_post).with( ANALYTICS_SEARCH_PATH, { from: 1_234_567_000, diff --git a/spec/lib.descope/api/v1/management/audit_spec.rb b/spec/lib.descope/api/v1/management/audit_spec.rb index 0396448d..1c78d373 100644 --- a/spec/lib.descope/api/v1/management/audit_spec.rb +++ b/spec/lib.descope/api/v1/management/audit_spec.rb @@ -31,7 +31,7 @@ end before do - allow(@instance).to receive(:post).twice.with( + allow(@instance).to receive(:mgmt_post).twice.with( AUDIT_SEARCH, { noTenants: true, @@ -144,7 +144,7 @@ end it 'is expected to create an audit event' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( '/v1/mgmt/audit/event', { action: 'get', diff --git a/spec/lib.descope/api/v1/management/authz_spec.rb b/spec/lib.descope/api/v1/management/authz_spec.rb index 66f022f9..859079d1 100644 --- a/spec/lib.descope/api/v1/management/authz_spec.rb +++ b/spec/lib.descope/api/v1/management/authz_spec.rb @@ -34,7 +34,7 @@ } ] } - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_SCHEMA_SAVE, { schema: schema, @@ -53,7 +53,7 @@ end it 'is expected to delete the schema for the project which will also delete all relations' do - expect(@instance).to receive(:post).with(AUTHZ_SCHEMA_DELETE) + expect(@instance).to receive(:mgmt_post).with(AUTHZ_SCHEMA_DELETE) expect do @instance.authz_delete_schema end.not_to raise_error @@ -66,7 +66,7 @@ end it 'is expected to load the schema for the project' do - expect(@instance).to receive(:post).with(AUTHZ_SCHEMA_LOAD) + expect(@instance).to receive(:mgmt_post).with(AUTHZ_SCHEMA_LOAD) expect do @instance.authz_load_schema end.not_to raise_error @@ -79,7 +79,7 @@ end it 'is expected to create or update the given namespace' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_NS_SAVE, { namespace: 'test-namespace', @@ -99,7 +99,7 @@ end it 'is expected to delete the given namespace' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_NS_DELETE, { name: 'test-namespace', @@ -118,7 +118,7 @@ end it 'is expected to create or update the given relation definition' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RD_SAVE, { relationDefinition: 'test-relation-definition', @@ -144,7 +144,7 @@ end it 'is expected to delete the given relation definition' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RD_DELETE, { name: 'test-relation-definition', @@ -168,7 +168,7 @@ end it 'is expected to create the given relation' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RE_CREATE, { relations: 'test-relations' @@ -186,7 +186,7 @@ end it 'is expected to delete the given relation' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RE_DELETE, { relations: [{ resource: 'some-note', relationDefinition: 'owner', namespace: 'note', target: 'some-user' }] } ) @@ -204,7 +204,7 @@ end it 'is expected to delete the given relations for resources' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RE_DELETE_RESOURCES, { resources: 'test-resources' @@ -222,7 +222,7 @@ end it 'is expected to return true if the given resource has relations' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RE_HAS_RELATIONS, { relationQueries: ['some-query'] @@ -240,7 +240,7 @@ end it 'is expected to return the list of targets who can access the given resource with the given RD' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RE_WHO, { resource: 'test-resource', @@ -261,7 +261,7 @@ end it 'is expected to return the list of relations for the given resources' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RE_RESOURCE, { resources: ['test-resources'] @@ -279,7 +279,7 @@ end it 'is expected to return the list of relations for the given targets' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RE_TARGETS, { targets: ['test-targets'] @@ -306,7 +306,7 @@ end before do - allow(@instance).to receive(:post).with( + allow(@instance).to receive(:mgmt_post).with( AUTHZ_RE_TARGET_ALL, { target: 'test-target' @@ -319,7 +319,7 @@ end it 'is expected to return the list of relations for the given target' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( AUTHZ_RE_TARGET_ALL, { target: 'test-target' diff --git a/spec/lib.descope/api/v1/management/descoper_spec.rb b/spec/lib.descope/api/v1/management/descoper_spec.rb index 3286a526..36fcadd3 100644 --- a/spec/lib.descope/api/v1/management/descoper_spec.rb +++ b/spec/lib.descope/api/v1/management/descoper_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create the given descopers' do - expect(@instance).to receive(:put).with( + expect(@instance).to receive(:mgmt_put).with( DESCOPER_CREATE_PATH, { descopers: [{ name: 'test-descoper' }] @@ -33,7 +33,7 @@ end it 'is expected to update the given descoper' do - expect(@instance).to receive(:patch).with( + expect(@instance).to receive(:mgmt_patch).with( DESCOPER_UPDATE_PATH, { id: 'test-id', @@ -53,7 +53,7 @@ end it 'is expected to get the given descoper by id' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( DESCOPER_GET_PATH, { id: 'test-id' @@ -71,7 +71,7 @@ end it 'is expected to delete the given descoper by id' do - expect(@instance).to receive(:delete).with( + expect(@instance).to receive(:mgmt_delete).with( DESCOPER_DELETE_PATH, { id: 'test-id' @@ -89,7 +89,7 @@ end it 'is expected to search (list) all descopers' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( DESCOPER_SEARCH_PATH, {} ) diff --git a/spec/lib.descope/api/v1/management/engine_spec.rb b/spec/lib.descope/api/v1/management/engine_spec.rb index 697f7037..5d4d76ac 100644 --- a/spec/lib.descope/api/v1/management/engine_spec.rb +++ b/spec/lib.descope/api/v1/management/engine_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create a new engine' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ENGINE_CREATE_PATH, { name: 'test-engine' @@ -33,7 +33,7 @@ end it 'is expected to update an existing engine' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ENGINE_UPDATE_PATH, { id: 'test-id', @@ -52,7 +52,7 @@ end it 'is expected to delete an existing engine' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ENGINE_DELETE_PATH, { id: 'test-id' @@ -70,7 +70,7 @@ end it 'is expected to load an engine by id' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( ENGINE_LOAD_PATH, { id: 'test-id' @@ -88,7 +88,7 @@ end it 'is expected to load all engines' do - expect(@instance).to receive(:get).with(ENGINE_LOAD_ALL_PATH) + expect(@instance).to receive(:mgmt_get).with(ENGINE_LOAD_ALL_PATH) expect do @instance.load_all_engines end.not_to raise_error @@ -101,7 +101,7 @@ end it 'is expected to rotate the secret for an engine' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ENGINE_ROTATE_SECRET_PATH, { id: 'test-id' diff --git a/spec/lib.descope/api/v1/management/fga_spec.rb b/spec/lib.descope/api/v1/management/fga_spec.rb index 8d518c69..0e200e13 100644 --- a/spec/lib.descope/api/v1/management/fga_spec.rb +++ b/spec/lib.descope/api/v1/management/fga_spec.rb @@ -16,7 +16,7 @@ it 'is expected to save the FGA schema' do schema = 'model AuthZ 1.0\ntype user\ntype doc\n relation owner: user' - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( FGA_SAVE_SCHEMA_PATH, { dsl: schema } ) @@ -32,7 +32,7 @@ end it 'is expected to load the FGA schema' do - expect(@instance).to receive(:get).with(FGA_LOAD_SCHEMA_PATH) + expect(@instance).to receive(:mgmt_get).with(FGA_LOAD_SCHEMA_PATH) expect do @instance.fga_load_schema end.not_to raise_error @@ -46,7 +46,7 @@ it 'is expected to create the given relations' do tuples = [{ resource: 'doc1', relation: 'owner', target: 'user1' }] - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( FGA_CREATE_RELATIONS_PATH, { tuples: tuples } ) @@ -63,7 +63,7 @@ it 'is expected to delete the given relations' do tuples = [{ resource: 'doc1', relation: 'owner', target: 'user1' }] - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( FGA_DELETE_RELATIONS_PATH, { tuples: tuples } ) @@ -80,7 +80,7 @@ it 'is expected to check the given relations' do tuples = [{ resource: 'doc1', relation: 'owner', target: 'user1' }] - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( FGA_CHECK_PATH, { tuples: tuples } ) @@ -96,7 +96,7 @@ end it 'is expected to load the mappable schema for the given tenant' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( FGA_LOAD_MAPPABLE_SCHEMA_PATH, { tenantId: 'tenant-1' } ) @@ -106,7 +106,7 @@ end it 'is expected to include resourcesLimit when options are given' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( FGA_LOAD_MAPPABLE_SCHEMA_PATH, { tenantId: 'tenant-1', resourcesLimit: 10 } ) @@ -123,7 +123,7 @@ it 'is expected to search for mappable resources for the given tenant' do resources_queries = [{ resourceType: 'doc' }] - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( FGA_SEARCH_MAPPABLE_RESOURCES_PATH, { tenantId: 'tenant-1', resourcesQueries: resources_queries } ) @@ -140,7 +140,7 @@ it 'is expected to load the details of the given resource identifiers' do resource_identifiers = [{ resourceId: 'doc1', resourceType: 'doc' }] - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( FGA_RESOURCES_LOAD_PATH, { resourceIdentifiers: resource_identifiers } ) @@ -157,7 +157,7 @@ it 'is expected to save the details of the given resources' do resources_details = [{ resourceId: 'doc1', resourceType: 'doc', displayName: 'Document 1' }] - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( FGA_RESOURCES_SAVE_PATH, { resourcesDetails: resources_details } ) diff --git a/spec/lib.descope/api/v1/management/flow_spec.rb b/spec/lib.descope/api/v1/management/flow_spec.rb index b003aa2b..59f26805 100644 --- a/spec/lib.descope/api/v1/management/flow_spec.rb +++ b/spec/lib.descope/api/v1/management/flow_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to get flows' do - expect(@instance).to receive(:post).with(FLOW_LIST_PATH, { ids: %w[123 456] }) + expect(@instance).to receive(:mgmt_post).with(FLOW_LIST_PATH, { ids: %w[123 456] }) expect { @instance.list_or_search_flows(%w[123 456]) }.not_to raise_error end end @@ -26,7 +26,7 @@ end it 'is expected to export flow' do - expect(@instance).to receive(:post).with(FLOW_EXPORT_PATH, { flowId: '123' }) + expect(@instance).to receive(:mgmt_post).with(FLOW_EXPORT_PATH, { flowId: '123' }) expect { @instance.export_flow('123') }.not_to raise_error end end @@ -37,7 +37,7 @@ end it 'is expected to import flow' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( FLOW_IMPORT_PATH, { flowId: '123', flow: 'flow', @@ -60,7 +60,7 @@ end it 'is expected to export theme' do - expect(@instance).to receive(:post).with(THEME_EXPORT_PATH) + expect(@instance).to receive(:mgmt_post).with(THEME_EXPORT_PATH) expect { @instance.export_theme }.not_to raise_error end end @@ -71,7 +71,7 @@ end it 'is expected to import theme' do - expect(@instance).to receive(:post).with(THEME_IMPORT_PATH, { theme: 'theme123' }) + expect(@instance).to receive(:mgmt_post).with(THEME_IMPORT_PATH, { theme: 'theme123' }) expect { @instance.import_theme('theme123') }.not_to raise_error end end diff --git a/spec/lib.descope/api/v1/management/group_spec.rb b/spec/lib.descope/api/v1/management/group_spec.rb index a58bf950..c2103d4b 100644 --- a/spec/lib.descope/api/v1/management/group_spec.rb +++ b/spec/lib.descope/api/v1/management/group_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to load all groups for a given tenant id' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( GROUP_LOAD_ALL_PATH, { tenantId: 'tenant-id' @@ -33,7 +33,7 @@ end it 'is expected to load all groups for the given user and login ids' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( GROUP_LOAD_ALL_FOR_MEMBER_PATH, { tenantId: 'tenant-id', @@ -57,7 +57,7 @@ end it 'is expected to load all members of the given group id' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( GROUP_LOAD_ALL_GROUP_MEMBERS_PATH, { tenantId: 'tenant-id', diff --git a/spec/lib.descope/api/v1/management/jwt_template_spec.rb b/spec/lib.descope/api/v1/management/jwt_template_spec.rb index 17d5bf4a..ecff9d29 100644 --- a/spec/lib.descope/api/v1/management/jwt_template_spec.rb +++ b/spec/lib.descope/api/v1/management/jwt_template_spec.rb @@ -22,7 +22,7 @@ conformanceIssuer: true, authSchema: 'default' } - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( JWT_TEMPLATE_CREATE_PATH, { template: template } ) @@ -43,7 +43,7 @@ name: 'name-of-template', template: 'the template body' } - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( JWT_TEMPLATE_UPDATE_PATH, { template: template } ) @@ -59,7 +59,7 @@ end it 'is expected to delete the given JWT template' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( JWT_TEMPLATE_DELETE_PATH, { id: 'template-id' } ) @@ -75,7 +75,7 @@ end it 'is expected to list all JWT templates' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( JWT_TEMPLATE_LIST_PATH, {} ) @@ -91,7 +91,7 @@ end it 'is expected to load the given JWT template' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( JWT_TEMPLATE_LOAD_PATH, { id: 'template-id' } ) diff --git a/spec/lib.descope/api/v1/management/lists_spec.rb b/spec/lib.descope/api/v1/management/lists_spec.rb index b4c174be..4cb40e8b 100644 --- a/spec/lib.descope/api/v1/management/lists_spec.rb +++ b/spec/lib.descope/api/v1/management/lists_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create a new list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_CREATE_PATH, { name: 'test-list', @@ -35,7 +35,7 @@ end it 'is expected to create a new list without optional fields' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_CREATE_PATH, { name: 'test-list', type: 'ip' } ) @@ -51,7 +51,7 @@ end it 'is expected to update an existing list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_UPDATE_PATH, { id: 'test-id', @@ -79,7 +79,7 @@ end it 'is expected to delete an existing list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_DELETE_PATH, { id: 'test-id' } ) @@ -95,7 +95,7 @@ end it 'is expected to load a list by id' do - expect(@instance).to receive(:get).with("#{LIST_LOAD_PATH}/test-id") + expect(@instance).to receive(:mgmt_get).with("#{LIST_LOAD_PATH}/test-id") expect do @instance.load_list(id: 'test-id') end.not_to raise_error @@ -108,7 +108,7 @@ end it 'is expected to load a list by name' do - expect(@instance).to receive(:get).with("#{LIST_LOAD_BY_NAME_PATH}/test-list") + expect(@instance).to receive(:mgmt_get).with("#{LIST_LOAD_BY_NAME_PATH}/test-list") expect do @instance.load_list_by_name(name: 'test-list') end.not_to raise_error @@ -121,7 +121,7 @@ end it 'is expected to load all lists' do - expect(@instance).to receive(:get).with(LIST_LOAD_ALL_PATH) + expect(@instance).to receive(:mgmt_get).with(LIST_LOAD_ALL_PATH) expect do @instance.load_all_lists end.not_to raise_error @@ -135,7 +135,7 @@ it 'is expected to import the given lists' do lists = [{ name: 'test-list', type: 'ip' }] - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_IMPORT_PATH, { lists: } ) @@ -151,7 +151,7 @@ end it 'is expected to add the given IPs to the list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_ADD_IPS_PATH, { id: 'test-id', ips: ['1.2.3.4'] } ) @@ -167,7 +167,7 @@ end it 'is expected to remove the given IPs from the list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_REMOVE_IPS_PATH, { id: 'test-id', ips: ['1.2.3.4'] } ) @@ -183,7 +183,7 @@ end it 'is expected to check whether the given IP exists in the list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_CHECK_IP_PATH, { id: 'test-id', ip: '1.2.3.4' } ) @@ -199,7 +199,7 @@ end it 'is expected to add the given texts to the list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_ADD_TEXTS_PATH, { id: 'test-id', texts: ['some-text'] } ) @@ -215,7 +215,7 @@ end it 'is expected to remove the given texts from the list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_REMOVE_TEXTS_PATH, { id: 'test-id', texts: ['some-text'] } ) @@ -231,7 +231,7 @@ end it 'is expected to check whether the given text exists in the list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_CHECK_TEXT_PATH, { id: 'test-id', text: 'some-text' } ) @@ -247,7 +247,7 @@ end it 'is expected to clear all entries from the list' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( LIST_CLEAR_PATH, { id: 'test-id' } ) diff --git a/spec/lib.descope/api/v1/management/management_key_spec.rb b/spec/lib.descope/api/v1/management/management_key_spec.rb index e1109900..3e0d0b45 100644 --- a/spec/lib.descope/api/v1/management/management_key_spec.rb +++ b/spec/lib.descope/api/v1/management/management_key_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create a management key' do - expect(@instance).to receive(:put).with( + expect(@instance).to receive(:mgmt_put).with( MGMT_KEY_CREATE_PATH, { name: 'test', description: 'test key', @@ -42,7 +42,7 @@ end it 'is expected to update a management key' do - expect(@instance).to receive(:patch).with( + expect(@instance).to receive(:mgmt_patch).with( MGMT_KEY_UPDATE_PATH, { id: '123', name: 'test1', @@ -69,7 +69,7 @@ end it 'is expected to get a management key' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( MGMT_KEY_GET_PATH, { id: '123' } ) expect { @instance.get_management_key(id: '123') }.not_to raise_error @@ -82,7 +82,7 @@ end it 'is expected to delete a management key' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( MGMT_KEY_DELETE_PATH, { ids: ['123'] } ) expect { @instance.delete_management_key(id: '123') }.not_to raise_error @@ -95,7 +95,7 @@ end it 'is expected to search management keys' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( MGMT_KEY_SEARCH_PATH, { tenantIds: %w[123 456], status: 'active' diff --git a/spec/lib.descope/api/v1/management/outbound_app_spec.rb b/spec/lib.descope/api/v1/management/outbound_app_spec.rb index f2630338..a0a10745 100644 --- a/spec/lib.descope/api/v1/management/outbound_app_spec.rb +++ b/spec/lib.descope/api/v1/management/outbound_app_spec.rb @@ -57,7 +57,7 @@ end it 'fetches token with required parameters only' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( '/v1/mgmt/outbound/app/user/token', { appId: 'app-123', @@ -70,7 +70,7 @@ end it 'fetches token with scopes' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( '/v1/mgmt/outbound/app/user/token', { appId: 'app-123', @@ -88,7 +88,7 @@ end it 'fetches token with options' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( '/v1/mgmt/outbound/app/user/token', { appId: 'app-123', @@ -110,7 +110,7 @@ end it 'fetches token with tenant_id' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( '/v1/mgmt/outbound/app/user/token', { appId: 'app-123', @@ -128,7 +128,7 @@ end it 'fetches token with all parameters' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( '/v1/mgmt/outbound/app/user/token', { appId: 'app-123', @@ -172,7 +172,7 @@ end it 'deletes tokens by app_id only' do - expect(@instance).to receive(:delete).with( + expect(@instance).to receive(:mgmt_delete).with( '/v1/mgmt/outbound/user/tokens', { appId: 'app-123' } ) @@ -183,7 +183,7 @@ end it 'deletes tokens by user_id only' do - expect(@instance).to receive(:delete).with( + expect(@instance).to receive(:mgmt_delete).with( '/v1/mgmt/outbound/user/tokens', { userId: 'user-123' } ) @@ -194,7 +194,7 @@ end it 'deletes tokens by both app_id and user_id' do - expect(@instance).to receive(:delete).with( + expect(@instance).to receive(:mgmt_delete).with( '/v1/mgmt/outbound/user/tokens', { appId: 'app-123', userId: 'user-123' } ) @@ -223,7 +223,7 @@ end it 'deletes token by id' do - expect(@instance).to receive(:delete).with( + expect(@instance).to receive(:mgmt_delete).with( '/v1/mgmt/outbound/token', { id: 'token-123' } ) diff --git a/spec/lib.descope/api/v1/management/password_spec.rb b/spec/lib.descope/api/v1/management/password_spec.rb index 931ca0ba..25fccb35 100644 --- a/spec/lib.descope/api/v1/management/password_spec.rb +++ b/spec/lib.descope/api/v1/management/password_spec.rb @@ -11,14 +11,14 @@ context '.get_password_settings' do it 'should get password settings' do - expect(@instance).to receive(:get).with('/v1/mgmt/password/settings', { tenantId: 'tenant_id' }) + expect(@instance).to receive(:mgmt_get).with('/v1/mgmt/password/settings', { tenantId: 'tenant_id' }) @instance.get_password_settings('tenant_id') end end context '.update_password_settings' do it 'should update password settings' do - expect(@instance).to receive(:post).with('/v1/mgmt/password/settings', { 'minLength' => 10 }) + expect(@instance).to receive(:mgmt_post).with('/v1/mgmt/password/settings', { 'minLength' => 10 }) @instance.update_password_settings({ min_length: 10 }) end end diff --git a/spec/lib.descope/api/v1/management/permission_spec.rb b/spec/lib.descope/api/v1/management/permission_spec.rb index 8bd463ef..070a3989 100644 --- a/spec/lib.descope/api/v1/management/permission_spec.rb +++ b/spec/lib.descope/api/v1/management/permission_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create a new permission' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( PERMISSION_CREATE_PATH, { name: 'test', description: 'test' @@ -36,7 +36,7 @@ end it 'is expected to update a permission' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( PERMISSION_UPDATE_PATH, { name: 'test', newName: 'production', @@ -59,7 +59,7 @@ end it 'is expected to delete a permission' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( PERMISSION_DELETE_PATH, { name: 'test' } ) expect do @@ -74,7 +74,7 @@ end it 'is expected to delete a permission' do - expect(@instance).to receive(:get).with(PERMISSION_LOAD_ALL_PATH) + expect(@instance).to receive(:mgmt_get).with(PERMISSION_LOAD_ALL_PATH) expect { @instance.load_all_permissions }.not_to raise_error end end diff --git a/spec/lib.descope/api/v1/management/project_spec.rb b/spec/lib.descope/api/v1/management/project_spec.rb index 7f80c498..2fe8b155 100644 --- a/spec/lib.descope/api/v1/management/project_spec.rb +++ b/spec/lib.descope/api/v1/management/project_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to rename the current project' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( PROJECT_UPDATE_NAME, { name: 'test' } ) expect { @instance.rename_project('test') }.not_to raise_error @@ -28,7 +28,7 @@ end it 'is expected to export the current project' do - expect(@instance).to receive(:post).with(PROJECT_EXPORT_PATH) + expect(@instance).to receive(:mgmt_post).with(PROJECT_EXPORT_PATH) expect do @instance.export_project end.not_to raise_error @@ -41,7 +41,7 @@ end it 'is expected to import a project' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( PROJECT_IMPORT_PATH, { files: 'files' } ) expect do @@ -56,7 +56,7 @@ end it 'is expected to clone the current project' do - expect(@instance).to receive(:post).with(PROJECT_CLONE, { name: 'test', tag: 'test' }) + expect(@instance).to receive(:mgmt_post).with(PROJECT_CLONE, { name: 'test', tag: 'test' }) expect { @instance.clone_project(name: 'test', tag: 'test') }.not_to raise_error end end diff --git a/spec/lib.descope/api/v1/management/role_spec.rb b/spec/lib.descope/api/v1/management/role_spec.rb index 3cf77d90..f7f6e244 100644 --- a/spec/lib.descope/api/v1/management/role_spec.rb +++ b/spec/lib.descope/api/v1/management/role_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create a new role' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ROLE_CREATE_PATH, { name: 'test', description: 'test', @@ -40,7 +40,7 @@ end it 'is expected to update a role' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ROLE_UPDATE_PATH, { name: 'test', newName: 'production', @@ -67,7 +67,7 @@ end it 'is expected to delete a role' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ROLE_DELETE_PATH, { name: 'test', tenantId: 'test' } ) expect do @@ -82,7 +82,7 @@ end it 'is expected to delete a role' do - expect(@instance).to receive(:get).with(ROLE_LOAD_ALL_PATH) + expect(@instance).to receive(:mgmt_get).with(ROLE_LOAD_ALL_PATH) expect { @instance.load_all_roles }.not_to raise_error end end @@ -93,7 +93,7 @@ end it 'is expected to search roles' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( ROLE_SEARCH_PATH, { roleNames: %w[tester test2], tenantIds: %w[t1 t2], diff --git a/spec/lib.descope/api/v1/management/scim_spec.rb b/spec/lib.descope/api/v1/management/scim_spec.rb index 928efe74..a2c358d2 100644 --- a/spec/lib.descope/api/v1/management/scim_spec.rb +++ b/spec/lib.descope/api/v1/management/scim_spec.rb @@ -24,7 +24,7 @@ start_index, count, excluded_attributes) - expect(@instance).to receive(:get).with(url) + expect(@instance).to receive(:mgmt_get).with(url) expect do @instance.scim_search_groups(filter:, start_index:, count:, excluded_attributes:) end.not_to raise_error @@ -48,7 +48,7 @@ members, external_id, excluded_attributes) - expect(@instance).to receive(:post).with(Descope::Api::V1::Management::Common::SCIM_GROUPS_PATH, body) + expect(@instance).to receive(:mgmt_post).with(Descope::Api::V1::Management::Common::SCIM_GROUPS_PATH, body) expect do @instance.scim_create_group(group_id:, display_name:, @@ -73,7 +73,7 @@ :compose_scim_create_group_url, group_id, display_name, external_id, excluded_attributes ) - expect(@instance).to receive(:get).with(url) + expect(@instance).to receive(:mgmt_get).with(url) expect do @instance.scim_load_group(group_id:, display_name:, external_id:, excluded_attributes:) end.not_to raise_error @@ -96,7 +96,7 @@ group_id, display_name, members, external_id, excluded_attributes ) url = "#{SCIM_GROUPS_PATH}/#{group_id}" - expect(@instance).to receive(:patch).with(url, body) + expect(@instance).to receive(:mgmt_patch).with(url, body) expect do @instance.scim_update_group(group_id:, display_name:, members:, external_id:, excluded_attributes:) end.not_to raise_error @@ -111,7 +111,7 @@ it 'is expected to delete scim group' do group_id = 'G123' url = "#{SCIM_GROUPS_PATH}/#{group_id}" - expect(@instance).to receive(:delete).with(url) + expect(@instance).to receive(:mgmt_delete).with(url) expect { @instance.scim_delete_group(group_id) }.not_to raise_error end end @@ -142,7 +142,7 @@ url = @instance.send(:compose_scim_patch_group_url, group_id, user_id, operations) - expect(@instance).to receive(:patch).with(url) + expect(@instance).to receive(:mgmt_patch).with(url) expect do @instance.scim_patch_group(group_id:, user_id:, operations:) end.not_to raise_error @@ -156,7 +156,7 @@ it 'is expected to load scim resource types' do url = "#{SCIM_RESOURCE_TYPES_PATH}" - expect(@instance).to receive(:get).with(url) + expect(@instance).to receive(:mgmt_get).with(url) expect { @instance.scim_load_resource_types }.not_to raise_error end end @@ -168,7 +168,7 @@ it 'is expected to load scim service provider config' do url = "#{SCIM_SERVICE_PROVIDER_CONFIG_PATH}" - expect(@instance).to receive(:get).with(url) + expect(@instance).to receive(:mgmt_get).with(url) expect { @instance.scim_load_service_provider_config }.not_to raise_error end end @@ -186,7 +186,7 @@ filter, start_index, count) - expect(@instance).to receive(:get).with(url) + expect(@instance).to receive(:mgmt_get).with(url) expect do @instance.scim_search_users(filter:, start_index:, count:) end.not_to raise_error @@ -219,7 +219,7 @@ active, name, user_name) - expect(@instance).to receive(:post).with(SCIM_USERS_PATH, body) + expect(@instance).to receive(:mgmt_post).with(SCIM_USERS_PATH, body) expect do @instance.scim_create_user( user_id:, @@ -242,7 +242,7 @@ it 'is expected to load scim user' do user_id = 'U123' url = "#{SCIM_USERS_PATH}/#{user_id}" - expect(@instance).to receive(:get).with(url) + expect(@instance).to receive(:mgmt_get).with(url) expect do @instance.scim_load_user(user_id) end.not_to raise_error @@ -257,7 +257,7 @@ it 'is expected to load scim user' do user_id = 'U123' url = "#{SCIM_USERS_PATH}/#{user_id}" - expect(@instance).to receive(:patch).with(url) + expect(@instance).to receive(:mgmt_patch).with(url) expect do @instance.scim_update_user(user_id) end.not_to raise_error @@ -272,7 +272,7 @@ it 'is expected to delete scim user' do user_id = 'U123' url = "#{SCIM_USERS_PATH}/#{user_id}" - expect(@instance).to receive(:delete).with(url) + expect(@instance).to receive(:mgmt_delete).with(url) expect { @instance.scim_delete_user(user_id) }.not_to raise_error end end @@ -303,7 +303,7 @@ body = @instance.send(:compose_scim_patch_user_body, user_id, group_id, operations) - expect(@instance).to receive(:patch).with(SCIM_USERS_PATH, body) + expect(@instance).to receive(:mgmt_patch).with(SCIM_USERS_PATH, body) expect do @instance.scim_patch_user(user_id:, group_id:, operations:) end.not_to raise_error diff --git a/spec/lib.descope/api/v1/management/scope_claim_mapping_spec.rb b/spec/lib.descope/api/v1/management/scope_claim_mapping_spec.rb index e2aa83b1..843dbc49 100644 --- a/spec/lib.descope/api/v1/management/scope_claim_mapping_spec.rb +++ b/spec/lib.descope/api/v1/management/scope_claim_mapping_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to get the project-wide OIDC scope-to-claim mappings' do - expect(@instance).to receive(:post).with(SCOPE_CLAIM_MAPPING_GET_PATH) + expect(@instance).to receive(:mgmt_post).with(SCOPE_CLAIM_MAPPING_GET_PATH) expect do @instance.get_scope_claim_mapping end.not_to raise_error @@ -34,7 +34,7 @@ claims: %w[claim1 claim2] } ] - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( SCOPE_CLAIM_MAPPING_SET_PATH, { mappings: mappings } ) @@ -50,7 +50,7 @@ end it 'is expected to delete the project-wide OIDC scope-to-claim mappings' do - expect(@instance).to receive(:post).with(SCOPE_CLAIM_MAPPING_DELETE_PATH) + expect(@instance).to receive(:mgmt_post).with(SCOPE_CLAIM_MAPPING_DELETE_PATH) expect do @instance.delete_scope_claim_mapping end.not_to raise_error diff --git a/spec/lib.descope/api/v1/management/sso_application_spec.rb b/spec/lib.descope/api/v1/management/sso_application_spec.rb index b61e7095..36e5f54a 100644 --- a/spec/lib.descope/api/v1/management/sso_application_spec.rb +++ b/spec/lib.descope/api/v1/management/sso_application_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create SAML application' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( SSO_APPLICATION_OIDC_CREATE_PATH, { id: 'tenant1', name: 'test', @@ -44,7 +44,7 @@ end it 'is expected to create SAML application' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( SSO_APPLICATION_SAML_CREATE_PATH, { name: 'test', description: 'awesome tenant', @@ -172,7 +172,7 @@ end it 'is expected to update sso oidc application' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( SSO_APPLICATION_OIDC_UPDATE_PATH, { id: 'tenant1', name: 'test', @@ -195,21 +195,21 @@ end it 'is expected to delete sso app' do - expect(@instance).to receive(:delete).with( + expect(@instance).to receive(:mgmt_delete).with( SSO_APPLICATION_DELETE_PATH, { id: 'tenant1' } ) expect { @instance.delete_sso_app('tenant1') }.not_to raise_error end it 'is expected to load sso app' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( SSO_APPLICATION_LOAD_PATH, { id: 'tenant1' } ) expect { @instance.load_sso_app('tenant1') }.not_to raise_error end it 'is expected to load all sso apps' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( SSO_APPLICATION_LOAD_ALL_PATH, {} ) expect { @instance.load_all_sso_apps }.not_to raise_error diff --git a/spec/lib.descope/api/v1/management/sso_settings_spec.rb b/spec/lib.descope/api/v1/management/sso_settings_spec.rb index dc95f095..70d8d7e7 100644 --- a/spec/lib.descope/api/v1/management/sso_settings_spec.rb +++ b/spec/lib.descope/api/v1/management/sso_settings_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to get SSO settings' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( SSO_SETTINGS_PATH, { tenantId: '123' } ) expect { @instance.get_sso_settings('123') }.not_to raise_error @@ -28,7 +28,7 @@ end it 'is expected to delete SSO settings' do - expect(@instance).to receive(:delete).with( + expect(@instance).to receive(:mgmt_delete).with( SSO_SETTINGS_PATH, { tenantId: '123' } ) expect { @instance.delete_sso_settings('123') }.not_to raise_error @@ -40,7 +40,7 @@ end it 'is expected to configure SSO settings' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( SSO_OIDC_PATH, { tenantId: '123', settings: { @@ -86,7 +86,7 @@ end it 'is expected to configure SSO settings' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( SSO_SETTINGS_PATH, { tenantId: '123', settings: { @@ -131,7 +131,7 @@ end it 'is expected to configure SAML metadata' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( SSO_METADATA_PATH, { tenantId: '123', settings: { diff --git a/spec/lib.descope/api/v1/management/tenant_spec.rb b/spec/lib.descope/api/v1/management/tenant_spec.rb index a5354172..144d3f11 100644 --- a/spec/lib.descope/api/v1/management/tenant_spec.rb +++ b/spec/lib.descope/api/v1/management/tenant_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create a new tenant' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( TENANT_CREATE_PATH, { name: 'test', id: 'test', @@ -46,7 +46,7 @@ end it 'is expected to update a tenant' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( TENANT_UPDATE_PATH, { name: 'test', id: 'test', @@ -77,7 +77,7 @@ end it 'is expected to delete a tenant' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( TENANT_DELETE_PATH, { id: 'test' } ) expect { @instance.delete_tenant('test') }.not_to raise_error @@ -90,7 +90,7 @@ end it 'is expected to load a tenant' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( TENANT_LOAD_PATH, { id: 'test' } ) expect { @instance.load_tenant('test') }.not_to raise_error @@ -103,7 +103,7 @@ end it 'is expected to load all tenants' do - expect(@instance).to receive(:get).with(TENANT_LOAD_ALL_PATH) + expect(@instance).to receive(:mgmt_get).with(TENANT_LOAD_ALL_PATH) expect { @instance.load_all_tenants }.not_to raise_error end end @@ -114,7 +114,7 @@ end it 'is expected to search all tenants' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( TENANT_SEARCH_ALL_PATH, { ids: %w[test1 test2], names: %w[test1 test2], diff --git a/spec/lib.descope/api/v1/management/third_party_application_spec.rb b/spec/lib.descope/api/v1/management/third_party_application_spec.rb index d473b3a4..5e2eb684 100644 --- a/spec/lib.descope/api/v1/management/third_party_application_spec.rb +++ b/spec/lib.descope/api/v1/management/third_party_application_spec.rb @@ -15,7 +15,7 @@ end it 'is expected to create a third party application' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( THIRD_PARTY_APP_CREATE_PATH, { id: 'app1', name: 'test', @@ -56,7 +56,7 @@ end it 'is expected to update a third party application' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( THIRD_PARTY_APP_UPDATE_PATH, { id: 'app1', name: 'test', @@ -83,7 +83,7 @@ end it 'is expected to patch a third party application' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( THIRD_PARTY_APP_PATCH_PATH, { id: 'app1', name: 'test' @@ -99,42 +99,42 @@ end it 'is expected to delete a third party application' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( THIRD_PARTY_APP_DELETE_PATH, { id: 'app1' } ) expect { @instance.delete_application('app1') }.not_to raise_error end it 'is expected to load a third party application' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( THIRD_PARTY_APP_LOAD_PATH, { id: 'app1' } ) expect { @instance.load_application('app1') }.not_to raise_error end it 'is expected to load all third party applications' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( THIRD_PARTY_APP_LOAD_ALL_PATH, {} ) expect { @instance.load_all_applications }.not_to raise_error end it 'is expected to get a third party application secret' do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( THIRD_PARTY_APP_SECRET_PATH, { id: 'app1' } ) expect { @instance.get_application_secret('app1') }.not_to raise_error end it 'is expected to rotate a third party application secret' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( THIRD_PARTY_APP_ROTATE_PATH, { id: 'app1' } ) expect { @instance.rotate_application_secret('app1') }.not_to raise_error end it 'is expected to delete consents' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( THIRD_PARTY_APP_DELETE_CONSENTS_PATH, { consentIds: %w[consent1 consent2], appId: 'app1', @@ -153,7 +153,7 @@ end it 'is expected to delete tenant consents' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( THIRD_PARTY_APP_DELETE_TENANT_CONSENTS_PATH, { consentIds: %w[consent1 consent2], appId: 'app1', diff --git a/spec/lib.descope/api/v1/management/user_spec.rb b/spec/lib.descope/api/v1/management/user_spec.rb index 5164d6e3..8c02258f 100644 --- a/spec/lib.descope/api/v1/management/user_spec.rb +++ b/spec/lib.descope/api/v1/management/user_spec.rb @@ -58,7 +58,7 @@ } it 'is expected to create a user with user data' do - expect(@instance).to receive(:post).with(USER_CREATE_PATH, params) + expect(@instance).to receive(:mgmt_post).with(USER_CREATE_PATH, params) expect do @instance.create_user(**args) @@ -67,7 +67,7 @@ it 'is expected to create a test user with user data' do params[:test] = true - expect(@instance).to receive(:post).with(TEST_USER_CREATE_PATH, params) + expect(@instance).to receive(:mgmt_post).with(TEST_USER_CREATE_PATH, params) expect do args[:test] = true @@ -101,7 +101,7 @@ } ] } - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_CREATE_BATCH_PATH, users_params ) @@ -117,7 +117,7 @@ end it "is expected to post #{USER_CREATE_PATH} with invite true" do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_CREATE_PATH, { loginId: 'name@mail.com', email: 'name@mail.com', @@ -143,7 +143,7 @@ end it 'is expected to respond to a user update method' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_UPDATE_PATH, { loginId: 'name@mail.com', email: 'name@mail.com', @@ -171,7 +171,7 @@ end it 'is expected to respond to a user delete method' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_DELETE_PATH, { loginId: 'name@mail.com' } ) @@ -183,7 +183,7 @@ context '.delete_all_user' do it 'is expected to respond to a user delete method' do - expect(@instance).to receive(:delete).with(USER_DELETE_ALL_TEST_USERS_PATH) + expect(@instance).to receive(:mgmt_delete).with(USER_DELETE_ALL_TEST_USERS_PATH) expect do @instance.delete_all_test_users @@ -197,7 +197,7 @@ end it "is expected to get #{USER_LOAD_PATH} with login_id" do - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( USER_LOAD_PATH, { loginId: 'someone' } ) expect { @instance.load_user('someone') }.not_to raise_error @@ -206,7 +206,7 @@ context '.load_by_user_id' do it "is expected to get #{USER_LOAD_PATH} with user_id" do - allow(@instance).to receive(:get).with( + allow(@instance).to receive(:mgmt_get).with( USER_LOAD_PATH, { userId: 'ABCD' } ) expect { @instance.load_by_user_id('ABCD') }.not_to raise_error @@ -215,7 +215,7 @@ context '.logout_user' do it 'is expected to respond to a logout user method' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_LOGOUT_PATH, { loginId: 'name@mail.com' } ) @@ -225,7 +225,7 @@ end it 'is expected to respond to a logout user by id method' do - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_LOGOUT_PATH, { userId: 'U2ZpARjKAJJmq0fzU2lXNNCGnF4j' } ) @@ -241,7 +241,7 @@ tenant_role_ids = { 'tenant1' => ['roleA', 'roleB'] } tenant_role_names = { 'tenant1' => ['roleName1', 'roleName2'] } - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USERS_SEARCH_PATH, { loginId: 'someone@example.com', tenantIds: [], @@ -284,7 +284,7 @@ it 'is expected to respond to a get_provider_token method' do expect(@instance).to respond_to(:get_provider_token) - expect(@instance).to receive(:get).with( + expect(@instance).to receive(:mgmt_get).with( USER_GET_PROVIDER_TOKEN, { loginId: 'someone@example.com', provider: 'google-oauth2' @@ -304,7 +304,7 @@ it 'is expected to respond to a activate method' do expect(@instance).to respond_to(:activate) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_UPDATE_STATUS_PATH, { loginId: 'someone@example.com', status: 'enabled' @@ -321,7 +321,7 @@ it 'is expected to respond to a activate method' do expect(@instance).to respond_to(:activate) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_UPDATE_STATUS_PATH, { loginId: 'someone@example.com', status: 'disabled' @@ -338,7 +338,7 @@ it 'is expected to respond to a update_email method' do expect(@instance).to respond_to(:update_email) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_UPDATE_EMAIL_PATH, { loginId: 'someone@example.com', email: 'tester@test.com', @@ -360,7 +360,7 @@ it 'is expected to respond to a update_phone method' do expect(@instance).to respond_to(:update_phone) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_UPDATE_PHONE_PATH, { loginId: 'someone@example.com', phone: '1234567890', @@ -382,7 +382,7 @@ it 'is expected to respond to a update_display_name method' do expect(@instance).to respond_to(:update_display_name) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_UPDATE_NAME_PATH, { loginId: 'someone@example.com', name: 'some guy', @@ -408,7 +408,7 @@ it 'is expected to respond to a update_picture method' do expect(@instance).to respond_to(:update_picture) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_UPDATE_PICTURE_PATH, { loginId: 'someone@example.com', picture: 'https://www.example.com/picture.png' @@ -428,7 +428,7 @@ it 'is expected to respond to a update_custom_attribute method' do expect(@instance).to respond_to(:update_custom_attribute) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_UPDATE_CUSTOM_ATTRIBUTE_PATH, { loginId: 'someone@example.com', attributeKey: 'OU', @@ -450,7 +450,7 @@ it 'is expected to respond to a add_roles method' do expect(@instance).to respond_to(:user_add_roles) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_ADD_ROLE_PATH, { loginId: 'someone@example.com', roleNames: %w[role1 role2], @@ -472,7 +472,7 @@ it 'is expected to respond to a user_remove_roles method' do expect(@instance).to respond_to(:user_remove_roles) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_REMOVE_ROLE_PATH, { loginId: 'someone@example.com', roleNames: %w[role1 role2], @@ -494,7 +494,7 @@ it 'is expected to respond to a add_tenant method' do expect(@instance).to respond_to(:user_add_tenant) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_ADD_TENANT_PATH, { loginId: 'someone@example.com', tenantId: 'tenant1' @@ -514,7 +514,7 @@ it 'is expected to respond to a remove_tenant method' do expect(@instance).to respond_to(:user_remove_tenant) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_REMOVE_TENANT_PATH, { loginId: 'someone@example.com', tenantId: 'tenant1' @@ -534,7 +534,7 @@ it 'is expected to respond to a add_tenant_role method' do expect(@instance).to respond_to(:add_tenant_role) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_ADD_TENANT_PATH, { loginId: 'someone@example.com', tenantId: 'tenant1', @@ -556,7 +556,7 @@ it 'is expected to respond to a remove_tenant_role method' do expect(@instance).to respond_to(:user_remove_tenant_roles) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_REMOVE_TENANT_PATH, { loginId: 'someone@example.com', tenantId: 'tenant1', @@ -578,7 +578,7 @@ it 'is expected to respond to a set_temporary_password method' do expect(@instance).to respond_to(:set_temporary_password) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_SET_TEMPORARY_PASSWORD_PATH, { loginId: 'someone@example.com', password: 's3cr3t' @@ -598,7 +598,7 @@ it 'is expected to respond to a set_active_password method' do expect(@instance).to respond_to(:set_active_password) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_SET_ACTIVE_PASSWORD_PATH, { loginId: 'someone@example.com', password: 's3cr3t' @@ -618,7 +618,7 @@ it 'is expected to respond to a set_password method' do expect(@instance).to respond_to(:set_password) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_SET_PASSWORD_PATH, { loginId: 'someone@example.com', password: 's3cr3t' @@ -638,7 +638,7 @@ it 'is expected to respond to a expire_password method' do expect(@instance).to respond_to(:expire_password) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_EXPIRE_PASSWORD_PATH, { loginId: 'someone@example.com' } ) @@ -650,7 +650,7 @@ it 'is expected to respond to a generate_otp_for_test method' do expect(@instance).to respond_to(:generate_otp_for_test_user) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_GENERATE_OTP_FOR_TEST_PATH, { loginId: 'someone@example.com', deliveryMethod: 'email' @@ -670,7 +670,7 @@ it 'is expected to respond to a generate_enchanted_link_for_test method' do expect(@instance).to respond_to(:generate_enchanted_link_for_test_user) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_GENERATE_ENCHANTED_LINK_FOR_TEST_PATH, { loginId: 'someone@example.com', URI: 'https://www.example.com' @@ -690,7 +690,7 @@ it 'is expected to respond to a update_jwt method' do expect(@instance).to respond_to(:update_jwt) - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( UPDATE_JWT_PATH, { jwt: 'eyJ3abcde12345', customClaims: { 'claim1' => 'value1', 'claim2' => 'value2' } @@ -717,7 +717,7 @@ customClaims: { 'abc': '123' } } - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( USER_GENERATE_EMBEDDED_LINK_PATH, request_params ) @@ -737,7 +737,7 @@ end it 'is expected to respond to a user patch method' do - expect(@instance).to receive(:patch).with( + expect(@instance).to receive(:mgmt_patch).with( USER_PATCH_PATH, { loginId: 'name@mail.com', email: 'name@mail.com', @@ -765,7 +765,7 @@ tenant_role_ids = { 'tenant1' => ['roleA', 'roleB'] } tenant_role_names = { 'tenant1' => ['roleName1', 'roleName2'] } - expect(@instance).to receive(:post).with( + expect(@instance).to receive(:mgmt_post).with( TEST_USERS_SEARCH_PATH, { tenantIds: %w[t1 t2], roleNames: %w[r1 r2], diff --git a/spec/lib.descope/auth_management_key_spec.rb b/spec/lib.descope/auth_management_key_spec.rb new file mode 100644 index 00000000..79421552 --- /dev/null +++ b/spec/lib.descope/auth_management_key_spec.rb @@ -0,0 +1,151 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Covers the Authorization header the SDK actually sends. The auth management key rides along with +# every authentication request so that methods whose public access has been disabled can still be +# used, and it is never sent on management requests - those carry the management key instead. +describe 'auth management key' do + let(:project_id) { 'P2abcde12345' } + let(:management_key) { 'mgmt-key' } + let(:auth_management_key) { 'auth-key' } + let(:refresh_token) { 'refresh-token' } + + # Stubs the RestClient boundary on both of the client's HTTP clients and hands back the + # Authorization header of whichever one ends up being used. + def authorization_for(client) + captured = nil + [client.auth_http, client.mgmt_http].each do |http| + allow(http).to receive(:call) do |_method, _url, _timeout, headers, _body| + captured = headers['Authorization'] + double('response', code: 200, body: '{}', cookies: {}, headers: {}) + end + end + yield + captured + end + + def build_client(**options) + Descope::Client.new({ project_id: project_id, log_level: 'fatal' }.merge(options)) + end + + # An authentication request that presents no token of its own. + def sign_up(client) + client.otp_sign_up(method: Descope::Mixins::Common::DeliveryMethod::EMAIL, login_id: 'someone@example.com') + end + + around do |example| + keys = %w[DESCOPE_MANAGEMENT_KEY DESCOPE_AUTH_MANAGEMENT_KEY] + saved = keys.to_h { |var| [var, ENV[var]] } + keys.each { |var| ENV.delete(var) } + example.run + ensure + saved.each { |var, value| ENV[var] = value } + end + + context 'on authentication requests' do + it 'sends only the project ID when no auth management key is configured' do + client = build_client + header = authorization_for(client) { sign_up(client) } + expect(header).to eq("Bearer #{project_id}") + end + + it 'appends the auth management key when one is configured' do + client = build_client(auth_management_key: auth_management_key) + header = authorization_for(client) { sign_up(client) } + expect(header).to eq("Bearer #{project_id}:#{auth_management_key}") + end + + it 'appends the auth management key after a refresh token' do + client = build_client(auth_management_key: auth_management_key) + header = authorization_for(client) { client.me(refresh_token) } + expect(header).to eq("Bearer #{project_id}:#{refresh_token}:#{auth_management_key}") + end + + it 'never sends the management key' do + client = build_client(management_key: management_key, auth_management_key: auth_management_key) + header = authorization_for(client) { sign_up(client) } + expect(header).to eq("Bearer #{project_id}:#{auth_management_key}") + expect(header).to_not include(management_key) + end + + # DummyClass swallows extra_headers, so only a real client exercises this argument. + it 'tolerates a nil extra_headers from the caller' do + client = build_client(auth_management_key: auth_management_key) + header = authorization_for(client) { client.post(SIGN_IN_PASSWORD_PATH, {}, nil, refresh_token) } + expect(header).to eq("Bearer #{project_id}:#{refresh_token}:#{auth_management_key}") + end + + it 'signs in with an enchanted link' do + client = build_client(auth_management_key: auth_management_key) + header = authorization_for(client) do + client.enchanted_link_sign_in(login_id: 'someone@example.com', uri: 'https://example.com') + end + expect(header).to eq("Bearer #{project_id}:#{auth_management_key}") + end + + it 'does not substitute a key for an empty refresh token' do + client = build_client(management_key: management_key, auth_management_key: auth_management_key) + header = authorization_for(client) { client.sign_out('') } + expect(header).to eq("Bearer #{project_id}:#{auth_management_key}") + end + end + + context 'on management requests' do + it 'appends the management key' do + client = build_client(management_key: management_key) + header = authorization_for(client) { client.load_all_tenants } + expect(header).to eq("Bearer #{project_id}:#{management_key}") + end + + it 'never sends the auth management key' do + client = build_client(management_key: management_key, auth_management_key: auth_management_key) + header = authorization_for(client) { client.load_all_tenants } + expect(header).to eq("Bearer #{project_id}:#{management_key}") + expect(header).to_not include(auth_management_key) + end + + it 'sends only the project ID when no management key is configured' do + client = build_client(auth_management_key: auth_management_key) + header = authorization_for(client) { client.load_all_tenants } + expect(header).to eq("Bearer #{project_id}") + end + end + + context 'configuration' do + it 'falls back to the DESCOPE_AUTH_MANAGEMENT_KEY env var' do + ENV['DESCOPE_AUTH_MANAGEMENT_KEY'] = 'env-auth-key' + client = build_client + header = authorization_for(client) { sign_up(client) } + expect(header).to eq("Bearer #{project_id}:env-auth-key") + end + + it 'prefers the configured key over the env var' do + ENV['DESCOPE_AUTH_MANAGEMENT_KEY'] = 'env-auth-key' + client = build_client(auth_management_key: auth_management_key) + header = authorization_for(client) { sign_up(client) } + expect(header).to eq("Bearer #{project_id}:#{auth_management_key}") + end + + it 'keeps the two keys distinct' do + ENV['DESCOPE_MANAGEMENT_KEY'] = management_key + ENV['DESCOPE_AUTH_MANAGEMENT_KEY'] = auth_management_key + client = build_client + expect(client.auth_http.authorization_header).to eq( + { 'Authorization' => "Bearer #{project_id}:#{auth_management_key}" } + ) + expect(client.mgmt_http.authorization_header).to eq( + { 'Authorization' => "Bearer #{project_id}:#{management_key}" } + ) + end + end + + describe 'debug logging' do + it 'masks everything after the project ID' do + client = build_client(auth_management_key: auth_management_key) + masked = client.auth_http.mask_authorization(client.auth_http.authorization_header) + expect(masked['Authorization']).to eq("Bearer #{project_id}:***") + expect(masked['Authorization']).to_not include(auth_management_key) + end + end +end diff --git a/spec/support/client_config.rb b/spec/support/client_config.rb index 46eb8f62..776baa68 100644 --- a/spec/support/client_config.rb +++ b/spec/support/client_config.rb @@ -11,6 +11,7 @@ def config descope_base_uri: ENV.fetch('DESCOPE_BASE_URI', Descope::Mixins::Common::DEFAULT_BASE_URL), project_id: ENV.fetch('DESCOPE_PROJECT_ID', nil), management_key: ENV.fetch('DESCOPE_MANAGEMENT_KEY', nil), + auth_management_key: ENV.fetch('DESCOPE_AUTH_MANAGEMENT_KEY', nil), log_level: ENV.fetch('DESCOPE_LOG_LEVEL', 'info') } end diff --git a/spec/support/dummy_class.rb b/spec/support/dummy_class.rb index 3aa02b17..b87af281 100644 --- a/spec/support/dummy_class.rb +++ b/spec/support/dummy_class.rb @@ -33,18 +33,21 @@ def add_headers(h = {}) @headers.merge!(h.to_hash) end + # Mirrors Descope::HttpClient#authorization_header. Specs that need to assert on the real bearer + # should drive a Descope::Client instead - see spec/lib.descope/auth_management_key_spec.rb. def authorization_header(pswd = nil) - pswd = @default_pswd if pswd.nil? || pswd.empty? - bearer = "#{@project_id}:#{pswd}" - add_headers('Authorization' => "Bearer #{bearer}") + bearer = [@project_id, pswd, @key].reject { |part| part.nil? || part.to_s.empty? }.join(':') + { 'Authorization' => "Bearer #{bearer}" } end - %i[get post post_file post_form put patch delete delete_with_body].each do |method| - define_method(method) do |uri, body = {}, extra_headers = {}, pswd = nil| - body = body.delete_if { |_, v| v.nil? } - authorization_header(pswd) unless pswd.nil? || pswd.empty? - {} + # The bare verbs stand in for authentication requests, the mgmt_ prefixed ones for management + # requests, matching how Descope::Client routes them to its two HTTP clients. + Descope::Mixins::HTTP::HTTP_METHODS.each do |method| + [method, :"mgmt_#{method}"].each do |name| + define_method(name) do |_uri, _body = {}, _extra_headers = {}, pswd = nil| + add_headers(authorization_header(pswd)) unless pswd.nil? || pswd.empty? + {} + end end end - end