Merge branch 'testing' of gitorious.org:statusnet/mainline into 0.9.x

This commit is contained in:
Brion Vibber 2010-02-26 12:33:50 -08:00
commit 9b366547d7
17 changed files with 576 additions and 78 deletions

View File

@ -769,3 +769,20 @@ StartShowSubscriptionsContent: before showing the subscriptions content
EndShowSubscriptionsContent: after showing the subscriptions content EndShowSubscriptionsContent: after showing the subscriptions content
- $action: the current action - $action: the current action
StartDeleteUserForm: starting the data in the form for deleting a user
- $action: action being shown
- $user: user being deleted
EndDeleteUserForm: Ending the data in the form for deleting a user
- $action: action being shown
- $user: user being deleted
StartDeleteUser: handling the post for deleting a user
- $action: action being shown
- $user: user being deleted
EndDeleteUser: handling the post for deleting a user
- $action: action being shown
- $user: user being deleted

View File

@ -131,6 +131,7 @@ class DeleteuserAction extends ProfileFormAction
$this->elementStart('fieldset'); $this->elementStart('fieldset');
$this->hidden('token', common_session_token()); $this->hidden('token', common_session_token());
$this->element('legend', _('Delete user')); $this->element('legend', _('Delete user'));
if (Event::handle('StartDeleteUserForm', array($this, $this->user))) {
$this->element('p', null, $this->element('p', null,
_('Are you sure you want to delete this user? '. _('Are you sure you want to delete this user? '.
'This will clear all data about the user from the '. 'This will clear all data about the user from the '.
@ -144,6 +145,8 @@ class DeleteuserAction extends ProfileFormAction
$this->hidden($k, $v); $this->hidden($k, $v);
} }
} }
Event::handle('EndDeleteUserForm', array($this, $this->user));
}
$this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user")); $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user"));
$this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Delete this user')); $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Delete this user'));
$this->elementEnd('fieldset'); $this->elementEnd('fieldset');
@ -158,7 +161,9 @@ class DeleteuserAction extends ProfileFormAction
function handlePost() function handlePost()
{ {
if (Event::handle('StartDeleteUser', array($this, $this->user))) {
$this->user->delete(); $this->user->delete();
Event::handle('EndDeleteUser', array($this, $this->user));
}
} }
} }

View File

@ -125,14 +125,6 @@ class ShowgroupAction extends GroupDesignAction
$local = Local_group::staticGet('nickname', $nickname); $local = Local_group::staticGet('nickname', $nickname);
if (!$local) { if (!$local) {
common_log(LOG_NOTICE, "Couldn't find local group for nickname '$nickname'");
$this->clientError(_('No such group.'), 404);
return false;
}
$this->group = User_group::staticGet('id', $local->group_id);
if (!$this->group) {
$alias = Group_alias::staticGet('alias', $nickname); $alias = Group_alias::staticGet('alias', $nickname);
if ($alias) { if ($alias) {
$args = array('id' => $alias->group_id); $args = array('id' => $alias->group_id);
@ -142,11 +134,19 @@ class ShowgroupAction extends GroupDesignAction
common_redirect(common_local_url('groupbyid', $args), 301); common_redirect(common_local_url('groupbyid', $args), 301);
return false; return false;
} else { } else {
common_log(LOG_NOTICE, "Couldn't find local group for nickname '$nickname'");
$this->clientError(_('No such group.'), 404); $this->clientError(_('No such group.'), 404);
return false; return false;
} }
} }
$this->group = User_group::staticGet('id', $local->group_id);
if (!$this->group) {
$this->clientError(_('No such group.'), 404);
return false;
}
common_set_returnto($this->selfUrl()); common_set_returnto($this->selfUrl());
return true; return true;

View File

@ -976,7 +976,7 @@ class Action extends HTMLOutputter // lawsuit
if (is_null($arg)) { if (is_null($arg)) {
return $def; return $def;
} else if (in_array($arg, array('true', 'yes', '1'))) { } else if (in_array($arg, array('true', 'yes', '1', 'on'))) {
return true; return true;
} else if (in_array($arg, array('false', 'no', '0'))) { } else if (in_array($arg, array('false', 'no', '0'))) {
return false; return false;

View File

@ -103,7 +103,7 @@ class AdminPanelAction extends Action
$name = mb_substr($name, 0, -10); $name = mb_substr($name, 0, -10);
if (!in_array($name, common_config('admin', 'panels'))) { if (!self::canAdmin($name)) {
$this->clientError(_('Changes to that panel are not allowed.'), 403); $this->clientError(_('Changes to that panel are not allowed.'), 403);
return false; return false;
} }
@ -262,6 +262,17 @@ class AdminPanelAction extends Action
return $result; return $result;
} }
function canAdmin($name)
{
$isOK = false;
if (Event::handle('AdminPanelCheck', array($name, &$isOK))) {
$isOK = in_array($name, common_config('admin', 'panels'));
}
return $isOK;
}
} }
/** /**
@ -307,32 +318,32 @@ class AdminPanelNav extends Widget
if (Event::handle('StartAdminPanelNav', array($this))) { if (Event::handle('StartAdminPanelNav', array($this))) {
if ($this->canAdmin('site')) { if (AdminPanelAction::canAdmin('site')) {
$this->out->menuItem(common_local_url('siteadminpanel'), _('Site'), $this->out->menuItem(common_local_url('siteadminpanel'), _('Site'),
_('Basic site configuration'), $action_name == 'siteadminpanel', 'nav_site_admin_panel'); _('Basic site configuration'), $action_name == 'siteadminpanel', 'nav_site_admin_panel');
} }
if ($this->canAdmin('design')) { if (AdminPanelAction::canAdmin('design')) {
$this->out->menuItem(common_local_url('designadminpanel'), _('Design'), $this->out->menuItem(common_local_url('designadminpanel'), _('Design'),
_('Design configuration'), $action_name == 'designadminpanel', 'nav_design_admin_panel'); _('Design configuration'), $action_name == 'designadminpanel', 'nav_design_admin_panel');
} }
if ($this->canAdmin('user')) { if (AdminPanelAction::canAdmin('user')) {
$this->out->menuItem(common_local_url('useradminpanel'), _('User'), $this->out->menuItem(common_local_url('useradminpanel'), _('User'),
_('User configuration'), $action_name == 'useradminpanel', 'nav_design_admin_panel'); _('User configuration'), $action_name == 'useradminpanel', 'nav_design_admin_panel');
} }
if ($this->canAdmin('access')) { if (AdminPanelAction::canAdmin('access')) {
$this->out->menuItem(common_local_url('accessadminpanel'), _('Access'), $this->out->menuItem(common_local_url('accessadminpanel'), _('Access'),
_('Access configuration'), $action_name == 'accessadminpanel', 'nav_design_admin_panel'); _('Access configuration'), $action_name == 'accessadminpanel', 'nav_design_admin_panel');
} }
if ($this->canAdmin('paths')) { if (AdminPanelAction::canAdmin('paths')) {
$this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'), $this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'),
_('Paths configuration'), $action_name == 'pathsadminpanel', 'nav_design_admin_panel'); _('Paths configuration'), $action_name == 'pathsadminpanel', 'nav_design_admin_panel');
} }
if ($this->canAdmin('sessions')) { if (AdminPanelAction::canAdmin('sessions')) {
$this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'), $this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'),
_('Sessions configuration'), $action_name == 'sessionsadminpanel', 'nav_design_admin_panel'); _('Sessions configuration'), $action_name == 'sessionsadminpanel', 'nav_design_admin_panel');
} }
@ -342,8 +353,4 @@ class AdminPanelNav extends Widget
$this->action->elementEnd('ul'); $this->action->elementEnd('ul');
} }
function canAdmin($name)
{
return in_array($name, common_config('admin', 'panels'));
}
} }

View File

@ -5341,7 +5341,7 @@ msgstr ""
"%7$s.\n" "%7$s.\n"
"\n" "\n"
"----\n" "----\n"
"మీ ఈమెయిలు చిరునామాని లేదా గమనింపుల ఎంపికలను %8$s వద్ద మార్చుకోండి" "మీ ఈమెయిలు చిరునామాని లేదా గమనింపుల ఎంపికలను %8$s వద్ద మార్చుకోండి\n"
#: lib/mail.php:258 #: lib/mail.php:258
#, php-format #, php-format

View File

@ -22,7 +22,7 @@
* @category Action * @category Action
* @package StatusNet * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
* @copyright 2009 StatusNet Inc. * @copyright 2010 StatusNet Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
@ -47,6 +47,55 @@ class BlacklistPlugin extends Plugin
public $nicknames = array(); public $nicknames = array();
public $urls = array(); public $urls = array();
public $canAdmin = true;
private $_nicknamePatterns = array();
private $_urlPatterns = array();
/**
* Initialize the plugin
*
* @return void
*/
function initialize()
{
$confNicknames = $this->_configArray('blacklist', 'nicknames');
$this->_nicknamePatterns = array_merge($this->nicknames,
$confNicknames);
$confURLs = $this->_configArray('blacklist', 'urls');
$this->_urlPatterns = array_merge($this->urls,
$confURLs);
}
/**
* Retrieve an array from configuration
*
* Carefully checks a section.
*
* @param string $section Configuration section
* @param string $setting Configuration setting
*
* @return array configuration values
*/
function _configArray($section, $setting)
{
$config = common_config($section, $setting);
if (empty($config)) {
return array();
} else if (is_array($config)) {
return $config;
} else if (is_string($config)) {
return explode("\r\n", $config);
} else {
throw new Exception("Unknown data type for config $section + $setting");
}
}
/** /**
* Hook registration to prevent blacklisted homepages or nicknames * Hook registration to prevent blacklisted homepages or nicknames
@ -173,7 +222,8 @@ class BlacklistPlugin extends Plugin
private function _checkUrl($url) private function _checkUrl($url)
{ {
foreach ($this->urls as $pattern) { foreach ($this->_urlPatterns as $pattern) {
common_debug("Checking $url against $pattern");
if (preg_match("/$pattern/", $url)) { if (preg_match("/$pattern/", $url)) {
return false; return false;
} }
@ -194,7 +244,8 @@ class BlacklistPlugin extends Plugin
private function _checkNickname($nickname) private function _checkNickname($nickname)
{ {
foreach ($this->nicknames as $pattern) { foreach ($this->_nicknamePatterns as $pattern) {
common_debug("Checking $nickname against $pattern");
if (preg_match("/$pattern/", $nickname)) { if (preg_match("/$pattern/", $nickname)) {
return false; return false;
} }
@ -203,14 +254,191 @@ class BlacklistPlugin extends Plugin
return true; return true;
} }
/**
* Add our actions to the URL router
*
* @param Net_URL_Mapper $m URL mapper for this hit
*
* @return boolean hook return
*/
function onRouterInitialized($m)
{
$m->connect('admin/blacklist', array('action' => 'blacklistadminpanel'));
return true;
}
/**
* Auto-load our classes if called
*
* @param string $cls Class to load
*
* @return boolean hook return
*/
function onAutoload($cls)
{
switch (strtolower($cls))
{
case 'blacklistadminpanelaction':
$base = strtolower(mb_substr($cls, 0, -6));
include_once INSTALLDIR.'/plugins/Blacklist/'.$base.'.php';
return false;
default:
return true;
}
}
/**
* Plugin version data
*
* @param array &$versions array of version blocks
*
* @return boolean hook value
*/
function onPluginVersion(&$versions) function onPluginVersion(&$versions)
{ {
$versions[] = array('name' => 'Blacklist', $versions[] = array('name' => 'Blacklist',
'version' => self::VERSION, 'version' => self::VERSION,
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Blacklist', 'homepage' =>
'http://status.net/wiki/Plugin:Blacklist',
'description' => 'description' =>
_m('Keep a blacklist of forbidden nickname and URL patterns.')); _m('Keep a blacklist of forbidden nickname '.
'and URL patterns.'));
return true; return true;
} }
/**
* Determines if our admin panel can be shown
*
* @param string $name name of the admin panel
* @param boolean &$isOK result
*
* @return boolean hook value
*/
function onAdminPanelCheck($name, &$isOK)
{
if ($name == 'blacklist') {
$isOK = $this->canAdmin;
return false;
}
return true;
}
/**
* Add our tab to the admin panel
*
* @param Widget $nav Admin panel nav
*
* @return boolean hook value
*/
function onEndAdminPanelNav($nav)
{
if (AdminPanelAction::canAdmin('blacklist')) {
$action_name = $nav->action->trimmed('action');
$nav->out->menuItem(common_local_url('blacklistadminpanel'),
_('Blacklist'),
_('Blacklist configuration'),
$action_name == 'blacklistadminpanel',
'nav_blacklist_admin_panel');
}
return true;
}
function onEndDeleteUserForm($action, $user)
{
$cur = common_current_user();
if (empty($cur) || !$cur->hasRight(Right::CONFIGURESITE)) {
return;
}
$profile = $user->getProfile();
if (empty($profile)) {
return;
}
$action->elementStart('ul', 'form_data');
$action->elementStart('li');
$this->checkboxAndText($action,
'blacklistnickname',
_('Add this nickname pattern to blacklist'),
'blacklistnicknamepattern',
$this->patternizeNickname($user->nickname));
$action->elementEnd('li');
if (!empty($profile->homepage)) {
$action->elementStart('li');
$this->checkboxAndText($action,
'blacklisthomepage',
_('Add this homepage pattern to blacklist'),
'blacklisthomepagepattern',
$this->patternizeHomepage($profile->homepage));
$action->elementEnd('li');
}
$action->elementEnd('ul');
}
function onEndDeleteUser($action, $user)
{
common_debug("Action args: " . print_r($action->args, true));
if ($action->boolean('blacklisthomepage')) {
$pattern = $action->trimmed('blacklisthomepagepattern');
$confURLs = $this->_configArray('blacklist', 'urls');
$confURLs[] = $pattern;
Config::save('blacklist', 'urls', implode("\r\n", $confURLs));
}
if ($action->boolean('blacklistnickname')) {
$pattern = $action->trimmed('blacklistnicknamepattern');
$confNicknames = $this->_configArray('blacklist', 'nicknames');
$confNicknames[] = $pattern;
Config::save('blacklist', 'nicknames', implode("\r\n", $confNicknames));
}
return true;
}
function checkboxAndText($action, $checkID, $label, $textID, $value)
{
$action->element('input', array('name' => $checkID,
'type' => 'checkbox',
'class' => 'checkbox',
'id' => $checkID));
$action->text(' ');
$action->element('label', array('class' => 'checkbox',
'for' => $checkID),
$label);
$action->text(' ');
$action->element('input', array('name' => $textID,
'type' => 'text',
'id' => $textID,
'value' => $value));
}
function patternizeNickname($nickname)
{
return $nickname;
}
function patternizeHomepage($homepage)
{
$hostname = parse_url($homepage, PHP_URL_HOST);
return $hostname;
}
} }

View File

@ -0,0 +1,222 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Blacklist administration panel
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Settings
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2010 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Administer blacklist
*
* @category Admin
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
class BlacklistadminpanelAction extends AdminPanelAction
{
/**
* title of the admin panel
*
* @return string title
*/
function title()
{
return _('Blacklist');
}
/**
* Panel instructions
*
* @return string instructions
*/
function getInstructions()
{
return _('Blacklisted URLs and nicknames');
}
/**
* Show the actual form
*
* @return void
*
* @see BlacklistAdminPanelForm
*/
function showForm()
{
$form = new BlacklistAdminPanelForm($this);
$form->show();
return;
}
/**
* Save the form settings
*
* @return void
*/
function saveSettings()
{
static $settings = array(
'blacklist' => array('nicknames', 'urls'),
);
$values = array();
foreach ($settings as $section => $parts) {
foreach ($parts as $setting) {
$values[$section][$setting] = $this->trimmed("$section-$setting");
}
}
// This throws an exception on validation errors
$this->validate($values);
// assert(all values are valid);
$config = new Config();
$config->query('BEGIN');
foreach ($settings as $section => $parts) {
foreach ($parts as $setting) {
Config::save($section, $setting, $values[$section][$setting]);
}
}
$config->query('COMMIT');
return;
}
/**
* Validate the values
*
* @param array &$values 2d array of values to check
*
* @return boolean success flag
*/
function validate(&$values)
{
return true;
}
}
/**
* Admin panel form for blacklist panel
*
* @category Admin
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
* @link http://status.net/
*/
class BlacklistAdminPanelForm extends Form
{
/**
* ID of the form
*
* @return string ID
*/
function id()
{
return 'blacklistadminpanel';
}
/**
* Class of the form
*
* @return string class
*/
function formClass()
{
return 'form_settings';
}
/**
* Action we post to
*
* @return string action URL
*/
function action()
{
return common_local_url('blacklistadminpanel');
}
/**
* Show the form controls
*
* @return void
*/
function formData()
{
$this->out->elementStart('ul', 'form_data');
$this->out->elementStart('li');
$this->out->textarea('blacklist-nicknames', _m('Nicknames'),
common_config('blacklist', 'nicknames'),
_('Patterns of nicknames to block, one per line'));
$this->out->elementEnd('li');
$this->out->elementStart('li');
$this->out->textarea('blacklist-urls', _m('URLs'),
common_config('blacklist', 'urls'),
_('Patterns of URLs to block, one per line'));
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
}
/**
* Buttons for submitting
*
* @return void
*/
function formActions()
{
$this->out->submit('submit',
_('Save'),
'submit',
null,
_('Save site settings'));
}
}

View File

@ -149,7 +149,8 @@ class OStatusPlugin extends Plugin
// Also, we'll add in the salmon link // Also, we'll add in the salmon link
$salmon = common_local_url($salmonAction, array('id' => $id)); $salmon = common_local_url($salmonAction, array('id' => $id));
$feed->addLink($salmon, array('rel' => 'salmon')); $feed->addLink($salmon, array('rel' => Salmon::NS_REPLIES));
$feed->addLink($salmon, array('rel' => Salmon::NS_MENTIONS));
} }
return true; return true;
@ -414,7 +415,7 @@ class OStatusPlugin extends Plugin
$act->actor = ActivityObject::fromProfile($subscriber); $act->actor = ActivityObject::fromProfile($subscriber);
$act->object = ActivityObject::fromProfile($other); $act->object = ActivityObject::fromProfile($other);
$oprofile->notifyActivity($act); $oprofile->notifyActivity($act, $subscriber);
return true; return true;
} }
@ -462,7 +463,7 @@ class OStatusPlugin extends Plugin
$act->actor = ActivityObject::fromProfile($profile); $act->actor = ActivityObject::fromProfile($profile);
$act->object = ActivityObject::fromProfile($other); $act->object = ActivityObject::fromProfile($other);
$oprofile->notifyActivity($act); $oprofile->notifyActivity($act, $profile);
return true; return true;
} }
@ -504,7 +505,7 @@ class OStatusPlugin extends Plugin
$member->getBestName(), $member->getBestName(),
$oprofile->getBestName()); $oprofile->getBestName());
if ($oprofile->notifyActivity($act)) { if ($oprofile->notifyActivity($act, $member)) {
return true; return true;
} else { } else {
$oprofile->garbageCollect(); $oprofile->garbageCollect();
@ -554,7 +555,7 @@ class OStatusPlugin extends Plugin
$member->getBestName(), $member->getBestName(),
$oprofile->getBestName()); $oprofile->getBestName());
$oprofile->notifyActivity($act); $oprofile->notifyActivity($act, $member);
} }
} }
@ -597,7 +598,7 @@ class OStatusPlugin extends Plugin
$act->actor = ActivityObject::fromProfile($profile); $act->actor = ActivityObject::fromProfile($profile);
$act->object = ActivityObject::fromNotice($notice); $act->object = ActivityObject::fromNotice($notice);
$oprofile->notifyActivity($act); $oprofile->notifyActivity($act, $profile);
return true; return true;
} }
@ -641,7 +642,7 @@ class OStatusPlugin extends Plugin
$act->actor = ActivityObject::fromProfile($profile); $act->actor = ActivityObject::fromProfile($profile);
$act->object = ActivityObject::fromNotice($notice); $act->object = ActivityObject::fromNotice($notice);
$oprofile->notifyActivity($act); $oprofile->notifyActivity($act, $profile);
return true; return true;
} }
@ -730,7 +731,7 @@ class OStatusPlugin extends Plugin
$act->object = $act->actor; $act->object = $act->actor;
while ($oprofile->fetch()) { while ($oprofile->fetch()) {
$oprofile->notifyDeferred($act); $oprofile->notifyDeferred($act, $profile);
} }
return true; return true;

View File

@ -80,10 +80,14 @@ class XrdAction extends Action
'href' => common_local_url('foaf', 'href' => common_local_url('foaf',
array('nickname' => $nick))); array('nickname' => $nick)));
$salmon_url = common_local_url('salmon', // Salmon
$salmon_url = common_local_url('usersalmon',
array('id' => $this->user->id)); array('id' => $this->user->id));
$xrd->links[] = array('rel' => 'salmon', $xrd->links[] = array('rel' => Salmon::NS_REPLIES,
'href' => $salmon_url);
$xrd->links[] = array('rel' => Salmon::NS_MENTIONS,
'href' => $salmon_url); 'href' => $salmon_url);
// Get this user's keypair // Get this user's keypair
@ -95,7 +99,7 @@ class XrdAction extends Action
} }
$xrd->links[] = array('rel' => Magicsig::PUBLICKEYREL, $xrd->links[] = array('rel' => Magicsig::PUBLICKEYREL,
'href' => 'data:application/magic-public-key;'. $magickey->keypair); 'href' => 'data:application/magic-public-key;'. $magickey->toString(false));
// TODO - finalize where the redirect should go on the publisher // TODO - finalize where the redirect should go on the publisher
$url = common_local_url('ostatussub') . '?profile={uri}'; $url = common_local_url('ostatussub') . '?profile={uri}';

View File

@ -49,7 +49,8 @@ class Magicsig extends Memcached_DataObject
public /*static*/ function staticGet($k, $v=null) public /*static*/ function staticGet($k, $v=null)
{ {
return parent::staticGet(__CLASS__, $k, $v); $obj = parent::staticGet(__CLASS__, $k, $v);
return Magicsig::fromString($obj->keypair);
} }

View File

@ -357,7 +357,7 @@ class Ostatus_profile extends Memcached_DataObject
common_log(LOG_INFO, "Posting to Salmon endpoint $this->salmonuri: $xml"); common_log(LOG_INFO, "Posting to Salmon endpoint $this->salmonuri: $xml");
$salmon = new Salmon(); // ? $salmon = new Salmon(); // ?
return $salmon->post($this->salmonuri, $xml); return $salmon->post($this->salmonuri, $xml, $actor);
} }
return false; return false;
} }
@ -369,11 +369,11 @@ class Ostatus_profile extends Memcached_DataObject
* @param mixed $entry XML string, Notice, or Activity * @param mixed $entry XML string, Notice, or Activity
* @return boolean success * @return boolean success
*/ */
public function notifyActivity($entry) public function notifyActivity($entry, $actor)
{ {
if ($this->salmonuri) { if ($this->salmonuri) {
$salmon = new Salmon(); $salmon = new Salmon();
return $salmon->post($this->salmonuri, $this->notifyPrepXml($entry)); return $salmon->post($this->salmonuri, $this->notifyPrepXml($entry), $actor);
} }
return false; return false;
@ -386,11 +386,12 @@ class Ostatus_profile extends Memcached_DataObject
* @param mixed $entry XML string, Notice, or Activity * @param mixed $entry XML string, Notice, or Activity
* @return boolean success * @return boolean success
*/ */
public function notifyDeferred($entry) public function notifyDeferred($entry, $actor)
{ {
if ($this->salmonuri) { if ($this->salmonuri) {
$data = array('salmonuri' => $this->salmonuri, $data = array('salmonuri' => $this->salmonuri,
'entry' => $this->notifyPrepXml($entry)); 'entry' => $this->notifyPrepXml($entry),
'actor' => $actor->id);
$qm = QueueManager::get(); $qm = QueueManager::get();
return $qm->enqueue($data, 'salmon'); return $qm->enqueue($data, 'salmon');
@ -707,7 +708,7 @@ class Ostatus_profile extends Memcached_DataObject
$huburi = $discover->getAtomLink('hub'); $huburi = $discover->getAtomLink('hub');
$hints['hub'] = $huburi; $hints['hub'] = $huburi;
$salmonuri = $discover->getAtomLink('salmon'); $salmonuri = $discover->getAtomLink(Salmon::NS_REPLIES);
$hints['salmon'] = $salmonuri; $hints['salmon'] = $salmonuri;
if (!$huburi) { if (!$huburi) {
@ -991,7 +992,7 @@ class Ostatus_profile extends Memcached_DataObject
$discover = new FeedDiscovery(); $discover = new FeedDiscovery();
$discover->discoverFromFeedURL($hints['feedurl']); $discover->discoverFromFeedURL($hints['feedurl']);
} }
$salmonuri = $discover->getAtomLink('salmon'); $salmonuri = $discover->getAtomLink(Salmon::NS_REPLIES);
} }
if (array_key_exists('hub', $hints)) { if (array_key_exists('hub', $hints)) {
@ -1299,7 +1300,7 @@ class Ostatus_profile extends Memcached_DataObject
case Discovery::PROFILEPAGE: case Discovery::PROFILEPAGE:
$profileUrl = $link['href']; $profileUrl = $link['href'];
break; break;
case 'salmon': case Salmon::NS_REPLIES:
$salmonEndpoint = $link['href']; $salmonEndpoint = $link['href'];
break; break;
case Discovery::UPDATESFROM: case Discovery::UPDATESFROM:

View File

@ -67,18 +67,8 @@ class MagicEnvelope
} }
public function signMessage($text, $mimetype, $signer_uri) public function signMessage($text, $mimetype, $keypair)
{ {
$signer_uri = $this->normalizeUser($signer_uri);
if (!$this->checkAuthor($text, $signer_uri)) {
throw new Exception("Unable to determine entry author.");
}
$keypair = $this->getKeyPair($signer_uri);
if (!$keypair) {
throw new Exception("Unable to retrive keypair for ". $signer_uri);
}
$signature_alg = Magicsig::fromString($keypair); $signature_alg = Magicsig::fromString($keypair);
$armored_text = base64_encode($text); $armored_text = base64_encode($text);

View File

@ -87,7 +87,7 @@ class OStatusQueueHandler extends QueueHandler
// remote user or group. // remote user or group.
// @fixme as an optimization we can skip this if the // @fixme as an optimization we can skip this if the
// remote profile is subscribed to the author. // remote profile is subscribed to the author.
$oprofile->notifyDeferred($this->notice); $oprofile->notifyDeferred($this->notice, $this->user);
} }
} }

View File

@ -28,6 +28,11 @@
*/ */
class Salmon class Salmon
{ {
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. * Sign and post the given Atom entry as a Salmon message.
* *
@ -37,14 +42,14 @@ class Salmon
* @param string $xml * @param string $xml
* @return boolean success * @return boolean success
*/ */
public function post($endpoint_uri, $xml) public function post($endpoint_uri, $xml, $actor)
{ {
if (empty($endpoint_uri)) { if (empty($endpoint_uri)) {
return false; return false;
} }
if (!common_config('ostatus', 'skip_signatures')) { if (!common_config('ostatus', 'skip_signatures')) {
$xml = $this->createMagicEnv($xml); $xml = $this->createMagicEnv($xml, $actor);
} }
$headers = array('Content-Type: application/atom+xml'); $headers = array('Content-Type: application/atom+xml');
@ -65,15 +70,27 @@ class Salmon
return true; return true;
} }
public function createMagicEnv($text) public function createMagicEnv($text, $actor)
{ {
common_log(LOG_DEBUG, "Got actor as : ". print_r($actor, true));
$magic_env = new MagicEnvelope(); $magic_env = new MagicEnvelope();
// TODO: Should probably be getting the signer uri as an argument? $user = User::staticGet('id', $actor->id);
$signer_uri = $magic_env->getAuthor($text); if ($user->id) {
// Use local key
$magickey = Magicsig::staticGet('user_id', $user->id);
if (!$magickey) {
// No keypair yet, let's generate one.
$magickey = new Magicsig();
$magickey->generate($user->id);
}
common_log(LOG_DEBUG, "Salmon: Loaded key for ". $user->id);
} else {
throw new Exception("Salmon invalid actor for signing");
}
try { try {
$env = $magic_env->signMessage($text, 'application/atom+xml', $signer_uri); $env = $magic_env->signMessage($text, 'application/atom+xml', $magickey->toString());
} catch (Exception $e) { } catch (Exception $e) {
common_log(LOG_ERR, "Salmon signing failed: ". $e->getMessage()); common_log(LOG_ERR, "Salmon signing failed: ". $e->getMessage());
return $text; return $text;

View File

@ -35,8 +35,10 @@ class SalmonQueueHandler extends QueueHandler
assert(is_string($data['salmonuri'])); assert(is_string($data['salmonuri']));
assert(is_string($data['entry'])); assert(is_string($data['entry']));
$actor = Profile::staticGet($data['actor']);
$salmon = new Salmon(); $salmon = new Salmon();
$salmon->post($data['salmonuri'], $data['entry']); $salmon->post($data['salmonuri'], $data['entry'], $actor);
// @fixme detect failure and attempt to resend // @fixme detect failure and attempt to resend
return true; return true;

View File

@ -119,6 +119,9 @@ function newSub($i)
function main($usercount, $noticeavg, $subsavg, $tagmax) function main($usercount, $noticeavg, $subsavg, $tagmax)
{ {
global $config;
$config['site']['dupelimit'] = -1;
$n = 1; $n = 1;
newUser(0); newUser(0);