diff --git a/.gitignore b/.gitignore index aa48ffdc..9d422a1c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ composer.phar composer.lock phpunit.xml vendor +.env \ No newline at end of file diff --git a/README.md b/README.md index 57518dd5..045aa00d 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ [](https://travis-ci.org/auth0/auth0-PHP) [](https://codeclimate.com/github/auth0/auth0-PHP) [](https://codeclimate.com/github/auth0/auth0-PHP/coverage) -[](https://www.versioneye.com/php/auth0:auth0-php) -[](http://hhvm.h4cc.de/package/auth0/auth0-php) [](https://packagist.org/packages/auth0/auth0-php) [](https://packagist.org/packages/auth0/auth0-php) @@ -62,7 +60,7 @@ Accepted params: - **cache**: Receives an instance of `Auth0\SDK\Helpers\Cache\CacheHandler` (Supported `FileSystemCacheHandler` and `NoCacheHandler`). Defaults to `NoCacheHandler`. - **guzzle_options**: Configuration propagated to guzzle when fetching the JWKs. - **supported_algs**: `RS256` and `HS256` supported. Defaults to `HS256`. -- **valid_audiences**: List of audiences that identifies the API (usefull for multitenant environments). +- **valid_audiences**: List of audiences that identifies the API (useful for multi-tenant environments). - **authorized_iss**: List of issues authorized to sign tokens for the API. - **client_secret**: Client secret used to verify the token signature (only for `HS256`). - **secret_base64_encoded**: When `true`, it will decode the secret used to verify the token signature. Defaults to `true` (used only for `HS256`). @@ -156,7 +154,7 @@ This is a common issue with latest PHP versions under windows (related to a inco > I am not using composer, my host does not allow using Composer -This package uses composer for mantianing dependencies. However, if you cannot use composer on your server. Please follow the following steps and upload these dependencies manually. +This package uses composer for maintaining dependencies. However, if you cannot use composer on your server. Please follow the following steps and upload these dependencies manually. - Download and install composer on your local environment. - Install auth0-PHP using composer. @@ -172,7 +170,7 @@ This package uses composer for mantianing dependencies. However, if you cannot u #### 4.0 -- Soon to deprecate the following clases: +- Soon to deprecate the following classes: + Auth0\SDK\Auth0Api: use \Auth0\SDK\API\Management instead + Auth0\SDK\Auth0AuthApi: use \Auth0\SDK\API\Authentication instead + Auth0\SDK\Auth0JWT: Use \Auth0\SDK\JWTVerifier instead @@ -182,7 +180,7 @@ This package uses composer for mantianing dependencies. However, if you cannot u #### 3.x -- SDK api changes, now the Auth0 API client is not build of static clases anymore. Usage example: +- SDK api changes, now the Auth0 API client is not build of static classes anymore. Usage example: ```php $token = "eyJhbGciO....eyJhdWQiOiI....1ZVDisdL..."; $domain = "account.auth0.com"; @@ -282,7 +280,7 @@ This SDK uses [Composer](http://getcomposer.org/doc/01-basic-usage.md) to manage Auth0 helps you to: -* Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. +* Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, among others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. @@ -300,7 +298,7 @@ If you have found a bug or if you have a feature request, please report them at ## Author -[Auth0](auth0.com) +[Auth0](https://auth0.com) ## License diff --git a/examples/basic-api/README.md b/examples/basic-api/README.md index 1e33bb50..c4c954e5 100644 --- a/examples/basic-api/README.md +++ b/examples/basic-api/README.md @@ -8,7 +8,7 @@ In order to run the example you need to have `composer` and `php` installed. Make sure that your app using `RS256` signature algorithm. You can change it under advanced settings of your app in tab `OAuth`. -You also need to set the ClientSecret and ClientId for your Auth0 app as enviroment variables with the following names respectively: `AUTH0_CLIENT_SECRET` and `AUTH0_CLIENT_ID`. +You also need to set the ClientSecret and ClientId for your Auth0 app as environment variables with the following names respectively: `AUTH0_CLIENT_SECRET` and `AUTH0_CLIENT_ID`. For that, if you just create a file named `.env` in the directory and set the values like the following, the app will just work: @@ -18,7 +18,7 @@ AUTH0_CLIENT_SECRET=myCoolSecret AUTH0_CLIENT_ID=myCoolClientId ```` -Once you've set those 2 enviroment variables, just run the following to get the app started: +Once you've set those 2 environment variables, just run the following to get the app started: ````bash composer install diff --git a/examples/basic-api/index.php b/examples/basic-api/index.php index 87f6c544..c35a923a 100644 --- a/examples/basic-api/index.php +++ b/examples/basic-api/index.php @@ -13,7 +13,6 @@ function apache_request_headers() { foreach($_SERVER as $key => $val) { if( preg_match($rx_http, $key) ) { $arh_key = preg_replace($rx_http, '', $key); - $rx_matches = array(); // do some nasty string manipulations to restore the original letter case // this should work in most cases $rx_matches = explode('_', $arh_key); diff --git a/examples/basic-oauth/public/app.css b/examples/basic-oauth/public/app.css index 3a965f1b..324ec24f 100644 --- a/examples/basic-oauth/public/app.css +++ b/examples/basic-oauth/public/app.css @@ -85,10 +85,9 @@ label { } .answer { width: 70%; - margin: auto; + margin: auto auto 20px; text-align: left; padding-left: 10%; - margin-bottom: 20px; } .login-page .login-box { padding: 100px 0; diff --git a/examples/basic-oauth/update-metadata.php b/examples/basic-oauth/update-metadata.php index 7e484d4f..835634a8 100644 --- a/examples/basic-oauth/update-metadata.php +++ b/examples/basic-oauth/update-metadata.php @@ -23,10 +23,7 @@ ?>
\ No newline at end of file diff --git a/examples/basic-webapp/public/app.css b/examples/basic-webapp/public/app.css index 3a965f1b..324ec24f 100644 --- a/examples/basic-webapp/public/app.css +++ b/examples/basic-webapp/public/app.css @@ -85,10 +85,9 @@ label { } .answer { width: 70%; - margin: auto; + margin: auto auto 20px; text-align: left; padding-left: 10%; - margin-bottom: 20px; } .login-page .login-box { padding: 100px 0; diff --git a/src/API/Authentication.php b/src/API/Authentication.php index 64727abe..3a3f97a8 100644 --- a/src/API/Authentication.php +++ b/src/API/Authentication.php @@ -1,4 +1,13 @@ client_id = $client_id; - $this->client_secret = $client_secret; - $this->domain = $domain; - $this->guzzleOptions = $guzzleOptions; - $this->audience = $audience; - $this->scope = $scope; +/** + * Class Authentication + * + * @package Auth0\SDK\API + */ +class Authentication +{ + + private $_client_id; + private $_client_secret; + private $_domain; + private $_apiClient; + private $_guzzleOptions; + private $_audience; + private $_scope; + + /** + * Authentication constructor. + * + * @param string $domain + * @param null $client_id + * @param null $client_secret + * @param null $audience + * @param null $scope + * @param array $guzzleOptions + */ + public function __construct( + $domain, + $client_id = null, + $client_secret = null, + $audience = null, + $scope = null, + $guzzleOptions = [] + ) { + + $this->_client_id = $client_id; + $this->_client_secret = $client_secret; + $this->_domain = $domain; + $this->_guzzleOptions = $guzzleOptions; + $this->_audience = $audience; + $this->_scope = $scope; $this->setApiClient(); } + + /** + * Set an ApiClient for use in this object + * + * @return void + */ + protected function setApiClient() + { + $apiDomain = "https://{$this->_domain}"; - protected function setApiClient() { - $apiDomain = "https://{$this->domain}"; - - $client = new ApiClient([ + $client = new ApiClient( + [ 'domain' => $apiDomain, 'basePath' => '/', - 'guzzleOptions' => $this->guzzleOptions - ]); + 'guzzleOptions' => $this->_guzzleOptions + ] + ); - $this->apiClient = $client; + $this->_apiClient = $client; } /** - * Builds and returns the `/authorize` url in order to initialize a new authN/authZ transaction - * - * @method get_authorize_link https://auth0.com/docs/api/authentication#!#get--authorize_db - * @param {String} response_type - * @param {String} redirect_uri - * @param {String} connection [optional] - * @param {String} state [optional] - * @param {Object} aditional_params [optional] + * Builds and returns the `/authorize` url in order to initialize a new + * authN/authZ transaction + * + * @param string $response_type + * @param string $redirect_uri + * @param string $connection [optional] + * @param string $state [optional] + * @param array $additional_params [optional] + * + * @return string + * + * @see https://auth0.com/docs/api/authentication#!#get--authorize_db */ - public function get_authorize_link($response_type, $redirect_uri, $connection = null, $state = null, $aditional_params = []) { - - $aditional_params['response_type'] = $response_type; - $aditional_params['redirect_uri'] = $redirect_uri; - $aditional_params['client_id'] = $this->client_id; - - if($connection !== null) { - $aditional_params['connection'] = $connection; + public function get_authorize_link( + $response_type, + $redirect_uri, + $connection = null, + $state = null, + $additional_params = [] + ) { + + $additional_params['response_type'] = $response_type; + $additional_params['redirect_uri'] = $redirect_uri; + $additional_params['client_id'] = $this->_client_id; + + if ($connection !== null) { + $additional_params['connection'] = $connection; } - if($state !== null) { - $aditional_params['state'] = $state; + if ($state !== null) { + $additional_params['state'] = $state; } - $query_string = Psr7\build_query($aditional_params); + $query_string = Psr7\build_query($additional_params); - return "https://{$this->domain}/authorize?$query_string"; + return "https://{$this->_domain}/authorize?{$query_string}"; } - - public function get_samlp_link($client_id, $connection = '') { - - return "https://{$this->domain}/samlp/$client_id?connection=$connection"; - + + /** + * Build and return a SAMLP link + * + * @param string $client_id + * @param string $connection + * + * @return string + * + * @see https://auth0.com/docs/connections/enterprise/samlp + */ + public function get_samlp_link( $client_id, $connection = '' ) + { + return "https://{$this->_domain}/samlp/$client_id?connection=$connection"; } - - public function get_samlp_metadata_link($client_id) { - - return "https://{$this->domain}/samlp/metadata/$client_id"; - + + /** + * Build and return a SAMLP metadata link + * + * @param string $client_id + * + * @return string + * + * @see https://auth0.com/docs/connections/enterprise/samlp + */ + public function get_samlp_metadata_link( $client_id ) + { + return "https://{$this->_domain}/samlp/metadata/$client_id"; } - - public function get_wsfed_link($client_id) { - - return "https://{$this->domain}/wsfed/$client_id"; - + + /** + * Build and return a WS-Federation link + * + * @param string $client_id + * + * @return string + * + * @see https://auth0.com/docs/protocols/ws-fed + */ + public function get_wsfed_link( $client_id ) + { + return "https://{$this->_domain}/wsfed/$client_id"; } - - public function get_wsfed_metadata_link() { - - return "https://{$this->domain}/wsfed/FederationMetadata/2007-06/FederationMetadata.xml"; - + + /** + * Build and return a WS-Federation metadata link + * + * @return string + * + * @see https://auth0.com/docs/protocols/ws-fed + */ + public function get_wsfed_metadata_link() + { + return 'https://' . $this->_domain . + '/wsfed/FederationMetadata/2007-06/FederationMetadata.xml'; } /** - * Builds and returns the Logout url in order to termiate a SSO session + * Builds and returns the Logout url in order to terminate a SSO session * - * @method get_logout_link https://auth0.com/docs/api/authentication#logout - * @param {String} returnTo - * @param {String} client_id - * @param {Boolean} federated + * @param null|string $returnTo + * @param null|string $client_id + * @param bool $federated + * + * @return string + * + * @see https://auth0.com/docs/api/authentication#logout */ - public function get_logout_link($returnTo = null, $client_id = null, $federated = false) { - + public function get_logout_link( + $returnTo = null, + $client_id = null, + $federated = false + ) { $params = []; if ($returnTo !== null) { $params['returnTo'] = $returnTo; @@ -115,30 +205,68 @@ public function get_logout_link($returnTo = null, $client_id = null, $federated $query_string = Psr7\build_query($params); - return "https://{$this->domain}/v2/logout?$query_string"; + return "https://{$this->_domain}/v2/logout?$query_string"; } - - public function authorize_with_accesstoken($access_token, $connection, $scope = 'openid', $aditional_params = []){ - - $data = array_merge($aditional_params, [ - 'client_id' => $this->client_id, - 'access_token' => $access_token, - 'connection' => $connection, - 'scope' => $scope, - ]); - - return $this->apiClient->post() - ->oauth() - ->access_token() - ->withHeader(new ContentType('application/json')) - ->withBody(json_encode($data)) - ->call(); + + /** + * Authorize using an access token + * + * @param string $access_token + * @param string $connection + * @param string $scope + * @param array $additional_params + * + * @return mixed + * + * @deprecated - This feature is disabled by default for new tenants as of 8 June + * 2017. Open the browser to do social authentication instead, which is + * what Google and Facebook are recommending. + * + * @see https://auth0.com/docs/api/authentication#social-with-provider-s-access-token + * @see https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html + * @see https://auth0.com/docs/api-auth/intro + */ + public function authorize_with_accesstoken( + $access_token, + $connection, + $scope = 'openid', + $additional_params = [] + ) { + + $data = array_merge( + $additional_params, + [ + 'client_id' => $this->_client_id, + 'access_token' => $access_token, + 'connection' => $connection, + 'scope' => $scope, + ] + ); + + return $this->_apiClient->post() + ->oauth() + ->access_token() + ->withHeader(new ContentType('application/json')) + ->withBody(json_encode($data)) + ->call(); } - - public function email_passwordless_start($email, $type, $authParams = []){ + + /** + * Start passwordless login process for email + * + * @param string $email + * @param string $type + * @param array $authParams + * + * @return mixed + * + * @see https://auth0.com/docs/api/authentication#get-code-or-link + */ + public function email_passwordless_start( $email, $type, $authParams = [] ) + { $data = [ - 'client_id' => $this->client_id, + 'client_id' => $this->_client_id, 'connection' => 'email', 'send' => $type, 'email' => $email, @@ -148,48 +276,107 @@ public function email_passwordless_start($email, $type, $authParams = []){ $data['authParams'] = $authParams; } - return $this->apiClient->post() - ->passwordless() - ->start() - ->withHeader(new ContentType('application/json')) - ->withBody(json_encode($data)) - ->call(); + return $this->_apiClient->post() + ->passwordless() + ->start() + ->withHeader(new ContentType('application/json')) + ->withBody(json_encode($data)) + ->call(); } - - public function sms_passwordless_start($phone_number){ + + /** + * Start passwordless login process for SMS + * + * @param string $phone_number + * + * @return mixed + * + * @see https://auth0.com/docs/api/authentication#get-code-or-link + */ + public function sms_passwordless_start( $phone_number ) + { $data = [ - 'client_id' => $this->client_id, + 'client_id' => $this->_client_id, 'connection' => 'sms', 'phone_number' => $phone_number, ]; - return $this->apiClient->post() - ->passwordless() - ->start() - ->withHeader(new ContentType('application/json')) - ->withBody(json_encode($data)) - ->call(); + return $this->_apiClient->post() + ->passwordless() + ->start() + ->withHeader(new ContentType('application/json')) + ->withBody(json_encode($data)) + ->call(); } - - public function sms_code_passwordless_verify($phone_number, $code, $scope = 'openid'){ - + + /** + * Verify SMS code + * + * @param string $phone_number + * @param string $code + * @param string $scope + * + * @return mixed + * + * @throws ApiException + */ + public function sms_code_passwordless_verify( + $phone_number, + $code, + $scope = 'openid' + ) { return $this->authorize_with_ro($phone_number, $code, $scope, 'sms'); - } - - public function email_code_passwordless_verify($email, $code, $scope = 'openid'){ - + + /** + * Verify email code + * + * @param string $email + * @param string $code + * @param string $scope + * + * @return mixed + * + * @throws ApiException + */ + public function email_code_passwordless_verify($email, $code, $scope = 'openid') + { return $this->authorize_with_ro($email, $code, $scope, 'email'); - } - + /** + * DEPRECATED - This endpoint is part of the legacy authentication pipeline and + * has been replaced in favor of the Password Grant. For more information on the + * latest authentication pipeline refer to Introducing OIDC Conformant + * Authentication. + * + * @param string $username + * @param string $password + * @param string $scope + * @param null|string $connection + * @param null|string $id_token + * @param null|string $device + * + * @return mixed + * + * @throws ApiException + * * @deprecated Use `login` instead. Use only for passwordless verify + * + * @see https://auth0.com/docs/api/authentication#resource-owner + * @see https://auth0.com/docs/api-auth/intro */ - public function authorize_with_ro($username, $password, $scope = 'openid', $connection = null, $id_token = null, $device = null){ + public function authorize_with_ro( + $username, + $password, + $scope = 'openid', + $connection = null, + $id_token = null, + $device = null + ) { $data = [ - 'client_id' => $this->client_id, + 'client_id' => $this->_client_id, 'username' => $username, 'password' => $password, 'scope' => $scope, @@ -202,30 +389,63 @@ public function authorize_with_ro($username, $password, $scope = 'openid', $conn $data['grant_type'] = 'urn:ietf:params:oauth:grant-type:jwt-bearer'; } else { if ($connection === null) { - throw new ApiException('You need to specify a conection for grant_type=password authentication'); + throw new ApiException( + 'You need to specify a connection for grant_type=password authentication' + ); } $data['grant_type'] = 'password'; $data['connection'] = $connection; } - return $this->apiClient->post() - ->oauth() - ->ro() - ->withHeader(new ContentType('application/json')) - ->withBody(json_encode($data)) - ->call(); + return $this->_apiClient->post() + ->oauth() + ->ro() + ->withHeader(new ContentType('application/json')) + ->withBody(json_encode($data)) + ->call(); } - - public function userinfo($access_token){ - - return $this->apiClient->get() - ->userinfo() - ->withHeader(new ContentType('application/json')) - ->withHeader(new AuthorizationBearer($access_token)) - ->call(); - + + /** + * Get the current user's info + * + * @param string $access_token + * + * @return mixed + * + * @see https://auth0.com/docs/api/authentication#user-profile + */ + public function userinfo( $access_token ) + { + + return $this->_apiClient->get() + ->userinfo() + ->withHeader(new ContentType('application/json')) + ->withHeader(new AuthorizationBearer($access_token)) + ->call(); } - - public function impersonate($access_token, $user_id, $protocol, $impersonator_id, $client_id, $additionalParameters=[]){ + + /** + * Obtain an impersonation URL to login as another user. + * Impersonation functionality may be disabled by default for your tenant. + * + * @param string $access_token + * @param string $user_id + * @param string $protocol + * @param string $impersonator_id + * @param string $client_id + * @param array $additionalParameters + * + * @return mixed + * + * @see https://auth0.com/docs/api/authentication#impersonation + */ + public function impersonate( + $access_token, + $user_id, + $protocol, + $impersonator_id, + $client_id, + $additionalParameters = [] + ) { $data = [ 'protocol' => $protocol, @@ -234,60 +454,72 @@ public function impersonate($access_token, $user_id, $protocol, $impersonator_id 'additionalParameters' => $additionalParameters, ]; - return $this->apiClient->post() - ->users($user_id) - ->impersonate() - ->withHeader(new ContentType('application/json')) - ->withHeader(new AuthorizationBearer($access_token)) - ->withBody(json_encode($data)) - ->call(); + return $this->_apiClient->post() + ->users($user_id) + ->impersonate() + ->withHeader(new ContentType('application/json')) + ->withHeader(new AuthorizationBearer($access_token)) + ->withBody(json_encode($data)) + ->call(); } /** * Makes a call to the `oauth/token` endpoint * - * @method oauth_token - * @param {Object} options: - * @param {Object} options.grantType - * @param {Object} options.client_id - * @param {Object} options.client_secret [optional] Only if grant type: client_credentials - * @param {Object} options.username [optional] Only if grant type: password/password-realm - * @param {Object} options.password [optional] Only if grant type: password/password-realm - * @param {Object} options.scope [optional] - * @param {Object} options.audience [optional] + * @param array $options - keys: + * - options.grantType + * - options.client_id + * - options.client_secret + * [optional] Only if grant type: client_credentials + * - options.username + * [optional] Only if grant type: password/password-realm + * - options.password + * [optional] Only if grant type: password/password-realm + * - options.scope [optional] + * - options.audience [optional] + * + * @return mixed|string + * + * @throws ApiException */ - public function oauth_token($options = []) { + public function oauth_token( $options = [] ) + { if (! isset($options['client_id'])) { - $options['client_id'] = $this->client_id; + $options['client_id'] = $this->_client_id; } if (! isset($options['client_secret'])) { - $options['client_secret'] = $this->client_secret; + $options['client_secret'] = $this->_client_secret; } if (! isset($options['grant_type'])) { throw new ApiException('grant_type is mandatory'); } - return $this->apiClient->post() - ->oauth() - ->token() - ->withHeader(new ContentType('application/json')) - ->withBody(json_encode($options)) - ->call(); + return $this->_apiClient->post() + ->oauth() + ->token() + ->withHeader(new ContentType('application/json')) + ->withBody(json_encode($options)) + ->call(); } /** * Makes a call to the `oauth/token` endpoint with `authorization_code` grant type * - * @method code_exchange - * @param {Object} code + * @param string $code + * @param string $redirect_uri + * + * @return mixed|string + * + * @throws ApiException */ - public function code_exchange($code, $redirect_uri) { + public function code_exchange($code, $redirect_uri) + { $options = []; - $options['client_secret'] = $this->client_secret; + $options['client_secret'] = $this->_client_secret; $options['redirect_uri'] = $redirect_uri; $options['code'] = $code; $options['grant_type'] = 'authorization_code'; @@ -298,15 +530,19 @@ public function code_exchange($code, $redirect_uri) { /** * Makes a call to the `oauth/token` endpoint with `password-realm` grant type * - * @method login - * @param {Object} options: - * @param {Object} options.username - * @param {Object} options.password - * @param {Object} options.realm - * @param {Object} options.scope [optional] - * @param {Object} options.audience [optional] + * @param array $options - keys: + * - options.username + * - options.password + * - options.realm + * - options.scope [optional] + * - options.audience [optional] + * + * @return mixed|string + * + * @throws ApiException */ - public function login($options) { + public function login( $options ) + { if (! isset($options['username'])) { throw new ApiException('username is mandatory'); } @@ -327,14 +563,20 @@ public function login($options) { /** * Makes a call to the `oauth/token` endpoint with `password` grant type * - * @method login_with_default_directory - * @param {Object} options: https://auth0.com/docs/api-auth/grant/password - * @param {Object} options.username - * @param {Object} options.password - * @param {Object} options.scope [optional] - * @param {Object} options.scope [audience] + * @param array $options - keys: + * - options.username + * - options.password + * - options.scope [optional] + * - options.scope [audience] + * + * @return mixed|string + * + * @throws ApiException + * + * @see https://auth0.com/docs/api-auth/grant/password */ - public function login_with_default_directory($options) { + public function login_with_default_directory( $options ) + { if (! isset($options['username'])) { throw new ApiException('username is mandatory'); } @@ -351,61 +593,96 @@ public function login_with_default_directory($options) { /** * Makes a call to the `oauth/token` endpoint with `client_credentials` grant type * - * @method client_credentials - * @param {Object} options: https://auth0.com/docs/api-auth/grant/client-credentials - * @param {Object} options.client_id - * @param {Object} options.client_secret - * @param {Object} options.scope [optional] - * @param {Object} options.audience [optional] + * @param array $options - keys: + * - options.client_id + * - options.client_secret + * - options.scope [optional] + * - options.audience [optional] + * + * @return mixed|string + * + * @throws ApiException + * + * @see https://auth0.com/docs/api-auth/grant/client-credentials */ - public function client_credentials($options) { + public function client_credentials( $options ) + { if (!isset($options['client_secret'])) { - $options['client_secret'] = $this->client_secret; + $options['client_secret'] = $this->_client_secret; } if (empty($options['client_secret'])) { throw new ApiException('client_secret is mandatory'); } if (!isset($options['client_id'])) { - $options['client_id'] = $this->client_id; + $options['client_id'] = $this->_client_id; } if (empty($options['client_id'])) { throw new ApiException('client_id is mandatory'); } if (!isset($options['scope'])) { - $options['scope'] = $this->scope; + $options['scope'] = $this->_scope; } if (!isset($options['audience'])) { - $options['audience'] = $this->audience; + $options['audience'] = $this->_audience; } $options['grant_type'] = 'client_credentials'; return $this->oauth_token($options); } - - public function dbconnections_signup($email, $password, $connection) { + + /** + * Create a new user using active authentication. + * This endpoint only works for database connections. + * + * @param string $email + * @param string $password + * @param string $connection + * + * @return mixed + * + * @see https://auth0.com/docs/api/authentication#signup + */ + public function dbconnections_signup( $email, $password, $connection ) + { $data = [ - 'client_id' => $this->client_id, + 'client_id' => $this->_client_id, 'email' => $email, 'password' => $password, 'connection' => $connection, ]; - return $this->apiClient->post() - ->dbconnections() - ->signup() - ->withHeader(new ContentType('application/json')) - ->withBody(json_encode($data)) - ->call(); + return $this->_apiClient->post() + ->dbconnections() + ->signup() + ->withHeader(new ContentType('application/json')) + ->withBody(json_encode($data)) + ->call(); } - - public function dbconnections_change_password($email, $connection, $password = null) { + + /** + * Send a change password email. + * This endpoint only works for database connections. + * + * @param string $email + * @param string $connection + * @param null|string $password + * + * @return mixed + * + * @see https://auth0.com/docs/api/authentication#change-password + */ + public function dbconnections_change_password( + $email, + $connection, + $password = null + ) { $data = [ - 'client_id' => $this->client_id, + 'client_id' => $this->_client_id, 'email' => $email, 'connection' => $connection, ]; @@ -414,11 +691,11 @@ public function dbconnections_change_password($email, $connection, $password = n $data['password'] = $password; } - return $this->apiClient->post() - ->dbconnections() - ->change_password() - ->withHeader(new ContentType('application/json')) - ->withBody(json_encode($data)) - ->call(); + return $this->_apiClient->post() + ->dbconnections() + ->change_password() + ->withHeader(new ContentType('application/json')) + ->withBody(json_encode($data)) + ->call(); } } \ No newline at end of file diff --git a/src/API/Helpers/RequestBuilder.php b/src/API/Helpers/RequestBuilder.php index 91badd40..ecff83a8 100644 --- a/src/API/Helpers/RequestBuilder.php +++ b/src/API/Helpers/RequestBuilder.php @@ -187,9 +187,11 @@ public function getGuzzleOptions() { ); } - /** - * @return mixed|string - */ + /** + * @return mixed|string + * + * @throws \Exception + */ public function call() { $client = new Client( $this->getGuzzleOptions() ); diff --git a/src/API/Helpers/State/DummyStateHandler.php b/src/API/Helpers/State/DummyStateHandler.php index 82ba7554..724e6513 100644 --- a/src/API/Helpers/State/DummyStateHandler.php +++ b/src/API/Helpers/State/DummyStateHandler.php @@ -21,26 +21,30 @@ class DummyStateHandler implements StateHandler /** * Generate state value to be used for the state param value during authorization. * - * @return string + * @return string|null */ public function issue() { return null; } - /** - * Store state value to be used for the state param value during authorization. - * - */ + /** + * Store state value to be used for the state param value during authorization. + * + * @param string $state + * + * @return string|void + */ public function store($state) { } /** * Perform validation of the returned state with the previously generated state. * - * @param string $state + * @param string $state * * @return bool result - * @throws exception + * + * @throws \Exception */ public function validate($state) { return true; diff --git a/src/API/Helpers/State/SessionStateHandler.php b/src/API/Helpers/State/SessionStateHandler.php index 999183ab..27c534e6 100644 --- a/src/API/Helpers/State/SessionStateHandler.php +++ b/src/API/Helpers/State/SessionStateHandler.php @@ -42,11 +42,13 @@ public function issue() { return $state; } - /** - * Store a given state value to be used for the state param value during authorization. - * - * @return string - */ + /** + * Store a given state value to be used for the state param value during authorization. + * + * @param string $state + * + * @return mixed|void + */ public function store($state) { $this->store->set(self::STATE_NAME, $state); } diff --git a/src/API/Helpers/State/StateHandler.php b/src/API/Helpers/State/StateHandler.php index 721820f8..9deca2c0 100644 --- a/src/API/Helpers/State/StateHandler.php +++ b/src/API/Helpers/State/StateHandler.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Helpers\State; -use Auth0\SDK\Store\StoreInterface; + /* * This file is part of Auth0-PHP package. @@ -28,11 +28,13 @@ interface StateHandler */ public function issue(); - /** - * Store a given state value to be used for the state param value during authorization. - * - * @return string - */ + /** + * Store a given state value to be used for the state param value during authorization. + * + * @param $state + * + * @return mixed + */ public function store($state); /** @@ -41,7 +43,8 @@ public function store($state); * @param string $state * * @return bool result - * @throws exception + * + * @throws \Exception */ public function validate($state); } \ No newline at end of file diff --git a/src/API/Helpers/TokenGenerator.php b/src/API/Helpers/TokenGenerator.php index 675b7ecc..3e58c948 100644 --- a/src/API/Helpers/TokenGenerator.php +++ b/src/API/Helpers/TokenGenerator.php @@ -14,6 +14,11 @@ class TokenGenerator { */ protected $client_secret; + /** + * @var string + */ + protected $secret_base64_encoded; + /** * TokenGenerator Constructor. * @@ -21,6 +26,7 @@ class TokenGenerator { * - client_id (String) Required. The id of the application, you can get this in the * auth0 console * - client_secret (String) Required. The application secret, same comment as above + * - secret_base64_encoded (Bool) Required. Is the secret Base64 encoded? * * @param array $credentials */ diff --git a/src/API/Management.php b/src/API/Management.php index f07079a8..387f53a4 100644 --- a/src/API/Management.php +++ b/src/API/Management.php @@ -118,6 +118,11 @@ class Management { */ public $users; + /** + * @var UsersByEmail + */ + public $usersByEmail; + /** * Management constructor. * diff --git a/src/API/Management/Blacklists.php b/src/API/Management/Blacklists.php index 2543f774..81538eb1 100644 --- a/src/API/Management/Blacklists.php +++ b/src/API/Management/Blacklists.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class Blacklists extends GenericResource diff --git a/src/API/Management/ClientGrants.php b/src/API/Management/ClientGrants.php index dbea33e1..b03729ce 100644 --- a/src/API/Management/ClientGrants.php +++ b/src/API/Management/ClientGrants.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class ClientGrants extends GenericResource diff --git a/src/API/Management/Clients.php b/src/API/Management/Clients.php index 3dbef4d7..b69ef145 100644 --- a/src/API/Management/Clients.php +++ b/src/API/Management/Clients.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class Clients extends GenericResource diff --git a/src/API/Management/Connections.php b/src/API/Management/Connections.php index df7d9be1..279f8655 100644 --- a/src/API/Management/Connections.php +++ b/src/API/Management/Connections.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class Connections extends GenericResource diff --git a/src/API/Management/DeviceCredentials.php b/src/API/Management/DeviceCredentials.php index df33cc3a..7eb5a875 100644 --- a/src/API/Management/DeviceCredentials.php +++ b/src/API/Management/DeviceCredentials.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class DeviceCredentials extends GenericResource diff --git a/src/API/Management/Emails.php b/src/API/Management/Emails.php index 3149b7f5..b0a3fa01 100644 --- a/src/API/Management/Emails.php +++ b/src/API/Management/Emails.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class Emails extends GenericResource diff --git a/src/API/Management/Jobs.php b/src/API/Management/Jobs.php index b9f6e2c8..ff36051c 100644 --- a/src/API/Management/Jobs.php +++ b/src/API/Management/Jobs.php @@ -2,7 +2,6 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; use Auth0\SDK\API\Header\ContentType; class Jobs extends GenericResource diff --git a/src/API/Management/Logs.php b/src/API/Management/Logs.php index 9a93fbf2..743aeec7 100644 --- a/src/API/Management/Logs.php +++ b/src/API/Management/Logs.php @@ -2,10 +2,8 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; -use Auth0\SDK\API\Header\ContentType; -class Logs extends GenericResource +class Logs extends GenericResource { /** * @param string $id diff --git a/src/API/Management/ResourceServers.php b/src/API/Management/ResourceServers.php index b780d0c3..2a651182 100644 --- a/src/API/Management/ResourceServers.php +++ b/src/API/Management/ResourceServers.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class ResourceServers extends GenericResource diff --git a/src/API/Management/Rules.php b/src/API/Management/Rules.php index 41e5815e..42166978 100644 --- a/src/API/Management/Rules.php +++ b/src/API/Management/Rules.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class Rules extends GenericResource diff --git a/src/API/Management/Stats.php b/src/API/Management/Stats.php index 27c6da5d..1ca587f4 100644 --- a/src/API/Management/Stats.php +++ b/src/API/Management/Stats.php @@ -2,10 +2,8 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; -use Auth0\SDK\API\Header\ContentType; -class Stats extends GenericResource +class Stats extends GenericResource { /** * @return mixed diff --git a/src/API/Management/Tenants.php b/src/API/Management/Tenants.php index d34fce49..a3fc0b74 100644 --- a/src/API/Management/Tenants.php +++ b/src/API/Management/Tenants.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class Tenants extends GenericResource diff --git a/src/API/Management/Tickets.php b/src/API/Management/Tickets.php index b26bfe7f..8acea8d3 100644 --- a/src/API/Management/Tickets.php +++ b/src/API/Management/Tickets.php @@ -2,7 +2,7 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; + use Auth0\SDK\API\Header\ContentType; class Tickets extends GenericResource diff --git a/src/API/Management/UserBlocks.php b/src/API/Management/UserBlocks.php index 36a00d33..450e329a 100644 --- a/src/API/Management/UserBlocks.php +++ b/src/API/Management/UserBlocks.php @@ -2,10 +2,8 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; -use Auth0\SDK\API\Header\ContentType; -class UserBlocks extends GenericResource +class UserBlocks extends GenericResource { /** * @param string $user_id diff --git a/src/API/Management/Users.php b/src/API/Management/Users.php index cfaffce1..824abc93 100644 --- a/src/API/Management/Users.php +++ b/src/API/Management/Users.php @@ -2,7 +2,6 @@ namespace Auth0\SDK\API\Management; -use Auth0\SDK\API\Helpers\ApiClient; use Auth0\SDK\API\Header\ContentType; class Users extends GenericResource { diff --git a/src/API/Oauth2Client.php b/src/API/Oauth2Client.php index 59aa3839..27ab6713 100644 --- a/src/API/Oauth2Client.php +++ b/src/API/Oauth2Client.php @@ -100,6 +100,13 @@ class Oauth2Client { */ protected $access_token; + /** + * JWT for identity information + * + * @var string + */ + protected $id_token; + /** * The user object * @@ -107,6 +114,13 @@ class Oauth2Client { */ protected $user; + /** + * Storage object + * + * @var string + */ + protected $store; + /** * OAuth2 Client. * @@ -304,6 +318,8 @@ public function exchangeCode() { * Requests user info to Auth0 server. * * @return array + * + * @throws ApiException */ public function getUser() { // Ensure we have the user info @@ -320,11 +336,15 @@ public function getUser() { /** * Updates the user metadata. This end up calling the path /users/{id_user} * To delete an attribute, just set it null. ie: [ 'old_attr' => null ] - * It will only update the existing attrs and keep the others untouch - * for more info: - * https://auth0.com/docs/apiv2#!/users/patch_users_by_id + * It will only update the existing attrs and keep the others untouched + * + * TODO: Replace Auth0Api with Management + * + * @see https://auth0.com/docs/apiv2#!/users/patch_users_by_id * * @param array $metadata + * + * @throws ApiException */ public function updateUserMetadata($metadata) { @@ -402,8 +422,11 @@ public function setRefreshToken($refresh_token) { } /** - * Gets $access_token. + * Gets an access_token + * * @return string + * + * @throws ApiException */ final public function getAccessToken() { if ($this->access_token === null) { @@ -413,7 +436,8 @@ final public function getAccessToken() { } /** - * Gets $refresh_token. + * Gets a refresh_token + * * @return string */ final public function getRefreshToken() { @@ -440,7 +464,10 @@ public function setIdToken($id_token) { /** * Gets the id token + * * @return string + * + * @throws ApiException */ final public function getIdToken() { if ($this->id_token === null) { @@ -450,7 +477,7 @@ final public function getIdToken() { } /** - * Logout (removes all persisten data) + * Logout (removes all persistent data) */ final public function logout() { diff --git a/src/Auth0.php b/src/Auth0.php index 82f95486..b332fa1c 100644 --- a/src/Auth0.php +++ b/src/Auth0.php @@ -115,6 +115,12 @@ class Auth0 { */ protected $access_token; /** + * JWT for identity information + * + * @var string + */ + protected $id_token; + /** * Store * * @var StoreInterface @@ -319,7 +325,10 @@ public function getRefreshToken() { /** * Code exchange * - * @throws CoreException If there is an active session already. + * @throws CoreException - if an active session already or state cannot be validated + * @throws ApiException - if access token is invalid + * + * @returns bool */ public function exchange() { $code = $this->getAuthorizationCode(); @@ -371,7 +380,7 @@ public function setUser($user) { * * @param string $access_token * - * @return Auth0\SDK\BaseAuth0 + * @return \Auth0\SDK\Auth0 */ public function setAccessToken($access_token) { $key = array_search('access_token',$this->persistantMap); @@ -386,7 +395,7 @@ public function setAccessToken($access_token) { * * @param string $id_token * - * @return Auth0\SDK\BaseAuth0 + * @return \Auth0\SDK\Auth0 */ public function setIdToken($id_token) { $key = array_search('id_token',$this->persistantMap); @@ -401,7 +410,7 @@ public function setIdToken($id_token) { * * @param string $refresh_token * - * @return Auth0\SDK\BaseAuth0 + * @return \Auth0\SDK\Auth0 */ public function setRefreshToken($refresh_token) { $key = array_search('refresh_token',$this->persistantMap); @@ -461,7 +470,7 @@ private function dontPersist($name) { /** * @param StoreInterface $store * - * @return Auth0\SDK\BaseAuth0 + * @return \Auth0\SDK\Auth0 */ public function setStore(StoreInterface $store) { $this->store = $store; diff --git a/src/Helpers/JWKFetcher.php b/src/Helpers/JWKFetcher.php index 8910bb03..d0902bcc 100644 --- a/src/Helpers/JWKFetcher.php +++ b/src/Helpers/JWKFetcher.php @@ -42,10 +42,13 @@ protected function convertCertToPem($cert) { .'-----END CERTIFICATE-----'.PHP_EOL; } - /** - * @param string $iss - * @return array|null - */ + /** + * @param string $iss + * + * @return array|mixed|null + * + * @throws \Exception + */ public function fetchKeys($iss) { $url = "{$iss}.well-known/jwks.json"; diff --git a/src/JWTVerifier.php b/src/JWTVerifier.php index e978d418..99f65826 100644 --- a/src/JWTVerifier.php +++ b/src/JWTVerifier.php @@ -4,7 +4,7 @@ use Auth0\SDK\Exception\CoreException; use Auth0\SDK\Exception\InvalidTokenException; -use Auth0\SDK\Exception\ApiException; + use Auth0\SDK\Helpers\JWKFetcher; use Firebase\JWT\JWT; @@ -15,6 +15,7 @@ class JWTVerifier { protected $valid_audiences = null; protected $authorized_iss = null; protected $client_secret = null; + protected $secret_base64_encoded = null; /** * JWTVerifier Constructor. @@ -82,12 +83,15 @@ public function __construct($config) { $this->JWKFetcher = new JWKFetcher($cache, $guzzleOptions); } - /** - * @param string $jwt - * @return object - * @throws CoreException - * @throws InvalidTokenException - */ + /** + * @param $jwt + * + * @return mixed + * + * @throws CoreException + * @throws InvalidTokenException + * @throws \Exception + */ public function verifyAndDecode($jwt) { $tks = explode('.', $jwt); @@ -99,8 +103,7 @@ public function verifyAndDecode($jwt) $body64 = $tks[1]; $head = json_decode(JWT::urlsafeB64Decode($headb64)); - if ( !is_object($head) || ! isset($head->alg)) - { + if ( !is_object($head) || ! isset($head->alg)) { throw new InvalidTokenException("Invalid token"); } diff --git a/src/Store/SessionStore.php b/src/Store/SessionStore.php index 9da9864c..20083a9b 100644 --- a/src/Store/SessionStore.php +++ b/src/Store/SessionStore.php @@ -44,7 +44,7 @@ private function initSession() { /** - * Persists $value on $_SESSION, idetified by $key. + * Persists $value on $_SESSION, identified by $key. * * @param string $key * @param mixed $value @@ -56,8 +56,8 @@ public function set($key, $value) { } /** - * Gets persisted values idetified by $key. - * If the value is not setted, returns $default. + * Gets persisted values identified by $key. + * If the value is not set, returns $default. * * @param string $key * @param mixed $default diff --git a/tests/API/BasicCrudTest.php b/tests/API/BasicCrudTest.php index fb1bf66c..9b243208 100644 --- a/tests/API/BasicCrudTest.php +++ b/tests/API/BasicCrudTest.php @@ -49,7 +49,7 @@ public function testAll() { $this->afterCreate($created); - $client3 = $client->update($this->getId($created), $this->getUpdateBody()); + $client->update($this->getId($created), $this->getUpdateBody()); $get = $client->get($this->getId($created)); $this->afterUpdate($get); diff --git a/tests/API/Management/BlacklistsTest.php b/tests/API/Management/BlacklistsTest.php index ec346c34..27c9c039 100644 --- a/tests/API/Management/BlacklistsTest.php +++ b/tests/API/Management/BlacklistsTest.php @@ -6,6 +6,8 @@ class BlacklistsTest extends ApiTests { + private $domain; + public function testBlacklistAndGet() { $env = $this->getEnv(); $token = $this->getToken($env, [