Add support for an anonymous OAuth consumer. Note: this requires a
small DB tweak. Oauth_application_user needs to have the primary compound key: (profile_id, application_id, token). http://status.net/open-source/issues/2761 This should also make it possible to have multiple access tokens per application. http://status.net/open-source/issues/2788
This commit is contained in:
parent
d48f4a81d6
commit
e8b6d7c946
|
@ -81,7 +81,7 @@ class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||||
$app = $datastore->getAppByRequestToken($this->reqToken);
|
$app = $datastore->getAppByRequestToken($this->reqToken);
|
||||||
$atok = $server->fetch_access_token($req);
|
$atok = $server->fetch_access_token($req);
|
||||||
|
|
||||||
} catch (OAuthException $e) {
|
} catch (Exception $e) {
|
||||||
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
||||||
common_debug(var_export($req, true));
|
common_debug(var_export($req, true));
|
||||||
$code = $e->getCode();
|
$code = $e->getCode();
|
||||||
|
@ -99,7 +99,7 @@ class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||||
$this->verifier
|
$this->verifier
|
||||||
);
|
);
|
||||||
|
|
||||||
common_log(LOG_WARNIGN, $msg);
|
common_log(LOG_WARNING, $msg);
|
||||||
$this->clientError(_("Invalid request token or verifier.", 400, 'text'));
|
$this->clientError(_("Invalid request token or verifier.", 400, 'text'));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -177,21 +177,6 @@ class ApiOauthAuthorizeAction extends Action
|
||||||
$this->serverError($e->getMessage());
|
$this->serverError($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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__);
|
|
||||||
$this->serverError(_('Database error deleting OAuth application user.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// associated the authorized req token with the user and the app
|
// associated the authorized req token with the user and the app
|
||||||
|
|
||||||
$appUser = new Oauth_application_user();
|
$appUser = new Oauth_application_user();
|
||||||
|
|
|
@ -150,7 +150,6 @@ require_once INSTALLDIR . '/lib/mediafile.php';
|
||||||
|
|
||||||
class ApiStatusesUpdateAction extends ApiAuthAction
|
class ApiStatusesUpdateAction extends ApiAuthAction
|
||||||
{
|
{
|
||||||
var $source = null;
|
|
||||||
var $status = null;
|
var $status = null;
|
||||||
var $in_reply_to_status_id = null;
|
var $in_reply_to_status_id = null;
|
||||||
var $lat = null;
|
var $lat = null;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
* @category Settings
|
* @category Settings
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
* @author Zach Copley <zach@status.net>
|
* @author Zach Copley <zach@status.net>
|
||||||
* @copyright 2008-2009 StatusNet, Inc.
|
* @copyright 2008-2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
@ -51,12 +51,12 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||||
{
|
{
|
||||||
|
|
||||||
var $page = null;
|
var $page = null;
|
||||||
var $id = null;
|
var $oauth_token = null;
|
||||||
|
|
||||||
function prepare($args)
|
function prepare($args)
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
$this->id = (int)$this->arg('id');
|
$this->oauth_token = $this->arg('oauth_token');
|
||||||
$this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
|
$this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||||
|
|
||||||
function getInstructions()
|
function getInstructions()
|
||||||
{
|
{
|
||||||
return _('You have allowed the following applications to access your account.');
|
return _('The following connections exist for your account.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,22 +97,26 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||||
$offset = ($this->page - 1) * APPS_PER_PAGE;
|
$offset = ($this->page - 1) * APPS_PER_PAGE;
|
||||||
$limit = APPS_PER_PAGE + 1;
|
$limit = APPS_PER_PAGE + 1;
|
||||||
|
|
||||||
$application = $profile->getApplications($offset, $limit);
|
$connection = $profile->getConnectedApps($offset, $limit);
|
||||||
|
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
|
|
||||||
if (!empty($application)) {
|
if (!empty($connection)) {
|
||||||
$al = new ApplicationList($application, $user, $this, true);
|
$cal = new ConnectedAppsList($connection, $user, $this);
|
||||||
$cnt = $al->show();
|
$cnt = $cal->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cnt == 0) {
|
if ($cnt == 0) {
|
||||||
$this->showEmptyListMessage();
|
$this->showEmptyListMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->pagination($this->page > 1, $cnt > APPS_PER_PAGE,
|
$this->pagination(
|
||||||
$this->page, 'connectionssettings',
|
$this->page > 1,
|
||||||
array('nickname' => $user->nickname));
|
$cnt > APPS_PER_PAGE,
|
||||||
|
$this->page,
|
||||||
|
'connectionssettings',
|
||||||
|
array('nickname' => $user->nickname)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,11 +142,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->arg('revoke')) {
|
if ($this->arg('revoke')) {
|
||||||
$this->revokeAccess($this->id);
|
$this->revokeAccess($this->oauth_token);
|
||||||
|
|
||||||
// XXX: Show some indicator to the user of what's been done.
|
|
||||||
|
|
||||||
$this->showPage();
|
|
||||||
} else {
|
} else {
|
||||||
$this->clientError(_('Unexpected form submission.'), 401);
|
$this->clientError(_('Unexpected form submission.'), 401);
|
||||||
return false;
|
return false;
|
||||||
|
@ -150,32 +150,27 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Revoke access to an authorized OAuth application
|
* Revoke an access token
|
||||||
|
*
|
||||||
|
* XXX: Confirm revoke before doing it
|
||||||
*
|
*
|
||||||
* @param int $appId the ID of the application
|
* @param int $appId the ID of the application
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function revokeAccess($appId)
|
function revokeAccess($token)
|
||||||
{
|
{
|
||||||
$cur = common_current_user();
|
$cur = common_current_user();
|
||||||
|
|
||||||
$app = Oauth_application::staticGet('id', $appId);
|
$appUser = Oauth_application_user::getByUserAndToken($cur, $token);
|
||||||
|
|
||||||
if (empty($app)) {
|
|
||||||
$this->clientError(_('No such application.'), 404);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX: Transaction here?
|
|
||||||
|
|
||||||
$appUser = Oauth_application_user::getByKeys($cur, $app);
|
|
||||||
|
|
||||||
if (empty($appUser)) {
|
if (empty($appUser)) {
|
||||||
$this->clientError(_('You are not a user of that application.'), 401);
|
$this->clientError(_('You are not a user of that application.'), 401);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$app = Oauth_application::staticGet('id', $appUser->application_id);
|
||||||
|
|
||||||
$datastore = new ApiStatusNetOAuthDataStore();
|
$datastore = new ApiStatusNetOAuthDataStore();
|
||||||
$datastore->revoke_token($appUser->token, 1);
|
$datastore->revoke_token($appUser->token, 1);
|
||||||
|
|
||||||
|
@ -187,10 +182,25 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$msg = 'User %s (id: %d) revoked access to app %s (id: %d)';
|
$msg = 'API OAuth - user %s (id: %d) revoked access token %s for app id %d';
|
||||||
common_log(LOG_INFO, sprintf($msg, $cur->nickname,
|
common_log(
|
||||||
$cur->id, $app->name, $app->id));
|
LOG_INFO,
|
||||||
|
sprintf(
|
||||||
|
$msg,
|
||||||
|
$cur->nickname,
|
||||||
|
$cur->id,
|
||||||
|
$appUser->token,
|
||||||
|
$appUser->application_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$msg = sprintf(
|
||||||
|
_('You have successfully revoked access for %s and the access token starting with %s'),
|
||||||
|
$app->name,
|
||||||
|
substr($appUser->token, 0, 7)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->showForm($msg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showEmptyListMessage()
|
function showEmptyListMessage()
|
||||||
|
@ -208,10 +218,15 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||||
|
|
||||||
$this->element('h2', null, 'Developers');
|
$this->element('h2', null, 'Developers');
|
||||||
$this->elementStart('p');
|
$this->elementStart('p');
|
||||||
$this->raw(_('Developers can edit the registration settings for their applications '));
|
|
||||||
$this->element('a',
|
$devMsg = sprintf(
|
||||||
array('href' => common_local_url('oauthappssettings')),
|
_('Are you a developer? [Register an OAuth client application](%s) to use with this instance of StatusNet.'),
|
||||||
'here.');
|
common_local_url('oauthappssettings')
|
||||||
|
);
|
||||||
|
|
||||||
|
$output = common_markup_to_html($devMsg);
|
||||||
|
|
||||||
|
$this->raw($output);
|
||||||
$this->elementEnd('p');
|
$this->elementEnd('p');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ 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 $token; // varchar(255) primary_key not_null
|
||||||
public $created; // datetime not_null
|
public $created; // datetime not_null
|
||||||
public $modified; // timestamp not_null default_CURRENT_TIMESTAMP
|
public $modified; // timestamp not_null default_CURRENT_TIMESTAMP
|
||||||
|
|
||||||
|
@ -24,20 +24,51 @@ class Oauth_application_user extends Memcached_DataObject
|
||||||
/* 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)
|
static function getByUserAndToken($user, $token)
|
||||||
{
|
{
|
||||||
if (empty($user) || empty($app)) {
|
if (empty($user) || empty($token)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oau = new Oauth_application_user();
|
$oau = new Oauth_application_user();
|
||||||
|
|
||||||
$oau->profile_id = $user->id;
|
$oau->profile_id = $user->id;
|
||||||
$oau->application_id = $app->id;
|
$oau->token = $token;
|
||||||
$oau->limit(1);
|
$oau->limit(1);
|
||||||
|
|
||||||
$result = $oau->find(true);
|
$result = $oau->find(true);
|
||||||
|
|
||||||
return empty($result) ? null : $oau;
|
return empty($result) ? null : $oau;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateKeys(&$orig)
|
||||||
|
{
|
||||||
|
$this->_connect();
|
||||||
|
$parts = array();
|
||||||
|
foreach (array('profile_id', 'application_id', 'token', 'access_type') as $k) {
|
||||||
|
if (strcmp($this->$k, $orig->$k) != 0) {
|
||||||
|
$parts[] = $k . ' = ' . $this->_quote($this->$k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count($parts) == 0) {
|
||||||
|
# No changes
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$toupdate = implode(', ', $parts);
|
||||||
|
|
||||||
|
$table = $this->tableName();
|
||||||
|
if(common_config('db','quote_identifiers')) {
|
||||||
|
$table = '"' . $table . '"';
|
||||||
|
}
|
||||||
|
$qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
|
||||||
|
' WHERE profile_id = ' . $orig->profile_id
|
||||||
|
. ' AND application_id = ' . $orig->application_id
|
||||||
|
. " AND token = '$orig->token'";
|
||||||
|
$orig->decache();
|
||||||
|
$result = $this->query($qry);
|
||||||
|
if ($result) {
|
||||||
|
$this->encache();
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,10 +401,10 @@ class Profile extends Memcached_DataObject
|
||||||
return $profile;
|
return $profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getApplications($offset = 0, $limit = null)
|
function getConnectedApps($offset = 0, $limit = null)
|
||||||
{
|
{
|
||||||
$qry =
|
$qry =
|
||||||
'SELECT a.* ' .
|
'SELECT u.* ' .
|
||||||
'FROM oauth_application_user u, oauth_application a ' .
|
'FROM oauth_application_user u, oauth_application a ' .
|
||||||
'WHERE u.profile_id = %d ' .
|
'WHERE u.profile_id = %d ' .
|
||||||
'AND a.id = u.application_id ' .
|
'AND a.id = u.application_id ' .
|
||||||
|
@ -419,11 +419,11 @@ class Profile extends Memcached_DataObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$application = new Oauth_application();
|
$apps = new Oauth_application_user();
|
||||||
|
|
||||||
$cnt = $application->query(sprintf($qry, $this->id));
|
$cnt = $apps->query(sprintf($qry, $this->id));
|
||||||
|
|
||||||
return $application;
|
return $apps;
|
||||||
}
|
}
|
||||||
|
|
||||||
function subscriptionCount()
|
function subscriptionCount()
|
||||||
|
|
|
@ -393,13 +393,14 @@ name = U
|
||||||
profile_id = 129
|
profile_id = 129
|
||||||
application_id = 129
|
application_id = 129
|
||||||
access_type = 17
|
access_type = 17
|
||||||
token = 2
|
token = 130
|
||||||
created = 142
|
created = 142
|
||||||
modified = 384
|
modified = 384
|
||||||
|
|
||||||
[oauth_application_user__keys]
|
[oauth_application_user__keys]
|
||||||
profile_id = K
|
profile_id = K
|
||||||
application_id = K
|
application_id = K
|
||||||
|
token = K
|
||||||
|
|
||||||
[profile]
|
[profile]
|
||||||
id = 129
|
id = 129
|
||||||
|
|
|
@ -231,10 +231,10 @@ 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',
|
access_type tinyint default 0 comment 'access type, bit 1 = read, bit 2 = write',
|
||||||
token varchar(255) comment 'request or access token',
|
token varchar(255) not null comment 'request or access token',
|
||||||
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',
|
modified timestamp comment 'date this record was modified',
|
||||||
constraint primary key (profile_id, application_id)
|
constraint primary key (profile_id, application_id, token)
|
||||||
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||||
|
|
||||||
/* These are used by JanRain OpenID library */
|
/* These are used by JanRain OpenID library */
|
||||||
|
|
|
@ -178,8 +178,10 @@ class ApiAuthAction extends ApiAction
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the source attr
|
// set the source attr
|
||||||
|
if ($app->name != 'anonymous') {
|
||||||
$this->source = $app->name;
|
$this->source = $app->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$appUser = Oauth_application_user::staticGet('token', $access_token);
|
$appUser = Oauth_application_user::staticGet('token', $access_token);
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,43 @@ require_once INSTALLDIR . '/lib/oauthstore.php';
|
||||||
|
|
||||||
class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||||
{
|
{
|
||||||
function lookup_consumer($consumer_key)
|
function lookup_consumer($consumerKey)
|
||||||
{
|
{
|
||||||
$con = Consumer::staticGet('consumer_key', $consumer_key);
|
$con = Consumer::staticGet('consumer_key', $consumerKey);
|
||||||
|
|
||||||
if (!$con) {
|
if (!$con) {
|
||||||
|
|
||||||
|
// Create an anon consumer and anon application if one
|
||||||
|
// doesn't exist already
|
||||||
|
if ($consumerKey == 'anonymous') {
|
||||||
|
$con = new Consumer();
|
||||||
|
$con->consumer_key = $consumerKey;
|
||||||
|
$con->consumer_secret = $consumerKey;
|
||||||
|
$result = $con->insert();
|
||||||
|
if (!$result) {
|
||||||
|
$this->serverError(_("Could not create anonymous consumer."));
|
||||||
|
}
|
||||||
|
$app = new OAuth_application();
|
||||||
|
$app->consumer_key = $con->consumer_key;
|
||||||
|
$app->name = 'anonymous';
|
||||||
|
|
||||||
|
// XXX: allow the user to set the access type when
|
||||||
|
// authorizing? Currently we default to r+w for anonymous
|
||||||
|
// OAuth client applications
|
||||||
|
$app->access_type = 3; // read + write
|
||||||
|
$id = $app->insert();
|
||||||
|
if (!$id) {
|
||||||
|
$this->serverError(_("Could not create anonymous OAuth application."));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new OAuthConsumer($con->consumer_key,
|
return new OAuthConsumer(
|
||||||
$con->consumer_secret);
|
$con->consumer_key,
|
||||||
|
$con->consumer_secret
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAppByRequestToken($token_key)
|
function getAppByRequestToken($token_key)
|
||||||
|
@ -94,7 +121,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||||
|
|
||||||
if ($rt->find(true) && $rt->state == 1 && $rt->verifier == $verifier) { // authorized
|
if ($rt->find(true) && $rt->state == 1 && $rt->verifier == $verifier) { // authorized
|
||||||
|
|
||||||
common_debug('request token found.', __FILE__);
|
common_debug('request token found.');
|
||||||
|
|
||||||
// find the associated user of the app
|
// find the associated user of the app
|
||||||
|
|
||||||
|
@ -140,6 +167,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||||
// update the token from req to access for the user
|
// update the token from req to access for the user
|
||||||
|
|
||||||
$orig = clone($appUser);
|
$orig = clone($appUser);
|
||||||
|
|
||||||
$appUser->token = $at->tok;
|
$appUser->token = $at->tok;
|
||||||
|
|
||||||
// It's at this point that we change the access type
|
// It's at this point that we change the access type
|
||||||
|
@ -150,11 +178,10 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||||
|
|
||||||
$appUser->access_type = $app->access_type;
|
$appUser->access_type = $app->access_type;
|
||||||
|
|
||||||
$result = $appUser->update($orig);
|
$result = $appUser->updateKeys($orig);
|
||||||
|
|
||||||
if (empty($result)) {
|
if (!$result) {
|
||||||
common_debug('couldn\'t update OAuth app user.');
|
throw new Exception('Couldn\'t update OAuth app user.');
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Okay, good
|
// Okay, good
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
* @category Application
|
* @category Application
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
* @author Zach Copley <zach@status.net>
|
* @author Zach Copley <zach@status.net>
|
||||||
* @copyright 2008-2009 StatusNet, Inc.
|
* @copyright 2008-2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
@ -55,14 +55,13 @@ class ApplicationList extends Widget
|
||||||
/** Action object using us. */
|
/** Action object using us. */
|
||||||
var $action = null;
|
var $action = null;
|
||||||
|
|
||||||
function __construct($application, $owner=null, $action=null, $connections = false)
|
function __construct($application, $owner=null, $action=null)
|
||||||
{
|
{
|
||||||
parent::__construct($action);
|
parent::__construct($action);
|
||||||
|
|
||||||
$this->application = $application;
|
$this->application = $application;
|
||||||
$this->owner = $owner;
|
$this->owner = $owner;
|
||||||
$this->action = $action;
|
$this->action = $action;
|
||||||
$this->connections = $connections;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function show()
|
function show()
|
||||||
|
@ -88,24 +87,34 @@ class ApplicationList extends Widget
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
|
||||||
$this->out->elementStart('li', array('class' => 'application',
|
$this->out->elementStart(
|
||||||
'id' => 'oauthclient-' . $this->application->id));
|
'li',
|
||||||
|
array(
|
||||||
|
'class' => 'application',
|
||||||
|
'id' => 'oauthclient-' . $this->application->id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
$this->out->elementStart('span', 'vcard author');
|
$this->out->elementStart('span', 'vcard author');
|
||||||
if (!$this->connections) {
|
|
||||||
$this->out->elementStart('a',
|
|
||||||
array('href' => common_local_url('showapplication',
|
|
||||||
array('id' => $this->application->id)),
|
|
||||||
'class' => 'url'));
|
|
||||||
|
|
||||||
} else {
|
$this->out->elementStart(
|
||||||
$this->out->elementStart('a', array('href' => $this->application->source_url,
|
'a',
|
||||||
'class' => 'url'));
|
array(
|
||||||
}
|
'href' => common_local_url(
|
||||||
|
'showapplication',
|
||||||
|
array('id' => $this->application->id)),
|
||||||
|
'class' => 'url'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (!empty($this->application->icon)) {
|
if (!empty($this->application->icon)) {
|
||||||
$this->out->element('img', array('src' => $this->application->icon,
|
$this->out->element(
|
||||||
'class' => 'photo avatar'));
|
'img',
|
||||||
|
array(
|
||||||
|
'src' => $this->application->icon,
|
||||||
|
'class' => 'photo avatar'
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->out->element('span', 'fn', $this->application->name);
|
$this->out->element('span', 'fn', $this->application->name);
|
||||||
|
@ -114,51 +123,18 @@ class ApplicationList extends Widget
|
||||||
|
|
||||||
$this->out->raw(' by ');
|
$this->out->raw(' by ');
|
||||||
|
|
||||||
$this->out->element('a', array('href' => $this->application->homepage,
|
$this->out->element(
|
||||||
'class' => 'url'),
|
'a',
|
||||||
$this->application->organization);
|
array(
|
||||||
|
'href' => $this->application->homepage,
|
||||||
|
'class' => 'url'
|
||||||
|
),
|
||||||
|
$this->application->organization
|
||||||
|
);
|
||||||
|
|
||||||
$this->out->element('p', 'note', $this->application->description);
|
$this->out->element('p', 'note', $this->application->description);
|
||||||
$this->out->elementEnd('li');
|
$this->out->elementEnd('li');
|
||||||
|
|
||||||
if ($this->connections) {
|
|
||||||
$appUser = Oauth_application_user::getByKeys($this->owner, $this->application);
|
|
||||||
|
|
||||||
if (empty($appUser)) {
|
|
||||||
common_debug("empty appUser!");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->out->elementStart('li');
|
|
||||||
|
|
||||||
// TRANS: Application access type
|
|
||||||
$readWriteText = _('read-write');
|
|
||||||
// TRANS: Application access type
|
|
||||||
$readOnlyText = _('read-only');
|
|
||||||
|
|
||||||
$access = ($this->application->access_type & Oauth_application::$writeAccess)
|
|
||||||
? $readWriteText : $readOnlyText;
|
|
||||||
$modifiedDate = common_date_string($appUser->modified);
|
|
||||||
// TRANS: Used in application list. %1$s is a modified date, %2$s is access type ("read-write" or "read-only")
|
|
||||||
$txt = sprintf(_('Approved %1$s - "%2$s" access.'),$modifiedDate,$access);
|
|
||||||
|
|
||||||
$this->out->raw($txt);
|
|
||||||
$this->out->elementEnd('li');
|
|
||||||
|
|
||||||
$this->out->elementStart('li', 'entity_revoke');
|
|
||||||
$this->out->elementStart('form', array('id' => 'form_revoke_app',
|
|
||||||
'class' => 'form_revoke_app',
|
|
||||||
'method' => 'POST',
|
|
||||||
'action' =>
|
|
||||||
common_local_url('oauthconnectionssettings')));
|
|
||||||
$this->out->elementStart('fieldset');
|
|
||||||
$this->out->hidden('id', $this->application->id);
|
|
||||||
$this->out->hidden('token', common_session_token());
|
|
||||||
// TRANS: Button label
|
|
||||||
$this->out->submit('revoke', _m('BUTTON','Revoke'));
|
|
||||||
$this->out->elementEnd('fieldset');
|
|
||||||
$this->out->elementEnd('form');
|
|
||||||
$this->out->elementEnd('li');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Override this in subclasses. */
|
/* Override this in subclasses. */
|
||||||
|
@ -166,4 +142,164 @@ class ApplicationList extends Widget
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widget to show a list of connected OAuth clients
|
||||||
|
*
|
||||||
|
* @category Application
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
class ConnectedAppsList extends Widget
|
||||||
|
{
|
||||||
|
/** Current connected application query */
|
||||||
|
var $connection = null;
|
||||||
|
|
||||||
|
/** Owner of this list */
|
||||||
|
var $owner = null;
|
||||||
|
|
||||||
|
/** Action object using us. */
|
||||||
|
var $action = null;
|
||||||
|
|
||||||
|
function __construct($connection, $owner=null, $action=null)
|
||||||
|
{
|
||||||
|
parent::__construct($action);
|
||||||
|
|
||||||
|
common_debug("ConnectedAppsList constructor");
|
||||||
|
|
||||||
|
$this->connection = $connection;
|
||||||
|
$this->owner = $owner;
|
||||||
|
$this->action = $action;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override this in subclasses. */
|
||||||
|
function showOwnerControls()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function show()
|
||||||
|
{
|
||||||
|
$this->out->elementStart('ul', 'applications');
|
||||||
|
|
||||||
|
$cnt = 0;
|
||||||
|
|
||||||
|
while ($this->connection->fetch()) {
|
||||||
|
$cnt++;
|
||||||
|
if($cnt > APPS_PER_PAGE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->showConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
|
||||||
|
return $cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showConnection()
|
||||||
|
{
|
||||||
|
$app = Oauth_application::staticGet('id', $this->connection->application_id);
|
||||||
|
|
||||||
|
$this->out->elementStart(
|
||||||
|
'li',
|
||||||
|
array(
|
||||||
|
'class' => 'application',
|
||||||
|
'id' => 'oauthclient-' . $app->id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->out->elementStart('span', 'vcard author');
|
||||||
|
|
||||||
|
$this->out->elementStart(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $app->source_url,
|
||||||
|
'class' => 'url'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!empty($app->icon)) {
|
||||||
|
$this->out->element(
|
||||||
|
'img',
|
||||||
|
array(
|
||||||
|
'src' => $app->icon,
|
||||||
|
'class' => 'photo avatar'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($app->name != 'anonymous') {
|
||||||
|
$this->out->element('span', 'fn', $app->name);
|
||||||
|
}
|
||||||
|
$this->out->elementEnd('a');
|
||||||
|
|
||||||
|
if ($app->name == 'anonymous') {
|
||||||
|
$this->out->element('span', 'fn', "Unknown application");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->elementEnd('span');
|
||||||
|
|
||||||
|
if ($app->name != 'anonymous') {
|
||||||
|
|
||||||
|
$this->out->raw(_(' by '));
|
||||||
|
|
||||||
|
$this->out->element(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $app->homepage,
|
||||||
|
'class' => 'url'
|
||||||
|
),
|
||||||
|
$app->organization
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TRANS: Application access type
|
||||||
|
$readWriteText = _('read-write');
|
||||||
|
// TRANS: Application access type
|
||||||
|
$readOnlyText = _('read-only');
|
||||||
|
|
||||||
|
$access = ($this->connection->access_type & Oauth_application::$writeAccess)
|
||||||
|
? $readWriteText : $readOnlyText;
|
||||||
|
$modifiedDate = common_date_string($this->connection->modified);
|
||||||
|
// TRANS: Used in application list. %1$s is a modified date, %2$s is access type ("read-write" or "read-only")
|
||||||
|
$txt = sprintf(_('Approved %1$s - "%2$s" access.'), $modifiedDate, $access);
|
||||||
|
|
||||||
|
$this->out->raw(" - $txt");
|
||||||
|
if (!empty($app->description)) {
|
||||||
|
$this->out->element(
|
||||||
|
'p', array('class' => 'application_description'),
|
||||||
|
$app->description
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$this->out->element(
|
||||||
|
'p', array(
|
||||||
|
'class' => 'access_token'),
|
||||||
|
_('Access token starting with: ') . substr($this->connection->token, 0, 7)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->out->elementStart(
|
||||||
|
'form',
|
||||||
|
array(
|
||||||
|
'id' => 'form_revoke_app',
|
||||||
|
'class' => 'form_revoke_app',
|
||||||
|
'method' => 'POST',
|
||||||
|
'action' => common_local_url('oauthconnectionssettings')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->out->elementStart('fieldset');
|
||||||
|
$this->out->hidden('oauth_token', $this->connection->token);
|
||||||
|
$this->out->hidden('token', common_session_token());
|
||||||
|
// TRANS: Button label
|
||||||
|
$this->out->submit('revoke', _('Revoke'));
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
$this->out->elementEnd('form');
|
||||||
|
|
||||||
|
$this->out->elementEnd('li');
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user