diff --git a/README.md b/README.md index 89f3fe5..5620ea9 100644 --- a/README.md +++ b/README.md @@ -768,6 +768,20 @@ roles = roles_resp['roles'] # ``` +# Search roles +roles_resp = descope_client.search_roles( + names: ['role1', 'role2'], # Search for roles with the names 'role1' and 'role2' + role_name_like: 'role', # Search for roles that contain the string 'role' + tenant_ids: ['tenant1', 'tenant2'], # Search for roles that are associated with the tenants 'tenant1' and 'tenant2' + permission_names: ['permission1', 'permission2'] # Search for roles that have the permissions 'permission1' and 'permission2' +) + +roles = roles_resp['roles'] +roles.each do |role| + # Do something +end +``` + ### Manage Flows and Theme You can list your flows and also import and export flows and screens, or the project theme: diff --git a/examples/ruby-on-rails-api/descope/Gemfile.lock b/examples/ruby-on-rails-api/descope/Gemfile.lock index 3a2bbcf..9b2fba1 100644 --- a/examples/ruby-on-rails-api/descope/Gemfile.lock +++ b/examples/ruby-on-rails-api/descope/Gemfile.lock @@ -134,7 +134,7 @@ GEM marcel (1.0.2) mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2023.1205) + mime-types-data (3.2024.0206) mini_mime (1.1.5) minitest (5.21.2) msgpack (1.7.2) diff --git a/examples/ruby/management/Gemfile.lock b/examples/ruby/management/Gemfile.lock index 0ee6d19..e12f26f 100644 --- a/examples/ruby/management/Gemfile.lock +++ b/examples/ruby/management/Gemfile.lock @@ -3,7 +3,7 @@ GEM specs: addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) - descope (1.0.0) + descope (1.0.4) addressable (~> 2.8) jwt (~> 2.7) rest-client (~> 2.1) @@ -16,7 +16,7 @@ GEM jwt (2.7.1) mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2023.1205) + mime-types-data (3.2024.0206) netrc (0.11.0) public_suffix (5.0.4) rest-client (2.1.0) diff --git a/lib/descope/api/v1/management/common.rb b/lib/descope/api/v1/management/common.rb index 2479285..ceaab80 100644 --- a/lib/descope/api/v1/management/common.rb +++ b/lib/descope/api/v1/management/common.rb @@ -15,7 +15,7 @@ module Common TENANT_SEARCH_ALL_PATH = '/v1/mgmt/tenant/search' PASSWORD_SETTINGS_PATH = '/v1/mgmt/password/settings' - # userUSER_CREATE_PATH + # user USER_CREATE_PATH = '/v1/mgmt/user/create' USER_CREATE_BATCH_PATH = '/v1/mgmt/user/create/batch' USER_UPDATE_PATH = '/v1/mgmt/user/update' @@ -82,6 +82,7 @@ module Common ROLE_UPDATE_PATH = '/v1/mgmt/role/update' ROLE_DELETE_PATH = '/v1/mgmt/role/delete' ROLE_LOAD_ALL_PATH = '/v1/mgmt/role/all' + ROLE_SEARCH_PATH = '/v1/mgmt/role/search' # flow FLOW_LIST_PATH = '/v1/mgmt/flow/list' diff --git a/lib/descope/api/v1/management/role.rb b/lib/descope/api/v1/management/role.rb index ab9f5d4..0e8a147 100644 --- a/lib/descope/api/v1/management/role.rb +++ b/lib/descope/api/v1/management/role.rb @@ -36,6 +36,8 @@ def update_role(name: nil, new_name: nil, description: nil, permission_names: ni def delete_role(name: nil, tenant_id: nil) # Delete an existing role. IMPORTANT: This action is irreversible. Use carefully. + raise Descope::ArgumentError, 'name is required' if name.nil? || name.empty? + request_params = { name: } request_params[:tenantId] = tenant_id if tenant_id post(ROLE_DELETE_PATH, request_params) @@ -45,6 +47,16 @@ def load_all_roles # Load all roles. get(ROLE_LOAD_ALL_PATH) end + + def search_roles(role_names: nil, tenant_ids: nil, role_name_like: nil, permission_names: nil) + # Search for roles using the given parameters. + request_params = {} + request_params[:roleNames] = role_names if role_names + 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) + end end end end diff --git a/lib/descope/mixins/common.rb b/lib/descope/mixins/common.rb index 8f154c8..c49644e 100644 --- a/lib/descope/mixins/common.rb +++ b/lib/descope/mixins/common.rb @@ -114,16 +114,6 @@ module EndpointsV1 module EndpointsV2 PUBLIC_KEY_PATH = '/v2/keys' end - - module LoginOptions - attr_accessor :stepup, :mfa, :custom_claims - - def initialize - @stepup = stepup || false - @mfa ||= false - @custom_claims ||= {} - end - end end end end diff --git a/spec/integration/lib.descope/api/v1/management/roles_spec.rb b/spec/integration/lib.descope/api/v1/management/roles_spec.rb index 70c2d08..c38b6c5 100644 --- a/spec/integration/lib.descope/api/v1/management/roles_spec.rb +++ b/spec/integration/lib.descope/api/v1/management/roles_spec.rb @@ -5,42 +5,112 @@ describe Descope::Api::V1::Management::Role do before(:all) do @client = DescopeClient.new(Configuration.config) + @client.logger.info('Staring cleanup before tests...') + @client.logger.info('Deleting all permissions for Ruby SDK...') @client.load_all_permissions['permissions'].each do |perm| - if perm['description'] == 'Ruby SDK' - puts "Deleting permission: #{perm['name']}" + if perm['description'] =~ /Ruby SDK/ + @client.logger.info("Deleting permission: #{perm['name']}") @client.delete_permission(perm['name']) end end + @client.logger.info('Deleting all roles for Ruby SDK...') @client.load_all_roles['roles'].each do |role| + puts "got role: #{role}" if role['description'] == 'Ruby SDK' - puts "Deleting role: #{role['name']}" - @client.delete_role(name: role['name']) + @client.logger.info("Deleting role: #{role['name']}") + @client.delete_role(name: role['name'], tenant_id: role['tenantId']) end end + + @client.logger.info('Deleting all tenants for Ruby SDK...') + @client.search_all_tenants(names: ['Ruby-SDK-test'])['tenants'].each do |tenant| + @client.logger.info("Deleting tenant: #{tenant['name']}") + @client.delete_tenant(tenant['id']) + end + @client.logger.info('Cleanup completed. Starting tests...') end it 'should create update and delete a role' do - puts 'creating permission for role' - @client.create_permission(name: 'test_permission', description: 'Ruby SDK') - puts 'creating role' - @client.create_role(name: 'Ruby SDK test role', description: 'Ruby SDK', permission_names: ['test_permission']) - puts 'loading all roles' - all_roles = @client.load_all_roles['roles'] - expect(all_roles.any? { |role| role['name'] == 'Ruby SDK test role' }).to eq(true) - expect(all_roles.any? { |role| role['permissionNames'] == ['test_permission'] }).to eq(true) - puts 'updating role' + @client.logger.info('Testing role creation, update, deletion and search...') + + # Create permissions + @client.logger.info('creating viewer permission for role') + @client.create_permission(name: 'viewer', description: 'Viewer Permission Ruby SDK') + + @client.logger.info('creating editor permission for role') + @client.create_permission(name: 'editor', description: 'Editor Permission Ruby SDK') + + @client.logger.info('creating admin permission for role') + @client.create_permission(name: 'admin', description: 'Admin Permission Ruby SDK') + + # Create tenants + @client.logger.info('creating Ruby-SDK-test tenant') + tenant_id = @client.create_tenant(name: 'Ruby-SDK-test')['id'] + + # Create roles + @client.logger.info('creating Ruby-SDK-test role') + @client.create_role(name: 'Ruby-SDK-test-viewer', description: 'Ruby SDK', permission_names: ['viewer']) + @client.logger.info('creating Ruby-SDK-test-admin role') + @client.create_role(name: 'Ruby-SDK-test-admin', description: 'Ruby SDK', permission_names: ['admin'], tenant_id:) + + # check all roles matching the correct permission + @client.logger.info('check all roles matching the correct permission (load roles)') + roles = @client.load_all_roles['roles'] + roles.each do |role| + expect(role['permissionNames']).to include('viewer') if role['name'] == 'Ruby-SDK-test-viewer' + expect(role['permissionNames']).to include('admin') if role['name'] == 'Ruby-SDK-test-admin' + end + + @client.logger.info('updating role') @client.update_role( - name: 'Ruby SDK test role', - new_name: 'Ruby SDK test role 2', + name: 'Ruby-SDK-test-viewer', + new_name: 'Ruby-SDK-test-editor', description: 'Ruby SDK', - permission_names: ['test_permission'] + permission_names: ['editor'] ) - all_roles = @client.load_all_roles['roles'] - expect(all_roles.any? { |role| role['name'] == 'Ruby SDK test role 2' }).to eq(true) - puts 'deleting permission' - @client.delete_permission('test_permission') - puts 'deleting role' - @client.delete_role(name: 'Ruby SDK test role 2') + + @client.logger.info('searching for roles by role names...') + all_roles = @client.search_roles(role_names: %w[Ruby-SDK-test-admin Ruby-SDK-test-editor])['roles'] + expected_roles = %w[Ruby-SDK-test-editor Ruby-SDK-test-admin] + role_count = 0 + expected_roles.each do |expected_role| + expect(all_roles.map { |role| role['name'] }).to include(expected_role) + role_count += 1 + end + expect(role_count).to eq(2) + + @client.logger.info('searching for roles with role name like...') + all_roles = @client.search_roles(role_name_like: 'Ruby-SDK-test')['roles'] + expected_roles = %w[Ruby-SDK-test-editor Ruby-SDK-test-admin] + role_count = 0 + expected_roles.each do |expected_role| + expect(all_roles.map { |role| role['name'] }).to include(expected_role) + role_count += 1 + end + + expect(role_count).to eq(2) + + @client.logger.info('searching for roles with permission names...') + all_roles = @client.search_roles(permission_names: %w[admin])['roles'] + expect(all_roles.map { |role| role['name'] }).to include('Ruby-SDK-test-admin') + + @client.logger.info('searching for roles with tenant ids...') + all_roles = @client.search_roles(tenant_ids: %w[Ruby-SDK-test])['roles'] + expect(all_roles.map { |role| role['name'] }).to include('Ruby-SDK-test-admin') + + @client.logger.info('deleting permission') + + @client.delete_permission('editor') + @client.delete_permission('admin') + + @client.logger.info('deleting editor role') + @client.delete_role(name: 'Ruby-SDK-test-editor') + + @client.logger.info('deleting admin role') + @client.delete_role(name: 'Ruby-SDK-test-admin', tenant_id:) + + @client.logger.info('deleting tenant') + @client.delete_tenant(tenant_id) 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 d07df88..3cf77d9 100644 --- a/spec/lib.descope/api/v1/management/role_spec.rb +++ b/spec/lib.descope/api/v1/management/role_spec.rb @@ -86,4 +86,29 @@ expect { @instance.load_all_roles }.not_to raise_error end end + + context '.search_roles' do + it 'should respond to .search_roles' do + expect(@instance).to respond_to :search_roles + end + + it 'is expected to search roles' do + expect(@instance).to receive(:post).with( + ROLE_SEARCH_PATH, { + roleNames: %w[tester test2], + tenantIds: %w[t1 t2], + roleNameLike: 'test', + permissionNames: %w[perm1 perm2] + } + ) + expect do + @instance.search_roles( + role_names: %w[tester test2], + tenant_ids: %w[t1 t2], + role_name_like: 'test', + permission_names: %w[perm1 perm2] + ) + end.not_to raise_error + end + end end