function post() { // Get parameters $code = $this->getInput('code'); $me = $this->getInput('me'); $redirect_uri = $this->getInput('redirect_uri'); $state = $this->getInput('state'); $client_id = $this->getInput('client_id'); $verified = Auth::verifyCode($code, $client_id, $redirect_uri, $state); if ($verified['valid'] === true) { // Get user & existing tokens $user = $verified['user']; $indieauth_tokens = $user->indieauth_tokens; if (empty($indieauth_tokens)) { $indieauth_tokens = array(); } // Generate access token and save it to the user $token = md5(rand(0, 99999) . time() . $user->getUUID() . $client_id . $state . rand(0, 999999)); $indieauth_tokens[$token] = array('me' => $me, 'redirect_uri' => $redirect_uri, 'scope' => 'post', 'client_id' => $client_id, 'issued_at' => time(), 'nonce' => mt_rand(1000000, pow(2, 30))); $user->indieauth_tokens = $indieauth_tokens; $user->save(); if (\Idno\Core\Idno::site()->session()->isLoggedOn() && $user->getUUID() == \Idno\Core\Idno::site()->session()->currentUser()->getUUID()) { \Idno\Core\Idno::site()->session()->refreshSessionUser($user); } // Output to the browser $this->setResponse(200); header('Content-Type: application/x-www-form-urlencoded'); echo http_build_query(array('access_token' => $token, 'scope' => 'post', 'me' => $me)); exit; } else { $this->setResponse(400); echo $verified['reason']; } }
static function verifyCode($code, $client_id, $redirect_uri, $state) { $found = Auth::findUserForCode($code); if (empty($found)) { return array('valid' => false, 'reason' => 'unrecognized code.'); } $user = $found['user']; $data = $found['data']; // codes can only be used once Auth::removeUsedAndExpiredCodes($user, $code); $elapsed = time() - $data['issued_at']; if ($elapsed > 10 * 60) { return array('valid' => false, 'reason' => 'authentication code has expired'); } if ($redirect_uri != $data['redirect_uri']) { return array('valid' => false, 'reason' => 'redirect_uri does not match'); } if ($client_id != $data['client_id']) { return array('valid' => false, 'reason' => 'client_id does not match'); } if ($state != $data['state']) { return array('valid' => false, 'reason' => 'state does not match'); } return array('valid' => true, 'user' => $user, 'me' => $data['me'], 'scope' => $data['scope']); }