diff --git a/lib/action.php b/lib/action.php index 73d7815904..a2638993f7 100644 --- a/lib/action.php +++ b/lib/action.php @@ -203,7 +203,7 @@ class Action extends HTMLOutputter // lawsuit if (Event::handle('StartShowStatusNetStyles', array($this)) && Event::handle('StartShowLaconicaStyles', array($this))) { - $this->cssLink('css/display.css',null, 'screen, projection, tv, print'); + $this->primaryCssLink(null, 'screen, projection, tv, print'); Event::handle('EndShowStatusNetStyles', array($this)); Event::handle('EndShowLaconicaStyles', array($this)); } @@ -251,6 +251,18 @@ class Action extends HTMLOutputter // lawsuit } } + function primaryCssLink($mainTheme=null, $media=null) + { + // If the currently-selected theme has dependencies on other themes, + // we'll need to load their display.css files as well in order. + $theme = new Theme($mainTheme); + $baseThemes = $theme->getDeps(); + foreach ($baseThemes as $baseTheme) { + $this->cssLink('css/display.css', $baseTheme, $media); + } + $this->cssLink('css/display.css', $mainTheme, $media); + } + /** * Show javascript headers * diff --git a/lib/theme.php b/lib/theme.php index a9d0cbc84d..992fce870e 100644 --- a/lib/theme.php +++ b/lib/theme.php @@ -54,6 +54,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { class Theme { + var $name = null; var $dir = null; var $path = null; @@ -70,6 +71,10 @@ class Theme if (empty($name)) { $name = common_config('site', 'theme'); } + if (!self::validName($name)) { + throw new ServerException("Invalid theme name."); + } + $this->name = $name; // Check to see if it's in the local dir @@ -177,6 +182,58 @@ class Theme return $this->path.'/'.$relative; } + /** + * Fetch a list of other themes whose CSS needs to be pulled in before + * this theme's, based on following the theme.ini 'include' settings. + * (May be empty if this theme has no include dependencies.) + * + * @return array of strings with theme names + */ + function getDeps() + { + $chain = $this->doGetDeps(array($this->name)); + array_pop($chain); // Drop us back off + return $chain; + } + + protected function doGetDeps($chain) + { + $data = $this->getMetadata(); + if (!empty($data['include'])) { + $include = $data['include']; + + // Protect against cycles! + if (!in_array($include, $chain)) { + try { + $theme = new Theme($include); + array_unshift($chain, $include); + return $theme->doGetDeps($chain); + } catch (Exception $e) { + common_log(LOG_ERR, + "Exception while fetching theme dependencies " . + "for $this->name: " . $e->getMessage()); + } + } + } + return $chain; + } + + /** + * Pull data from the theme's theme.ini file. + * @fixme calling getFile will fall back to default theme, this may be unsafe. + * + * @return associative array of strings + */ + function getMetadata() + { + $iniFile = $this->getFile('theme.ini'); + if (file_exists($iniFile)) { + return parse_ini_file($iniFile); + } else { + return array(); + } + } + /** * Gets the full path of a file in a theme dir based on its relative name * @@ -285,4 +342,9 @@ class Theme return $instroot; } + + static function validName($name) + { + return preg_match('/^[a-z0-9][a-z0-9_-]*$/i', $name); + } } diff --git a/lib/themeuploader.php b/lib/themeuploader.php index abf0658d31..5a48e884ed 100644 --- a/lib/themeuploader.php +++ b/lib/themeuploader.php @@ -192,37 +192,52 @@ class ThemeUploader if (in_array(strtolower($ext), $skip)) { return true; } + if ($filename == '' || substr($filename, 0, 1) == '.') { + // Skip Unix-style hidden files + return true; + } + if ($filename == '__MACOSX') { + // Skip awful metadata files Mac OS X slips in for you. + // Thanks Apple! + return true; + } return false; } protected function validateFile($filename, $ext) { $this->validateFileOrFolder($filename); - $this->validateExtension($ext); + $this->validateExtension($filename, $ext); // @fixme validate content } protected function validateFileOrFolder($name) { if (!preg_match('/^[a-z0-9_\.-]+$/i', $name)) { + common_log(LOG_ERR, "Bad theme filename: $name"); $msg = _("Theme contains invalid file or folder name. " . "Stick with ASCII letters, digits, underscore, and minus sign."); throw new ClientException($msg); } if (preg_match('/\.(php|cgi|asp|aspx|js|vb)\w/i', $name)) { + common_log(LOG_ERR, "Unsafe theme filename: $name"); $msg = _("Theme contains unsafe file extension names; may be unsafe."); throw new ClientException($msg); } return true; } - protected function validateExtension($ext) + protected function validateExtension($base, $ext) { $allowed = array('css', // CSS may need validation 'png', 'gif', 'jpg', 'jpeg', 'svg', // SVG images/fonts may need validation 'ttf', 'eot', 'woff'); if (!in_array(strtolower($ext), $allowed)) { + if ($ext == 'ini' && $base == 'theme') { + // theme.ini exception + return true; + } $msg = sprintf(_("Theme contains file of type '.%s', " . "which is not allowed."), $ext); diff --git a/plugins/MobileProfile/MobileProfilePlugin.php b/plugins/MobileProfile/MobileProfilePlugin.php index 6076bbde0b..72a6a04fbd 100644 --- a/plugins/MobileProfile/MobileProfilePlugin.php +++ b/plugins/MobileProfile/MobileProfilePlugin.php @@ -241,7 +241,7 @@ class MobileProfilePlugin extends WAP20Plugin return true; } - $action->cssLink('css/display.css'); + $action->primaryCssLink(); if (file_exists(Theme::file('css/mp-screen.css'))) { $action->cssLink('css/mp-screen.css', null, 'screen'); diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index f9a8782faa..77bc9872b4 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -564,7 +564,9 @@ class OStatusPlugin extends Plugin $act->time = time(); $act->title = _("Follow"); - $act->content = sprintf(_("%s is now following %s."), + // TRANS: Success message for subscribe to user attempt through OStatus. + // TRANS: %1$s is the subscriber name, %2$s is the subscribed user's name. + $act->content = sprintf(_("%1$s is now following %2$s."), $subscriber->getBestName(), $other->getBestName()); @@ -612,7 +614,9 @@ class OStatusPlugin extends Plugin $act->time = time(); $act->title = _("Unfollow"); - $act->content = sprintf(_("%s stopped following %s."), + // TRANS: Success message for unsubscribe from user attempt through OStatus. + // TRANS: %1$s is the unsubscriber's name, %2$s is the unsubscribed user's name. + $act->content = sprintf(_("%1$s stopped following %2$s."), $profile->getBestName(), $other->getBestName()); @@ -657,7 +661,9 @@ class OStatusPlugin extends Plugin $act->time = time(); $act->title = _m("Join"); - $act->content = sprintf(_m("%s has joined group %s."), + // TRANS: Success message for subscribe to group attempt through OStatus. + // TRANS: %1$s is the member name, %2$s is the subscribed group's name. + $act->content = sprintf(_m("%1$s has joined group %2$s."), $member->getBestName(), $oprofile->getBestName()); @@ -706,7 +712,9 @@ class OStatusPlugin extends Plugin $act->time = time(); $act->title = _m("Leave"); - $act->content = sprintf(_m("%s has left group %s."), + // TRANS: Success message for unsubscribe from group attempt through OStatus. + // TRANS: %1$s is the member name, %2$s is the unsubscribed group's name. + $act->content = sprintf(_m("%1$s has left group %2$s."), $member->getBestName(), $oprofile->getBestName()); @@ -746,7 +754,9 @@ class OStatusPlugin extends Plugin $act->time = time(); $act->title = _("Favor"); - $act->content = sprintf(_("%s marked notice %s as a favorite."), + // TRANS: Success message for adding a favorite notice through OStatus. + // TRANS: %1$s is the favoring user's name, %2$s is URI to the favored notice. + $act->content = sprintf(_("%1$s marked notice %2$s as a favorite."), $profile->getBestName(), $notice->uri); @@ -790,7 +800,9 @@ class OStatusPlugin extends Plugin common_date_iso8601(time())); $act->time = time(); $act->title = _("Disfavor"); - $act->content = sprintf(_("%s marked notice %s as no longer a favorite."), + // TRANS: Success message for remove a favorite notice through OStatus. + // TRANS: %1$s is the unfavoring user's name, %2$s is URI to the no longer favored notice. + $act->content = sprintf(_("%1$s marked notice %2$s as no longer a favorite."), $profile->getBestName(), $notice->uri); @@ -865,7 +877,7 @@ class OStatusPlugin extends Plugin 'class' => 'entity_subscribe')); $action->element('a', array('href' => common_local_url($target), 'class' => 'entity_remote_subscribe') - , _m('Remote')); + , _m('Remote')); // @todo: i18n: Add translator hint for this text. $action->elementEnd('p'); $action->elementEnd('div'); } @@ -905,6 +917,8 @@ class OStatusPlugin extends Plugin common_date_iso8601(time())); $act->time = time(); $act->title = _m("Profile update"); + // TRANS: Ping text for remote profile update through OStatus. + // TRANS: %s is user that updated their profile. $act->content = sprintf(_m("%s has updated their profile page."), $profile->getBestName()); @@ -934,7 +948,7 @@ class OStatusPlugin extends Plugin array('nickname' => $profileUser->nickname)); $output->element('a', array('href' => $url, 'class' => 'entity_remote_subscribe'), - _m('Subscribe')); + _m('Subscribe')); // @todo: i18n: Add context. $output->elementEnd('li'); } } @@ -950,7 +964,7 @@ class OStatusPlugin extends Plugin 'homepage' => 'http://status.net/wiki/Plugin:OStatus', 'rawdescription' => _m('Follow people across social networks that implement '. - 'OStatus.')); + 'OStatus.')); // @todo i18n: Add translator hint. return true; } diff --git a/plugins/OStatus/actions/ostatusgroup.php b/plugins/OStatus/actions/ostatusgroup.php index 1b368de63c..1861e866f2 100644 --- a/plugins/OStatus/actions/ostatusgroup.php +++ b/plugins/OStatus/actions/ostatusgroup.php @@ -74,7 +74,7 @@ class OStatusGroupAction extends OStatusSubAction $this->input('profile', _m('Join group'), $this->profile_uri, - _m("OStatus group's address, like http://example.net/group/nickname")); + _m("OStatus group's address, like http://example.net/group/nickname.")); $this->elementEnd('li'); $this->elementEnd('ul'); diff --git a/plugins/OStatus/actions/ostatusinit.php b/plugins/OStatus/actions/ostatusinit.php index 22aea9f709..0c991aba98 100644 --- a/plugins/OStatus/actions/ostatusinit.php +++ b/plugins/OStatus/actions/ostatusinit.php @@ -45,13 +45,13 @@ class OStatusInitAction extends Action // Local user or group the remote wants to subscribe to $this->nickname = $this->trimmed('nickname'); $this->group = $this->trimmed('group'); - + // Webfinger or profile URL of the remote user $this->profile = $this->trimmed('profile'); return true; } - + function handle($args) { parent::handle($args); @@ -69,7 +69,7 @@ class OStatusInitAction extends Action $this->showForm(); } } - + function showForm($err = null) { $this->err = $err; @@ -109,12 +109,12 @@ class OStatusInitAction extends Action $this->elementStart('ul', 'form_data'); $this->elementStart('li', array('id' => 'ostatus_nickname')); $this->input('nickname', _m('User nickname'), $this->nickname, - _m('Nickname of the user you want to follow')); + _m('Nickname of the user you want to follow.')); $this->hidden('group', $this->group); // pass-through for magic links $this->elementEnd('li'); $this->elementStart('li', array('id' => 'ostatus_profile')); $this->input('profile', _m('Profile Account'), $this->profile, - _m('Your account id (i.e. user@identi.ca)')); + _m('Your account id (e.g. user@identi.ca).')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->submit('submit', $submit); @@ -199,7 +199,7 @@ class OStatusInitAction extends Action function title() { - return _m('OStatus Connect'); + return _m('OStatus Connect'); } - + } diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 28714514f5..4cbd7d0348 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -64,11 +64,11 @@ class OStatusSubAction extends Action $this->input('profile', _m('Subscribe to'), $this->profile_uri, - _m("OStatus user's address, like nickname@example.com or http://example.net/nickname")); + _m("OStatus user's address, like nickname@example.com or http://example.net/nickname")); // @todo i18n FIXME: needs context/translator hint. $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('validate', _m('Continue')); + $this->submit('validate', _m('Continue')); // @todo i18n FIXME: needs context/translator hint. $this->elementEnd('fieldset'); @@ -103,10 +103,10 @@ class OStatusSubAction extends Action $this->hidden('profile', $this->profile_uri); if ($this->oprofile->isGroup()) { $this->submit('submit', _m('Join'), 'submit', null, - _m('Join this group')); + _m('Join this group')); // @todo i18n FIXME: needs context/translator hint. } else { $this->submit('submit', _m('Confirm'), 'submit', null, - _m('Subscribe to this user')); + _m('Subscribe to this user')); // @todo i18n FIXME: needs context/translator hint. } $this->elementEnd('fieldset'); $this->elementEnd('form'); @@ -244,13 +244,13 @@ class OStatusSubAction extends Action } else if (Validate::uri($this->profile_uri)) { $this->oprofile = Ostatus_profile::ensureProfileURL($this->profile_uri); } else { - $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname"); + $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname."); common_debug('Invalid address format.', __FILE__); return false; } return true; } catch (FeedSubBadURLException $e) { - $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname"); + $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname."); common_debug('Invalid URL or could not reach server.', __FILE__); } catch (FeedSubBadResponseException $e) { $this->error = _m("Sorry, we could not reach that feed. Please try that OStatus address again later."); @@ -269,7 +269,7 @@ class OStatusSubAction extends Action common_debug('Not a recognized feed type.', __FILE__); } catch (Exception $e) { // Any new ones we forgot about - $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname"); + $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname."); common_debug(sprintf('Bad feed URL: %s %s', get_class($e), $e->getMessage()), __FILE__); } diff --git a/plugins/OStatus/actions/ownerxrd.php b/plugins/OStatus/actions/ownerxrd.php index 9c141d8c79..3fcb982b87 100644 --- a/plugins/OStatus/actions/ownerxrd.php +++ b/plugins/OStatus/actions/ownerxrd.php @@ -32,7 +32,7 @@ class OwnerxrdAction extends XrdAction function prepare($args) { $this->user = User::siteOwner(); - + if (!$this->user) { $this->clientError(_('No such user.'), 404); return false; @@ -40,7 +40,7 @@ class OwnerxrdAction extends XrdAction $nick = common_canonical_nickname($this->user->nickname); $acct = 'acct:' . $nick . '@' . common_config('site', 'server'); - + $this->xrd = new XRD(); // Check to see if a $config['webfinger']['owner'] has been set diff --git a/plugins/OStatus/actions/pushcallback.php b/plugins/OStatus/actions/pushcallback.php index 9a2067b8ca..6c69787455 100644 --- a/plugins/OStatus/actions/pushcallback.php +++ b/plugins/OStatus/actions/pushcallback.php @@ -37,7 +37,7 @@ class PushCallbackAction extends Action $this->handleGet(); } } - + /** * Handler for POST content updates from the hub */ @@ -46,11 +46,12 @@ class PushCallbackAction extends Action $feedid = $this->arg('feed'); common_log(LOG_INFO, "POST for feed id $feedid"); if (!$feedid) { - throw new ServerException('Empty or invalid feed id', 400); + throw new ServerException('Empty or invalid feed id.', 400); } $feedsub = FeedSub::staticGet('id', $feedid); if (!$feedsub) { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ServerException('Unknown PuSH feed id ' . $feedid, 400); } @@ -70,7 +71,7 @@ class PushCallbackAction extends Action $qm = QueueManager::get(); $qm->enqueue($data, 'pushin'); } - + /** * Handler for GET verification requests from the hub. */ @@ -88,20 +89,24 @@ class PushCallbackAction extends Action $feedsub = FeedSub::staticGet('uri', $topic); if (!$feedsub) { - throw new ClientException("Bad hub.topic feed $topic", 404); + // @todo i18n FIXME: added i18n and use sprintf when using parameters. + throw new ClientException("Bad hub.topic feed $topic.", 404); } if ($feedsub->verify_token !== $verify_token) { - throw new ClientException("Bad hub.verify_token $token for $topic", 404); + // @todo i18n FIXME: added i18n and use sprintf when using parameters. + throw new ClientException("Bad hub.verify_token $token for $topic.", 404); } if ($mode == 'subscribe') { // We may get re-sub requests legitimately. if ($feedsub->sub_state != 'subscribe' && $feedsub->sub_state != 'active') { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Unexpected subscribe request for $topic.", 404); } } else { if ($feedsub->sub_state != 'unsubscribe') { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Unexpected unsubscribe request for $topic.", 404); } } diff --git a/plugins/OStatus/actions/pushhub.php b/plugins/OStatus/actions/pushhub.php index 842d65e7d2..6909b85391 100644 --- a/plugins/OStatus/actions/pushhub.php +++ b/plugins/OStatus/actions/pushhub.php @@ -36,7 +36,6 @@ Things to consider... */ - class PushHubAction extends Action { function arg($arg, $def=null) @@ -63,8 +62,10 @@ class PushHubAction extends Action $this->subunsub($mode); break; case "publish": + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Publishing outside feeds not supported.", 400); default: + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Unrecognized mode '$mode'.", 400); } } @@ -84,16 +85,19 @@ class PushHubAction extends Action $topic = $this->argUrl('hub.topic'); if (!$this->recognizedFeed($topic)) { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Unsupported hub.topic $topic; this hub only serves local user and group Atom feeds."); } $verify = $this->arg('hub.verify'); // @fixme may be multiple if ($verify != 'sync' && $verify != 'async') { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Invalid hub.verify $verify; must be sync or async."); } $lease = $this->arg('hub.lease_seconds', null); if ($mode == 'subscribe' && $lease != '' && !preg_match('/^\d+$/', $lease)) { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Invalid hub.lease $lease; must be empty or positive integer."); } @@ -101,6 +105,7 @@ class PushHubAction extends Action $secret = $this->arg('hub.secret', null); if ($secret != '' && strlen($secret) >= 200) { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Invalid hub.secret $secret; must be under 200 bytes."); } @@ -152,6 +157,7 @@ class PushHubAction extends Action if ($feed == $userFeed) { $user = User::staticGet('id', $id); if (!$user) { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Invalid hub.topic $feed; user doesn't exist."); } else { return true; @@ -160,6 +166,7 @@ class PushHubAction extends Action if ($feed == $groupFeed) { $user = User_group::staticGet('id', $id); if (!$user) { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Invalid hub.topic $feed; group doesn't exist."); } else { return true; @@ -183,6 +190,7 @@ class PushHubAction extends Action if (Validate::uri($url, $params)) { return $url; } else { + // @todo i18n FIXME: added i18n and use sprintf when using parameters. throw new ClientException("Invalid URL passed for $arg: '$url'"); } } @@ -199,4 +207,3 @@ class PushHubAction extends Action return HubSub::staticGet($feed, $callback); } } - diff --git a/plugins/OStatus/actions/userxrd.php b/plugins/OStatus/actions/userxrd.php index 6a6886eb8c..dd720568b4 100644 --- a/plugins/OStatus/actions/userxrd.php +++ b/plugins/OStatus/actions/userxrd.php @@ -33,7 +33,7 @@ class UserxrdAction extends XrdAction $this->uri = $this->trimmed('uri'); $this->uri = Discovery::normalize($this->uri); - + if (Discovery::isWebfinger($this->uri)) { $parts = explode('@', substr(urldecode($this->uri), 5)); if (count($parts) == 2) { diff --git a/plugins/OStatus/classes/FeedSub.php b/plugins/OStatus/classes/FeedSub.php index dd1968db12..6f9e0856ab 100644 --- a/plugins/OStatus/classes/FeedSub.php +++ b/plugins/OStatus/classes/FeedSub.php @@ -249,7 +249,7 @@ class FeedSub extends Memcached_DataObject // We'll never actually get updates in this mode. return true; } else { - throw new ServerException("Attempting to start PuSH subscription for feed with no hub"); + throw new ServerException("Attempting to start PuSH subscription for feed with no hub."); } } @@ -279,7 +279,7 @@ class FeedSub extends Memcached_DataObject // We'll never actually get updates in this mode. return true; } else { - throw new ServerException("Attempting to end PuSH subscription for feed with no hub"); + throw new ServerException("Attempting to end PuSH subscription for feed with no hub."); } } @@ -502,4 +502,3 @@ class FeedSub extends Memcached_DataObject } } - diff --git a/plugins/OStatus/classes/HubSub.php b/plugins/OStatus/classes/HubSub.php index 7db528a4e8..e01ae4e798 100644 --- a/plugins/OStatus/classes/HubSub.php +++ b/plugins/OStatus/classes/HubSub.php @@ -206,6 +206,7 @@ class HubSub extends Memcached_DataObject if ($status >= 200 && $status < 300) { common_log(LOG_INFO, "Verified $mode of $this->callback:$this->topic"); } else { + // @todo i18n FIXME: add i18n and use sprintf for parameter. throw new ClientException("Hub subscriber verification returned HTTP $status"); } @@ -307,9 +308,9 @@ class HubSub extends Memcached_DataObject /** * Queue up a large batch of pushes to multiple subscribers * for this same topic update. - * + * * If queues are disabled, this will run immediately. - * + * * @param string $atom well-formed Atom feed * @param array $pushCallbacks list of callback URLs */ @@ -359,4 +360,3 @@ class HubSub extends Memcached_DataObject } } } - diff --git a/plugins/OStatus/classes/Magicsig.php b/plugins/OStatus/classes/Magicsig.php index f8c56a05f3..e39a6d8f7c 100644 --- a/plugins/OStatus/classes/Magicsig.php +++ b/plugins/OStatus/classes/Magicsig.php @@ -33,21 +33,21 @@ class Magicsig extends Memcached_DataObject { const PUBLICKEYREL = 'magic-public-key'; - + public $__table = 'magicsig'; public $user_id; public $keypair; public $alg; - + public $publicKey; public $privateKey; - + public function __construct($alg = 'RSA-SHA256') { $this->alg = $alg; } - + public /*static*/ function staticGet($k, $v=null) { $obj = parent::staticGet(__CLASS__, $k, $v); @@ -111,7 +111,7 @@ class Magicsig extends Memcached_DataObject public function generate($user_id) { $rsa = new Crypt_RSA(); - + $keypair = $rsa->createKey(); $rsa->loadKey($keypair['privatekey']); @@ -121,7 +121,7 @@ class Magicsig extends Memcached_DataObject $this->publicKey = new Crypt_RSA(); $this->publicKey->loadKey($keypair['publickey']); - + $this->user_id = $user_id; $this->insert(); } @@ -136,13 +136,13 @@ class Magicsig extends Memcached_DataObject $private_exp = '.' . Magicsig::base64_url_encode($this->privateKey->exponent->toBytes()); } - return 'RSA.' . $mod . '.' . $exp . $private_exp; + return 'RSA.' . $mod . '.' . $exp . $private_exp; } - + public static function fromString($text) { $magic_sig = new Magicsig(); - + // remove whitespace $text = preg_replace('/\s+/', '', $text); @@ -150,7 +150,7 @@ class Magicsig extends Memcached_DataObject if (!preg_match('/RSA\.([^\.]+)\.([^\.]+)(.([^\.]+))?/', $text, $matches)) { return false; } - + $mod = $matches[1]; $exp = $matches[2]; if (!empty($matches[4])) { @@ -184,7 +184,7 @@ class Magicsig extends Memcached_DataObject $this->publicKey = $rsa; } } - + public function getName() { return $this->alg; @@ -199,7 +199,7 @@ class Magicsig extends Memcached_DataObject } } - + public function sign($bytes) { $sig = $this->privateKey->sign($bytes); @@ -223,5 +223,3 @@ class Magicsig extends Memcached_DataObject return base64_decode(strtr($input, '-_', '+/')); } } - - diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 898c63e83e..6a0fd1f3bd 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -188,9 +188,11 @@ class Ostatus_profile extends Memcached_DataObject } else if ($this->group_id && !$this->profile_id) { return true; } else if ($this->group_id && $this->profile_id) { - throw new ServerException("Invalid ostatus_profile state: both group and profile IDs set for $this->uri"); + // @todo i18n FIXME: use sprintf and add i18n. + throw new ServerException("Invalid ostatus_profile state: both group and profile IDs set for $this->uri."); } else { - throw new ServerException("Invalid ostatus_profile state: both group and profile IDs empty for $this->uri"); + // @todo i18n FIXME: use sprintf and add i18n. + throw new ServerException("Invalid ostatus_profile state: both group and profile IDs empty for $this->uri."); } } @@ -370,7 +372,8 @@ class Ostatus_profile extends Memcached_DataObject } else if ($entry instanceof Notice) { return $preamble . $entry->asAtomEntry(true, true); } else { - throw new ServerException("Invalid type passed to Ostatus_profile::notify; must be XML string or Activity entry"); + // @todo i18n FIXME: use sprintf and add i18n. + throw new ServerException("Invalid type passed to Ostatus_profile::notify; must be XML string or Activity entry."); } } @@ -549,7 +552,8 @@ class Ostatus_profile extends Memcached_DataObject $sourceContent = $note->title; } else { // @fixme fetch from $sourceUrl? - throw new ClientException("No content for notice {$sourceUri}"); + // @todo i18n FIXME: use sprintf and add i18n. + throw new ClientException("No content for notice {$sourceUri}."); } // Get (safe!) HTML and text versions of the content @@ -587,7 +591,7 @@ class Ostatus_profile extends Memcached_DataObject ' class="attachment more"' . ' title="'. htmlspecialchars(_m('Show more')) . '">' . '…' . - ''; + ''; // @todo i18n FIXME: add translator hint/context. } } @@ -772,6 +776,7 @@ class Ostatus_profile extends Memcached_DataObject $response = $client->get($profile_url); if (!$response->isOk()) { + // @todo i18n FIXME: use sprintf and add i18n. throw new Exception("Could not reach profile page: " . $profile_url); } @@ -829,6 +834,7 @@ class Ostatus_profile extends Memcached_DataObject return self::ensureFeedURL($feedurl, $hints); } + // @todo i18n FIXME: use sprintf and add i18n. throw new Exception("Could not find a feed URL for profile page " . $finalUrl); } @@ -861,6 +867,7 @@ class Ostatus_profile extends Memcached_DataObject $user = User::staticGet('id', $profile->id); if (!empty($user)) { + // @todo i18n FIXME: use sprintf and add i18n. throw new OStatusShadowException($profile, "'$profile_url' is the profile for local user '{$user->nickname}'."); } @@ -1025,7 +1032,7 @@ class Ostatus_profile extends Memcached_DataObject return; } if (!common_valid_http_url($url)) { - throw new ServerException(sprintf(_m("Invalid avatar URL %s"), $url)); + throw new ServerException(sprintf(_m("Invalid avatar URL %s."), $url)); } if ($this->isGroup()) { @@ -1035,7 +1042,7 @@ class Ostatus_profile extends Memcached_DataObject } if (!$self) { throw new ServerException(sprintf( - _m("Tried to update avatar for unsaved remote profile %s"), + _m("Tried to update avatar for unsaved remote profile %s."), $this->uri)); } @@ -1043,7 +1050,7 @@ class Ostatus_profile extends Memcached_DataObject // ripped from oauthstore.php (for old OMB client) $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); if (!copy($url, $temp_filename)) { - throw new ServerException(sprintf(_m("Unable to fetch avatar from %s"), $url)); + throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url)); } if ($this->isGroup()) { @@ -1226,7 +1233,7 @@ class Ostatus_profile extends Memcached_DataObject if ($object->link && common_valid_http_url($object->link)) { return $object->link; } - throw new ServerException("No author ID URI found"); + throw new ServerException("No author ID URI found."); } /** @@ -1256,10 +1263,12 @@ class Ostatus_profile extends Memcached_DataObject $user = User::staticGet('uri', $homeuri); if ($user) { + // @todo i18n FIXME: add i18n. throw new Exception("Local user can't be referenced as remote."); } if (OStatusPlugin::localGroupFromUrl($homeuri)) { + // @todo i18n FIXME: add i18n. throw new Exception("Local group can't be referenced as remote."); } @@ -1311,7 +1320,8 @@ class Ostatus_profile extends Memcached_DataObject $oprofile->profile_id = $profile->insert(); if (!$oprofile->profile_id) { - throw new ServerException("Can't save local profile"); + // @todo i18n FIXME: add i18n. + throw new ServerException("Can't save local profile."); } } else { $group = new User_group(); @@ -1321,14 +1331,16 @@ class Ostatus_profile extends Memcached_DataObject $oprofile->group_id = $group->insert(); if (!$oprofile->group_id) { - throw new ServerException("Can't save local profile"); + // @todo i18n FIXME: add i18n. + throw new ServerException("Can't save local profile."); } } $ok = $oprofile->insert(); if (!$ok) { - throw new ServerException("Can't save OStatus profile"); + // @todo i18n FIXME: add i18n. + throw new ServerException("Can't save OStatus profile."); } $avatar = self::getActivityObjectAvatar($object, $hints); @@ -1586,6 +1598,7 @@ class Ostatus_profile extends Memcached_DataObject if ($uri !== false) { if (is_null($uri)) { // Negative cache entry + // @todo i18n FIXME: add i18n. throw new Exception('Not a valid webfinger address.'); } $oprofile = Ostatus_profile::staticGet('uri', $uri); @@ -1613,6 +1626,7 @@ class Ostatus_profile extends Memcached_DataObject // Save negative cache entry so we don't waste time looking it up again. // @fixme distinguish temporary failures? self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null); + // @todo i18n FIXME: add i18n. throw new Exception('Not a valid webfinger address.'); } @@ -1694,7 +1708,8 @@ class Ostatus_profile extends Memcached_DataObject if (!$profile_id) { common_log_db_error($profile, 'INSERT', __FILE__); - throw new Exception("Couldn't save profile for '$addr'"); + // @todo i18n FIXME: add i18n and use sprintf for parameter. + throw new Exception("Couldn't save profile for '$addr'."); } $oprofile = new Ostatus_profile(); @@ -1712,13 +1727,15 @@ class Ostatus_profile extends Memcached_DataObject if (!$result) { common_log_db_error($oprofile, 'INSERT', __FILE__); - throw new Exception("Couldn't save ostatus_profile for '$addr'"); + // @todo i18n FIXME: add i18n and use sprintf for parameter. + throw new Exception("Couldn't save ostatus_profile for '$addr'."); } self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri); return $oprofile; } + // @todo i18n FIXME: add i18n and use sprintf for parameter. throw new Exception("Couldn't find a valid profile for '$addr'"); } @@ -1818,4 +1835,3 @@ class OStatusShadowException extends Exception parent::__construct($message); } } - diff --git a/plugins/OStatus/lib/discovery.php b/plugins/OStatus/lib/discovery.php index 7187c1f3e9..ed22b452f1 100644 --- a/plugins/OStatus/lib/discovery.php +++ b/plugins/OStatus/lib/discovery.php @@ -106,7 +106,8 @@ class Discovery } } - throw new Exception('Unable to find services for '. $id); + // @todo Needs i18n. + throw new Exception('Unable to find services for '. $id '.'); } public static function getService($links, $service) { @@ -160,7 +161,7 @@ class Discovery_LRDD_Host_Meta implements Discovery_LRDD } else { $domain = parse_url($uri, PHP_URL_HOST); } - + $url = 'http://'. $domain .'/.well-known/host-meta'; $xrd = Discovery::fetchXrd($url); diff --git a/plugins/OStatus/lib/hubconfqueuehandler.php b/plugins/OStatus/lib/hubconfqueuehandler.php index c8e0b72fee..8219f8420e 100644 --- a/plugins/OStatus/lib/hubconfqueuehandler.php +++ b/plugins/OStatus/lib/hubconfqueuehandler.php @@ -51,4 +51,3 @@ class HubConfQueueHandler extends QueueHandler return true; } } - diff --git a/plugins/OStatus/lib/magicenvelope.php b/plugins/OStatus/lib/magicenvelope.php index 967e5f6d17..bbd4ce17a2 100644 --- a/plugins/OStatus/lib/magicenvelope.php +++ b/plugins/OStatus/lib/magicenvelope.php @@ -32,7 +32,7 @@ class MagicEnvelope const ENCODING = 'base64url'; const NS = 'http://salmon-protocol.org/ns/magic-env'; - + private function normalizeUser($user_id) { if (substr($user_id, 0, 5) == 'http:' || @@ -70,13 +70,13 @@ class MagicEnvelope $keypair = $parts[1]; } } - + if ($keypair) { return $keypair; } } } - throw new Exception('Unable to locate signer public key'); + throw new Exception('Unable to locate signer public key.'); } @@ -92,8 +92,7 @@ class MagicEnvelope 'sig' => $signature_alg->sign($armored_text), 'alg' => $signature_alg->getName() ); - - + } public function toXML($env) { @@ -105,13 +104,13 @@ class MagicEnvelope $xs->element('me:alg', null, $env['alg']); $xs->element('me:sig', null, $env['sig']); $xs->elementEnd('me:env'); - + $string = $xs->getString(); common_debug($string); return $string; } - + public function unfold($env) { $dom = new DOMDocument(); @@ -137,7 +136,7 @@ class MagicEnvelope return $dom->saveXML(); } - + public function getAuthor($text) { $doc = new DOMDocument(); if (!$doc->loadXML($text)) { @@ -154,12 +153,12 @@ class MagicEnvelope } } } - + public function checkAuthor($text, $signer_uri) { return ($this->getAuthor($text) == $signer_uri); } - + public function verify($env) { if ($env['alg'] != 'RSA-SHA256') { @@ -181,14 +180,14 @@ class MagicEnvelope common_log(LOG_DEBUG, "Salmon error: ".$e->getMessage()); return false; } - + $verifier = Magicsig::fromString($keypair); if (!$verifier) { common_log(LOG_DEBUG, "Salmon error: unable to parse keypair"); return false; } - + return $verifier->verify($env['data'], $env['sig']); } diff --git a/plugins/OStatus/lib/ostatusqueuehandler.php b/plugins/OStatus/lib/ostatusqueuehandler.php index 5e318116a6..9814cab9f1 100644 --- a/plugins/OStatus/lib/ostatusqueuehandler.php +++ b/plugins/OStatus/lib/ostatusqueuehandler.php @@ -223,4 +223,3 @@ class OStatusQueueHandler extends QueueHandler } } - diff --git a/plugins/OStatus/lib/salmon.php b/plugins/OStatus/lib/salmon.php index ef7719a40c..631ebc7d86 100644 --- a/plugins/OStatus/lib/salmon.php +++ b/plugins/OStatus/lib/salmon.php @@ -31,10 +31,10 @@ class Salmon const REL_SALMON = 'salmon'; const REL_MENTIONED = 'mentioned'; - // XXX: these are deprecated + // XXX: these are deprecated const NS_REPLIES = "http://salmon-protocol.org/ns/salmon-replies"; const NS_MENTIONS = "http://salmon-protocol.org/ns/salmon-mention"; - + /** * Sign and post the given Atom entry as a Salmon message. * @@ -87,9 +87,10 @@ class Salmon // No keypair yet, let's generate one. $magickey = new Magicsig(); $magickey->generate($user->id); - } + } } else { - throw new Exception("Salmon invalid actor for signing"); + // @todo i18n FIXME: added i18n and use sprintf when using parameters. + throw new Exception("Salmon invalid actor for signing."); } try { @@ -104,7 +105,7 @@ class Salmon public function verifyMagicEnv($text) { $magic_env = new MagicEnvelope(); - + $env = $magic_env->parse($text); return $magic_env->verify($env); diff --git a/plugins/OStatus/lib/salmonaction.php b/plugins/OStatus/lib/salmonaction.php index 9d6c6b269a..5fdb11abe4 100644 --- a/plugins/OStatus/lib/salmonaction.php +++ b/plugins/OStatus/lib/salmonaction.php @@ -42,7 +42,7 @@ class SalmonAction extends Action } if (empty($_SERVER['CONTENT_TYPE']) || $_SERVER['CONTENT_TYPE'] != 'application/magic-envelope+xml') { - $this->clientError(_m('Salmon requires application/magic-envelope+xml')); + $this->clientError(_m('Salmon requires "application/magic-envelope+xml".')); } $xml = file_get_contents('php://input'); diff --git a/plugins/OStatus/lib/salmonqueuehandler.php b/plugins/OStatus/lib/salmonqueuehandler.php index 7eeb5f8e9c..56d3c9eff2 100644 --- a/plugins/OStatus/lib/salmonqueuehandler.php +++ b/plugins/OStatus/lib/salmonqueuehandler.php @@ -36,7 +36,7 @@ class SalmonQueueHandler extends QueueHandler assert(is_string($data['entry'])); $actor = Profile::staticGet($data['actor']); - + $salmon = new Salmon(); $salmon->post($data['salmonuri'], $data['entry'], $actor); diff --git a/plugins/OStatus/lib/xrd.php b/plugins/OStatus/lib/xrd.php index a10b9f4272..145cd64cb4 100644 --- a/plugins/OStatus/lib/xrd.php +++ b/plugins/OStatus/lib/xrd.php @@ -31,11 +31,11 @@ class XRD { const XML_NS = 'http://www.w3.org/2000/xmlns/'; - + const XRD_NS = 'http://docs.oasis-open.org/ns/xri/xrd-1.0'; const HOST_META_NS = 'http://host-meta.net/xrd/1.0'; - + public $expires; public $subject; @@ -43,11 +43,11 @@ class XRD public $host; public $alias = array(); - + public $types = array(); - + public $links = array(); - + public static function parse($xml) { $xrd = new XRD(); @@ -61,11 +61,11 @@ class XRD error_reporting($old); if (!$ok) { - throw new Exception("Invalid XML"); + throw new Exception("Invalid XML."); } $xrd_element = $dom->getElementsByTagName('XRD')->item(0); if (!$xrd_element) { - throw new Exception("Invalid XML, missing XRD root"); + throw new Exception("Invalid XML, missing XRD root."); } // Check for host-meta host @@ -86,7 +86,7 @@ class XRD case 'Subject': $xrd->subject = $node->nodeValue; break; - + case 'Alias': $xrd->alias[] = $node->nodeValue; break; @@ -114,7 +114,7 @@ class XRD if ($this->host) { $xs->element('hm:Host', array('xmlns:hm' => XRD::HOST_META_NS), $this->host); } - + if ($this->expires) { $xs->element('Expires', null, $this->expires); } @@ -139,7 +139,7 @@ class XRD } $xs->elementEnd('Link'); } - + $xs->elementEnd('XRD'); return $xs->getString(); @@ -149,7 +149,7 @@ class XRD { return array(); } - + function parseLink($element) { $link = array(); @@ -169,4 +169,3 @@ class XRD return $link; } } - diff --git a/plugins/OStatus/lib/xrdaction.php b/plugins/OStatus/lib/xrdaction.php index d8cf648d6d..91bb87cc23 100644 --- a/plugins/OStatus/lib/xrdaction.php +++ b/plugins/OStatus/lib/xrdaction.php @@ -26,13 +26,12 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } class XrdAction extends Action { - public $uri; - + public $user; public $xrd; - + function handle() { $nick = $this->user->nickname; diff --git a/plugins/OStatus/scripts/fixup-shadow.php b/plugins/OStatus/scripts/fixup-shadow.php index 6522ca240a..4b6ad08a31 100644 --- a/plugins/OStatus/scripts/fixup-shadow.php +++ b/plugins/OStatus/scripts/fixup-shadow.php @@ -77,7 +77,7 @@ while ($oprofile->fetch()) { echo "$uri matched query, but we don't recognize it.\n"; continue; } - + if ($dry) { echo " - skipping\n"; } else { @@ -93,4 +93,3 @@ if ($count && $dry) { } else { echo "done.\n"; } - diff --git a/plugins/OStatus/scripts/testfeed.php b/plugins/OStatus/scripts/testfeed.php index 5e3ccd433a..82a1c65865 100644 --- a/plugins/OStatus/scripts/testfeed.php +++ b/plugins/OStatus/scripts/testfeed.php @@ -86,4 +86,3 @@ if ($skip || $count) { } Event::handle('StartFeedSubReceive', array($sub, $feed)); - diff --git a/plugins/OStatus/scripts/updateostatus.php b/plugins/OStatus/scripts/updateostatus.php index ff0d86d379..052cca1467 100644 --- a/plugins/OStatus/scripts/updateostatus.php +++ b/plugins/OStatus/scripts/updateostatus.php @@ -49,7 +49,7 @@ try { $nickname = get_option_value('n', 'nickname'); $user = User::staticGet('nickname', $nickname); if (empty($user)) { - throw new Exception("Can't find user with nickname '$nickname'"); + throw new Exception("Can't find user with nickname '$nickname'."); } updateOStatus($user); } else if (have_option('a', 'all')) { diff --git a/plugins/OStatus/tests/FeedDiscoveryTest.php b/plugins/OStatus/tests/FeedDiscoveryTest.php index 0e6354a867..3be4bf736c 100644 --- a/plugins/OStatus/tests/FeedDiscoveryTest.php +++ b/plugins/OStatus/tests/FeedDiscoveryTest.php @@ -53,7 +53,7 @@ class FeedDiscoveryTest extends PHPUnit_Framework_TestCase - + diff --git a/plugins/OStatus/tests/remote-tests.php b/plugins/OStatus/tests/remote-tests.php index 24b4b1660a..c2c9a5d97b 100644 --- a/plugins/OStatus/tests/remote-tests.php +++ b/plugins/OStatus/tests/remote-tests.php @@ -500,7 +500,7 @@ class SNTestClient extends TestBase $me = $this->getProfileUri(); return $this->checkSubscription($profile_uri, $me); } - + protected function checkSubscription($subscriber, $subscribed) { // Using FOAF as the API methods for checking the social graph @@ -552,4 +552,3 @@ $b = $args[1]; $tester = new OStatusTester($a, $b); $tester->run(); -