$this->response_type, 'redirect_uri' => $this->redirect_url(), 'client_id' => $this->client_id, 'scope' => $this->scope, 'access_type' => 'offline', 'state' => md5($this->client_secret.$this->provider).'::'.urlencode($url), ], $args); return $this->authentication_url()."?".Authenticator::build_query($parameters); } /** * Takes an OAuth request token and exchanges it for an access token. * * @param $request_token */ function get_access_token($request_token) { $code = $request_token['code']; $state_args = explode('::', $request_token['state']); if ($state_args[0] == md5($this->client_secret.$this->provider)) { $url = urldecode($state_args[1]); $response = Photonic::http($this->access_token_URL(), 'POST', [ 'code' => $code, 'grant_type' => 'authorization_code', 'client_id' => $this->client_id, 'client_secret' => $this->client_secret, 'redirect_uri' => $this->redirect_url(), ]); if (is_wp_error($response)) { $url = add_query_arg('error', $response->get_error_code(), $url); } else if ($response == null) { $url = add_query_arg('error', 'null', $url); } } else { $url = remove_query_arg(['token', 'code', 'state']); } wp_redirect($url); exit(); } /** * @param $base_token */ public function authenticate($base_token) { $photonic_authentication = get_option('photonic_authentication'); if (!isset($photonic_authentication)) { $photonic_authentication = []; } if (!isset($photonic_authentication[$this->provider]) && !empty($base_token)) { // Nothing is in the authentication option, but there is a token in overall Photonic Options. // Refresh it if required, and save it to the authentication option. $token = $this->refresh_access_token($base_token, true); } else if (isset($photonic_authentication[$this->provider])) { $token = $photonic_authentication[$this->provider]; if (!empty($token)) { if ($this->is_token_expired($token)) { $token = $this->refresh_access_token($base_token, true); } else { $this->set_token_validity(true); } } } if (!empty($token)) { $this->access_token = $token['oauth_token']; } else { $this->set_token_validity(false); } } function is_token_expired($token) { if (empty($token)) { return true; } if (!isset($token['oauth_token']) || !isset($token['oauth_token_created']) || !isset($token['oauth_token_expires'])) { return true; } if (!isset($token['client_id']) || (isset($token['client_id']) && $token['client_id'] !== $this->client_id)) { return true; } $current = time(); if ($token['oauth_token_created'] + $token['oauth_token_expires'] < $current) { return true; } return false; } /** * Checks if a token will expire soon. This is used to trigger a refresh for sources such as Instagram. Google uses a separate "Refresh Token", * so this is not applicable to it. The soon_limit defines how many days is "soon", and a refresh is triggered if the current date * is in the "soon" range. E.g. If you have a soon limit of 30 days, and your token expires in 15 days when you load the page, this method will * return true. * * For cases where the token does not exist yet, the method returns null. * * @param $soon_limit int Number of days to check the expiry limit for. * @return int|null If there is no token, return null. Otherwise, if there are < $soon_limit days left, return 1, if token is expired return -1, and if there is time return 0. */ function is_token_expiring_soon($soon_limit) { $photonic_authentication = get_option('photonic_authentication'); if (empty($photonic_authentication) || empty($photonic_authentication[$this->provider]) || empty($photonic_authentication[$this->provider]['oauth_token']) || empty($photonic_authentication[$this->provider]['oauth_token_created']) || empty($photonic_authentication[$this->provider]['oauth_token_expires'])) { return null; // There is no token! } $token = $photonic_authentication[$this->provider]; $token_expiry = $token['oauth_token_created'] + $token['oauth_token_expires']; $current = time(); $test_expiry = $current + $soon_limit * 24 * 60 * 60; $time_left = $token_expiry - $test_expiry; if ($current >= $token_expiry) { return -1; // already expired } else if ($time_left <= 0) { return 1; // Expiring soon } else { return 0; // There is still time } /* if ($current + $soon_limit * 24 * 60 * 60 > $token['oauth_token_created'] + $token['oauth_token_expires']) { return true; } return false;*/ } /** * Takes a token response from a request token call, then puts it in an appropriate array. * * @param $response * @return array */ public function parse_token($response) { $token = []; if (!is_wp_error($response) && is_array($response)) { $body = $response['body']; $body = json_decode($body); if (empty($body->error)) { $token['oauth_token'] = $body->access_token; $token['oauth_token_type'] = $body->token_type; $token['oauth_token_created'] = time(); $token['oauth_token_expires'] = $body->expires_in; $this->set_token_validity(true); } else { $this->set_token_validity(false); } } return $token; } }