driver = $driver; $this->api_url = $api_url; $this->client_id = $client_id; $this->client_secret = $client_secret; $this->transient = $transient; // Load the token from the transient cache $this->load_token(); } /** * {@inheritdoc} * * @since [*next-version*] */ public function authorize(Request $request) { // Check if we have a token - a token is ALWAYS needed if (empty($this->token)) { // If not, request one from the REST API $token = $this->request_token(); // Cache it for subsequent requests $this->save_token($token); } $type = $this->token->token_type; $code = $this->token->access_token; $request->headers[static::H_AUTH_TOKEN] = $type.' '.$code; $request->headers[static::H_3PV_ID] = static::V_3PV_ID; return $request; } /** * Requests an access token from the API. * * Sends the client ID and client secret to the REST API to obtain the access token. The access token is then * used to authorize all other requests. * See https://api-qa.deutschepost.com/dpi-apidoc/#/reference/authentication/access-token/get-access-token * * @since [*next-version*] * * @return object The token object. * * @throws RuntimeException If failed to retrieve the access token. */ public function request_token() { // Base64 encode the ":" and send as the "Authorization" header $auth_str_64 = base64_encode($this->client_id.':'.$this->client_secret); $headers = [static::H_AUTH_CREDENTIALS => 'Basic '.$auth_str_64]; // Prepare the full request URL $full_url = URL_Utils::merge_url_and_route($this->api_url, static::AUTH_ROUTE); // Send the authorization request to obtain the access token $request = new Request(Request::TYPE_GET, $full_url, [], '', $headers); $response = $this->driver->send($request); // If the status code is not 200, throw an error with the raw response body if ($response->status !== 200) { $response_body = json_decode($response->body); throw new RuntimeException(esc_html($response_body->detail)); } return $response->body; } /** * Revokes the access token. * * @since [*next-version*] * * @return string The response body. */ public function revoke() { // Do nothing if we didn't already have a token if (empty($this->token) || empty($this->token->access_token)) { return ''; } // Prepare the full request URL $full_url = URL_Utils::merge_url_and_route($this->api_url, static::REVOKE_ROUTE); // Create the request $params = ['token' => $this->token->access_token]; $request = new Request(Request::TYPE_GET, $full_url, $params); // Send the request $response = $this->driver->send($request); if ($response->status !== 200 && $response->status !== 401) { throw new RuntimeException('Failed to revoke the Deutsche Post access token'); } // Delete the cached token $this->delete_token(); return $response->body; } /** * Tests the connection with a given client ID and secret. * * @since [*next-version*] * * @param string $client_id The client ID. * @param string $client_secret The client secret. * @return object */ public function test_connection($client_id, $client_secret) { // Backup the client credentials $backup_client_id = $this->client_id; $backup_client_secret = $this->client_secret; // Set params as credentials $this->client_id = $client_id; $this->client_secret = $client_secret; // Send the request $token = $this->request_token(); // Restore the credentials $this->client_id = $backup_client_id; $this->client_secret = $backup_client_secret; return $token; } /** * Saves the access token. * * @param object $token The token to save. */ public function save_token($token) { $expires_in = isset($token->expires_in) ? $token->expires_in : time() + DAY_IN_SECONDS; set_transient($this->transient, $token, $expires_in); $this->token = $token; } /** * Retrieves the access token. * * @return object */ public function load_token() { return $this->token = get_transient($this->transient); } /** * Deletes the cached access token. * * @return array */ public function delete_token() { return delete_transient($this->transient); } }