Associate request tokens with OAuth apps and app users

This commit is contained in:
Zach Copley 2010-01-10 23:03:30 -08:00
parent e9e448bcee
commit c473a39a7d
4 changed files with 81 additions and 16 deletions

View File

@ -125,19 +125,12 @@ class ApiOauthAuthorizeAction extends Action
parent::handle($args); parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') { if ($_SERVER['REQUEST_METHOD'] == 'POST') {
/* Use a 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;
}
$this->handlePost(); $this->handlePost();
} else { } else {
common_debug('ApiOauthAuthorize::handle()'); // XXX: make better error messages
if (empty($this->oauth_token)) { if (empty($this->oauth_token)) {
@ -160,7 +153,7 @@ class ApiOauthAuthorizeAction extends Action
function handlePost() function handlePost()
{ {
/* Use a session token for CSRF protection. */ // check session token for CSRF protection.
$token = $this->trimmed('token'); $token = $this->trimmed('token');
@ -175,25 +168,66 @@ class ApiOauthAuthorizeAction extends Action
return; return;
} }
// is the user already logged in?
// check creds // check creds
$user = null;
if (!common_logged_in()) { if (!common_logged_in()) {
$user = common_check_user($this->nickname, $this->password); $user = common_check_user($this->nickname, $this->password);
if (empty($user)) { if (empty($user)) {
$this->showForm(_("Invalid nickname / password!")); $this->showForm(_("Invalid nickname / password!"));
return; return;
} }
} } else {
$user = common_current_user();
}
if ($this->arg('allow')) { if ($this->arg('allow')) {
// mark the req token as authorized
$this->store->authorize_token($this->oauth_token); $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 you're doing this you
// probably don'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(_('DB error deleting OAuth app user.'));
return;
}
}
// associated the new req token with the user and the app
$appUser = new Oauth_application_user();
$appUser->profile_id = $user->id;
$appUser->application_id = $this->app->id;
$appUser->access_type = $this->app->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(_('DB error inserting OAuth app user.'));
return;
}
// if we have a callback redirect and provide the token // if we have a callback redirect and provide the token
if (!empty($this->callback)) { if (!empty($this->callback)) {
// XXX: Need better way to build this redirect url.
$target_url = $this->callback . '?oauth_token=' . $this->oauth_token; $target_url = $this->callback . '?oauth_token=' . $this->oauth_token;
common_redirect($target_url, 303); common_redirect($target_url, 303);
} }
@ -202,7 +236,7 @@ class ApiOauthAuthorizeAction extends Action
$this->elementStart('p'); $this->elementStart('p');
// XXX: Do verifier code? // XXX: Do OAuth 1.0a verifier code?
$this->raw(sprintf(_("The request token %s has been authorized. " . $this->raw(sprintf(_("The request token %s has been authorized. " .
'Please exchange it for an access token.'), 'Please exchange it for an access token.'),
@ -233,7 +267,9 @@ class ApiOauthAuthorizeAction extends Action
function showScripts() function showScripts()
{ {
parent::showScripts(); parent::showScripts();
// $this->autofocus('nickname'); if (!common_logged_in()) {
$this->autofocus('nickname');
}
} }
/** /**

View File

@ -13,12 +13,34 @@ class Oauth_application_user extends Memcached_DataObject
public $profile_id; // int(4) primary_key not_null public $profile_id; // int(4) primary_key not_null
public $application_id; // int(4) primary_key not_null public $application_id; // int(4) primary_key not_null
public $access_type; // tinyint(1) public $access_type; // tinyint(1)
public $token; // varchar(255)
public $secret; // varchar(255)
public $verifier; // varchar(255)
public $created; // datetime not_null public $created; // datetime not_null
public $modified; // timestamp not_null default_CURRENT_TIMESTAMP
/* Static get */ /* Static get */
function staticGet($k,$v=NULL) { function staticGet($k,$v=NULL) {
return Memcached_DataObject::staticGet('Oauth_application_user',$k,$v); return Memcached_DataObject::staticGet('Oauth_application_user',$k,$v);
} }
/* the code above is auto generated do not remove the tag below */ /* the code above is auto generated do not remove the tag below */
###END_AUTOCODE ###END_AUTOCODE
static function getByKeys($user, $app)
{
if (empty($user) || empty($app)) {
return null;
}
$oau = new Oauth_application_user();
$oau->profile_id = $user->id;
$oau->application_id = $app->id;
$oau->limit(1);
$result = $oau->find(true);
return empty($result) ? null : $oau;
}
} }

View File

@ -372,7 +372,11 @@ id = N
profile_id = 129 profile_id = 129
application_id = 129 application_id = 129
access_type = 17 access_type = 17
token = 2
secret = 2
verifier = 2
created = 142 created = 142
modified = 384
[oauth_application_user__keys] [oauth_application_user__keys]
profile_id = K profile_id = K

View File

@ -229,8 +229,11 @@ create table oauth_application_user (
profile_id integer not null comment 'user of the application' references profile (id), profile_id integer not null comment 'user of the application' references profile (id),
application_id integer not null comment 'id of the application' references oauth_application (id), application_id integer not null comment 'id of the application' references oauth_application (id),
access_type tinyint default 0 comment 'access type, bit 1 = read, bit 2 = write, bit 3 = revoked', access_type tinyint default 0 comment 'access type, bit 1 = read, bit 2 = write, bit 3 = revoked',
token varchar(255) comment 'authorization token',
secret varchar(255) comment 'token secret',
verifier varchar(255) not null comment 'verification code',
created datetime not null comment 'date this record was created', created datetime not null comment 'date this record was created',
modified timestamp comment 'date this record was modified',
constraint primary key (profile_id, application_id) constraint primary key (profile_id, application_id)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;