Merge branch '0.9.x' into 1.0.x
Conflicts: actions/confirmaddress.php actions/emailsettings.php actions/hostmeta.php actions/imsettings.php actions/login.php actions/profilesettings.php actions/showgroup.php actions/smssettings.php actions/urlsettings.php actions/userauthorization.php actions/userdesignsettings.php classes/Memcached_DataObject.php index.php lib/accountsettingsaction.php lib/action.php lib/common.php lib/connectsettingsaction.php lib/designsettings.php lib/personalgroupnav.php lib/profileaction.php lib/userprofile.php plugins/ClientSideShorten/ClientSideShortenPlugin.php plugins/Facebook/FBConnectSettings.php plugins/Facebook/FacebookPlugin.php plugins/NewMenu/NewMenuPlugin.php plugins/NewMenu/newmenu.css
This commit is contained in:
@@ -39,11 +39,41 @@ class Magicsig extends Memcached_DataObject
|
||||
|
||||
public $__table = 'magicsig';
|
||||
|
||||
/**
|
||||
* Key to user.id/profile.id for the local user whose key we're storing.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $user_id;
|
||||
|
||||
/**
|
||||
* Flattened string representation of the key pair; callers should
|
||||
* usually use $this->publicKey and $this->privateKey directly,
|
||||
* which hold live Crypt_RSA key objects.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $keypair;
|
||||
|
||||
/**
|
||||
* Crypto algorithm used for this key; currently only RSA-SHA256 is supported.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $alg;
|
||||
|
||||
/**
|
||||
* Public RSA key; gets serialized in/out via $this->keypair string.
|
||||
*
|
||||
* @var Crypt_RSA
|
||||
*/
|
||||
public $publicKey;
|
||||
|
||||
/**
|
||||
* PrivateRSA key; gets serialized in/out via $this->keypair string.
|
||||
*
|
||||
* @var Crypt_RSA
|
||||
*/
|
||||
public $privateKey;
|
||||
|
||||
public function __construct($alg = 'RSA-SHA256')
|
||||
@@ -51,6 +81,13 @@ class Magicsig extends Memcached_DataObject
|
||||
$this->alg = $alg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a Magicsig object from the cache or database on a field match.
|
||||
*
|
||||
* @param string $k
|
||||
* @param mixed $v
|
||||
* @return Magicsig
|
||||
*/
|
||||
public /*static*/ function staticGet($k, $v=null)
|
||||
{
|
||||
$obj = parent::staticGet(__CLASS__, $k, $v);
|
||||
@@ -103,6 +140,14 @@ class Magicsig extends Memcached_DataObject
|
||||
return array(false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save this keypair into the database.
|
||||
*
|
||||
* Overloads default insert behavior to encode the live key objects
|
||||
* as a flat string for storage.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function insert()
|
||||
{
|
||||
$this->keypair = $this->toString();
|
||||
@@ -110,6 +155,14 @@ class Magicsig extends Memcached_DataObject
|
||||
return parent::insert();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new keypair for a local user and store in the database.
|
||||
*
|
||||
* Warning: this can be very slow on systems without the GMP module.
|
||||
* Runtimes of 20-30 seconds are not unheard-of.
|
||||
*
|
||||
* @param int $user_id id of local user we're creating a key for
|
||||
*/
|
||||
public function generate($user_id)
|
||||
{
|
||||
$rsa = new Crypt_RSA();
|
||||
@@ -128,6 +181,12 @@ class Magicsig extends Memcached_DataObject
|
||||
$this->insert();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the keypair or public key as a string.
|
||||
*
|
||||
* @param boolean $full_pair set to false to leave out the private key.
|
||||
* @return string
|
||||
*/
|
||||
public function toString($full_pair = true)
|
||||
{
|
||||
$mod = Magicsig::base64_url_encode($this->publicKey->modulus->toBytes());
|
||||
@@ -140,6 +199,13 @@ class Magicsig extends Memcached_DataObject
|
||||
return 'RSA.' . $mod . '.' . $exp . $private_exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a string representation of an RSA public key or keypair
|
||||
* as a Magicsig object which can be used to sign or verify.
|
||||
*
|
||||
* @param string $text
|
||||
* @return Magicsig
|
||||
*/
|
||||
public static function fromString($text)
|
||||
{
|
||||
$magic_sig = new Magicsig();
|
||||
@@ -168,6 +234,14 @@ class Magicsig extends Memcached_DataObject
|
||||
return $magic_sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill out $this->privateKey or $this->publicKey with a Crypt_RSA object
|
||||
* representing the give key (as mod/exponent pair).
|
||||
*
|
||||
* @param string $mod base64-encoded
|
||||
* @param string $exp base64-encoded exponent
|
||||
* @param string $type one of 'public' or 'private'
|
||||
*/
|
||||
public function loadKey($mod, $exp, $type = 'public')
|
||||
{
|
||||
common_log(LOG_DEBUG, "Adding ".$type." key: (".$mod .', '. $exp .")");
|
||||
@@ -186,11 +260,22 @@ class Magicsig extends Memcached_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the crypto algorithm used for this key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->alg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of a hash function to use for signing with this key.
|
||||
*
|
||||
* @return string
|
||||
* @fixme is this used? doesn't seem to be called by name.
|
||||
*/
|
||||
public function getHash()
|
||||
{
|
||||
switch ($this->alg) {
|
||||
@@ -200,24 +285,48 @@ class Magicsig extends Memcached_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate base64-encoded signature for the given byte string
|
||||
* using our private key.
|
||||
*
|
||||
* @param string $bytes as raw byte string
|
||||
* @return string base64-encoded signature
|
||||
*/
|
||||
public function sign($bytes)
|
||||
{
|
||||
$sig = $this->privateKey->sign($bytes);
|
||||
return Magicsig::base64_url_encode($sig);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $signed_bytes as raw byte string
|
||||
* @param string $signature as base64
|
||||
* @return boolean
|
||||
*/
|
||||
public function verify($signed_bytes, $signature)
|
||||
{
|
||||
$signature = Magicsig::base64_url_decode($signature);
|
||||
return $this->publicKey->verify($signed_bytes, $signature);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* URL-encoding-friendly base64 variant encoding.
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public static function base64_url_encode($input)
|
||||
{
|
||||
return strtr(base64_encode($input), '+/', '-_');
|
||||
}
|
||||
|
||||
/**
|
||||
* URL-encoding-friendly base64 variant decoding.
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public static function base64_url_decode($input)
|
||||
{
|
||||
return base64_decode(strtr($input, '-_', '+/'));
|
||||
|
@@ -293,6 +293,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
* an acceptable response from the remote site.
|
||||
*
|
||||
* @param mixed $entry XML string, Notice, or Activity
|
||||
* @param Profile $actor
|
||||
* @return boolean success
|
||||
*/
|
||||
public function notifyActivity($entry, $actor)
|
||||
@@ -1073,7 +1074,8 @@ class Ostatus_profile extends Managed_DataObject
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
return common_path('plugins/OStatus/images/96px-Feed-icon.svg.png');
|
||||
|
||||
return Plugin::staticPath('OStatus', 'images/96px-Feed-icon.svg.png');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1314,7 +1316,17 @@ class Ostatus_profile extends Managed_DataObject
|
||||
{
|
||||
$orig = clone($profile);
|
||||
|
||||
$profile->nickname = self::getActivityObjectNickname($object, $hints);
|
||||
// Existing nickname is better than nothing.
|
||||
|
||||
if (!array_key_exists('nickname', $hints)) {
|
||||
$hints['nickname'] = $profile->nickname;
|
||||
}
|
||||
|
||||
$nickname = self::getActivityObjectNickname($object, $hints);
|
||||
|
||||
if (!empty($nickname)) {
|
||||
$profile->nickname = $nickname;
|
||||
}
|
||||
|
||||
if (!empty($object->title)) {
|
||||
$profile->fullname = $object->title;
|
||||
@@ -1330,9 +1342,23 @@ class Ostatus_profile extends Managed_DataObject
|
||||
$profile->profileurl = $object->id;
|
||||
}
|
||||
|
||||
$profile->bio = self::getActivityObjectBio($object, $hints);
|
||||
$profile->location = self::getActivityObjectLocation($object, $hints);
|
||||
$profile->homepage = self::getActivityObjectHomepage($object, $hints);
|
||||
$bio = self::getActivityObjectBio($object, $hints);
|
||||
|
||||
if (!empty($bio)) {
|
||||
$profile->bio = $bio;
|
||||
}
|
||||
|
||||
$location = self::getActivityObjectLocation($object, $hints);
|
||||
|
||||
if (!empty($location)) {
|
||||
$profile->location = $location;
|
||||
}
|
||||
|
||||
$homepage = self::getActivityObjectHomepage($object, $hints);
|
||||
|
||||
if (!empty($homepage)) {
|
||||
$profile->homepage = $homepage;
|
||||
}
|
||||
|
||||
if (!empty($object->geopoint)) {
|
||||
$location = ActivityContext::locationFromPoint($object->geopoint);
|
||||
@@ -1740,12 +1766,16 @@ class Ostatus_profile extends Managed_DataObject
|
||||
case 'mailto':
|
||||
$rest = $match[2];
|
||||
$oprofile = Ostatus_profile::ensureWebfinger($rest);
|
||||
break;
|
||||
default:
|
||||
common_log("Unrecognized URI protocol for profile: $protocol ($uri)");
|
||||
throw new ServerException("Unrecognized URI protocol for profile: $protocol ($uri)");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
throw new ServerException("No URI protocol for profile: ($uri)");
|
||||
}
|
||||
}
|
||||
|
||||
return $oprofile;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user