/**
  * Class handler.
  *
  * @param array $args array of arguments
  *
  * @return void
  */
 function handle($args)
 {
     parent::handle($args);
     $datastore = new ApiStatusNetOAuthDataStore();
     $server = new OAuthServer($datastore);
     $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
     $server->add_signature_method($hmac_method);
     $atok = $app = null;
     // XXX: Insist that oauth_token and oauth_verifier be populated?
     // Spec doesn't say they MUST be.
     try {
         $req = OAuthRequest::from_request();
         $this->reqToken = $req->get_parameter('oauth_token');
         $this->verifier = $req->get_parameter('oauth_verifier');
         $app = $datastore->getAppByRequestToken($this->reqToken);
         $atok = $server->fetch_access_token($req);
     } catch (Exception $e) {
         common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
         common_debug(var_export($req, true));
         $code = $e->getCode();
         $this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
         return;
     }
     if (empty($atok)) {
         // Token exchange failed -- log it
         $msg = sprintf('API OAuth - Failure exchanging OAuth request token for access token, ' . 'request token = %s, verifier = %s', $this->reqToken, $this->verifier);
         common_log(LOG_WARNING, $msg);
         // TRANS: Client error given from the OAuth API when the request token or verifier is invalid.
         $this->clientError(_('Invalid request token or verifier.'), 400, 'text');
     } else {
         common_log(LOG_INFO, sprintf("Issued access token '%s' for application %d (%s).", $atok->key, $app->id, $app->name));
         $this->showAccessToken($atok);
     }
 }
 /**
  * Revoke an access token
  *
  * XXX: Confirm revoke before doing it
  *
  * @param int $appId the ID of the application
  *
  */
 function revokeAccess($token)
 {
     $cur = common_current_user();
     $appUser = Oauth_application_user::getByUserAndToken($cur, $token);
     if (empty($appUser)) {
         // TRANS: Client error when trying to revoke access for an application while not being a user of it.
         $this->clientError(_('You are not a user of that application.'), 401);
         return false;
     }
     $app = Oauth_application::staticGet('id', $appUser->application_id);
     $datastore = new ApiStatusNetOAuthDataStore();
     $datastore->revoke_token($appUser->token, 1);
     $result = $appUser->delete();
     if (!$result) {
         common_log_db_error($orig, 'DELETE', __FILE__);
         // TRANS: Client error when revoking access has failed for some reason.
         // TRANS: %s is the application ID revoking access failed for.
         $this->clientError(sprintf(_('Unable to revoke access for application: %s.'), $app->id));
         return false;
     }
     $msg = 'API OAuth - user %s (id: %d) revoked access token %s for app id %d';
     common_log(LOG_INFO, sprintf($msg, $cur->nickname, $cur->id, $appUser->token, $appUser->application_id));
     $msg = sprintf(_('You have successfully revoked access for %1$s and the access token starting with %2$s.'), $app->name, substr($appUser->token, 0, 7));
     $this->showForm($msg, true);
 }
 function handlePost()
 {
     // check session token for CSRF protection.
     $token = $this->trimmed('token');
     if (!$token || $token != common_session_token()) {
         $this->showForm(_('There was a problem with your session token. ' . 'Try again, please.'));
         return;
     }
     // check creds
     $user = null;
     if (!common_logged_in()) {
         $user = common_check_user($this->nickname, $this->password);
         if (empty($user)) {
             $this->showForm(_("Invalid nickname / password!"));
             return;
         }
     } else {
         $user = common_current_user();
     }
     if ($this->arg('allow')) {
         // mark the req token as authorized
         $this->store->authorize_token($this->oauth_token);
         // Check to see if there was a previous token associated
         // with this user/app and kill it. If the user is doing this she
         // probably doesn't want any old tokens anyway.
         $appUser = Oauth_application_user::getByKeys($user, $this->app);
         if (!empty($appUser)) {
             $result = $appUser->delete();
             if (!$result) {
                 common_log_db_error($appUser, 'DELETE', __FILE__);
                 throw new ServerException(_('Database error deleting OAuth application user.'));
                 return;
             }
         }
         // associated the authorized req token with the user and the app
         $appUser = new Oauth_application_user();
         $appUser->profile_id = $user->id;
         $appUser->application_id = $this->app->id;
         // Note: do not copy the access type from the application.
         // The access type should always be 0 when the OAuth app
         // user record has a request token associated with it.
         // Access type gets assigned once an access token has been
         // granted.  The OAuth app user record then gets updated
         // with the new access token and access type.
         $appUser->token = $this->oauth_token;
         $appUser->created = common_sql_now();
         $result = $appUser->insert();
         if (!$result) {
             common_log_db_error($appUser, 'INSERT', __FILE__);
             throw new ServerException(_('Database error inserting OAuth application user.'));
             return;
         }
         // if we have a callback redirect and provide the token
         // A callback specified in the app setup overrides whatever
         // is passed in with the request.
         if (!empty($this->app->callback_url)) {
             $this->callback = $this->app->callback_url;
         }
         if (!empty($this->callback)) {
             $target_url = $this->getCallback($this->callback, array('oauth_token' => $this->oauth_token));
             common_redirect($target_url, 303);
         } else {
             common_debug("callback was empty!");
         }
         // otherwise inform the user that the rt was authorized
         $this->elementStart('p');
         // XXX: Do OAuth 1.0a verifier code
         $this->raw(sprintf(_("The request token %s has been authorized. " . 'Please exchange it for an access token.'), $this->oauth_token));
         $this->elementEnd('p');
     } else {
         if ($this->arg('deny')) {
             $datastore = new ApiStatusNetOAuthDataStore();
             $datastore->revoke_token($this->oauth_token, 0);
             $this->elementStart('p');
             $this->raw(sprintf(_("The request token %s has been denied and revoked."), $this->oauth_token));
             $this->elementEnd('p');
         } else {
             $this->clientError(_('Unexpected form submission.'));
             return;
         }
     }
 }
 /**
  * Revoke access to an authorized OAuth application
  *
  * @param int $appId the ID of the application
  *
  */
 function revokeAccess($appId)
 {
     $cur = common_current_user();
     $app = Oauth_application::staticGet('id', $appId);
     if (empty($app)) {
         $this->clientError(_('No such application.'), 404);
         return false;
     }
     // XXX: Transaction here?
     $appUser = Oauth_application_user::getByKeys($cur, $app);
     if (empty($appUser)) {
         $this->clientError(_('You are not a user of that application.'), 401);
         return false;
     }
     $datastore = new ApiStatusNetOAuthDataStore();
     $datastore->revoke_token($appUser->token, 1);
     $result = $appUser->delete();
     if (!$result) {
         common_log_db_error($orig, 'DELETE', __FILE__);
         $this->clientError(sprintf(_('Unable to revoke access for app: %s.'), $app->id));
         return false;
     }
     $msg = 'User %s (id: %d) revoked access to app %s (id: %d)';
     common_log(LOG_INFO, sprintf($msg, $cur->nickname, $cur->id, $app->name, $app->id));
 }