forked from GNUsocial/gnu-social
Merge branch 'master' into 0.9.x
Conflicts: lib/attachmentlist.php
This commit is contained in:
commit
f0d905112e
87
README
87
README
@ -2,8 +2,8 @@
|
|||||||
README
|
README
|
||||||
------
|
------
|
||||||
|
|
||||||
StatusNet 0.9.0 ("Stand")
|
StatusNet 0.9.1 ("Everybody Hurts")
|
||||||
4 Mar 2010
|
28 Mar 2010
|
||||||
|
|
||||||
This is the README file for StatusNet, the Open Source microblogging
|
This is the README file for StatusNet, the Open Source microblogging
|
||||||
platform. It includes installation instructions, descriptions of
|
platform. It includes installation instructions, descriptions of
|
||||||
@ -77,57 +77,34 @@ for additional terms.
|
|||||||
New this version
|
New this version
|
||||||
================
|
================
|
||||||
|
|
||||||
This is a major feature release since version 0.8.3, released Feb 1
|
This is a minor bug and feature release since version 0.9.0 released 4
|
||||||
2010. It is the final release version of 0.9.0, replacing any beta
|
March 2010.
|
||||||
versions.
|
|
||||||
|
Because of fixes to OStatus bugs, it is highly recommended that all
|
||||||
|
public sites upgrade to the new version immediately.
|
||||||
|
|
||||||
Notable changes this version:
|
Notable changes this version:
|
||||||
|
|
||||||
- Support for the new distributed status update standard OStatus
|
- Twitter bridge truncates and links back to original for long
|
||||||
<http://ostatus.org>, based on PubSubHubbub, Salmon, Webfinger,
|
notices.
|
||||||
and Activity Streams.
|
- Changed "Home" link in main menu to "Personal".
|
||||||
- Support for location using the Geolocation API. Notices are (optionally)
|
- A new memcached plugin (using pecl/memcached versus pecl/memcache)
|
||||||
marked with lat-long information with geo microformats, and can be shown
|
- Opt-in subscription to update@status.net
|
||||||
on a map.
|
- Script to run commands on behalf of a user.
|
||||||
- No fixed content size. Notice size is configurable, from 1 to
|
- Better Web UI for long notices.
|
||||||
unlimited number of characters. Default is still 140!
|
- A plugin to open external links in their own window or tab
|
||||||
- An authorization framework, allowing different levels of users.
|
- Fixes to Salmon protocol for compatibility with other systems.
|
||||||
- A Web-based administration panel.
|
- Updates to latest ActivityStreams definition.
|
||||||
- A moderation system that lets site moderators sandbox, silence,
|
- Twitpic-compatible API for image upload.
|
||||||
or delete uncooperative users.
|
- Background deletion of user accounts.
|
||||||
- A flag system that lets users flag profiles for moderator review.
|
- Better support for HTTP basic authentication with CGI/FastCGI
|
||||||
- Support for OAuth <http://oauth.net> authentication in the Twitter
|
- Better discovery on OStatus
|
||||||
API.
|
- Support for PuSH-enabled RSS 2.0 feeds
|
||||||
- User roles system that lets the owner of the site to assign
|
- OpenID-only mode
|
||||||
administrator and moderator roles to other users.
|
- OpenID blacklist/whitelist
|
||||||
- A pluggable authentication system.
|
- OStatus unit tests
|
||||||
- An authentication plugin for LDAP servers.
|
|
||||||
- Many features that were core in 0.8.x are now plugins, such
|
|
||||||
as OpenID, Twitter integration, Facebook integration
|
|
||||||
- A much-improved offline processing system
|
|
||||||
- In-browser "realtime" updates using a number of realtime
|
|
||||||
servers (Meteor, Orbited, Cometd)
|
|
||||||
- A plugin to provide an interface optimized for mobile browsers
|
|
||||||
- Support for Facebook Connect
|
|
||||||
- Support for logging in with a Twitter account
|
|
||||||
- Vastly improved translation with additional languages and
|
|
||||||
translation in plugins
|
|
||||||
- Support for all-SSL instances
|
|
||||||
- Core support for "repeats" (like Twitter's "retweets")
|
|
||||||
- Pluggable caching system, with plugins for Memcached,
|
|
||||||
APC, XCache, and a disk-based cache
|
|
||||||
- Plugin to support RSSCloud
|
|
||||||
- A framework for adding advertisements to a public site,
|
|
||||||
and plugins for Google AdSense and OpenX server
|
|
||||||
- Plugins to throttle excessive subscriptions and registrations.
|
|
||||||
- A plugin to blacklist particular URLs or nicknames.
|
|
||||||
|
|
||||||
There are also literally thousands of bugs fixed and minor features
|
A full changelog is available at http://status.net/wiki/StatusNet_0.9.1.
|
||||||
added. A full changelog is available at http://status.net/wiki/StatusNet_0.9.0.
|
|
||||||
|
|
||||||
Under the covers, the software has a vastly improved plugin and
|
|
||||||
extension mechanism that makes writing powerful and flexible additions
|
|
||||||
to the core functionality much easier.
|
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
=============
|
=============
|
||||||
@ -239,9 +216,9 @@ especially if you've previously installed PHP/MySQL packages.
|
|||||||
1. Unpack the tarball you downloaded on your Web server. Usually a
|
1. Unpack the tarball you downloaded on your Web server. Usually a
|
||||||
command like this will work:
|
command like this will work:
|
||||||
|
|
||||||
tar zxf statusnet-0.9.0.tar.gz
|
tar zxf statusnet-0.9.1.tar.gz
|
||||||
|
|
||||||
...which will make a statusnet-0.9.0 subdirectory in your current
|
...which will make a statusnet-0.9.1 subdirectory in your current
|
||||||
directory. (If you don't have shell access on your Web server, you
|
directory. (If you don't have shell access on your Web server, you
|
||||||
may have to unpack the tarball on your local computer and FTP the
|
may have to unpack the tarball on your local computer and FTP the
|
||||||
files to the server.)
|
files to the server.)
|
||||||
@ -249,7 +226,7 @@ especially if you've previously installed PHP/MySQL packages.
|
|||||||
2. Move the tarball to a directory of your choosing in your Web root
|
2. Move the tarball to a directory of your choosing in your Web root
|
||||||
directory. Usually something like this will work:
|
directory. Usually something like this will work:
|
||||||
|
|
||||||
mv statusnet-0.9.0 /var/www/statusnet
|
mv statusnet-0.9.1 /var/www/statusnet
|
||||||
|
|
||||||
This will make your StatusNet instance available in the statusnet path of
|
This will make your StatusNet instance available in the statusnet path of
|
||||||
your server, like "http://example.net/statusnet". "microblog" or
|
your server, like "http://example.net/statusnet". "microblog" or
|
||||||
@ -664,7 +641,7 @@ with this situation.
|
|||||||
If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've
|
If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've
|
||||||
been tracking the "git" version of the software, you will probably
|
been tracking the "git" version of the software, you will probably
|
||||||
want to upgrade and keep your existing data. There is no automated
|
want to upgrade and keep your existing data. There is no automated
|
||||||
upgrade procedure in StatusNet 0.9.0. Try these step-by-step
|
upgrade procedure in StatusNet 0.9.1. Try these step-by-step
|
||||||
instructions; read to the end first before trying them.
|
instructions; read to the end first before trying them.
|
||||||
|
|
||||||
0. Download StatusNet and set up all the prerequisites as if you were
|
0. Download StatusNet and set up all the prerequisites as if you were
|
||||||
@ -685,7 +662,7 @@ instructions; read to the end first before trying them.
|
|||||||
5. Once all writing processes to your site are turned off, make a
|
5. Once all writing processes to your site are turned off, make a
|
||||||
final backup of the Web directory and database.
|
final backup of the Web directory and database.
|
||||||
6. Move your StatusNet directory to a backup spot, like "statusnet.bak".
|
6. Move your StatusNet directory to a backup spot, like "statusnet.bak".
|
||||||
7. Unpack your StatusNet 0.9.0 tarball and move it to "statusnet" or
|
7. Unpack your StatusNet 0.9.1 tarball and move it to "statusnet" or
|
||||||
wherever your code used to be.
|
wherever your code used to be.
|
||||||
8. Copy the config.php file and avatar directory from your old
|
8. Copy the config.php file and avatar directory from your old
|
||||||
directory to your new directory.
|
directory to your new directory.
|
||||||
@ -1522,7 +1499,7 @@ repository (see below), and you get a compilation error ("unexpected
|
|||||||
T_STRING") in the browser, check to see that you don't have any
|
T_STRING") in the browser, check to see that you don't have any
|
||||||
conflicts in your code.
|
conflicts in your code.
|
||||||
|
|
||||||
If you upgraded to StatusNet 0.9.0 without reading the "Notice
|
If you upgraded to StatusNet 0.9.1 without reading the "Notice
|
||||||
inboxes" section above, and all your users' 'Personal' tabs are empty,
|
inboxes" section above, and all your users' 'Personal' tabs are empty,
|
||||||
read the "Notice inboxes" section above.
|
read the "Notice inboxes" section above.
|
||||||
|
|
||||||
|
@ -670,8 +670,12 @@ class User extends Memcached_DataObject
|
|||||||
|
|
||||||
function delete()
|
function delete()
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$profile = $this->getProfile();
|
$profile = $this->getProfile();
|
||||||
$profile->delete();
|
$profile->delete();
|
||||||
|
} catch (UserNoProfileException $unp) {
|
||||||
|
common_log(LOG_INFO, "User {$this->nickname} has no profile; continuing deletion.");
|
||||||
|
}
|
||||||
|
|
||||||
$related = array('Fave',
|
$related = array('Fave',
|
||||||
'Confirm_address',
|
'Confirm_address',
|
||||||
@ -679,6 +683,7 @@ class User extends Memcached_DataObject
|
|||||||
'Foreign_link',
|
'Foreign_link',
|
||||||
'Invitation',
|
'Invitation',
|
||||||
);
|
);
|
||||||
|
|
||||||
Event::handle('UserDeleteRelated', array($this, &$related));
|
Event::handle('UserDeleteRelated', array($this, &$related));
|
||||||
|
|
||||||
foreach ($related as $cls) {
|
foreach ($related as $cls) {
|
||||||
|
@ -179,6 +179,17 @@ class Activity
|
|||||||
|
|
||||||
$this->actor = new ActivityObject($actorEl);
|
$this->actor = new ActivityObject($actorEl);
|
||||||
|
|
||||||
|
// Cliqset has bad actor IDs (just nickname of user). We
|
||||||
|
// work around it by getting the author data and using its
|
||||||
|
// id instead
|
||||||
|
|
||||||
|
if (!preg_match('/^\w+:/', $this->actor->id)) {
|
||||||
|
$authorEl = ActivityUtils::child($entry, 'author');
|
||||||
|
if (!empty($authorEl)) {
|
||||||
|
$authorObj = new ActivityObject($authorEl);
|
||||||
|
$this->actor->id = $authorObj->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (!empty($feed) &&
|
} else if (!empty($feed) &&
|
||||||
$subjectEl = $this->_child($feed, self::SUBJECT)) {
|
$subjectEl = $this->_child($feed, self::SUBJECT)) {
|
||||||
|
|
||||||
|
@ -177,10 +177,7 @@ class ActivityObject
|
|||||||
$this->type = self::PERSON; // XXX: is this fair?
|
$this->type = self::PERSON; // XXX: is this fair?
|
||||||
$this->title = $this->_childContent($element, self::NAME);
|
$this->title = $this->_childContent($element, self::NAME);
|
||||||
|
|
||||||
$id = $this->_childContent($element, self::URI);
|
$this->id = $this->_childContent($element, self::URI);
|
||||||
if (ActivityUtils::validateUri($id)) {
|
|
||||||
$this->id = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($this->id)) {
|
if (empty($this->id)) {
|
||||||
$email = $this->_childContent($element, self::EMAIL);
|
$email = $this->_childContent($element, self::EMAIL);
|
||||||
@ -193,15 +190,6 @@ class ActivityObject
|
|||||||
|
|
||||||
private function _fromAtomEntry($element)
|
private function _fromAtomEntry($element)
|
||||||
{
|
{
|
||||||
if ($element->localName == 'actor') {
|
|
||||||
// Old-fashioned <activity:actor>...
|
|
||||||
// First pull anything from <author>, then we'll add on top.
|
|
||||||
$author = ActivityUtils::child($element->parentNode, 'author');
|
|
||||||
if ($author) {
|
|
||||||
$this->_fromAuthor($author);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->type = $this->_childContent($element, Activity::OBJECTTYPE,
|
$this->type = $this->_childContent($element, Activity::OBJECTTYPE,
|
||||||
Activity::SPEC);
|
Activity::SPEC);
|
||||||
|
|
||||||
@ -209,11 +197,6 @@ class ActivityObject
|
|||||||
$this->type = ActivityObject::NOTE;
|
$this->type = ActivityObject::NOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $this->_childContent($element, self::ID);
|
|
||||||
if (ActivityUtils::validateUri($id)) {
|
|
||||||
$this->id = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->summary = ActivityUtils::childHtmlContent($element, self::SUMMARY);
|
$this->summary = ActivityUtils::childHtmlContent($element, self::SUMMARY);
|
||||||
$this->content = ActivityUtils::getContent($element);
|
$this->content = ActivityUtils::getContent($element);
|
||||||
|
|
||||||
@ -226,6 +209,12 @@ class ActivityObject
|
|||||||
$this->source = $this->_getSource($element);
|
$this->source = $this->_getSource($element);
|
||||||
|
|
||||||
$this->link = ActivityUtils::getPermalink($element);
|
$this->link = ActivityUtils::getPermalink($element);
|
||||||
|
|
||||||
|
$this->id = $this->_childContent($element, self::ID);
|
||||||
|
|
||||||
|
if (empty($this->id) && !empty($this->link)) { // fallback if there's no ID
|
||||||
|
$this->id = $this->link;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @fixme rationalize with Activity::_fromRssItem()
|
// @fixme rationalize with Activity::_fromRssItem()
|
||||||
|
@ -337,7 +337,7 @@ class Attachment extends AttachmentListItem
|
|||||||
$this->showHtmlFile($this->attachment);
|
$this->showHtmlFile($this->attachment);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Fall through to default
|
// Fall through to default.
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$this->showFallback();
|
$this->showFallback();
|
||||||
|
@ -22,10 +22,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
|||||||
//exit with 200 response, if this is checking fancy from the installer
|
//exit with 200 response, if this is checking fancy from the installer
|
||||||
if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; }
|
if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; }
|
||||||
|
|
||||||
define('STATUSNET_VERSION', '0.9.0');
|
define('STATUSNET_VERSION', '0.9.1');
|
||||||
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility
|
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility
|
||||||
|
|
||||||
define('STATUSNET_CODENAME', 'Stand');
|
define('STATUSNET_CODENAME', 'Everybody Hurts');
|
||||||
|
|
||||||
define('AVATAR_PROFILE_SIZE', 96);
|
define('AVATAR_PROFILE_SIZE', 96);
|
||||||
define('AVATAR_STREAM_SIZE', 48);
|
define('AVATAR_STREAM_SIZE', 48);
|
||||||
|
@ -49,30 +49,24 @@ class BlacklistPlugin extends Plugin
|
|||||||
public $urls = array();
|
public $urls = array();
|
||||||
public $canAdmin = true;
|
public $canAdmin = true;
|
||||||
|
|
||||||
private $_nicknamePatterns = array();
|
function _getNicknamePatterns()
|
||||||
private $_urlPatterns = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the plugin
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function initialize()
|
|
||||||
{
|
{
|
||||||
$confNicknames = $this->_configArray('blacklist', 'nicknames');
|
$confNicknames = $this->_configArray('blacklist', 'nicknames');
|
||||||
|
|
||||||
$dbNicknames = Nickname_blacklist::getPatterns();
|
$dbNicknames = Nickname_blacklist::getPatterns();
|
||||||
|
|
||||||
$this->_nicknamePatterns = array_merge($this->nicknames,
|
return array_merge($this->nicknames,
|
||||||
$confNicknames,
|
$confNicknames,
|
||||||
$dbNicknames);
|
$dbNicknames);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getUrlPatterns()
|
||||||
|
{
|
||||||
$confURLs = $this->_configArray('blacklist', 'urls');
|
$confURLs = $this->_configArray('blacklist', 'urls');
|
||||||
|
|
||||||
$dbURLs = Homepage_blacklist::getPatterns();
|
$dbURLs = Homepage_blacklist::getPatterns();
|
||||||
|
|
||||||
$this->_urlPatterns = array_merge($this->urls,
|
return array_merge($this->urls,
|
||||||
$confURLs,
|
$confURLs,
|
||||||
$dbURLs);
|
$dbURLs);
|
||||||
}
|
}
|
||||||
@ -265,8 +259,9 @@ class BlacklistPlugin extends Plugin
|
|||||||
|
|
||||||
private function _checkUrl($url)
|
private function _checkUrl($url)
|
||||||
{
|
{
|
||||||
foreach ($this->_urlPatterns as $pattern) {
|
$patterns = $this->_getUrlPatterns();
|
||||||
common_debug("Checking $url against $pattern");
|
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
if (preg_match("/$pattern/", $url)) {
|
if (preg_match("/$pattern/", $url)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -287,8 +282,9 @@ class BlacklistPlugin extends Plugin
|
|||||||
|
|
||||||
private function _checkNickname($nickname)
|
private function _checkNickname($nickname)
|
||||||
{
|
{
|
||||||
foreach ($this->_nicknamePatterns as $pattern) {
|
$patterns = $this->_getNicknamePatterns();
|
||||||
common_debug("Checking $nickname against $pattern");
|
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
if (preg_match("/$pattern/", $nickname)) {
|
if (preg_match("/$pattern/", $nickname)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,8 @@ class OStatusPlugin extends Plugin
|
|||||||
*/
|
*/
|
||||||
function onStartEnqueueNotice($notice, &$transports)
|
function onStartEnqueueNotice($notice, &$transports)
|
||||||
{
|
{
|
||||||
$transports[] = 'ostatus';
|
// put our transport first, in case there's any conflict (like OMB)
|
||||||
|
array_unshift($transports, 'ostatus');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,11 +129,11 @@ class Magicsig extends Memcached_DataObject
|
|||||||
|
|
||||||
public function toString($full_pair = true)
|
public function toString($full_pair = true)
|
||||||
{
|
{
|
||||||
$mod = base64_url_encode($this->publicKey->modulus->toBytes());
|
$mod = Magicsig::base64_url_encode($this->publicKey->modulus->toBytes());
|
||||||
$exp = base64_url_encode($this->publicKey->exponent->toBytes());
|
$exp = Magicsig::base64_url_encode($this->publicKey->exponent->toBytes());
|
||||||
$private_exp = '';
|
$private_exp = '';
|
||||||
if ($full_pair && $this->privateKey->exponent->toBytes()) {
|
if ($full_pair && $this->privateKey->exponent->toBytes()) {
|
||||||
$private_exp = '.' . base64_url_encode($this->privateKey->exponent->toBytes());
|
$private_exp = '.' . Magicsig::base64_url_encode($this->privateKey->exponent->toBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'RSA.' . $mod . '.' . $exp . $private_exp;
|
return 'RSA.' . $mod . '.' . $exp . $private_exp;
|
||||||
@ -174,9 +174,9 @@ class Magicsig extends Memcached_DataObject
|
|||||||
$rsa = new Crypt_RSA();
|
$rsa = new Crypt_RSA();
|
||||||
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
|
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
|
||||||
$rsa->setHash('sha256');
|
$rsa->setHash('sha256');
|
||||||
$rsa->modulus = new Math_BigInteger(base64_url_decode($mod), 256);
|
$rsa->modulus = new Math_BigInteger(Magicsig::base64_url_decode($mod), 256);
|
||||||
$rsa->k = strlen($rsa->modulus->toBytes());
|
$rsa->k = strlen($rsa->modulus->toBytes());
|
||||||
$rsa->exponent = new Math_BigInteger(base64_url_decode($exp), 256);
|
$rsa->exponent = new Math_BigInteger(Magicsig::base64_url_decode($exp), 256);
|
||||||
|
|
||||||
if ($type == 'private') {
|
if ($type == 'private') {
|
||||||
$this->privateKey = $rsa;
|
$this->privateKey = $rsa;
|
||||||
@ -203,23 +203,25 @@ class Magicsig extends Memcached_DataObject
|
|||||||
public function sign($bytes)
|
public function sign($bytes)
|
||||||
{
|
{
|
||||||
$sig = $this->privateKey->sign($bytes);
|
$sig = $this->privateKey->sign($bytes);
|
||||||
return base64_url_encode($sig);
|
return Magicsig::base64_url_encode($sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function verify($signed_bytes, $signature)
|
public function verify($signed_bytes, $signature)
|
||||||
{
|
{
|
||||||
$signature = base64_url_decode($signature);
|
$signature = Magicsig::base64_url_decode($signature);
|
||||||
return $this->publicKey->verify($signed_bytes, $signature);
|
return $this->publicKey->verify($signed_bytes, $signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function base64_url_encode($input)
|
public static function base64_url_encode($input)
|
||||||
{
|
{
|
||||||
return strtr(base64_encode($input), '+/', '-_');
|
return strtr(base64_encode($input), '+/', '-_');
|
||||||
}
|
}
|
||||||
|
|
||||||
function base64_url_decode($input)
|
public static function base64_url_decode($input)
|
||||||
{
|
{
|
||||||
return base64_decode(strtr($input, '-_', '+/'));
|
return base64_decode(strtr($input, '-_', '+/'));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ class MagicEnvelope
|
|||||||
public function signMessage($text, $mimetype, $keypair)
|
public function signMessage($text, $mimetype, $keypair)
|
||||||
{
|
{
|
||||||
$signature_alg = Magicsig::fromString($keypair);
|
$signature_alg = Magicsig::fromString($keypair);
|
||||||
$armored_text = base64_url_encode($text);
|
$armored_text = Magicsig::base64_url_encode($text);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'data' => $armored_text,
|
'data' => $armored_text,
|
||||||
@ -121,7 +121,7 @@ class MagicEnvelope
|
|||||||
public function unfold($env)
|
public function unfold($env)
|
||||||
{
|
{
|
||||||
$dom = new DOMDocument();
|
$dom = new DOMDocument();
|
||||||
$dom->loadXML(base64_url_decode($env['data']));
|
$dom->loadXML(Magicsig::base64_url_decode($env['data']));
|
||||||
|
|
||||||
if ($dom->documentElement->tagName != 'entry') {
|
if ($dom->documentElement->tagName != 'entry') {
|
||||||
return false;
|
return false;
|
||||||
@ -178,7 +178,7 @@ class MagicEnvelope
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$text = base64_url_decode($env['data']);
|
$text = Magicsig::base64_url_decode($env['data']);
|
||||||
$signer_uri = $this->getAuthor($text);
|
$signer_uri = $this->getAuthor($text);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
$shortoptions = 'i:n:';
|
$shortoptions = 'i:n:o';
|
||||||
$longoptions = array('id=', 'nickname=');
|
$longoptions = array('id=', 'nickname=', 'owner');
|
||||||
|
|
||||||
$helptext = <<<END_OF_USERROLE_HELP
|
$helptext = <<<END_OF_USERROLE_HELP
|
||||||
command.php [options] [command line]
|
command.php [options] [command line]
|
||||||
@ -29,13 +29,12 @@ Perform commands on behalf of a user, such as sub, unsub, join, drop
|
|||||||
|
|
||||||
-i --id ID of the user
|
-i --id ID of the user
|
||||||
-n --nickname nickname of the user
|
-n --nickname nickname of the user
|
||||||
|
-o --owner use the site owner
|
||||||
|
|
||||||
END_OF_USERROLE_HELP;
|
END_OF_USERROLE_HELP;
|
||||||
|
|
||||||
require_once INSTALLDIR.'/scripts/commandline.inc';
|
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function interpretCommand($user, $body)
|
function interpretCommand($user, $body)
|
||||||
{
|
{
|
||||||
$inter = new CommandInterpreter();
|
$inter = new CommandInterpreter();
|
||||||
@ -50,8 +49,6 @@ function interpretCommand($user, $body)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (have_option('i', 'id')) {
|
if (have_option('i', 'id')) {
|
||||||
$id = get_option_value('i', 'id');
|
$id = get_option_value('i', 'id');
|
||||||
$user = User::staticGet('id', $id);
|
$user = User::staticGet('id', $id);
|
||||||
@ -66,6 +63,12 @@ if (have_option('i', 'id')) {
|
|||||||
print "Can't find user with nickname '$nickname'\n";
|
print "Can't find user with nickname '$nickname'\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
} else if (have_option('o', 'owner')) {
|
||||||
|
$user = User::siteOwner();
|
||||||
|
if (empty($user)) {
|
||||||
|
print "Site has no owner.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
print "You must provide either an ID or a nickname.\n\n";
|
print "You must provide either an ID or a nickname.\n\n";
|
||||||
print $helptext;
|
print $helptext;
|
||||||
|
@ -22,14 +22,14 @@ class ActivityParseTests extends PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->assertFalse(empty($act));
|
$this->assertFalse(empty($act));
|
||||||
|
|
||||||
$this->assertEquals($act->time, 1243860840);
|
$this->assertEquals(1243860840, $act->time);
|
||||||
$this->assertEquals($act->verb, ActivityVerb::POST);
|
$this->assertEquals(ActivityVerb::POST, $act->verb);
|
||||||
|
|
||||||
$this->assertFalse(empty($act->objects[0]));
|
$this->assertFalse(empty($act->objects[0]));
|
||||||
$this->assertEquals($act->objects[0]->title, 'Punctuation Changeset');
|
$this->assertEquals('Punctuation Changeset', $act->objects[0]->title);
|
||||||
$this->assertEquals($act->objects[0]->type, 'http://versioncentral.example.org/activity/changeset');
|
$this->assertEquals('http://versioncentral.example.org/activity/changeset', $act->objects[0]->type);
|
||||||
$this->assertEquals($act->objects[0]->summary, 'Fixing punctuation because it makes it more readable.');
|
$this->assertEquals('Fixing punctuation because it makes it more readable.', $act->objects[0]->summary);
|
||||||
$this->assertEquals($act->objects[0]->id, 'tag:versioncentral.example.org,2009:/change/1643245');
|
$this->assertEquals('tag:versioncentral.example.org,2009:/change/1643245', $act->objects[0]->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testExample3()
|
public function testExample3()
|
||||||
@ -46,22 +46,22 @@ class ActivityParseTests extends PHPUnit_Framework_TestCase
|
|||||||
$act = new Activity($entry, $feed);
|
$act = new Activity($entry, $feed);
|
||||||
|
|
||||||
$this->assertFalse(empty($act));
|
$this->assertFalse(empty($act));
|
||||||
$this->assertEquals($act->time, 1071340202);
|
$this->assertEquals(1071340202, $act->time);
|
||||||
$this->assertEquals($act->link, 'http://example.org/2003/12/13/atom03.html');
|
$this->assertEquals('http://example.org/2003/12/13/atom03.html', $act->link);
|
||||||
|
|
||||||
$this->assertEquals($act->verb, ActivityVerb::POST);
|
$this->assertEquals($act->verb, ActivityVerb::POST);
|
||||||
|
|
||||||
$this->assertFalse(empty($act->actor));
|
$this->assertFalse(empty($act->actor));
|
||||||
$this->assertEquals($act->actor->type, ActivityObject::PERSON);
|
$this->assertEquals(ActivityObject::PERSON, $act->actor->type);
|
||||||
$this->assertEquals($act->actor->title, 'John Doe');
|
$this->assertEquals('John Doe', $act->actor->title);
|
||||||
$this->assertEquals($act->actor->id, 'mailto:johndoe@example.com');
|
$this->assertEquals('mailto:johndoe@example.com', $act->actor->id);
|
||||||
|
|
||||||
$this->assertFalse(empty($act->objects[0]));
|
$this->assertFalse(empty($act->objects[0]));
|
||||||
$this->assertEquals($act->objects[0]->type, ActivityObject::NOTE);
|
$this->assertEquals(ActivityObject::NOTE, $act->objects[0]->type);
|
||||||
$this->assertEquals($act->objects[0]->id, 'urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a');
|
$this->assertEquals('urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a', $act->objects[0]->id);
|
||||||
$this->assertEquals($act->objects[0]->title, 'Atom-Powered Robots Run Amok');
|
$this->assertEquals('Atom-Powered Robots Run Amok', $act->objects[0]->title);
|
||||||
$this->assertEquals($act->objects[0]->summary, 'Some text.');
|
$this->assertEquals('Some text.', $act->objects[0]->summary);
|
||||||
$this->assertEquals($act->objects[0]->link, 'http://example.org/2003/12/13/atom03.html');
|
$this->assertEquals('http://example.org/2003/12/13/atom03.html', $act->objects[0]->link);
|
||||||
|
|
||||||
$this->assertFalse(empty($act->context));
|
$this->assertFalse(empty($act->context));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user