diff --git a/src/API/Management.php b/src/API/Management.php index 054a505a..67b80754 100644 --- a/src/API/Management.php +++ b/src/API/Management.php @@ -4,9 +4,9 @@ namespace Auth0\SDK\API; -use Auth0\SDK\API\Management\{Actions, AttackProtection, Blacklists, ClientGrants, Clients, Connections, DeviceCredentials, EmailTemplates, Emails, Grants, Guardian, Jobs, Keys, LogStreams, Logs, NetworkAcls, Organizations, RefreshTokens, ResourceServers, Roles, Rules, Sessions, Stats, Tenants, Tickets, UserBlocks, Users, UsersByEmail}; +use Auth0\SDK\API\Management\{Actions, AttackProtection, Blacklists, ClientGrants, Clients, Connections, DeviceCredentials, EmailTemplates, Emails, Grants, Guardian, Jobs, Keys, LogStreams, Logs, NetworkAcls, Organizations, RefreshTokens, ResourceServers, Roles, Rules, SelfServiceProfiles, Sessions, Stats, Tenants, Tickets, UserBlocks, Users, UsersByEmail}; use Auth0\SDK\Configuration\SdkConfiguration; -use Auth0\SDK\Contract\API\Management\{ActionsInterface, AttackProtectionInterface, BlacklistsInterface, ClientGrantsInterface, ClientsInterface, ConnectionsInterface, DeviceCredentialsInterface, EmailTemplatesInterface, EmailsInterface, GrantsInterface, GuardianInterface, JobsInterface, KeysInterface, LogStreamsInterface, LogsInterface, NetworkAclsInterface, OrganizationsInterface, RefreshTokensInterface, ResourceServersInterface, RolesInterface, RulesInterface, SessionsInterface, StatsInterface, TenantsInterface, TicketsInterface, UserBlocksInterface, UsersByEmailInterface, UsersInterface}; +use Auth0\SDK\Contract\API\Management\{ActionsInterface, AttackProtectionInterface, BlacklistsInterface, ClientGrantsInterface, ClientsInterface, ConnectionsInterface, DeviceCredentialsInterface, EmailTemplatesInterface, EmailsInterface, GrantsInterface, GuardianInterface, JobsInterface, KeysInterface, LogStreamsInterface, LogsInterface, NetworkAclsInterface, OrganizationsInterface, RefreshTokensInterface, ResourceServersInterface, RolesInterface, RulesInterface, SelfServiceProfilesInterface, SessionsInterface, StatsInterface, TenantsInterface, TicketsInterface, UserBlocksInterface, UsersByEmailInterface, UsersInterface}; use Auth0\SDK\Contract\API\{AuthenticationInterface, ManagementInterface}; use Auth0\SDK\Utility\{HttpClient, HttpResponse, HttpResponsePaginator}; use Psr\Cache\CacheItemPoolInterface; @@ -227,6 +227,11 @@ public function rules(): RulesInterface return Rules::instance($this->getHttpClient()); } + public function selfServiceProfiles(): SelfServiceProfilesInterface + { + return SelfServiceProfiles::instance($this->getHttpClient()); + } + public function sessions(): SessionsInterface { return Sessions::instance($this->getHttpClient()); diff --git a/src/API/Management/SelfServiceProfiles.php b/src/API/Management/SelfServiceProfiles.php new file mode 100644 index 00000000..2ef39118 --- /dev/null +++ b/src/API/Management/SelfServiceProfiles.php @@ -0,0 +1,208 @@ +string()->trim(); + [$body] = Toolkit::filter([$body])->array()->trim(); + + Toolkit::assert([ + [$name, \Auth0\SDK\Exception\ArgumentException::missing('name')], + ])->isString(); + + /** @var array $body */ + + return $this->getHttpClient() + ->method('post') + ->addPath(['self-service-profiles']) + ->withBody( + (object) Toolkit::merge([[ + 'name' => $name, + ], $body]), + ) + ->withOptions($options) + ->call(); + } + + public function createSsoTicket( + string $id, + ?array $body = null, + ?RequestOptions $options = null, + ): ResponseInterface { + [$id] = Toolkit::filter([$id])->string()->trim(); + [$body] = Toolkit::filter([$body])->array()->trim(); + + Toolkit::assert([ + [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')], + ])->isString(); + + /** @var array $body */ + + return $this->getHttpClient() + ->method('post') + ->addPath(['self-service-profiles', $id, 'sso-ticket']) + ->withBody((object) $body) + ->withOptions($options) + ->call(); + } + + public function delete( + string $id, + ?RequestOptions $options = null, + ): ResponseInterface { + [$id] = Toolkit::filter([$id])->string()->trim(); + + Toolkit::assert([ + [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')], + ])->isString(); + + return $this->getHttpClient() + ->method('delete') + ->addPath(['self-service-profiles', $id]) + ->withOptions($options) + ->call(); + } + + public function get( + string $id, + ?RequestOptions $options = null, + ): ResponseInterface { + [$id] = Toolkit::filter([$id])->string()->trim(); + + Toolkit::assert([ + [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')], + ])->isString(); + + return $this->getHttpClient() + ->method('get') + ->addPath(['self-service-profiles', $id]) + ->withOptions($options) + ->call(); + } + + public function getAll( + ?array $parameters = null, + ?RequestOptions $options = null, + ): ResponseInterface { + [$parameters] = Toolkit::filter([$parameters])->array()->trim(); + + /** @var array $parameters */ + + return $this->getHttpClient() + ->method('get') + ->addPath(['self-service-profiles']) + ->withParams($parameters) + ->withOptions($options) + ->call(); + } + + public function getCustomTextForProfile( + string $id, + string $language, + string $page, + ?RequestOptions $options = null, + ): ResponseInterface { + [$id] = Toolkit::filter([$id])->string()->trim(); + [$language] = Toolkit::filter([$language])->string()->trim(); + [$page] = Toolkit::filter([$page])->string()->trim(); + + Toolkit::assert([ + [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')], + [$language, \Auth0\SDK\Exception\ArgumentException::missing('language')], + [$page, \Auth0\SDK\Exception\ArgumentException::missing('page')], + ])->isString(); + + return $this->getHttpClient() + ->method('get') + ->addPath(['self-service-profiles', $id, 'custom-text', $language, $page]) + ->withOptions($options) + ->call(); + } + + public function revokeSsoTicket( + string $profileId, + string $id, + ?RequestOptions $options = null, + ): ResponseInterface { + [$profileId, $id] = Toolkit::filter([$profileId, $id])->string()->trim(); + + Toolkit::assert([ + [$profileId, \Auth0\SDK\Exception\ArgumentException::missing('profileId')], + [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')], + ])->isString(); + + return $this->getHttpClient() + ->method('post') + ->addPath(['self-service-profiles', $profileId, 'sso-ticket', $id, 'revoke']) + ->withOptions($options) + ->call(); + } + + public function setCustomTextForProfile( + string $id, + string $language, + string $page, + array $body, + ?RequestOptions $options = null, + ): ResponseInterface { + [$id] = Toolkit::filter([$id])->string()->trim(); + [$language] = Toolkit::filter([$language])->string()->trim(); + [$page] = Toolkit::filter([$page])->string()->trim(); + [$body] = Toolkit::filter([$body])->array()->trim(); + + Toolkit::assert([ + [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')], + [$language, \Auth0\SDK\Exception\ArgumentException::missing('language')], + [$page, \Auth0\SDK\Exception\ArgumentException::missing('page')], + ])->isString(); + + return $this->getHttpClient() + ->method('put') + ->addPath(['self-service-profiles', $id, 'custom-text', $language, $page]) + ->withOptions($options) + ->withBody($body) + ->call(); + } + + public function update( + string $id, + array $body, + ?RequestOptions $options = null, + ): ResponseInterface { + [$id] = Toolkit::filter([$id])->string()->trim(); + [$body] = Toolkit::filter([$body])->array()->trim(); + + Toolkit::assert([ + [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')], + ])->isString(); + + Toolkit::assert([ + [$body, \Auth0\SDK\Exception\ArgumentException::missing('body')], + ])->isArray(); + + return $this->getHttpClient() + ->method('patch') + ->addPath(['self-service-profiles', $id]) + ->withBody((object) $body) + ->withOptions($options) + ->call(); + } +} diff --git a/src/Contract/API/Management/SelfServiceProfilesInterface.php b/src/Contract/API/Management/SelfServiceProfilesInterface.php new file mode 100644 index 00000000..9624dfed --- /dev/null +++ b/src/Contract/API/Management/SelfServiceProfilesInterface.php @@ -0,0 +1,182 @@ + $body Configuration for the new Profile. See @see for supported options. + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/post-self-service-profiles + */ + public function create( + string $name, + array $body, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Creates an SSO access ticket to initiate the Self Service SSO Flow using a self-service profile. + * Required scopes: + * - `create:sso_access_tickets` for any call to this endpoint. + * + * @param string $id The id of the self-service profile + * @param array $body Configuration for the new Profile. See @see for supported options. + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/post-sso-ticket + */ + public function createSsoTicket( + string $id, + ?array $body = null, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Delete a Profile. + * Required scopes: + * - `delete:self_service_profiles` for any call to this endpoint. + * + * @param string $id The id of the self-service profile + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/delete-self-service-profiles-by-id + */ + public function delete( + string $id, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Get a Profile. + * Required scopes: + * - `read:self_service_profiles` for any call to this endpoint. + * + * @param string $id The id of the self-service profile + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/get-self-service-profiles-by-id + */ + public function get( + string $id, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Search all Profiles. + * Required scopes: + * - `read:self_service_profiles` for any call to this endpoint. + * + * @param null|array $parameters Optional. Query parameters to pass with the API request. See @see for supported options. + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/get-self-service-profiles + */ + public function getAll( + ?array $parameters = null, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Get the custom text for a Self Service Profile. + * Required scopes: + * - `read:self_service_profile_custom_texts` for any call to this endpoint. + * + * @param string $id The id of the self-service profile + * @param string $language The language of the custom text + * @param string $page The page where the custom text is shown + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/get-self-service-profile-custom-text + */ + public function getCustomTextForProfile( + string $id, + string $language, + string $page, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Revokes an SSO access ticket and invalidates associated sessions + * Required scopes: + * - `delete:sso_access_tickets` for any call to this endpoint. + * + * @param string $profileId The id of the self-service profile + * @param string $id The id of the ticket to revoke + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/post-revoke + */ + public function revokeSsoTicket( + string $profileId, + string $id, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Set the custom text for a Self Service Profile. + * Required scopes: + * - `update:self_service_profile_custom_texts` for any call to this endpoint. + * + * @param string $id The id of the self-service profile + * @param string $language The language of the custom text + * @param string $page The page where the custom text is shown + * @param array $body Configuration for the new Profile. See @see for supported options. + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/put-self-service-profile-custom-text + */ + public function setCustomTextForProfile( + string $id, + string $language, + string $page, + array $body, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Update a Profile. + * Required scopes: + * - `update:self_service_profiles` for any call to this endpoint. + * + * @param string $id The id of the self-service profile + * @param array $body Configuration for the new Profile. See @see for supported options. + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2/self-service-profiles/patch-self-service-profiles-by-id + */ + public function update( + string $id, + array $body, + ?RequestOptions $options = null, + ): ResponseInterface; +} diff --git a/src/Contract/API/ManagementInterface.php b/src/Contract/API/ManagementInterface.php index 377337b7..8821f978 100644 --- a/src/Contract/API/ManagementInterface.php +++ b/src/Contract/API/ManagementInterface.php @@ -4,7 +4,7 @@ namespace Auth0\SDK\Contract\API; -use Auth0\SDK\Contract\API\Management\{ActionsInterface, BlacklistsInterface, ClientGrantsInterface, ClientsInterface, ConnectionsInterface, DeviceCredentialsInterface, EmailTemplatesInterface, EmailsInterface, GrantsInterface, GuardianInterface, JobsInterface, LogStreamsInterface, LogsInterface, NetworkAclsInterface, OrganizationsInterface, ResourceServersInterface, RolesInterface, RulesInterface, StatsInterface, TenantsInterface, TicketsInterface, UserBlocksInterface, UsersByEmailInterface, UsersInterface}; +use Auth0\SDK\Contract\API\Management\{ActionsInterface, BlacklistsInterface, ClientGrantsInterface, ClientsInterface, ConnectionsInterface, DeviceCredentialsInterface, EmailTemplatesInterface, EmailsInterface, GrantsInterface, GuardianInterface, JobsInterface, LogStreamsInterface, LogsInterface, NetworkAclsInterface, OrganizationsInterface, ResourceServersInterface, RolesInterface, RulesInterface, SelfServiceProfilesInterface, StatsInterface, TenantsInterface, TicketsInterface, UserBlocksInterface, UsersByEmailInterface, UsersInterface}; use Auth0\SDK\Utility\HttpResponsePaginator; interface ManagementInterface extends ClientInterface @@ -50,6 +50,8 @@ public function roles(): RolesInterface; public function rules(): RulesInterface; + public function selfServiceProfiles(): SelfServiceProfilesInterface; + public function stats(): StatsInterface; public function tenants(): TenantsInterface; diff --git a/tests/Unit/API/Management/SelfSerivceProfiles.php b/tests/Unit/API/Management/SelfSerivceProfiles.php new file mode 100644 index 00000000..8732be6f --- /dev/null +++ b/tests/Unit/API/Management/SelfSerivceProfiles.php @@ -0,0 +1,178 @@ +group('management', 'management.self-service-profiles'); + +beforeEach(function(): void { + $this->endpoint = $this->api->mock()->selfServiceProfiles(); +}); + +test('getAll() issues an appropriate request', function(): void { + $id = uniqid(); + + $this->endpoint->getAll(['test' => $id]); + + expect($this->api->getRequestMethod())->toEqual('GET'); + expect($this->api->getRequestUrl())->toStartWith('https://' . $this->api->mock()->getConfiguration()->getDomain() . '/api/v2/self-service-profiles'); + + $query = $this->api->getRequestQuery(); + expect($query)->toContain('&test=' . $id); +}); + +test('get() issues an appropriate request', function(): void { + $id = uniqid(); + + $this->endpoint->get($id); + + expect($this->api->getRequestMethod())->toEqual('GET'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/self-service-profiles/' . $id); +}); + +test('update() issues an appropriate request', function(): void { + $mockup = (object) [ + 'id' => uniqid(), + 'query' => [ + 'name' => uniqid(), + 'description' => uniqid(), + 'user_attributes' => [ + '__test_meta_key__' => uniqid(), + ], + ], + ]; + + $this->endpoint->update($mockup->id, $mockup->query); + + expect($this->api->getRequestMethod())->toEqual('PATCH'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/self-service-profiles/' . $mockup->id); + + $headers = $this->api->getRequestHeaders(); + expect($headers['Content-Type'][0])->toEqual('application/json'); + + $body = $this->api->getRequestBody(); + + $this->assertArrayHasKey('name', $body); + expect($body['name'])->toEqual($mockup->query['name']); + $this->assertArrayHasKey('description', $body); + expect($body['description'])->toEqual($mockup->query['description']); + $this->assertArrayHasKey('user_attributes', $body); + $this->assertArrayHasKey('__test_meta_key__', $body['user_attributes']); + expect($body['user_attributes']['__test_meta_key__'])->toEqual($mockup->query['user_attributes']['__test_meta_key__']); + + $body = $this->api->getRequestBodyAsString(); + expect($body)->toEqual(json_encode($mockup->query)); +}); + +test('create() issues an appropriate request', function(): void { + $mockup = (object) [ + 'name' => uniqid(), + 'query' => [ + 'description' => uniqid(), + ], + ]; + + $this->endpoint->create($mockup->name, $mockup->query); + + expect($this->api->getRequestMethod())->toEqual('POST'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/self-service-profiles'); + + $headers = $this->api->getRequestHeaders(); + expect($headers['Content-Type'][0])->toEqual('application/json'); + + $body = $this->api->getRequestBody(); + $this->assertArrayHasKey('name', $body); + expect($body['name'])->toEqual($mockup->name); + $this->assertArrayHasKey('description', $body); + expect($body['description'])->toEqual($mockup->query['description']); + + $body = $this->api->getRequestBodyAsString(); + expect($body)->toEqual(json_encode(array_merge(['name' => $mockup->name], $mockup->query))); +}); + +test('delete() issues an appropriate request', function(): void { + $id = uniqid(); + + $this->endpoint->delete($id); + + expect($this->api->getRequestMethod())->toEqual('DELETE'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/self-service-profiles/' . $id); + + $headers = $this->api->getRequestHeaders(); + expect($headers['Content-Type'][0])->toEqual('application/json'); +}); + +test('getCustomTextForProfile() issues an appropriate request', function(): void { + $mockup = (object) [ + 'id' => uniqid(), + 'language' => uniqid(), + 'page' => uniqid(), + ]; + + $this->endpoint->getCustomTextForProfile($mockup->id, $mockup->language, $mockup->page); + + expect($this->api->getRequestMethod())->toEqual('GET'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/self-service-profiles/' . $mockup->id . '/custom-text/' . $mockup->language . '/' . $mockup->page); +}); + +test('setCustomTextForProfile() issues an appropriate request', function(): void { + $mockup = (object) [ + 'id' => uniqid(), + 'language' => uniqid(), + 'page' => uniqid(), + 'query' => [ + 'text' => uniqid(), + ], + ]; + + $this->endpoint->setCustomTextForProfile($mockup->id, $mockup->language, $mockup->page, $mockup->query); + + expect($this->api->getRequestMethod())->toEqual('PUT'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/self-service-profiles/' . $mockup->id . '/custom-text/' . $mockup->language . '/' . $mockup->page); + + $headers = $this->api->getRequestHeaders(); + expect($headers['Content-Type'][0])->toEqual('application/json'); + + $body = $this->api->getRequestBody(); + $this->assertArrayHasKey('text', $body); + expect($body['text'])->toEqual($mockup->query['text']); + + $body = $this->api->getRequestBodyAsString(); + expect($body)->toEqual(json_encode($mockup->query)); +}); + +test('createSsoTicket() issues an appropriate request', function(): void { + $mockup = (object) [ + 'id' => uniqid(), + 'query' => [ + 'connection_id' => uniqid(), + ], + ]; + + $this->endpoint->createSsoTicket($mockup->id, $mockup->query); + + expect($this->api->getRequestMethod())->toEqual('POST'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/self-service-profiles/' . $mockup->id . '/sso-ticket'); + + $headers = $this->api->getRequestHeaders(); + expect($headers['Content-Type'][0])->toEqual('application/json'); + + $body = $this->api->getRequestBody(); + $this->assertArrayHasKey('connection_id', $body); + expect($body['connection_id'])->toEqual($mockup->query['connection_id']); + + $body = $this->api->getRequestBodyAsString(); + expect($body)->toEqual(json_encode($mockup->query)); +}); + +test('revokeSsoTicket() issues an appropriate request', function(): void { + $id = uniqid(); + $profileId = uniqid(); + + $this->endpoint->revokeSsoTicket($id, $profileId); + + expect($this->api->getRequestMethod())->toEqual('POST'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/self-service-profiles/' . $id . '/sso-ticket/' . $profileId . '/revoke'); + + $headers = $this->api->getRequestHeaders(); + expect($headers['Content-Type'][0])->toEqual('application/json'); +});