From 4b4894b121bdf62dca067cb72ad4f8e29a2963b5 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Wed, 20 Oct 2010 00:35:39 +0200 Subject: Many i18n/L10n updates and lots of descriptions for translators added. --- lib/common.php | 4 +-- lib/mail.php | 109 ++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 68 insertions(+), 45 deletions(-) (limited to 'lib') diff --git a/lib/common.php b/lib/common.php index c2117164c..cd4fbfb15 100644 --- a/lib/common.php +++ b/lib/common.php @@ -133,10 +133,10 @@ try { // XXX: Throw a conniption if database not installed // XXX: Find a way to use htmlwriter for this instead of handcoded markup // TRANS: Error message displayed when no configuration file was found for a StatusNet installation. - echo '

'. _('No configuration file found. ') .'

'; + echo '

'. _('No configuration file found.') .'

'; // TRANS: Error message displayed when no configuration file was found for a StatusNet installation. // TRANS: Is followed by a list of directories (separated by HTML breaks). - echo '

'. _('I looked for configuration files in the following places: ') .'
'; + echo '

'. _('I looked for configuration files in the following places:') .'
'; echo implode($e->configFiles, '
'); // TRANS: Error message displayed when no configuration file was found for a StatusNet installation. echo '

'. _('You may wish to run the installer to fix this.') .'

'; diff --git a/lib/mail.php b/lib/mail.php index ab5742e33..3703e5c35 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -170,19 +170,21 @@ function mail_to_user(&$user, $subject, $body, $headers=array(), $address=null) function mail_confirm_address($user, $code, $nickname, $address) { - // TRANS: Subject for address confirmation email + // TRANS: Subject for address confirmation email. $subject = _('Email address confirmation'); // TRANS: Body for address confirmation email. - $body = sprintf(_("Hey, %s.\n\n". - "Someone just entered this email address on %s.\n\n" . + // TRANS: %1$s is the addressed user's nickname, %2$s is the StatusNet sitename, + // TRANS: %3$s is the URL to confirm at. + $body = sprintf(_("Hey, %1\$s.\n\n". + "Someone just entered this email address on %2\$s.\n\n" . "If it was you, and you want to confirm your entry, ". - "use the URL below:\n\n\t%s\n\n" . + "use the URL below:\n\n\t%3\$s\n\n" . "If not, just ignore this message.\n\n". - "Thanks for your time, \n%s\n"), - $nickname, common_config('site', 'name'), - common_local_url('confirmaddress', array('code' => $code)), - common_config('site', 'name')); + "Thanks for your time, \n%2\$s\n"), + $nickname, + common_config('site', 'name'), + common_local_url('confirmaddress', array('code' => $code))); $headers = array(); return mail_to_user($user, $subject, $body, $headers, $address); @@ -239,41 +241,50 @@ function mail_subscribe_notify_profile($listenee, $other) $headers = _mail_prepare_headers('subscribe', $listenee->nickname, $other->nickname); $headers['From'] = mail_notify_from(); $headers['To'] = $name . ' <' . $listenee->email . '>'; - // TRANS: Subject of new-subscriber notification e-mail + // TRANS: Subject of new-subscriber notification e-mail. + // TRANS: %1$s is the subscribing user's nickname, %2$s is the StatusNet sitename. $headers['Subject'] = sprintf(_('%1$s is now listening to '. 'your notices on %2$s.'), $other->getBestName(), common_config('site', 'name')); + // TRANS: This is a paragraph in a new-subscriber e-mail. + // TRANS: %s is a URL where the subscriber can be reported as abusive. $blocklink = sprintf(_("If you believe this account is being used abusively, " . "you can block them from your subscribers list and " . "report as spam to site administrators at %s"), common_local_url('block', array('profileid' => $other->id))); - // TRANS: Main body of new-subscriber notification e-mail + // TRANS: Main body of new-subscriber notification e-mail. + // TRANS: %1$s is the subscriber's long name, %2$s is the StatusNet sitename, + // TRANS: %3$s is the subscriber's profile URL, %4$s is the subscriber's location (or empty) + // TRANS: %5$s is the subscriber's homepage URL (or empty), %6%s is the subscriber's bio (or empty) + // TRANS: %7$s is a link to the addressed user's e-mail settings. $body = sprintf(_('%1$s is now listening to your notices on %2$s.'."\n\n". "\t".'%3$s'."\n\n". '%4$s'. '%5$s'. '%6$s'. - "\n".'Faithfully yours,'."\n".'%7$s.'."\n\n". + "\n".'Faithfully yours,'."\n".'%2$s.'."\n\n". "----\n". "Change your email address or ". - "notification options at ".'%8$s' ."\n"), + "notification options at ".'%7$s' ."\n"), $long_name, common_config('site', 'name'), $other->profileurl, ($other->location) ? - // TRANS: Profile info line in new-subscriber notification e-mail + // TRANS: Profile info line in new-subscriber notification e-mail. + // TRANS: %s is a location. sprintf(_("Location: %s"), $other->location) . "\n" : '', ($other->homepage) ? - // TRANS: Profile info line in new-subscriber notification e-mail + // TRANS: Profile info line in new-subscriber notification e-mail. + // TRANS: %s is a homepage. sprintf(_("Homepage: %s"), $other->homepage) . "\n" : '', (($other->bio) ? - // TRANS: Profile info line in new-subscriber notification e-mail + // TRANS: Profile info line in new-subscriber notification e-mail. + // TRANS: %s is biographical information. sprintf(_("Bio: %s"), $other->bio) . "\n" : '') . "\n\n" . $blocklink . "\n", - common_config('site', 'name'), common_local_url('emailsettings')); // reset localization @@ -291,7 +302,6 @@ function mail_subscribe_notify_profile($listenee, $other) * * @return void */ - function mail_new_incoming_notify($user) { $profile = $user->getProfile(); @@ -300,19 +310,21 @@ function mail_new_incoming_notify($user) $headers['From'] = $user->incomingemail; $headers['To'] = $name . ' <' . $user->email . '>'; - // TRANS: Subject of notification mail for new posting email address + // TRANS: Subject of notification mail for new posting email address. + // TRANS: %s is the StatusNet sitename. $headers['Subject'] = sprintf(_('New email address for posting to %s'), common_config('site', 'name')); - // TRANS: Body of notification mail for new posting email address + // TRANS: Body of notification mail for new posting email address. + // TRANS: %1$s is the StatusNet sitename, %2$s is the e-mail address to send + // TRANS: to to post by e-mail, %3$s is a URL to more instructions. $body = sprintf(_("You have a new posting address on %1\$s.\n\n". "Send email to %2\$s to post new messages.\n\n". "More email instructions at %3\$s.\n\n". - "Faithfully yours,\n%4\$s"), + "Faithfully yours,\n%1\$s"), common_config('site', 'name'), $user->incomingemail, - common_local_url('doc', array('title' => 'email')), - common_config('site', 'name')); + common_local_url('doc', array('title' => 'email'))); mail_send($user->email, $headers, $body); } @@ -324,7 +336,6 @@ function mail_new_incoming_notify($user) * * @return string new email address for incoming messages */ - function mail_new_incoming_address() { $prefix = common_confirmation_code(64); @@ -343,7 +354,6 @@ function mail_new_incoming_address() * * @return success flag */ - function mail_broadcast_notice_sms($notice) { // Now, get users subscribed to this profile @@ -395,7 +405,6 @@ function mail_broadcast_notice_sms($notice) * * @return boolean success flag */ - function mail_send_sms_notice($notice, $user) { return mail_send_sms_notice_address($notice, @@ -415,7 +424,6 @@ function mail_send_sms_notice($notice, $user) * * @return boolean success flag */ - function mail_send_sms_notice_address($notice, $smsemail, $incomingemail) { $to = $nickname . ' <' . $smsemail . '>'; @@ -429,7 +437,8 @@ function mail_send_sms_notice_address($notice, $smsemail, $incomingemail) $headers['From'] = ($incomingemail) ? $incomingemail : mail_notify_from(); $headers['To'] = $to; - // TRANS: Subject line for SMS-by-email notification messages + // TRANS: Subject line for SMS-by-email notification messages. + // TRANS: %s is the posting user's nickname. $headers['Subject'] = sprintf(_('%s status'), $other->getBestName()); @@ -449,17 +458,17 @@ function mail_send_sms_notice_address($notice, $smsemail, $incomingemail) * * @return void */ - function mail_confirm_sms($code, $nickname, $address) { $recipients = $address; $headers['From'] = mail_notify_from(); $headers['To'] = $nickname . ' <' . $address . '>'; - // TRANS: Subject line for SMS-by-email address confirmation message + // TRANS: Subject line for SMS-by-email address confirmation message. $headers['Subject'] = _('SMS confirmation'); - // TRANS: Main body heading for SMS-by-email address confirmation message + // TRANS: Main body heading for SMS-by-email address confirmation message. + // TRANS: %s is the addressed user's nickname. $body = sprintf(_("%s: confirm you own this phone number with this code:"), $nickname); $body .= "\n\n"; $body .= $code; @@ -476,16 +485,18 @@ function mail_confirm_sms($code, $nickname, $address) * * @return boolean success flag */ - function mail_notify_nudge($from, $to) { common_switch_locale($to->language); - // TRANS: Subject for 'nudge' notification email + // TRANS: Subject for 'nudge' notification email. + // TRANS: %s is the nudging user. $subject = sprintf(_('You\'ve been nudged by %s'), $from->nickname); $from_profile = $from->getProfile(); - // TRANS: Body for 'nudge' notification email + // TRANS: Body for 'nudge' notification email. + // TRANS: %1$s is the nuding user's long name, $2$s is the nudging user's nickname, + // TRANS: %3$s is a URL to post notices at, %4$s is the StatusNet sitename. $body = sprintf(_("%1\$s (%2\$s) is wondering what you are up to ". "these days and is inviting you to post some news.\n\n". "So let's hear from you :)\n\n". @@ -516,7 +527,6 @@ function mail_notify_nudge($from, $to) * * @return boolean success code */ - function mail_notify_message($message, $from=null, $to=null) { if (is_null($from)) { @@ -532,12 +542,16 @@ function mail_notify_message($message, $from=null, $to=null) } common_switch_locale($to->language); - // TRANS: Subject for direct-message notification email + // TRANS: Subject for direct-message notification email. + // TRANS: %s is the sending user's nickname. $subject = sprintf(_('New private message from %s'), $from->nickname); $from_profile = $from->getProfile(); - // TRANS: Body for direct-message notification email + // TRANS: Body for direct-message notification email. + // TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname, + // TRANS: %3$s is the message content, %4$s a URL to the message, + // TRANS: %5$s is the StatusNet sitename. $body = sprintf(_("%1\$s (%2\$s) sent you a private message:\n\n". "------------------------------------------------------\n". "%3\$s\n". @@ -572,7 +586,6 @@ function mail_notify_message($message, $from=null, $to=null) * * @return void */ - function mail_notify_fave($other, $user, $notice) { if (!$user->hasRight(Right::EMAILONFAVE)) { @@ -585,10 +598,15 @@ function mail_notify_fave($other, $user, $notice) common_switch_locale($other->language); - // TRANS: Subject for favorite notification email - $subject = sprintf(_('%s (@%s) added your notice as a favorite'), $bestname, $user->nickname); + // TRANS: Subject for favorite notification e-mail. + // TRANS: %1$s is the adding user's long name, %2$s is the adding user's nickname. + $subject = sprintf(_('%1s$ (@%2$s) added your notice as a favorite'), $bestname, $user->nickname); - // TRANS: Body for favorite notification email + // TRANS: Body for favorite notification e-mail. + // TRANS: %1$s is the adding user's long name, $2$s is the date the notice was created, + // TRANS: %3$s is a URL to the faved notice, %4$s is the faved notice text, + // TRANS: %5$s is a URL to all faves of the adding user, %6$s is the StatusNet sitename, + // TRANS: %7$s is the adding user's nickname. $body = sprintf(_("%1\$s (@%7\$s) just added your notice from %2\$s". " as one of their favorites.\n\n" . "The URL of your notice is:\n\n" . @@ -623,7 +641,6 @@ function mail_notify_fave($other, $user, $notice) * * @return void */ - function mail_notify_attn($user, $notice) { if (!$user->email || !$user->emailnotifyattn) { @@ -654,9 +671,16 @@ function mail_notify_attn($user, $notice) $conversationEmailText = ''; } - $subject = sprintf(_('%s (@%s) sent a notice to your attention'), $bestname, $sender->nickname); + // TRANS: E-mail subject for notice notification. + // TRANS: %1$s is the sending user's long name, %2$s is the adding user's nickname. + $subject = sprintf(_('%1$s (@%2$s) sent a notice to your attention'), $bestname, $sender->nickname); // TRANS: Body of @-reply notification e-mail. + // TRANS: %1$s is the sending user's long name, $2$s is the StatusNet sitename, + // TRANS: %3$s is a URL to the notice, %4$s is the notice text, + // TRANS: %5$s is a URL to the full conversion if it exists (otherwise empty), + // TRANS: %6$s is a URL to reply to the notice, %7$s is a URL to all @-replied for the addressed user, + // TRANS: %8$s is a URL to the addressed user's e-mail settings, %9$s is the sender's nickname. $body = sprintf(_("%1\$s (@%9\$s) just sent a notice to your attention (an '@-reply') on %2\$s.\n\n". "The notice is here:\n\n". "\t%3\$s\n\n" . @@ -709,4 +733,3 @@ function _mail_prepare_headers($msg_type, $to, $from) return $headers; } - -- cgit v1.2.3-54-g00ecf From 25b9552ec3e7606b2d054fba10428c6cef38b971 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Wed, 20 Oct 2010 00:53:42 +0200 Subject: More complete sentence and translator documentation added. --- lib/webcolor.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/webcolor.php b/lib/webcolor.php index 6fa603fa2..7f264c674 100644 --- a/lib/webcolor.php +++ b/lib/webcolor.php @@ -32,7 +32,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { } class WebColor { - // XXX: Maybe make getters and setters for r,g,b values and tuples, // e.g.: to support this kinda CSS representation: rgb(255,0,0) // http://www.w3.org/TR/CSS21/syndata.html#color-units @@ -65,7 +64,6 @@ class WebColor { * * @return nothing */ - function parseColor($color) { if (is_numeric($color)) { @@ -90,13 +88,11 @@ class WebColor { * * @return nothing */ - function setNamedColor($name) { // XXX Implement this } - /** * Sets the RGB color values from a a hex tuple * @@ -104,7 +100,6 @@ class WebColor { * * @return nothing */ - function setHexColor($hexcolor) { if ($hexcolor[0] == '#') { @@ -120,7 +115,9 @@ class WebColor { $hexcolor[1].$hexcolor[1], $hexcolor[2].$hexcolor[2]); } else { - $errmsg = _('%s is not a valid color! Use 3 or 6 hex chars.'); + // TRANS: Validation error for a web colour. + // TRANS: %s is the provided (invalid) text for colour. + $errmsg = _('%s is not a valid color! Use 3 or 6 hex characters.'); throw new WebColorException(sprintf($errmsg, $hexcolor)); } @@ -137,7 +134,6 @@ class WebColor { * * @return nothing */ - function setIntColor($intcolor) { // We could do 32 bit and have an alpha channel because @@ -154,7 +150,6 @@ class WebColor { * * @return string */ - function hexValue() { $hexcolor = (strlen(dechex($this->red)) < 2 ? '0' : '' ) . @@ -165,7 +160,6 @@ class WebColor { dechex($this->blue); return strtoupper($hexcolor); - } /** @@ -176,7 +170,6 @@ class WebColor { * * @return int */ - function intValue() { $intcolor = 256 * 256 * $this->red + 256 * $this->green + $this->blue; @@ -188,5 +181,3 @@ class WebColor { class WebColorException extends Exception { } - -?> \ No newline at end of file -- cgit v1.2.3-54-g00ecf From e8b6d7c946da5fb2ce5397bccfd332de8ca1f9dd Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 19 Oct 2010 20:54:53 -0700 Subject: 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 --- actions/apioauthaccesstoken.php | 4 +- actions/apioauthauthorize.php | 15 --- actions/apistatusesupdate.php | 1 - actions/oauthconnectionssettings.php | 99 ++++++++------ classes/Oauth_application_user.php | 41 +++++- classes/Profile.php | 10 +- classes/statusnet.ini | 3 +- db/statusnet.sql | 4 +- lib/apiauth.php | 4 +- lib/apioauthstore.php | 53 ++++++-- lib/applicationlist.php | 248 +++++++++++++++++++++++++++-------- 11 files changed, 339 insertions(+), 143 deletions(-) (limited to 'lib') diff --git a/actions/apioauthaccesstoken.php b/actions/apioauthaccesstoken.php index 6b36d1919..21e0049ce 100644 --- a/actions/apioauthaccesstoken.php +++ b/actions/apioauthaccesstoken.php @@ -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 { diff --git a/actions/apioauthauthorize.php b/actions/apioauthauthorize.php index eb1000e25..01cbca18f 100644 --- a/actions/apioauthauthorize.php +++ b/actions/apioauthauthorize.php @@ -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(); diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index 4715f7002..91dcdd10f 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -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; diff --git a/actions/oauthconnectionssettings.php b/actions/oauthconnectionssettings.php index 1fa70662f..72624de84 100644 --- a/actions/oauthconnectionssettings.php +++ b/actions/oauthconnectionssettings.php @@ -22,7 +22,7 @@ * @category Settings * @package StatusNet * @author Zach Copley - * @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(); - - $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'); + $cur = common_current_user(); + + $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'); } } diff --git a/classes/Oauth_application_user.php b/classes/Oauth_application_user.php index 3d4238d64..fcf6553ff 100644 --- a/classes/Oauth_application_user.php +++ b/classes/Oauth_application_user.php @@ -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; + } } diff --git a/classes/Profile.php b/classes/Profile.php index 12ce5d9b6..a32051d07 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -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() diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 3fb8ee208..7aa115fec 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -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 diff --git a/db/statusnet.sql b/db/statusnet.sql index 3f95948e1..4ae7e5684 100644 --- a/db/statusnet.sql +++ b/db/statusnet.sql @@ -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 */ diff --git a/lib/apiauth.php b/lib/apiauth.php index a1c698bba..0ebd7aa10 100644 --- a/lib/apiauth.php +++ b/lib/apiauth.php @@ -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); diff --git a/lib/apioauthstore.php b/lib/apioauthstore.php index 6e0039bdd..e30eea129 100644 --- a/lib/apioauthstore.php +++ b/lib/apioauthstore.php @@ -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)) { diff --git a/lib/applicationlist.php b/lib/applicationlist.php index 8b6e3a8ad..6801fb6cf 100644 --- a/lib/applicationlist.php +++ b/lib/applicationlist.php @@ -22,7 +22,7 @@ * @category Application * @package StatusNet * @author Zach Copley - * @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,58 @@ 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!"); - } + /* Override this in subclasses. */ + function showOwnerControls() + { + return; + } - $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'); - } +} + + +/** + * Widget to show a list of connected OAuth clients + * + * @category Application + * @package StatusNet + * @author Zach Copley + * @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. */ @@ -166,4 +182,124 @@ class ApplicationList extends Widget { 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'); + + } } -- cgit v1.2.3-54-g00ecf From 1459110124c012364800484cd3677f754917de63 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Wed, 20 Oct 2010 11:16:21 +0200 Subject: Fix nasty bug in parameter for e-mail notification for favourite. --- lib/mail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mail.php b/lib/mail.php index 3703e5c35..30d743848 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -600,7 +600,7 @@ function mail_notify_fave($other, $user, $notice) // TRANS: Subject for favorite notification e-mail. // TRANS: %1$s is the adding user's long name, %2$s is the adding user's nickname. - $subject = sprintf(_('%1s$ (@%2$s) added your notice as a favorite'), $bestname, $user->nickname); + $subject = sprintf(_('%1$s (@%2$s) added your notice as a favorite'), $bestname, $user->nickname); // TRANS: Body for favorite notification e-mail. // TRANS: %1$s is the adding user's long name, $2$s is the date the notice was created, -- cgit v1.2.3-54-g00ecf From dc62cf1c0b6f77ebd4e4bf885aa3de7846b3232a Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Wed, 20 Oct 2010 19:34:27 +0200 Subject: * i18n/L10n fixes. * translator documentation updated/added. * superfluous whitespace removed. --- actions/apioauthaccesstoken.php | 3 +-- actions/apioauthauthorize.php | 46 +++++++++++++++++++++++------------- actions/apistatusesupdate.php | 35 +++++++++++++-------------- actions/oauthconnectionssettings.php | 21 ++++++++++------ lib/apiauth.php | 5 ++-- lib/apioauthstore.php | 9 ++++--- lib/applicationlist.php | 9 ++++--- 7 files changed, 70 insertions(+), 58 deletions(-) (limited to 'lib') diff --git a/actions/apioauthaccesstoken.php b/actions/apioauthaccesstoken.php index 21e0049ce..59abcf812 100644 --- a/actions/apioauthaccesstoken.php +++ b/actions/apioauthaccesstoken.php @@ -44,7 +44,6 @@ require_once INSTALLDIR . '/lib/apioauth.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiOauthAccessTokenAction extends ApiOauthAction { protected $reqToken = null; @@ -73,7 +72,6 @@ class ApiOauthAccessTokenAction extends ApiOauthAction // Spec doesn't say they MUST be. try { - $req = OAuthRequest::from_request(); $this->reqToken = $req->get_parameter('oauth_token'); @@ -100,6 +98,7 @@ class ApiOauthAccessTokenAction extends ApiOauthAction ); 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 { diff --git a/actions/apioauthauthorize.php b/actions/apioauthauthorize.php index 01cbca18f..0e61cdf2c 100644 --- a/actions/apioauthauthorize.php +++ b/actions/apioauthauthorize.php @@ -43,7 +43,6 @@ require_once INSTALLDIR . '/lib/info.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiOauthAuthorizeAction extends Action { var $oauthTokenParam; @@ -106,6 +105,7 @@ class ApiOauthAuthorizeAction extends Action // Make sure a oauth_token parameter was provided if (empty($this->oauthTokenParam)) { + // TRANS: Client error given when no oauth_token was passed to the OAuth API. $this->clientError(_('No oauth_token parameter provided.')); } else { @@ -113,11 +113,13 @@ class ApiOauthAuthorizeAction extends Action $this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam); if (empty($this->reqToken)) { + // TRANS: Client error given when an invalid request token was passed to the OAuth API. $this->clientError(_('Invalid request token.')); } else { // Check to make sure we haven't already authorized the token if ($this->reqToken->state != 0) { + // TRANS: Client error given when an invalid request token was passed to the OAuth API. $this->clientError(_("Invalid request token.")); } } @@ -125,6 +127,7 @@ class ApiOauthAuthorizeAction extends Action // make sure there's an app associated with this token if (empty($this->app)) { + // TRANS: Client error given when an invalid request token was passed to the OAuth API. $this->clientError(_('Invalid request token.')); } @@ -158,6 +161,7 @@ class ApiOauthAuthorizeAction extends Action $user = common_check_user($this->nickname, $this->password); if (empty($user)) { + // TRANS: Form validation error given when an invalid username and/or password was passed to the OAuth API. $this->showForm(_("Invalid nickname / password!")); return; } @@ -198,6 +202,7 @@ class ApiOauthAuthorizeAction extends Action if (!$result) { common_log_db_error($appUser, 'INSERT', __FILE__); + // TRANS: Server error given when a database error occurs inserting an OAuth application user. $this->serverError(_('Database error inserting OAuth application user.')); } @@ -211,7 +216,6 @@ class ApiOauthAuthorizeAction extends Action } if (!empty($this->callback)) { - $targetUrl = $this->getCallback( $this->callback, array( @@ -222,9 +226,7 @@ class ApiOauthAuthorizeAction extends Action // Redirect the user to the provided OAuth callback common_redirect($targetUrl, 303); - } elseif ($this->app->type == 2) { - // Strangely, a web application seems to want to do the OOB // workflow. Because no callback was specified anywhere. common_log( @@ -261,6 +263,7 @@ class ApiOauthAuthorizeAction extends Action } } else { + // TRANS: Client error given on when invalid data was passed through a form in the OAuth API. $this->clientError(_('Unexpected form submission.')); } } @@ -287,6 +290,7 @@ class ApiOauthAuthorizeAction extends Action function title() { + // TRANS: Title for a page where a user can confirm/deny account access by an external application. return _('An application would like to connect to your account'); } @@ -304,6 +308,7 @@ class ApiOauthAuthorizeAction extends Action 'action' => common_local_url('ApiOauthAuthorize'))); $this->elementStart('fieldset'); $this->element('legend', array('id' => 'apioauthauthorize_allowdeny'), + // TRANS: Fieldset legend. _('Allow or deny access')); $this->hidden('token', common_session_token()); @@ -320,6 +325,9 @@ class ApiOauthAuthorizeAction extends Action $access = ($this->app->access_type & Oauth_application::$writeAccess) ? 'access and update' : 'access'; + // TRANS: User notification of external application requesting account access. + // TRANS: %1$s is the application name requesting access, %2$s is the organisation behind the application, + // TRANS: %3$s is the access type requested, %4$s is the StatusNet sitename. $msg = _('The application %1$s by ' . '%2$s would like the ability ' . 'to %3$s your %4$s account data. ' . @@ -336,33 +344,37 @@ class ApiOauthAuthorizeAction extends Action $this->elementEnd('ul'); if (!common_logged_in()) { - $this->elementStart('fieldset'); - $this->element('legend', null, _('Account')); + // TRANS: Fieldset legend. + $this->element('legend', null, _m('LEGEND','Account')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); + // TRANS: Field label on OAuth API authorisation form. $this->input('nickname', _('Nickname')); $this->elementEnd('li'); $this->elementStart('li'); + // TRANS: Field label on OAuth API authorisation form. $this->password('password', _('Password')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->elementEnd('fieldset'); - } $this->element('input', array('id' => 'cancel_submit', 'class' => 'submit submit form_action-primary', 'name' => 'cancel', 'type' => 'submit', - 'value' => _('Cancel'))); + // TRANS: Button text that when clicked will cancel the process of allowing access to an account + // TRANS: by an external application. + 'value' => _m('BUTTON','Cancel'))); $this->element('input', array('id' => 'allow_submit', 'class' => 'submit submit form_action-secondary', 'name' => 'allow', 'type' => 'submit', - 'value' => _('Allow'))); + // TRANS: Button text that when clicked will allow access to an account by an external application. + 'value' => _m('BUTTON','Allow'))); $this->elementEnd('fieldset'); $this->elementEnd('form'); @@ -376,9 +388,9 @@ class ApiOauthAuthorizeAction extends Action * * @return void */ - function getInstructions() { + // TRANS: Form instructions. return _('Authorize access to your account information.'); } @@ -389,7 +401,6 @@ class ApiOauthAuthorizeAction extends Action * * @return void */ - function showLocalNav() { // NOP @@ -400,7 +411,6 @@ class ApiOauthAuthorizeAction extends Action * * @return nothing */ - function showSiteNotice() { // NOP @@ -413,7 +423,6 @@ class ApiOauthAuthorizeAction extends Action * * @return nothing */ - function showNoticeForm() { // NOP @@ -425,12 +434,14 @@ class ApiOauthAuthorizeAction extends Action * * @return nothing */ - function showCanceled() { $info = new InfoAction( + // TRANS: Header for user notification after revoking OAuth access to an application. _('Authorization canceled.'), sprintf( + // TRANS: User notification after revoking OAuth access to an application. + // TRANS: %s is an OAuth token. _('The request token %s has been revoked.'), $this->oauthTokenParm ) @@ -445,15 +456,18 @@ class ApiOauthAuthorizeAction extends Action * * @return nothing */ - function showAuthorized() { $title = sprintf( + // TRANS: Header of user notification after authorising an application access to a profile. + // TRANS: %s is the authorised application name. _("You have successfully authorized %s."), $this->app->name ); $msg = sprintf( + // TRANS: Uer notification after authorising an application access to a profile. + // TRANS: %s is the authorised application name. _('Please return to %s and enter the following security code to complete the process.'), $this->app->name ); @@ -488,7 +502,6 @@ class ApiOauthAuthorizeAction extends Action * * @return string $url a URL to use for redirecting to */ - function getCallback($url, $params) { foreach ($params as $k => $v) { @@ -512,7 +525,6 @@ class ApiOauthAuthorizeAction extends Action * * @return string $url the new URL with added parameter */ - function appendQueryVar($url, $k, $v) { $url = preg_replace('/(.*)(\?|&)' . $k . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&'); $url = substr($url, 0, -1); diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index 91dcdd10f..822ebacbd 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -147,7 +147,6 @@ require_once INSTALLDIR . '/lib/mediafile.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class ApiStatusesUpdateAction extends ApiAuthAction { var $status = null; @@ -163,7 +162,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction * @return boolean success flag * */ - function prepare($args) { parent::prepare($args); @@ -187,7 +185,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction * * @return void */ - function handle($args) { parent::handle($args); @@ -209,8 +206,11 @@ class ApiStatusesUpdateAction extends ApiAuthAction && empty($_POST) && ($_SERVER['CONTENT_LENGTH'] > 0) ) { - $msg = _('The server was unable to handle that much POST ' . - 'data (%s bytes) due to its current configuration.'); + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; @@ -218,6 +218,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction if (empty($this->status)) { $this->clientError( + // TRANS: Client error displayed when the parameter "status" is missing. _('Client must provide a \'status\' parameter with a value.'), 400, $this->format @@ -239,7 +240,11 @@ class ApiStatusesUpdateAction extends ApiAuthAction $this->clientError( sprintf( - _('That\'s too long. Max notice size is %d chars.'), + // TRANS: Client error displayed when the parameter "status" is missing. + // TRANS: %d is the maximum number of character for a notice. + _m('That\'s too long. Maximum notice size is %d character.', + 'That\'s too long. Maximum notice size is %d characters.', + Notice::maxContent()), Notice::maxContent() ), 406, @@ -255,7 +260,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction $cmd = $inter->handle_command($this->auth_user, $status_shortened); if ($cmd) { - if ($this->supported($cmd)) { $cmd->execute(new Channel()); } @@ -265,13 +269,10 @@ class ApiStatusesUpdateAction extends ApiAuthAction // or not! $this->notice = $this->auth_user->getCurrentNotice(); - } else { - $reply_to = null; if (!empty($this->in_reply_to_status_id)) { - // Check whether notice actually exists $reply = Notice::staticGet($this->in_reply_to_status_id); @@ -280,7 +281,8 @@ class ApiStatusesUpdateAction extends ApiAuthAction $reply_to = $this->in_reply_to_status_id; } else { $this->clientError( - _('Not found.'), + // TRANS: Client error displayed when replying to a non-existing notice. + _('Parent notice not found.'), $code = 404, $this->format ); @@ -302,10 +304,9 @@ class ApiStatusesUpdateAction extends ApiAuthAction if (Notice::contentTooLong($status_shortened)) { $upload->delete(); - $msg = _( - 'Max notice size is %d chars, ' . - 'including attachment URL.' - ); + $msg = _m('Maximum notice size is %d character, including attachment URL.', + 'Maximum notice size is %d characters, including attachment URL.', + Notice::maxContent()); $this->clientError( sprintf($msg, Notice::maxContent()), 400, @@ -344,7 +345,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction if (isset($upload)) { $upload->attachToNotice($this->notice); } - } $this->showNotice(); @@ -355,7 +355,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction * * @return void */ - function showNotice() { if (!empty($this->notice)) { @@ -374,7 +373,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction * * @return boolean true or false */ - function supported($cmd) { static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand', @@ -386,5 +384,4 @@ class ApiStatusesUpdateAction extends ApiAuthAction return false; } - } diff --git a/actions/oauthconnectionssettings.php b/actions/oauthconnectionssettings.php index 0590b729c..9a7cda924 100644 --- a/actions/oauthconnectionssettings.php +++ b/actions/oauthconnectionssettings.php @@ -46,10 +46,8 @@ require_once INSTALLDIR . '/lib/apioauthstore.php'; * * @see SettingsAction */ - class OauthconnectionssettingsAction extends ConnectSettingsAction { - var $page = null; var $oauth_token = null; @@ -69,6 +67,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction function title() { + // TRANS: Title for OAuth connection settings. return _('Connected applications'); } @@ -80,6 +79,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction function getInstructions() { + // TRANS: Instructions for OAuth connection settings. return _('The following connections exist for your account.'); } @@ -129,7 +129,6 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction * * @return void */ - function handlePost() { // CSRF protection @@ -144,6 +143,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction if ($this->arg('revoke')) { $this->revokeAccess($this->oauth_token); } else { + // TRANS: Client error when submitting a form with unexpected information. $this->clientError(_('Unexpected form submission.'), 401); return false; } @@ -157,7 +157,6 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction * @param int $appId the ID of the application * */ - function revokeAccess($token) { $cur = common_current_user(); @@ -165,6 +164,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction $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; } @@ -178,7 +178,9 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction if (!$result) { common_log_db_error($orig, 'DELETE', __FILE__); - $this->clientError(sprintf(_('Unable to revoke access for app: %s.'), $app->id)); + // 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; } @@ -195,7 +197,9 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction ); $msg = sprintf( - _('You have successfully revoked access for %s and the access token starting with %s'), + // TRANS: Success message after revoking access for an application. + // TRANS: %1$s is the application name, %2$s is the first part of the user token. + _('You have successfully revoked access for %1$s and the access token starting with %2$s.'), $app->name, substr($appUser->token, 0, 7) ); @@ -205,6 +209,7 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction function showEmptyListMessage() { + // TRANS: Empty list message when no applications have been authorised yet. $message = _('You have not authorized any applications to use your account.'); $this->elementStart('div', 'guide'); @@ -222,6 +227,9 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction $this->elementStart('p'); $devMsg = sprintf( + // TRANS: Note for developers in the OAuth connection settings form. + // TRANS: This message contains a Markdown link. Do not separate "](". + // TRANS: %s is the URL to the OAuth settings. _('Are you a developer? [Register an OAuth client application](%s) to use with this instance of StatusNet.'), common_local_url('oauthappssettings') ); @@ -233,5 +241,4 @@ class OauthconnectionssettingsAction extends ConnectSettingsAction $this->elementEnd('section'); } - } diff --git a/lib/apiauth.php b/lib/apiauth.php index 0ebd7aa10..1dacf1409 100644 --- a/lib/apiauth.php +++ b/lib/apiauth.php @@ -263,7 +263,7 @@ class ApiAuthAction extends ApiAction // show error if the user clicks 'cancel' // TRANS: Client error thrown when authentication fails becaus a user clicked "Cancel". - $this->clientError(_("Could not authenticate you."), 401, $this->format); + $this->clientError(_('Could not authenticate you.'), 401, $this->format); exit; } else { @@ -290,7 +290,7 @@ class ApiAuthAction extends ApiAction ); $this->logAuthFailure($msg); // TRANS: Client error thrown when authentication fails. - $this->clientError(_("Could not authenticate you."), 401, $this->format); + $this->clientError(_('Could not authenticate you.'), 401, $this->format); exit; } } @@ -342,7 +342,6 @@ class ApiAuthAction extends ApiAction * * @param string $logMsg additional log message */ - function logAuthFailure($logMsg) { list($proxy, $ip) = common_client_ip(); diff --git a/lib/apioauthstore.php b/lib/apioauthstore.php index e30eea129..76df6c1ed 100644 --- a/lib/apioauthstore.php +++ b/lib/apioauthstore.php @@ -37,7 +37,8 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore $con->consumer_secret = $consumerKey; $result = $con->insert(); if (!$result) { - $this->serverError(_("Could not create anonymous consumer.")); + // TRANS: Server error displayed when trying to create an anynymous OAuth consumer. + $this->serverError(_('Could not create anonymous consumer.')); } $app = new OAuth_application(); $app->consumer_key = $con->consumer_key; @@ -49,7 +50,8 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore $app->access_type = 3; // read + write $id = $app->insert(); if (!$id) { - $this->serverError(_("Could not create anonymous OAuth application.")); + // TRANS: Server error displayed when trying to create an anynymous OAuth application. + $this->serverError(_('Could not create anonymous OAuth application.')); } } else { return null; @@ -230,7 +232,6 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore * * @return OAuthToken $token a new unauthorized OAuth request token */ - function new_request_token($consumer, $callback) { $t = new Token(); @@ -255,6 +256,4 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore return new OAuthToken($t->tok, $t->secret); } } - - } diff --git a/lib/applicationlist.php b/lib/applicationlist.php index 6801fb6cf..ff9ac5a20 100644 --- a/lib/applicationlist.php +++ b/lib/applicationlist.php @@ -142,10 +142,8 @@ class ApplicationList extends Widget { return; } - } - /** * Widget to show a list of connected OAuth clients * @@ -279,7 +277,9 @@ class ConnectedAppsList extends Widget $this->out->element( 'p', array( 'class' => 'access_token'), - _('Access token starting with: ') . substr($this->connection->token, 0, 7) + // TRANS: Access token in the application list. + // TRANS: %s are the first 7 characters of the access token. + sprintf(_('Access token starting with: %s'), substr($this->connection->token, 0, 7)) ); $this->out->elementStart( @@ -295,11 +295,10 @@ class ConnectedAppsList extends Widget $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->submit('revoke', _m('BUTTON','Revoke')); $this->out->elementEnd('fieldset'); $this->out->elementEnd('form'); $this->out->elementEnd('li'); - } } -- cgit v1.2.3-54-g00ecf From e980da3d20b5f18bd10e4c25e97366de84255867 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Wed, 20 Oct 2010 20:01:12 +0200 Subject: Add FIXME --- lib/applicationlist.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/applicationlist.php b/lib/applicationlist.php index ff9ac5a20..3f50f110b 100644 --- a/lib/applicationlist.php +++ b/lib/applicationlist.php @@ -243,7 +243,7 @@ class ConnectedAppsList extends Widget $this->out->elementEnd('span'); if ($app->name != 'anonymous') { - + // @todo FIXME: i18n trouble. $this->out->raw(_(' by ')); $this->out->element( -- cgit v1.2.3-54-g00ecf From 8004e2809d98bdd535a3c59bd7d15c3fa2dd7ba9 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 20 Oct 2010 14:34:25 -0700 Subject: Fix for ticket #2845: singleuser nickname configuration was being overridden by site owner in router setup. I've consolidated the checks for which user to use for single-user mode into User::singleUser(), which now uses the configured nickname by preference, falling back to the site owner if it's unset. This is now called consistently from the places that needed to use the primary user's nickname in routing setup. Setting $config['singleuser']['nickname'] should now work again as expected. --- README | 3 ++- classes/User.php | 29 +++++++++++++++++++++++++++++ lib/action.php | 3 ++- lib/router.php | 12 ++---------- lib/util.php | 3 ++- 5 files changed, 37 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/README b/README index 26a9fe4ec..43a9bb5e9 100644 --- a/README +++ b/README @@ -1486,7 +1486,8 @@ If an installation has only one user, this can simplify a lot of the interface. It also makes the user's profile the root URL. enabled: Whether to run in "single user mode". Default false. -nickname: nickname of the single user. +nickname: nickname of the single user. If no nickname is specified, + the site owner account will be used (if present). robotstxt --------- diff --git a/classes/User.php b/classes/User.php index e784fd9e9..c68be223d 100644 --- a/classes/User.php +++ b/classes/User.php @@ -875,4 +875,33 @@ class User extends Memcached_DataObject return $owner; } + + /** + * Pull the primary site account to use in single-user mode. + * If a valid user nickname is listed in 'singleuser':'nickname' + * in the config, this will be used; otherwise the site owner + * account is taken by default. + * + * @return User + * @throws ServerException if no valid single user account is present + * @throws ServerException if called when not in single-user mode + */ + static function singleUser() + { + if (common_config('singleuser', 'enabled')) { + $nickname = common_config('singleuser', 'nickname'); + if ($nickname) { + $user = User::staticGet('nickname', $nickname); + } else { + $user = User::siteOwner(); + } + if ($user) { + return $user; + } else { + throw new ServerException(_("No single user defined for single-user mode.")); + } + } else { + throw new ServerException(_('Single-user mode code called when not enabled.')); + } + } } diff --git a/lib/action.php b/lib/action.php index 55ee83bde..e273b5d04 100644 --- a/lib/action.php +++ b/lib/action.php @@ -419,8 +419,9 @@ class Action extends HTMLOutputter // lawsuit 'class' => 'vcard')); if (Event::handle('StartAddressData', array($this))) { if (common_config('singleuser', 'enabled')) { + $user = User::singleUser(); $url = common_local_url('showstream', - array('nickname' => common_config('singleuser', 'nickname'))); + array('nickname' => $user->nickname)); } else { $url = common_local_url('public'); } diff --git a/lib/router.php b/lib/router.php index b1cc8d529..8c682cefa 100644 --- a/lib/router.php +++ b/lib/router.php @@ -701,16 +701,8 @@ class Router if (common_config('singleuser', 'enabled')) { - $user = User::siteOwner(); - - if (!empty($user)) { - $nickname = $user->nickname; - } else { - $nickname = common_config('singleuser', 'nickname'); - if (empty($nickname)) { - throw new ServerException(_("No single user defined for single-user mode.")); - } - } + $user = User::singleUser(); + $nickname = $user->nickname; foreach (array('subscriptions', 'subscribers', 'all', 'foaf', 'xrds', diff --git a/lib/util.php b/lib/util.php index 5a94182bd..86380af28 100644 --- a/lib/util.php +++ b/lib/util.php @@ -974,8 +974,9 @@ function common_tag_link($tag) $canonical = common_canonical_tag($tag); if (common_config('singleuser', 'enabled')) { // regular TagAction isn't set up in 1user mode + $user = User::singleUser(); $url = common_local_url('showstream', - array('nickname' => common_config('singleuser', 'nickname'), + array('nickname' => $user->nickname, 'tag' => $canonical)); } else { $url = common_local_url('tag', array('tag' => $canonical)); -- cgit v1.2.3-54-g00ecf From 28ec9d64632a7a43be9144a474432a3c5b8d6b97 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Thu, 21 Oct 2010 01:12:56 +0200 Subject: * translator documentation added. * moved some translator comments that were not directly above the line with the message to the correct location. * i18n for UI text. * superfluous whitespace removed. --- classes/User.php | 4 +++- lib/action.php | 6 +++--- lib/router.php | 8 ++------ 3 files changed, 8 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/classes/User.php b/classes/User.php index c68be223d..f381ec607 100644 --- a/classes/User.php +++ b/classes/User.php @@ -898,9 +898,11 @@ class User extends Memcached_DataObject if ($user) { return $user; } else { - throw new ServerException(_("No single user defined for single-user mode.")); + // TRANS: Server exception. + throw new ServerException(_('No single user defined for single-user mode.')); } } else { + // TRANS: Server exception. throw new ServerException(_('Single-user mode code called when not enabled.')); } } diff --git a/lib/action.php b/lib/action.php index e273b5d04..3d7d1d808 100644 --- a/lib/action.php +++ b/lib/action.php @@ -527,20 +527,20 @@ class Action extends HTMLOutputter // lawsuit } // TRANS: Tooltip for main menu option "Login" $tooltip = _m('TOOLTIP', 'Login to the site'); - // TRANS: Main menu option when not logged in to log in $this->menuItem(common_local_url('login'), + // TRANS: Main menu option when not logged in to log in _m('MENU', 'Login'), $tooltip, false, 'nav_login'); } // TRANS: Tooltip for main menu option "Help" $tooltip = _m('TOOLTIP', 'Help me!'); - // TRANS: Main menu option for help on the StatusNet site $this->menuItem(common_local_url('doc', array('title' => 'help')), + // TRANS: Main menu option for help on the StatusNet site _m('MENU', 'Help'), $tooltip, false, 'nav_help'); if ($user || !common_config('site', 'private')) { // TRANS: Tooltip for main menu option "Search" $tooltip = _m('TOOLTIP', 'Search for people or text'); - // TRANS: Main menu option when logged in or when the StatusNet instance is not private $this->menuItem(common_local_url('peoplesearch'), + // TRANS: Main menu option when logged in or when the StatusNet instance is not private _m('MENU', 'Search'), $tooltip, false, 'nav_search'); } Event::handle('EndPrimaryNav', array($this)); diff --git a/lib/router.php b/lib/router.php index 8c682cefa..417206e6b 100644 --- a/lib/router.php +++ b/lib/router.php @@ -34,7 +34,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { require_once 'Net/URL/Mapper.php'; class StatusNet_URL_Mapper extends Net_URL_Mapper { - private static $_singleton = null; private function __construct() @@ -71,7 +70,6 @@ class StatusNet_URL_Mapper extends Net_URL_Mapper { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class Router { var $m = null; @@ -692,7 +690,6 @@ class Router $m->connect('admin/snapshot', array('action' => 'snapshotadminpanel')); $m->connect('admin/license', array('action' => 'licenseadminpanel')); - $m->connect('getfile/:filename', array('action' => 'getfile'), array('filename' => '[A-Za-z0-9._-]+')); @@ -757,9 +754,7 @@ class Router $m->connect('', array('action' => 'showstream', 'nickname' => $nickname)); - } else { - $m->connect('', array('action' => 'public')); $m->connect('rss', array('action' => 'publicrss')); $m->connect('featuredrss', array('action' => 'featuredrss')); @@ -840,7 +835,8 @@ class Router } catch (Net_URL_Mapper_InvalidException $e) { common_log(LOG_ERR, "Problem getting route for $path - " . $e->getMessage()); - $cac = new ClientErrorAction("Page not found.", 404); + // TRANS: Client error on action trying to visit a non-existing page. + $cac = new ClientErrorAction(_('Page not found.'), 404); $cac->showPage(); } -- cgit v1.2.3-54-g00ecf From e56385a7bb25336a72c1d37ad43d51ba8e238231 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 20 Oct 2010 17:21:04 -0700 Subject: Use a new table (oauth_token_association) to associate authorized request tokins with OAuth client applications and profiles. --- actions/apioauthaccesstoken.php | 5 +- actions/apioauthauthorize.php | 54 +++++++---- classes/Oauth_token_association.php | 44 +++++++++ classes/statusnet.ini | 12 +++ db/statusnet.sql | 9 ++ lib/apioauthstore.php | 184 ++++++++++++++++++++++++------------ 6 files changed, 230 insertions(+), 78 deletions(-) create mode 100644 classes/Oauth_token_association.php (limited to 'lib') diff --git a/actions/apioauthaccesstoken.php b/actions/apioauthaccesstoken.php index 21e0049ce..d4bd493ee 100644 --- a/actions/apioauthaccesstoken.php +++ b/actions/apioauthaccesstoken.php @@ -78,7 +78,8 @@ class ApiOauthAccessTokenAction extends ApiOauthAction $this->reqToken = $req->get_parameter('oauth_token'); $this->verifier = $req->get_parameter('oauth_verifier'); - $app = $datastore->getAppByRequestToken($this->reqToken); + + $app = $datastore->getAppByRequestToken($this->reqToken); $atok = $server->fetch_access_token($req); } catch (Exception $e) { @@ -106,7 +107,7 @@ class ApiOauthAccessTokenAction extends ApiOauthAction common_log( LOG_INFO, sprintf( - "Issued now access token '%s' for application %d (%s).", + "Issued access token '%s' for application %d (%s).", $atok->key, $app->id, $app->name diff --git a/actions/apioauthauthorize.php b/actions/apioauthauthorize.php index 01cbca18f..51b130296 100644 --- a/actions/apioauthauthorize.php +++ b/actions/apioauthauthorize.php @@ -177,28 +177,24 @@ class ApiOauthAuthorizeAction extends Action $this->serverError($e->getMessage()); } - // associated the authorized req token with the user and the app + // XXX: Make sure we have a oauth_token_association table. The table + // is now in the main schema, but because it is being added with + // a point release, it's unlikely to be there. This code can be + // removed as of 1.0. + $this->ensureOauthTokenAssociationTable(); - $appUser = new Oauth_application_user(); + $tokenAssoc = new Oauth_token_association(); - $appUser->profile_id = $user->id; - $appUser->application_id = $this->app->id; + $tokenAssoc->profile_id = $user->id; + $tokenAssoc->application_id = $this->app->id; + $tokenAssoc->token = $this->oauthTokenParam; + $tokenAssoc->created = common_sql_now(); - // 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->oauthTokenParam; - $appUser->created = common_sql_now(); - - $result = $appUser->insert(); + $result = $tokenAssoc->insert(); if (!$result) { - common_log_db_error($appUser, 'INSERT', __FILE__); - $this->serverError(_('Database error inserting OAuth application user.')); + common_log_db_error($tokenAssoc, 'INSERT', __FILE__); + $this->serverError(_('Database error inserting oauth_token_association.')); } // If we have a callback redirect and provide the token @@ -265,6 +261,30 @@ class ApiOauthAuthorizeAction extends Action } } + // XXX Remove this function when we hit 1.0 + function ensureOauthTokenAssociationTable() + { + $schema = Schema::get(); + + $reqTokenCols = array( + new ColumnDef('profile_id', 'integer', null, true, 'PRI'), + new ColumnDef('application_id', 'integer', null, true, 'PRI'), + new ColumnDef('token', 'varchar', 255, true, 'PRI'), + new ColumnDef('created', 'datetime', null, false), + new ColumnDef( + 'modified', + 'timestamp', + null, + false, + null, + 'CURRENT_TIMESTAMP', + 'on update CURRENT_TIMESTAMP' + ) + ); + + $schema->ensureTable('oauth_token_association', $reqTokenCols); + } + function showForm($error=null) { $this->error = $error; diff --git a/classes/Oauth_token_association.php b/classes/Oauth_token_association.php new file mode 100644 index 000000000..051732712 --- /dev/null +++ b/classes/Oauth_token_association.php @@ -0,0 +1,44 @@ +profile_id = $user->id; + $oau->token = $token; + $oau->limit(1); + + $result = $oau->find(true); + + return empty($result) ? null : $oau; + } + +} + diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 3fb8ee208..ef631e28d 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -401,6 +401,18 @@ modified = 384 profile_id = K application_id = K +[oauth_token_association] +profile_id = 129 +application_id = 129 +token = 130 +created = 142 +modified = 384 + +[oauth_token_association__keys] +profile_id = K +application_id = K +token = K + [profile] id = 129 nickname = 130 diff --git a/db/statusnet.sql b/db/statusnet.sql index 3f95948e1..ac48e6253 100644 --- a/db/statusnet.sql +++ b/db/statusnet.sql @@ -237,6 +237,15 @@ create table oauth_application_user ( constraint primary key (profile_id, application_id) ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; +create table oauth_token_association ( + 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), + token varchar(255) 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, token) +) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; + /* These are used by JanRain OpenID library */ create table oid_associations ( diff --git a/lib/apioauthstore.php b/lib/apioauthstore.php index e30eea129..9a2608263 100644 --- a/lib/apioauthstore.php +++ b/lib/apioauthstore.php @@ -32,24 +32,41 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore // Create an anon consumer and anon application if one // doesn't exist already if ($consumerKey == 'anonymous') { + + common_debug("API OAuth - creating anonymous consumer"); $con = new Consumer(); $con->consumer_key = $consumerKey; $con->consumer_secret = $consumerKey; + $con->created = common_sql_now(); + $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.")); + + $app = Oauth_application::getByConsumerKey('anonymous'); + + if (!$app) { + + common_debug("API OAuth - creating anonymous application"); + $app = new OAuth_application(); + $app->owner = 1; // XXX: What to do here? + $app->consumer_key = $con->consumer_key; + $app->name = 'anonymous'; + $app->icon = 'default-avatar-stream.png'; // XXX: Fix this! + $app->description = "An anonymous application"; + // 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 + $app->type = 2; // desktop + $app->created = common_sql_now(); + + $id = $app->insert(); + + if (!$id) { + $this->serverError(_("Could not create anonymous OAuth application.")); + } } } else { return null; @@ -64,10 +81,12 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore function getAppByRequestToken($token_key) { - // Look up the full req tokenx - $req_token = $this->lookup_token(null, - 'request', - $token_key); + // Look up the full req token + $req_token = $this->lookup_token( + null, + 'request', + $token_key + ); if (empty($req_token)) { common_debug("couldn't get request token from oauth datastore"); @@ -85,7 +104,6 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore } // Look up the app - $app = new Oauth_application(); $app->consumer_key = $token->consumer_key; $result = $app->find(true); @@ -102,12 +120,12 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore { common_debug( sprintf( - "%s - New access token from request token %s, consumer %s and verifier %s ", - __FILE__, + "New access token from request token %s, consumer %s and verifier %s ", $token, $consumer, $verifier - ) + ), + __FILE__ ); $rt = new Token(); @@ -121,73 +139,121 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore if ($rt->find(true) && $rt->state == 1 && $rt->verifier == $verifier) { // authorized - common_debug('request token found.'); + common_debug('Request token found.', __FILE__); + + // find the app and profile associated with this token - // find the associated user of the app + $tokenAssoc = OAuth_token_association::staticGet('token', $rt->tok); + + if (!$tokenAssoc) { + throw new Exception( + _('Could not find a profile and application associated with the request token.') + ); + } + + // check to see if we have previously issued an access token for this application + // and profile $appUser = new Oauth_application_user(); $appUser->application_id = $app->id; - $appUser->token = $rt->tok; + $appUser->profile_id = $tokenAssoc->profile_id; $result = $appUser->find(true); if (!empty($result)) { - common_debug("Ouath app user found."); - } else { - common_debug("Oauth app user not found. app id $app->id token $rt->tok"); - return null; - } - // go ahead and make the access token + common_log(LOG_INFO, + sprintf( + "Existing access token found for application %s, profile %s.", + $app->id, + $tokenAssoc->profile_id + ) + ); - $at = new Token(); - $at->consumer_key = $consumer->key; - $at->tok = common_good_rand(16); - $at->secret = common_good_rand(16); - $at->type = 1; // access - $at->verifier = $verifier; - $at->verified_callback = $rt->verified_callback; // 1.0a - $at->created = DB_DataObject_Cast::dateTime(); + $at = new Token(); - if (!$at->insert()) { - $e = $at->_lastError; - common_debug('access token "'.$at->tok.'" not inserted: "'.$e->message.'"', __FILE__); - return null; - } else { - common_debug('access token "'.$at->tok.'" inserted', __FILE__); - // burn the old one - $orig_rt = clone($rt); - $rt->state = 2; // used - if (!$rt->update($orig_rt)) { - return null; + // fetch the full access token + $at->consumer_key = $consumer->key; + $at->tok = $appUser->token; + + $result = $at->find(true); + + if (!$result) { + throw new Exception( + _('Could not issue access token.') + ); } - common_debug('request token "'.$rt->tok.'" updated', __FILE__); - // update the token from req to access for the user + // Yay, we can re-issue the access token + return new OAuthToken($at->tok, $at->secret); - $orig = clone($appUser); + } else { - $appUser->token = $at->tok; + common_log(LOG_INFO, + sprintf( + "Creating new access token for application %s, profile %s.", + $app->id, + $tokenAssoc->profile_id + ) + ); + + // make a brand new access token + $at = new Token(); + + $at->consumer_key = $consumer->key; + $at->tok = common_good_rand(16); + $at->secret = common_good_rand(16); + $at->type = 1; // access + $at->verifier = $verifier; + $at->verified_callback = $rt->verified_callback; // 1.0a + $at->created = common_sql_now(); + + if (!$at->insert()) { + $e = $at->_lastError; + common_debug('access token "' . $at->tok . '" not inserted: "' . $e->message . '"', __FILE__); + return null; + } else { + common_debug('access token "' . $at->tok . '" inserted', __FILE__); + // burn the old one + $orig_rt = clone($rt); + $rt->state = 2; // used + if (!$rt->update($orig_rt)) { + return null; + } + common_debug('request token "' . $rt->tok . '" updated', __FILE__); + } - // It's at this point that we change the access type - // to whatever the application's access is. Request - // tokens should always have an access type of 0, and - // therefore be unuseable for making requests for - // protected resources. + // insert a new Oauth_application_user record w/access token + $appUser = new Oauth_application_user(); - $appUser->access_type = $app->access_type; + $appUser->profile_id = $tokenAssoc->profile_id;; + $appUser->application_id = $app->id; + $appUser->access_type = $app->access_type; + $appUser->token = $at->tok; + $appUser->created = common_sql_now(); - $result = $appUser->updateKeys($orig); + $result = $appUser->insert(); if (!$result) { - throw new Exception('Couldn\'t update OAuth app user.'); + common_log_db_error($appUser, 'INSERT', __FILE__); + $this->serverError(_('Database error inserting OAuth application user.')); } // Okay, good return new OAuthToken($at->tok, $at->secret); } + } else { + + // the token was not authorized or not verfied + common_log( + LOG_INFO, + sprintf( + "API OAuth - Attempt to exchange unauthorized or unverified request token %s for an access token.", + $rt->tok + ) + ); return null; } } -- cgit v1.2.3-54-g00ecf From fb12094f616c52674b9a0a719fd78469ae60a6e6 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Thu, 21 Oct 2010 03:10:46 +0200 Subject: i18n/L10n updates, translator docs updated, superfluous whitespace removed. --- actions/apioauthauthorize.php | 9 ++------- classes/Oauth_token_association.php | 2 -- lib/apioauthstore.php | 6 ++++-- lib/dberroraction.php | 1 - lib/feed.php | 1 - lib/feedlist.php | 1 - lib/groupsbymemberssection.php | 2 +- lib/groupsbypostssection.php | 2 +- lib/groupsection.php | 1 - lib/grouptagcloudsection.php | 3 ++- lib/xmppmanager.php | 15 +++++++++------ lib/xmppoutqueuehandler.php | 1 - 12 files changed, 19 insertions(+), 25 deletions(-) (limited to 'lib') diff --git a/actions/apioauthauthorize.php b/actions/apioauthauthorize.php index ca32c8540..013cca029 100644 --- a/actions/apioauthauthorize.php +++ b/actions/apioauthauthorize.php @@ -92,7 +92,6 @@ class ApiOauthAuthorizeAction extends Action * * @return void */ - function handle($args) { parent::handle($args); @@ -120,7 +119,7 @@ class ApiOauthAuthorizeAction extends Action // Check to make sure we haven't already authorized the token if ($this->reqToken->state != 0) { // TRANS: Client error given when an invalid request token was passed to the OAuth API. - $this->clientError(_("Invalid request token.")); + $this->clientError(_('Invalid request token.')); } } } @@ -202,6 +201,7 @@ class ApiOauthAuthorizeAction extends Action if (!$result) { common_log_db_error($tokenAssoc, 'INSERT', __FILE__); + // TRANS: Server error displayed when a database action fails. $this->serverError(_('Database error inserting oauth_token_association.')); } @@ -251,16 +251,13 @@ class ApiOauthAuthorizeAction extends Action // Otherwise, inform the user that the rt was authorized $this->showAuthorized(); - } else if ($this->arg('cancel')) { - try { $this->store->revoke_token($this->oauthTokenParam, 0); $this->showCanceled(); } catch (Exception $e) { $this->ServerError($e->getMessage()); } - } else { // TRANS: Client error given on when invalid data was passed through a form in the OAuth API. $this->clientError(_('Unexpected form submission.')); @@ -310,7 +307,6 @@ class ApiOauthAuthorizeAction extends Action * * @return string title of the page */ - function title() { // TRANS: Title for a page where a user can confirm/deny account access by an external application. @@ -322,7 +318,6 @@ class ApiOauthAuthorizeAction extends Action * * @return void */ - function showContent() { $this->elementStart('form', array('method' => 'post', diff --git a/classes/Oauth_token_association.php b/classes/Oauth_token_association.php index 051732712..66be22b5d 100644 --- a/classes/Oauth_token_association.php +++ b/classes/Oauth_token_association.php @@ -39,6 +39,4 @@ class Oauth_token_association extends Memcached_DataObject return empty($result) ? null : $oau; } - } - diff --git a/lib/apioauthstore.php b/lib/apioauthstore.php index 6b9b97756..a5e807d03 100644 --- a/lib/apioauthstore.php +++ b/lib/apioauthstore.php @@ -48,7 +48,6 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore $app = Oauth_application::getByConsumerKey('anonymous'); if (!$app) { - common_debug("API OAuth - creating anonymous application"); $app = new OAuth_application(); $app->owner = 1; // XXX: What to do here? @@ -66,7 +65,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore $id = $app->insert(); if (!$id) { - // TRANS: Server error displayed when trying to create an anynymous OAuth application. + // TRANS: Server error displayed when trying to create an anynymous OAuth application. $this->serverError(_("Could not create anonymous OAuth application.")); } } @@ -149,6 +148,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore if (!$tokenAssoc) { throw new Exception( + // TRANS: Exception thrown when no token association could be found. _('Could not find a profile and application associated with the request token.') ); } @@ -183,6 +183,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore if (!$result) { throw new Exception( + // TRANS: Exception thrown when no access token can be issued. _('Could not issue access token.') ); } @@ -239,6 +240,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore if (!$result) { common_log_db_error($appUser, 'INSERT', __FILE__); + // TRANS: Server error displayed when a database error occurs. $this->serverError(_('Database error inserting OAuth application user.')); } diff --git a/lib/dberroraction.php b/lib/dberroraction.php index 2cb66a022..0a6fce100 100644 --- a/lib/dberroraction.php +++ b/lib/dberroraction.php @@ -47,7 +47,6 @@ require_once INSTALLDIR.'/lib/servererroraction.php'; * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ */ - class DBErrorAction extends ServerErrorAction { function __construct($message='Error', $code=500) diff --git a/lib/feed.php b/lib/feed.php index e9fb6fdff..590265367 100644 --- a/lib/feed.php +++ b/lib/feed.php @@ -43,7 +43,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class Feed { const RSS1 = 1; diff --git a/lib/feedlist.php b/lib/feedlist.php index 4aacf0b3d..076576028 100644 --- a/lib/feedlist.php +++ b/lib/feedlist.php @@ -46,7 +46,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * * @see Action::showExportList() */ - class FeedList extends Widget { var $action = null; diff --git a/lib/groupsbymemberssection.php b/lib/groupsbymemberssection.php index 19b35eddb..5cf1a563c 100644 --- a/lib/groupsbymemberssection.php +++ b/lib/groupsbymemberssection.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupsByMembersSection extends GroupSection { function getGroups() @@ -68,6 +67,7 @@ class GroupsByMembersSection extends GroupSection function title() { + // TRANS: Title for groups with the most members section. return _('Groups with most members'); } diff --git a/lib/groupsbypostssection.php b/lib/groupsbypostssection.php index 45d49aba6..50d60e87c 100644 --- a/lib/groupsbypostssection.php +++ b/lib/groupsbypostssection.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupsByPostsSection extends GroupSection { function getGroups() @@ -68,6 +67,7 @@ class GroupsByPostsSection extends GroupSection function title() { + // TRANS: Title for groups with the most posts section. return _('Groups with most posts'); } diff --git a/lib/groupsection.php b/lib/groupsection.php index 3b0b3029d..019b13135 100644 --- a/lib/groupsection.php +++ b/lib/groupsection.php @@ -45,7 +45,6 @@ define('GROUPS_PER_SECTION', 6); * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupSection extends Section { function showContent() diff --git a/lib/grouptagcloudsection.php b/lib/grouptagcloudsection.php index f1106cc7b..5b914c007 100644 --- a/lib/grouptagcloudsection.php +++ b/lib/grouptagcloudsection.php @@ -40,7 +40,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ - class GroupTagCloudSection extends TagCloudSection { var $group = null; @@ -53,6 +52,8 @@ class GroupTagCloudSection extends TagCloudSection function title() { + // TRANS: Title for group tag cloud section. + // TRANS: %s is a group name. return sprintf(_('Tags in %s group\'s notices'), $this->group->nickname); } diff --git a/lib/xmppmanager.php b/lib/xmppmanager.php index 829eaa36c..7acd7663a 100644 --- a/lib/xmppmanager.php +++ b/lib/xmppmanager.php @@ -30,7 +30,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } * In a multi-site queuedaemon.php run, one connection will be instantiated * for each site being handled by the current process that has XMPP enabled. */ - class XmppManager extends IoManager { protected $site = null; @@ -102,6 +101,7 @@ class XmppManager extends IoManager $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this); $this->conn->setReconnectTimeout(600); + // @todo Needs i18n? jabber_send_presence("Send me a message to post a notice", 'available', null, 'available', 100); return !is_null($this->conn); @@ -281,9 +281,9 @@ class XmppManager extends IoManager $_cur = $user; if (!$user) { - $this->from_site($from, 'Unknown user; go to ' . - common_local_url('imsettings') . - ' to add your address to your account'); + // TRANS: %s is the URL to the StatusNet site's Instant Messaging settings. + $this->from_site($from, sprintf(_('Unknown user. Go to %s ' . + 'to add your address to your account'),common_local_url('imsettings'))); $this->log(LOG_WARNING, 'Message from unknown user ' . $from); return; } @@ -314,7 +314,6 @@ class XmppManager extends IoManager unset($pl); } - function is_self($from) { return preg_match('/^'.strtolower(jabber_daemon_address()).'/', strtolower($from)); @@ -400,7 +399,11 @@ class XmppManager extends IoManager $content_shortened = common_shorten_links($body); if (Notice::contentTooLong($content_shortened)) { $from = jabber_normalize_jid($pl['from']); - $this->from_site($from, sprintf(_('Message too long - maximum is %1$d characters, you sent %2$d.'), + // TRANS: Response to XMPP source when it sent too long a message. + // TRANS: %1$d the maximum number of allowed characters (used for plural), %2$d is the sent number. + $this->from_site($from, sprintf(_m('Message too long. Maximum is %1$d character, you sent %2$d.', + 'Message too long. Maximum is %1$d characters, you sent %2$d.', + Notice::maxContent()), Notice::maxContent(), mb_strlen($content_shortened))); return; diff --git a/lib/xmppoutqueuehandler.php b/lib/xmppoutqueuehandler.php index 2afa260f1..a4c9bbc4d 100644 --- a/lib/xmppoutqueuehandler.php +++ b/lib/xmppoutqueuehandler.php @@ -52,4 +52,3 @@ class XmppOutQueueHandler extends QueueHandler return $ok; } } - -- cgit v1.2.3-54-g00ecf From f283a283b7101d95f7bed4558b37947f3c5b6951 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 21 Oct 2010 01:17:59 +0000 Subject: Fix syntax error --- lib/apioauthstore.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/apioauthstore.php b/lib/apioauthstore.php index 6b9b97756..e67b864af 100644 --- a/lib/apioauthstore.php +++ b/lib/apioauthstore.php @@ -144,8 +144,7 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore common_debug('Request token found.', __FILE__); // find the app and profile associated with this token - - $tokenAssoc = OAuth_token_association::staticGet('token', $rt->tok); + $tokenAssoc = Oauth_token_association::staticGet('token', $rt->tok); if (!$tokenAssoc) { throw new Exception( -- cgit v1.2.3-54-g00ecf From 648f79be10c1f62eb649563aa4f1cd5c51ddb19f Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 21 Oct 2010 13:00:03 -0700 Subject: Change OAuth authorization page's action name to be inline with other web page action names so the body id outputs correctly. Fix some other bugs. --- actions/apioauthauthorize.php | 10 +++++----- lib/router.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/actions/apioauthauthorize.php b/actions/apioauthauthorize.php index 8bbe0d737..82269e440 100644 --- a/actions/apioauthauthorize.php +++ b/actions/apioauthauthorize.php @@ -35,7 +35,7 @@ require_once INSTALLDIR . '/lib/apioauth.php'; require_once INSTALLDIR . '/lib/info.php'; /** - * Authorize an OAuth request token + * Authorize an Oputh request token * * @category API * @package StatusNet @@ -43,7 +43,7 @@ require_once INSTALLDIR . '/lib/info.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ -class ApiOauthAuthorizeAction extends Action +class ApioauthauthorizeAction extends Action { var $oauthTokenParam; var $reqToken; @@ -120,7 +120,7 @@ class ApiOauthAuthorizeAction extends Action // Check to make sure we haven't already authorized the token if ($this->reqToken->state != 0) { // TRANS: Client error given when an invalid request token was passed to the OAuth API. - $this->clientError(_('Invalid request token.')); + $this->clientError(_('Request token already authorized.')); } } } @@ -461,7 +461,7 @@ class ApiOauthAuthorizeAction extends Action function showAside() { if ($this->desktopMode() == false) { - parent::showHeader(); + parent::showAside(); } } @@ -471,7 +471,7 @@ class ApiOauthAuthorizeAction extends Action function showFooter() { if ($this->desktopMode() == false) { - parent::showHeader(); + parent::showFooter(); } } diff --git a/lib/router.php b/lib/router.php index 417206e6b..ff1b27925 100644 --- a/lib/router.php +++ b/lib/router.php @@ -676,7 +676,7 @@ class Router array('action' => 'ApiOauthAccessToken')); $m->connect('api/oauth/authorize', - array('action' => 'ApiOauthAuthorize')); + array('action' => 'apioauthauthorize')); // Admin -- cgit v1.2.3-54-g00ecf From fb86e7c2857a467e9606cf7e024dda6807639c0c Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 21 Oct 2010 13:03:56 -0700 Subject: Normalize all action HTML body ids to lowercase --- lib/action.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/action.php b/lib/action.php index 3d7d1d808..4aa6ace77 100644 --- a/lib/action.php +++ b/lib/action.php @@ -362,7 +362,7 @@ class Action extends HTMLOutputter // lawsuit */ function showBody() { - $this->elementStart('body', (common_current_user()) ? array('id' => $this->trimmed('action'), + $this->elementStart('body', (common_current_user()) ? array('id' => strtolower($this->trimmed('action')), 'class' => 'user_in') : array('id' => $this->trimmed('action'))); $this->elementStart('div', array('id' => 'wrap')); -- cgit v1.2.3-54-g00ecf From 0b134d3e6904b67b6e8e8d424a26e2a4f2f37dd6 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 21 Oct 2010 18:15:11 -0700 Subject: Re-camelcase ApiOauthAuthorizeAction so it will be accessible when a site is in pivate mode --- actions/showapplication.php | 2 +- lib/router.php | 2 +- plugins/OpenID/OpenIDPlugin.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/actions/showapplication.php b/actions/showapplication.php index 387273006..10aaff538 100644 --- a/actions/showapplication.php +++ b/actions/showapplication.php @@ -281,7 +281,7 @@ class ShowApplicationAction extends OwnerDesignAction $this->elementStart('dl', 'entity_authorize_url'); $this->element('dt', null, _('Authorize URL')); - $this->element('dd', null, common_local_url('apioauthauthorize')); + $this->element('dd', null, common_local_url('ApiOauthAuthorize')); $this->elementEnd('dl'); $this->element('p', 'note', diff --git a/lib/router.php b/lib/router.php index ff1b27925..417206e6b 100644 --- a/lib/router.php +++ b/lib/router.php @@ -676,7 +676,7 @@ class Router array('action' => 'ApiOauthAccessToken')); $m->connect('api/oauth/authorize', - array('action' => 'apioauthauthorize')); + array('action' => 'ApiOauthAuthorize')); // Admin diff --git a/plugins/OpenID/OpenIDPlugin.php b/plugins/OpenID/OpenIDPlugin.php index 87eab94a2..d8127aa68 100644 --- a/plugins/OpenID/OpenIDPlugin.php +++ b/plugins/OpenID/OpenIDPlugin.php @@ -713,7 +713,7 @@ class OpenIDPlugin extends Plugin require_once dirname(__FILE__) . '/openid.php'; oid_assert_allowed($openid_url); - $returnto = common_local_url('apioauthauthorize', array(), + $returnto = common_local_url('ApiOauthAuthorize', array(), array('oauth_token' => $action->arg('oauth_token'))); common_set_returnto($returnto); -- cgit v1.2.3-54-g00ecf From d6f4588b9ede2cb26b06084b3117ec9184f9e64e Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 21 Oct 2010 19:10:43 -0700 Subject: Workaround for http_build_query() oddities in low-level router parent code when PHP config is set with non-default separator. --- lib/router.php | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib') diff --git a/lib/router.php b/lib/router.php index 417206e6b..ab8c40668 100644 --- a/lib/router.php +++ b/lib/router.php @@ -863,7 +863,16 @@ class Router if ($qpos !== false) { $url = substr($url, 0, $qpos+1) . str_replace('?', '&', substr($url, $qpos+1)); + + // @fixme this is a hacky workaround for http_build_query in the + // lower-level code and bad configs that set the default separator + // to & instead of &. Encoded &s in parameters will not be + // affected. + $url = substr($url, 0, $qpos+1) . + str_replace('&', '&', substr($url, $qpos+1)); + } + return $url; } } -- cgit v1.2.3-54-g00ecf From 3969870cf3878933f0c37c23e1d481d338b52d29 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Fri, 22 Oct 2010 18:32:08 +0000 Subject: Normalize HTML body ids to lowercase when the user is logged out as well. --- lib/action.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/action.php b/lib/action.php index 4aa6ace77..01bb0f7e9 100644 --- a/lib/action.php +++ b/lib/action.php @@ -364,7 +364,7 @@ class Action extends HTMLOutputter // lawsuit { $this->elementStart('body', (common_current_user()) ? array('id' => strtolower($this->trimmed('action')), 'class' => 'user_in') - : array('id' => $this->trimmed('action'))); + : array('id' => strtolower($this->trimmed('action')))); $this->elementStart('div', array('id' => 'wrap')); if (Event::handle('StartShowHeader', array($this))) { $this->showHeader(); -- cgit v1.2.3-54-g00ecf From 2d124e4aabdc2f4c5a30c5b0b087bbfa1e7bac7b Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 22 Oct 2010 13:51:28 -0700 Subject: Fix for ticket #2532: fixed API block create/destroy when specifying the target user/profile as a separate query parameter, such as api/blocks/create.xml?param=xxx The router settings weren't quite right so we ended up with bogus regex values passed in as the 'id' parameter, which broke the regular fallback ordering of parameter checks. --- lib/router.php | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib') diff --git a/lib/router.php b/lib/router.php index ab8c40668..9aaac7dfe 100644 --- a/lib/router.php +++ b/lib/router.php @@ -551,11 +551,19 @@ class Router 'format' => '(xml|json)')); // blocks + $m->connect('api/blocks/create.:format', + array('action' => 'ApiBlockCreate', + 'format' => '(xml|json)')); + $m->connect('api/blocks/create/:id.:format', array('action' => 'ApiBlockCreate', 'id' => '[a-zA-Z0-9]+', 'format' => '(xml|json)')); + $m->connect('api/blocks/destroy.:format', + array('action' => 'ApiBlockDestroy', + 'format' => '(xml|json)')); + $m->connect('api/blocks/destroy/:id.:format', array('action' => 'ApiBlockDestroy', 'id' => '[a-zA-Z0-9]+', -- cgit v1.2.3-54-g00ecf From eb30c6651a0f726e44e4b8c318f5c1274969202d Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 22 Oct 2010 13:53:10 -0700 Subject: Additional fixes found while looking at ticket #2532: when given a screen name as API parameter for a profile, do the nickname lookup on local users only. The profile table can't guarantee unique lookups, so using names isn't currently safe there. This won't affect anything using local nicknames correctly, and may avoid some weird bugs if there were conflicts between local and remote nicknames. --- lib/apiaction.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/apiaction.php b/lib/apiaction.php index afba8ab63..4e9dbb310 100644 --- a/lib/apiaction.php +++ b/lib/apiaction.php @@ -1398,8 +1398,10 @@ class ApiAction extends Action if (is_numeric($this->arg('id'))) { return Profile::staticGet($this->arg('id')); } else if ($this->arg('id')) { + // Screen names currently can only uniquely identify a local user. $nickname = common_canonical_nickname($this->arg('id')); - return Profile::staticGet('nickname', $nickname); + $user = User::staticGet('nickname', $nickname); + return $user ? $user->getProfile() : null; } else if ($this->arg('user_id')) { // This is to ensure that a non-numeric user_id still // overrides screen_name even if it doesn't get used @@ -1408,13 +1410,15 @@ class ApiAction extends Action } } else if ($this->arg('screen_name')) { $nickname = common_canonical_nickname($this->arg('screen_name')); - return Profile::staticGet('nickname', $nickname); + $user = User::staticGet('nickname', $nickname); + return $user ? $user->getProfile() : null; } } else if (is_numeric($id)) { return Profile::staticGet($id); } else { $nickname = common_canonical_nickname($id); - return Profile::staticGet('nickname', $nickname); + $user = User::staticGet('nickname', $nickname); + return $user ? $user->getProfile() : null; } } -- cgit v1.2.3-54-g00ecf From 3954ab39ae068a98f6b25720981a3505f27cd271 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 25 Oct 2010 11:52:17 -0700 Subject: Add OAuth token exchange endpoint to 'sensitive' array; i.e.: use SSL if available --- lib/util.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/util.php b/lib/util.php index 86380af28..d1c084e2e 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1080,7 +1080,17 @@ function common_local_url($action, $args=null, $params=null, $fragment=null, $ad function common_is_sensitive($action) { - static $sensitive = array('login', 'register', 'passwordsettings', 'api'); + static $sensitive = array( + 'login', + 'register', + 'passwordsettings', + 'api', + 'ApiOauthRequestToken', + 'ApiOauthAccessToken', + 'ApiOauthAuthorize', + 'showapplication', + 'editapplication' + ); $ssl = null; if (Event::handle('SensitiveAction', array($action, &$ssl))) { -- cgit v1.2.3-54-g00ecf From 0dcc3f8d71341b1351c6abfa6c324becd5f27208 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 25 Oct 2010 12:10:52 -0700 Subject: We don't need to have editapplication (only showapplication) in the sensitive array because it doesn't expose the consumer keypair --- lib/util.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/util.php b/lib/util.php index d1c084e2e..ecf1baa87 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1088,8 +1088,7 @@ function common_is_sensitive($action) 'ApiOauthRequestToken', 'ApiOauthAccessToken', 'ApiOauthAuthorize', - 'showapplication', - 'editapplication' + 'showapplication' ); $ssl = null; -- cgit v1.2.3-54-g00ecf From 78396db28a01866bd3bd8aad390a921e49d8e220 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Mon, 25 Oct 2010 12:36:03 -0700 Subject: Forgot to add the OAuth verifier pin page to sensitive array --- lib/util.php | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/util.php b/lib/util.php index ecf1baa87..6044fdd92 100644 --- a/lib/util.php +++ b/lib/util.php @@ -1088,6 +1088,7 @@ function common_is_sensitive($action) 'ApiOauthRequestToken', 'ApiOauthAccessToken', 'ApiOauthAuthorize', + 'ApiOauthPin', 'showapplication' ); $ssl = null; -- cgit v1.2.3-54-g00ecf