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);
|
||||
$atok = $server->fetch_access_token($req);
|
||||
|
||||
} catch (OAuthException $e) {
|
||||
} catch (Exception $e) {
|
||||
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
||||
common_debug(var_export($req, true));
|
||||
$code = $e->getCode();
|
||||
@ -99,7 +99,7 @@ class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||
$this->verifier
|
||||
);
|
||||
|
||||
common_log(LOG_WARNIGN, $msg);
|
||||
common_log(LOG_WARNING, $msg);
|
||||
$this->clientError(_("Invalid request token or verifier.", 400, 'text'));
|
||||
|
||||
} else {
|
||||
|
@ -177,21 +177,6 @@ class ApiOauthAuthorizeAction extends Action
|
||||
$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
|
||||
|
||||
$appUser = new Oauth_application_user();
|
||||
|
@ -150,7 +150,6 @@ require_once INSTALLDIR . '/lib/mediafile.php';
|
||||
|
||||
class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
{
|
||||
var $source = null;
|
||||
var $status = null;
|
||||
var $in_reply_to_status_id = null;
|
||||
var $lat = null;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* @category Settings
|
||||
* @package StatusNet
|
||||
* @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
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -50,13 +50,13 @@ require_once INSTALLDIR . '/lib/apioauthstore.php';
|
||||
class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||
{
|
||||
|
||||
var $page = null;
|
||||
var $id = null;
|
||||
var $page = null;
|
||||
var $oauth_token = null;
|
||||
|
||||
function 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;
|
||||
return true;
|
||||
}
|
||||
@ -80,7 +80,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||
|
||||
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;
|
||||
$limit = APPS_PER_PAGE + 1;
|
||||
|
||||
$application = $profile->getApplications($offset, $limit);
|
||||
$connection = $profile->getConnectedApps($offset, $limit);
|
||||
|
||||
$cnt = 0;
|
||||
|
||||
if (!empty($application)) {
|
||||
$al = new ApplicationList($application, $user, $this, true);
|
||||
$cnt = $al->show();
|
||||
if (!empty($connection)) {
|
||||
$cal = new ConnectedAppsList($connection, $user, $this);
|
||||
$cnt = $cal->show();
|
||||
}
|
||||
|
||||
if ($cnt == 0) {
|
||||
$this->showEmptyListMessage();
|
||||
}
|
||||
|
||||
$this->pagination($this->page > 1, $cnt > APPS_PER_PAGE,
|
||||
$this->page, 'connectionssettings',
|
||||
array('nickname' => $user->nickname));
|
||||
$this->pagination(
|
||||
$this->page > 1,
|
||||
$cnt > APPS_PER_PAGE,
|
||||
$this->page,
|
||||
'connectionssettings',
|
||||
array('nickname' => $user->nickname)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,11 +142,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||
}
|
||||
|
||||
if ($this->arg('revoke')) {
|
||||
$this->revokeAccess($this->id);
|
||||
|
||||
// XXX: Show some indicator to the user of what's been done.
|
||||
|
||||
$this->showPage();
|
||||
$this->revokeAccess($this->oauth_token);
|
||||
} else {
|
||||
$this->clientError(_('Unexpected form submission.'), 401);
|
||||
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
|
||||
*
|
||||
*/
|
||||
|
||||
function revokeAccess($appId)
|
||||
function revokeAccess($token)
|
||||
{
|
||||
$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);
|
||||
$appUser = Oauth_application_user::getByUserAndToken($cur, $token);
|
||||
|
||||
if (empty($appUser)) {
|
||||
$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);
|
||||
|
||||
@ -187,10 +182,25 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||
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));
|
||||
$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 %s and the access token starting with %s'),
|
||||
$app->name,
|
||||
substr($appUser->token, 0, 7)
|
||||
);
|
||||
|
||||
$this->showForm($msg, true);
|
||||
}
|
||||
|
||||
function showEmptyListMessage()
|
||||
@ -204,15 +214,20 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction
|
||||
|
||||
function showSections()
|
||||
{
|
||||
$cur = common_current_user();
|
||||
$cur = common_current_user();
|
||||
|
||||
$this->element('h2', null, 'Developers');
|
||||
$this->elementStart('p');
|
||||
$this->raw(_('Developers can edit the registration settings for their applications '));
|
||||
$this->element('a',
|
||||
array('href' => common_local_url('oauthappssettings')),
|
||||
'here.');
|
||||
$this->elementEnd('p');
|
||||
$this->element('h2', null, 'Developers');
|
||||
$this->elementStart('p');
|
||||
|
||||
$devMsg = sprintf(
|
||||
_('Are you a developer? [Register an OAuth client application](%s) to use with this instance of StatusNet.'),
|
||||
common_local_url('oauthappssettings')
|
||||
);
|
||||
|
||||
$output = common_markup_to_html($devMsg);
|
||||
|
||||
$this->raw($output);
|
||||
$this->elementEnd('p');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class Oauth_application_user extends Memcached_DataObject
|
||||
public $profile_id; // int(4) primary_key not_null
|
||||
public $application_id; // int(4) primary_key not_null
|
||||
public $access_type; // tinyint(1)
|
||||
public $token; // varchar(255)
|
||||
public $token; // varchar(255) primary_key not_null
|
||||
public $created; // datetime not_null
|
||||
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 */
|
||||
###END_AUTOCODE
|
||||
|
||||
static function getByKeys($user, $app)
|
||||
static function getByUserAndToken($user, $token)
|
||||
{
|
||||
if (empty($user) || empty($app)) {
|
||||
if (empty($user) || empty($token)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$oau = new Oauth_application_user();
|
||||
|
||||
$oau->profile_id = $user->id;
|
||||
$oau->application_id = $app->id;
|
||||
$oau->profile_id = $user->id;
|
||||
$oau->token = $token;
|
||||
$oau->limit(1);
|
||||
|
||||
$result = $oau->find(true);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function getApplications($offset = 0, $limit = null)
|
||||
function getConnectedApps($offset = 0, $limit = null)
|
||||
{
|
||||
$qry =
|
||||
'SELECT a.* ' .
|
||||
'SELECT u.* ' .
|
||||
'FROM oauth_application_user u, oauth_application a ' .
|
||||
'WHERE u.profile_id = %d ' .
|
||||
'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()
|
||||
|
@ -393,13 +393,14 @@ name = U
|
||||
profile_id = 129
|
||||
application_id = 129
|
||||
access_type = 17
|
||||
token = 2
|
||||
token = 130
|
||||
created = 142
|
||||
modified = 384
|
||||
|
||||
[oauth_application_user__keys]
|
||||
profile_id = K
|
||||
application_id = K
|
||||
token = K
|
||||
|
||||
[profile]
|
||||
id = 129
|
||||
|
@ -231,10 +231,10 @@ create table oauth_application_user (
|
||||
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),
|
||||
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',
|
||||
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;
|
||||
|
||||
/* These are used by JanRain OpenID library */
|
||||
|
@ -178,8 +178,10 @@ class ApiAuthAction extends ApiAction
|
||||
}
|
||||
|
||||
// set the source attr
|
||||
if ($app->name != 'anonymous') {
|
||||
$this->source = $app->name;
|
||||
}
|
||||
|
||||
$this->source = $app->name;
|
||||
|
||||
$appUser = Oauth_application_user::staticGet('token', $access_token);
|
||||
|
||||
|
@ -23,16 +23,43 @@ require_once INSTALLDIR . '/lib/oauthstore.php';
|
||||
|
||||
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) {
|
||||
return null;
|
||||
|
||||
// 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 new OAuthConsumer($con->consumer_key,
|
||||
$con->consumer_secret);
|
||||
return new OAuthConsumer(
|
||||
$con->consumer_key,
|
||||
$con->consumer_secret
|
||||
);
|
||||
}
|
||||
|
||||
function getAppByRequestToken($token_key)
|
||||
@ -94,7 +121,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||
|
||||
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
|
||||
|
||||
@ -140,6 +167,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||
// update the token from req to access for the user
|
||||
|
||||
$orig = clone($appUser);
|
||||
|
||||
$appUser->token = $at->tok;
|
||||
|
||||
// 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;
|
||||
|
||||
$result = $appUser->update($orig);
|
||||
$result = $appUser->updateKeys($orig);
|
||||
|
||||
if (empty($result)) {
|
||||
common_debug('couldn\'t update OAuth app user.');
|
||||
return null;
|
||||
if (!$result) {
|
||||
throw new Exception('Couldn\'t update OAuth app user.');
|
||||
}
|
||||
|
||||
// Okay, good
|
||||
@ -179,9 +206,9 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||
* @return void
|
||||
*/
|
||||
public function revoke_token($token_key, $type = 0) {
|
||||
$rt = new Token();
|
||||
$rt->tok = $token_key;
|
||||
$rt->type = $type;
|
||||
$rt = new Token();
|
||||
$rt->tok = $token_key;
|
||||
$rt->type = $type;
|
||||
$rt->state = 0;
|
||||
|
||||
if (!$rt->find(true)) {
|
||||
|
@ -22,7 +22,7 @@
|
||||
* @category Application
|
||||
* @package StatusNet
|
||||
* @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
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -55,14 +55,13 @@ class ApplicationList extends Widget
|
||||
/** Action object using us. */
|
||||
var $action = null;
|
||||
|
||||
function __construct($application, $owner=null, $action=null, $connections = false)
|
||||
function __construct($application, $owner=null, $action=null)
|
||||
{
|
||||
parent::__construct($action);
|
||||
|
||||
$this->application = $application;
|
||||
$this->owner = $owner;
|
||||
$this->action = $action;
|
||||
$this->connections = $connections;
|
||||
}
|
||||
|
||||
function show()
|
||||
@ -88,24 +87,34 @@ class ApplicationList extends Widget
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
$this->out->elementStart('li', array('class' => 'application',
|
||||
'id' => 'oauthclient-' . $this->application->id));
|
||||
$this->out->elementStart(
|
||||
'li',
|
||||
array(
|
||||
'class' => 'application',
|
||||
'id' => 'oauthclient-' . $this->application->id
|
||||
)
|
||||
);
|
||||
|
||||
$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('a', array('href' => $this->application->source_url,
|
||||
'class' => 'url'));
|
||||
}
|
||||
$this->out->elementStart(
|
||||
'a',
|
||||
array(
|
||||
'href' => common_local_url(
|
||||
'showapplication',
|
||||
array('id' => $this->application->id)),
|
||||
'class' => 'url'
|
||||
)
|
||||
);
|
||||
|
||||
if (!empty($this->application->icon)) {
|
||||
$this->out->element('img', array('src' => $this->application->icon,
|
||||
'class' => 'photo avatar'));
|
||||
$this->out->element(
|
||||
'img',
|
||||
array(
|
||||
'src' => $this->application->icon,
|
||||
'class' => 'photo avatar'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->out->element('span', 'fn', $this->application->name);
|
||||
@ -114,51 +123,18 @@ class ApplicationList extends Widget
|
||||
|
||||
$this->out->raw(' by ');
|
||||
|
||||
$this->out->element('a', array('href' => $this->application->homepage,
|
||||
'class' => 'url'),
|
||||
$this->application->organization);
|
||||
$this->out->element(
|
||||
'a',
|
||||
array(
|
||||
'href' => $this->application->homepage,
|
||||
'class' => 'url'
|
||||
),
|
||||
$this->application->organization
|
||||
);
|
||||
|
||||
$this->out->element('p', 'note', $this->application->description);
|
||||
$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. */
|
||||
@ -166,4 +142,164 @@ class ApplicationList extends Widget
|
||||
{
|
||||
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