Merge remote branch 'gitorious/1.0.x' into 1.0.x
This commit is contained in:
commit
9abe6fa666
@ -1160,3 +1160,9 @@ StartShowFeedLink: before showing an individual feed item
|
||||
EndShowFeedLink: after showing an individual feed
|
||||
- $action: action being executed
|
||||
- $feed: feed to show
|
||||
|
||||
StartShowNoticeForm: before showing the notice form (before <form>)
|
||||
- $action: action being executed
|
||||
|
||||
EndShowNoticeForm: after showing the notice form (after <form>)
|
||||
- $action: action being executed
|
||||
|
18
README
18
README
@ -852,6 +852,8 @@ notice: A plain string that will appear on every page. A good place
|
||||
be escaped.
|
||||
logo: URL of an image file to use as the logo for the site. Overrides
|
||||
the logo in the theme, if any.
|
||||
ssllogo: URL of an image file to use as the logo on SSL pages. If unset,
|
||||
theme logo is used instead.
|
||||
ssl: Whether to use SSL and https:// URLs for some or all pages.
|
||||
Possible values are 'always' (use it for all pages), 'never'
|
||||
(don't use it for any pages), or 'sometimes' (use it for
|
||||
@ -1109,6 +1111,9 @@ path: Path part of theme URLs, before the theme name. Relative to the
|
||||
which means to use the site path + '/theme'.
|
||||
ssl: Whether to use SSL for theme elements. Default is null, which means
|
||||
guess based on site SSL settings.
|
||||
sslserver: SSL server to use when page is HTTPS-encrypted. If
|
||||
unspecified, site ssl server and so on will be used.
|
||||
sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted.
|
||||
|
||||
javascript
|
||||
----------
|
||||
@ -1120,6 +1125,9 @@ path: Path part of Javascript URLs. Defaults to null,
|
||||
which means to use the site path + '/js/'.
|
||||
ssl: Whether to use SSL for JavaScript files. Default is null, which means
|
||||
guess based on site SSL settings.
|
||||
sslserver: SSL server to use when page is HTTPS-encrypted. If
|
||||
unspecified, site ssl server and so on will be used.
|
||||
sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted.
|
||||
|
||||
xmpp
|
||||
----
|
||||
@ -1347,6 +1355,11 @@ ssl: whether to use HTTPS for file URLs. Defaults to null, meaning to
|
||||
filecommand: command to use for determining the type of a file. May be
|
||||
skipped if fileinfo extension is installed. Defaults to
|
||||
'/usr/bin/file'.
|
||||
sslserver: if specified, this server will be used when creating HTTPS
|
||||
URLs. Otherwise, the site SSL server will be used, with /file/ path.
|
||||
sslpath: if this and the sslserver are specified, this path will be used
|
||||
when creating HTTPS URLs. Otherwise, the attachments|path value
|
||||
will be used.
|
||||
|
||||
group
|
||||
-----
|
||||
@ -1403,8 +1416,9 @@ dir: directory to write backgrounds too. Default is '/background/'
|
||||
subdir of install dir.
|
||||
path: path to backgrounds. Default is sub-path of install path; note
|
||||
that you may need to change this if you change site-path too.
|
||||
ssl: Whether or not to use HTTPS for background files. Defaults to
|
||||
null, meaning to guess from site-wide SSL settings.
|
||||
sslserver: SSL server to use when page is HTTPS-encrypted. If
|
||||
unspecified, site ssl server and so on will be used.
|
||||
sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted.
|
||||
|
||||
ping
|
||||
----
|
||||
|
@ -2,7 +2,8 @@
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Exchange an authorized OAuth request token for an access token
|
||||
* Action for getting OAuth token credentials (exchange an authorized
|
||||
* request token for an access token)
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
@ -34,7 +35,8 @@ if (!defined('STATUSNET')) {
|
||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
|
||||
/**
|
||||
* Exchange an authorized OAuth request token for an access token
|
||||
* Action for getting OAuth token credentials (exchange an authorized
|
||||
* request token for an access token)
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
@ -45,6 +47,8 @@ require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
|
||||
class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||
{
|
||||
protected $reqToken = null;
|
||||
protected $verifier = null;
|
||||
|
||||
/**
|
||||
* Class handler.
|
||||
@ -65,30 +69,58 @@ class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||
|
||||
$atok = null;
|
||||
|
||||
// XXX: Insist that oauth_token and oauth_verifier be populated?
|
||||
// Spec doesn't say they MUST be.
|
||||
|
||||
try {
|
||||
|
||||
$req = OAuthRequest::from_request();
|
||||
|
||||
$this->reqToken = $req->get_parameter('oauth_token');
|
||||
$this->verifier = $req->get_parameter('oauth_verifier');
|
||||
|
||||
$atok = $server->fetch_access_token($req);
|
||||
|
||||
} catch (OAuthException $e) {
|
||||
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
||||
common_debug(var_export($req, true));
|
||||
$this->outputError($e->getMessage());
|
||||
return;
|
||||
$code = $e->getCode();
|
||||
$this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
|
||||
}
|
||||
|
||||
if (empty($atok)) {
|
||||
common_debug('couldn\'t get access token.');
|
||||
print "Token exchange failed. Has the request token been authorized?\n";
|
||||
|
||||
// Token exchange failed -- log it
|
||||
|
||||
list($proxy, $ip) = common_client_ip();
|
||||
|
||||
$msg = sprintf(
|
||||
'API OAuth - Failure exchanging request token for access token, '
|
||||
. 'request token = %s, verifier = %s, IP = %s, proxy = %s',
|
||||
$this->reqToken,
|
||||
$this->verifier,
|
||||
$ip,
|
||||
$proxy
|
||||
);
|
||||
|
||||
common_log(LOG_WARNING, $msg);
|
||||
|
||||
$this->clientError(_("Invalid request token or verifier.", 400, 'text'));
|
||||
|
||||
} else {
|
||||
print $atok;
|
||||
$this->showAccessToken($atok);
|
||||
}
|
||||
}
|
||||
|
||||
function outputError($msg)
|
||||
/*
|
||||
* Display OAuth token credentials
|
||||
*
|
||||
* @param OAuthToken token the access token
|
||||
*/
|
||||
|
||||
function showAccessToken($token)
|
||||
{
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
print $msg . "\n";
|
||||
header('Content-Type: application/x-www-form-urlencoded');
|
||||
print $token;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ if (!defined('STATUSNET')) {
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
require_once INSTALLDIR . '/lib/info.php';
|
||||
|
||||
/**
|
||||
* Authorize an OAuth request token
|
||||
@ -43,9 +44,10 @@ require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
class ApiOauthAuthorizeAction extends Action
|
||||
{
|
||||
var $oauth_token;
|
||||
var $oauthTokenParam;
|
||||
var $reqToken;
|
||||
var $callback;
|
||||
var $app;
|
||||
var $nickname;
|
||||
@ -69,10 +71,15 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
|
||||
$this->nickname = $this->trimmed('nickname');
|
||||
$this->password = $this->arg('password');
|
||||
$this->oauth_token = $this->arg('oauth_token');
|
||||
$this->oauthTokenParam = $this->arg('oauth_token');
|
||||
$this->callback = $this->arg('oauth_callback');
|
||||
$this->store = new ApiStatusNetOAuthDataStore();
|
||||
$this->app = $this->store->getAppByRequestToken($this->oauth_token);
|
||||
|
||||
try {
|
||||
$this->app = $this->store->getAppByRequestToken($this->oauthTokenParam);
|
||||
} catch (Exception $e) {
|
||||
$this->clientError($e->getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -97,14 +104,30 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
|
||||
} else {
|
||||
|
||||
if (empty($this->oauth_token)) {
|
||||
// Make sure a oauth_token parameter was provided
|
||||
if (empty($this->oauthTokenParam)) {
|
||||
$this->clientError(_('No oauth_token parameter provided.'));
|
||||
return;
|
||||
} else {
|
||||
|
||||
// Check to make sure the token exists
|
||||
$this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam);
|
||||
|
||||
if (empty($this->reqToken)) {
|
||||
$this->serverError(
|
||||
_('Invalid request token.')
|
||||
);
|
||||
} else {
|
||||
|
||||
// Check to make sure we haven't already authorized the token
|
||||
if ($this->reqToken->state != 0) {
|
||||
$this->clientError("Invalid request token.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure there's an app associated with this token
|
||||
if (empty($this->app)) {
|
||||
$this->clientError(_('Invalid token.'));
|
||||
return;
|
||||
$this->clientError(_('Invalid request token.'));
|
||||
}
|
||||
|
||||
$name = $this->app->name;
|
||||
@ -120,8 +143,8 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
$token = $this->trimmed('token');
|
||||
|
||||
if (!$token || $token != common_session_token()) {
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
$this->showForm(
|
||||
_('There was a problem with your session token. Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -130,6 +153,11 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
$user = null;
|
||||
|
||||
if (!common_logged_in()) {
|
||||
|
||||
// XXX Force credentials check?
|
||||
|
||||
// XXX OpenID
|
||||
|
||||
$user = common_check_user($this->nickname, $this->password);
|
||||
if (empty($user)) {
|
||||
$this->showForm(_("Invalid nickname / password!"));
|
||||
@ -141,9 +169,15 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
|
||||
if ($this->arg('allow')) {
|
||||
|
||||
// mark the req token as authorized
|
||||
// fetch the token
|
||||
$this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam);
|
||||
|
||||
$this->store->authorize_token($this->oauth_token);
|
||||
// mark the req token as authorized
|
||||
try {
|
||||
$this->store->authorize_token($this->oauthTokenParam);
|
||||
} catch (Exception $e) {
|
||||
$this->serverError($e->getMessage());
|
||||
}
|
||||
|
||||
// Check to see if there was a previous token associated
|
||||
// with this user/app and kill it. If the user is doing this she
|
||||
@ -156,8 +190,7 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($appUser, 'DELETE', __FILE__);
|
||||
throw new ServerException(_('Database error deleting OAuth application user.'));
|
||||
return;
|
||||
$this->serverError(_('Database error deleting OAuth application user.'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,20 +208,19 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
// granted. The OAuth app user record then gets updated
|
||||
// with the new access token and access type.
|
||||
|
||||
$appUser->token = $this->oauth_token;
|
||||
$appUser->token = $this->oauthTokenParam;
|
||||
$appUser->created = common_sql_now();
|
||||
|
||||
$result = $appUser->insert();
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($appUser, 'INSERT', __FILE__);
|
||||
throw new ServerException(_('Database error inserting OAuth application user.'));
|
||||
return;
|
||||
$this->serverError(_('Database error inserting OAuth application user.'));
|
||||
}
|
||||
|
||||
// if we have a callback redirect and provide the token
|
||||
// If we have a callback redirect and provide the token
|
||||
|
||||
// A callback specified in the app setup overrides whatever
|
||||
// Note: A callback specified in the app setup overrides whatever
|
||||
// is passed in with the request.
|
||||
|
||||
if (!empty($this->app->callback_url)) {
|
||||
@ -197,40 +229,40 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
|
||||
if (!empty($this->callback)) {
|
||||
|
||||
$target_url = $this->getCallback($this->callback,
|
||||
array('oauth_token' => $this->oauth_token));
|
||||
$targetUrl = $this->getCallback(
|
||||
$this->callback,
|
||||
array(
|
||||
'oauth_token' => $this->oauthTokenParam,
|
||||
'oauth_verifier' => $this->reqToken->verifier // 1.0a
|
||||
)
|
||||
);
|
||||
|
||||
// Redirect the user to the provided OAuth callback
|
||||
common_redirect($targetUrl, 303);
|
||||
|
||||
common_redirect($target_url, 303);
|
||||
} else {
|
||||
common_debug("callback was empty!");
|
||||
common_log(
|
||||
LOG_INFO,
|
||||
"No oauth_callback parameter provided for application ID "
|
||||
. $this->app->id
|
||||
. " when authorizing request token."
|
||||
);
|
||||
}
|
||||
|
||||
// otherwise inform the user that the rt was authorized
|
||||
// Otherwise, inform the user that the rt was authorized
|
||||
$this->showAuthorized();
|
||||
|
||||
$this->elementStart('p');
|
||||
} else if ($this->arg('cancel')) {
|
||||
|
||||
// XXX: Do OAuth 1.0a verifier code
|
||||
try {
|
||||
$this->store->revoke_token($this->oauthTokenParam, 0);
|
||||
$this->showCanceled();
|
||||
} catch (Exception $e) {
|
||||
$this->ServerError($e->getMessage());
|
||||
}
|
||||
|
||||
$this->raw(sprintf(_("The request token %s has been authorized. " .
|
||||
'Please exchange it for an access token.'),
|
||||
$this->oauth_token));
|
||||
|
||||
$this->elementEnd('p');
|
||||
|
||||
} else if ($this->arg('deny')) {
|
||||
|
||||
$datastore = new ApiStatusNetOAuthDataStore();
|
||||
$datastore->revoke_token($this->oauth_token, 0);
|
||||
|
||||
$this->elementStart('p');
|
||||
|
||||
$this->raw(sprintf(_("The request token %s has been denied and revoked."),
|
||||
$this->oauth_token));
|
||||
|
||||
$this->elementEnd('p');
|
||||
} else {
|
||||
$this->clientError(_('Unexpected form submission.'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,7 +308,7 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
_('Allow or deny access'));
|
||||
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->hidden('oauth_token', $this->oauth_token);
|
||||
$this->hidden('oauth_token', $this->oauthTokenParam);
|
||||
$this->hidden('oauth_callback', $this->callback);
|
||||
|
||||
$this->elementStart('ul', 'form_data');
|
||||
@ -321,11 +353,11 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
|
||||
}
|
||||
|
||||
$this->element('input', array('id' => 'deny_submit',
|
||||
$this->element('input', array('id' => 'cancel_submit',
|
||||
'class' => 'submit submit form_action-primary',
|
||||
'name' => 'deny',
|
||||
'name' => 'cancel',
|
||||
'type' => 'submit',
|
||||
'value' => _('Deny')));
|
||||
'value' => _('Cancel')));
|
||||
|
||||
$this->element('input', array('id' => 'allow_submit',
|
||||
'class' => 'submit submit form_action-secondary',
|
||||
@ -348,7 +380,7 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('Allow or deny access to your account information.');
|
||||
return _('Authorize access to your account information.');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -388,4 +420,107 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||
// NOP
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a nice message confirming the authorization
|
||||
* operation was canceled.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function showCanceled()
|
||||
{
|
||||
$info = new InfoAction(
|
||||
_('Authorization canceled.'),
|
||||
sprintf(
|
||||
_('The request token %s has been revoked.'),
|
||||
$this->oauthTokenParm
|
||||
)
|
||||
);
|
||||
|
||||
$info->showPage();
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a nice message that the authorization was successful.
|
||||
* If the operation is out-of-band, show a pin.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function showAuthorized()
|
||||
{
|
||||
$title = sprintf(
|
||||
_("You have successfully authorized %s."),
|
||||
$this->app->name
|
||||
);
|
||||
|
||||
$msg = sprintf(
|
||||
_('Please return to %s and enter the following security code to complete the process.'),
|
||||
$this->app->name
|
||||
);
|
||||
|
||||
if ($this->reqToken->verified_callback == 'oob') {
|
||||
$pin = new ApiOauthPinAction($title, $msg, $this->reqToken->verifier);
|
||||
$pin->showPage();
|
||||
} else {
|
||||
|
||||
// NOTE: This would only happen if an application registered as
|
||||
// a web application but sent in 'oob' for the oauth_callback
|
||||
// parameter. Usually web apps will send in a callback and
|
||||
// not use the pin-based workflow.
|
||||
|
||||
$info = new InfoAction(
|
||||
$title,
|
||||
$msg,
|
||||
$this->oauthTokenParam,
|
||||
$this->reqToken->verifier
|
||||
);
|
||||
|
||||
$info->showPage();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Properly format the callback URL and parameters so it's
|
||||
* suitable for a redirect in the OAuth dance
|
||||
*
|
||||
* @param string $url the URL
|
||||
* @param array $params an array of parameters
|
||||
*
|
||||
* @return string $url a URL to use for redirecting to
|
||||
*/
|
||||
|
||||
function getCallback($url, $params)
|
||||
{
|
||||
foreach ($params as $k => $v) {
|
||||
$url = $this->appendQueryVar(
|
||||
$url,
|
||||
OAuthUtil::urlencode_rfc3986($k),
|
||||
OAuthUtil::urlencode_rfc3986($v)
|
||||
);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a new query parameter after any existing query
|
||||
* parameters.
|
||||
*
|
||||
* @param string $url the URL
|
||||
* @prarm string $k the parameter name
|
||||
* @param string $v value of the paramter
|
||||
*
|
||||
* @return string $url the new URL with added parameter
|
||||
*/
|
||||
|
||||
function appendQueryVar($url, $k, $v) {
|
||||
$url = preg_replace('/(.*)(\?|&)' . $k . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
|
||||
$url = substr($url, 0, -1);
|
||||
if (strpos($url, '?') === false) {
|
||||
return ($url . '?' . $k . '=' . $v);
|
||||
} else {
|
||||
return ($url . '&' . $k . '=' . $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
67
actions/apioauthpin.php
Normal file
67
actions/apioauthpin.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Action for displaying an OAuth verifier pin
|
||||
*
|
||||
* 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 Action
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/info.php';
|
||||
|
||||
/**
|
||||
* Class for displaying an OAuth verifier pin
|
||||
*
|
||||
* XXX: I'm pretty sure we don't need to check the logged in state here. -- Zach
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiOauthPinAction extends InfoAction
|
||||
{
|
||||
function __construct($title, $message, $verifier)
|
||||
{
|
||||
$this->verifier = $verifier;
|
||||
$this->title = $title;
|
||||
parent::__construct($title, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display content.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$this->element('div', array('class' => 'info'), $this->message);
|
||||
$this->element('div', array('id' => 'oauth_pin'), $this->verifier);
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Get an OAuth request token
|
||||
* Issue temporary OAuth credentials (a request token)
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
@ -34,7 +34,7 @@ if (!defined('STATUSNET')) {
|
||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
||||
|
||||
/**
|
||||
* Get an OAuth request token
|
||||
* Issue temporary OAuth credentials (a request token)
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
@ -58,22 +58,23 @@ class ApiOauthRequestTokenAction extends ApiOauthAction
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->callback = $this->arg('oauth_callback');
|
||||
|
||||
if (!empty($this->callback)) {
|
||||
common_debug("callback: $this->callback");
|
||||
}
|
||||
// XXX: support "force_login" parameter like Twitter? (Forces the user to enter
|
||||
// their credentials to ensure the correct users account is authorized.)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class handler.
|
||||
* Handle a request for temporary OAuth credentials
|
||||
*
|
||||
* Make sure the request is kosher, then emit a set of temporary
|
||||
* credentials -- AKA an unauthorized request token.
|
||||
*
|
||||
* @param array $args array of arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
@ -85,14 +86,78 @@ class ApiOauthRequestTokenAction extends ApiOauthAction
|
||||
$server->add_signature_method($hmac_method);
|
||||
|
||||
try {
|
||||
|
||||
$req = OAuthRequest::from_request();
|
||||
|
||||
// verify callback
|
||||
if (!$this->verifyCallback($req->get_parameter('oauth_callback'))) {
|
||||
throw new OAuthException(
|
||||
"You must provide a valid URL or 'oob' in oauth_callback.",
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
// check signature and issue a new request token
|
||||
$token = $server->fetch_request_token($req);
|
||||
print $token;
|
||||
|
||||
common_log(
|
||||
LOG_INFO,
|
||||
sprintf(
|
||||
"API OAuth - Issued request token %s for consumer %s with oauth_callback %s",
|
||||
$token->key,
|
||||
$req->get_parameter('oauth_consumer_key'),
|
||||
"'" . $req->get_parameter('oauth_callback') ."'"
|
||||
)
|
||||
);
|
||||
|
||||
// return token to the client
|
||||
$this->showRequestToken($token);
|
||||
|
||||
} catch (OAuthException $e) {
|
||||
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
print $e->getMessage() . "\n";
|
||||
|
||||
// Return 401 for for bad credentials or signature problems,
|
||||
// and 400 for missing or unsupported parameters
|
||||
|
||||
$code = $e->getCode();
|
||||
$this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Display temporary OAuth credentials
|
||||
*/
|
||||
|
||||
function showRequestToken($token)
|
||||
{
|
||||
header('Content-Type: application/x-www-form-urlencoded');
|
||||
print $token;
|
||||
print '&oauth_callback_confirmed=true';
|
||||
}
|
||||
|
||||
/* Make sure the callback parameter contains either a real URL
|
||||
* or the string 'oob'.
|
||||
*
|
||||
* @todo Check for evil/banned URLs here
|
||||
*
|
||||
* @return boolean true or false
|
||||
*/
|
||||
|
||||
function verifyCallback($callback)
|
||||
{
|
||||
if ($callback == "oob") {
|
||||
common_debug("OAuth request token requested for out of bounds client.");
|
||||
|
||||
// XXX: Should we throw an error if a client is registered as a
|
||||
// web application but requests the pin based workflow? For now I'm
|
||||
// allowing the workflow to proceed and issuing a pin. --Zach
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return Validate::uri(
|
||||
$callback,
|
||||
array('allowed_schemes' => array('http', 'https'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
$themeChanged = ($this->trimmed('theme') != $oldtheme);
|
||||
}
|
||||
|
||||
static $settings = array('theme', 'logo');
|
||||
static $settings = array('theme', 'logo', 'ssllogo');
|
||||
|
||||
$values = array();
|
||||
|
||||
@ -230,6 +230,7 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
function restoreDefaults()
|
||||
{
|
||||
$this->deleteSetting('site', 'logo');
|
||||
$this->deleteSetting('site', 'ssllogo');
|
||||
$this->deleteSetting('site', 'theme');
|
||||
|
||||
$settings = array(
|
||||
@ -331,6 +332,11 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
$this->clientError(_('Invalid logo URL.'));
|
||||
}
|
||||
|
||||
if (!empty($values['ssllogo']) &&
|
||||
!Validate::uri($values['ssllogo'], array('allowed_schemes' => array('https')))) {
|
||||
$this->clientError(_('Invalid SSL logo URL.'));
|
||||
}
|
||||
|
||||
if (!in_array($values['theme'], Theme::listAvailable())) {
|
||||
$this->clientError(sprintf(_("Theme not available: %s."), $values['theme']));
|
||||
}
|
||||
@ -444,6 +450,10 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$this->input('logo', _('Site logo'), 'Logo for the site (full URL)');
|
||||
$this->unli();
|
||||
|
||||
$this->li();
|
||||
$this->input('ssllogo', _('SSL logo'), 'Logo to show on SSL pages');
|
||||
$this->unli();
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
|
||||
$this->out->elementEnd('fieldset');
|
||||
|
@ -139,7 +139,42 @@ class Design extends Memcached_DataObject
|
||||
|
||||
static function url($filename)
|
||||
{
|
||||
if (StatusNet::isHTTPS()) {
|
||||
|
||||
$sslserver = common_config('background', 'sslserver');
|
||||
|
||||
if (empty($sslserver)) {
|
||||
// XXX: this assumes that background dir == site dir + /background/
|
||||
// not true if there's another server
|
||||
if (is_string(common_config('site', 'sslserver')) &&
|
||||
mb_strlen(common_config('site', 'sslserver')) > 0) {
|
||||
$server = common_config('site', 'sslserver');
|
||||
} else if (common_config('site', 'server')) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
$path = common_config('site', 'path') . '/background/';
|
||||
} else {
|
||||
$server = $sslserver;
|
||||
$path = common_config('background', 'sslpath');
|
||||
if (empty($path)) {
|
||||
$path = common_config('background', 'path');
|
||||
}
|
||||
}
|
||||
|
||||
$protocol = 'https';
|
||||
|
||||
} else {
|
||||
|
||||
$path = common_config('background', 'path');
|
||||
|
||||
$server = common_config('background', 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
$protocol = 'http';
|
||||
}
|
||||
|
||||
if ($path[strlen($path)-1] != '/') {
|
||||
$path .= '/';
|
||||
@ -149,25 +184,6 @@ class Design extends Memcached_DataObject
|
||||
$path = '/'.$path;
|
||||
}
|
||||
|
||||
$server = common_config('background', 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
$ssl = common_config('background', 'ssl');
|
||||
|
||||
if (is_null($ssl)) { // null -> guess
|
||||
if (common_config('site', 'ssl') == 'always' &&
|
||||
!common_config('background', 'server')) {
|
||||
$ssl = true;
|
||||
} else {
|
||||
$ssl = false;
|
||||
}
|
||||
}
|
||||
|
||||
$protocol = ($ssl) ? 'https' : 'http';
|
||||
|
||||
return $protocol.'://'.$server.$path.$filename;
|
||||
}
|
||||
|
||||
|
@ -261,13 +261,51 @@ class File extends Memcached_DataObject
|
||||
// TRANS: Client exception thrown if a file upload does not have a valid name.
|
||||
throw new ClientException(_("Invalid filename."));
|
||||
}
|
||||
if(common_config('site','private')) {
|
||||
|
||||
if (common_config('site','private')) {
|
||||
|
||||
return common_local_url('getfile',
|
||||
array('filename' => $filename));
|
||||
|
||||
}
|
||||
|
||||
if (StatusNet::isHTTPS()) {
|
||||
|
||||
$sslserver = common_config('attachments', 'sslserver');
|
||||
|
||||
if (empty($sslserver)) {
|
||||
// XXX: this assumes that background dir == site dir + /file/
|
||||
// not true if there's another server
|
||||
if (is_string(common_config('site', 'sslserver')) &&
|
||||
mb_strlen(common_config('site', 'sslserver')) > 0) {
|
||||
$server = common_config('site', 'sslserver');
|
||||
} else if (common_config('site', 'server')) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
$path = common_config('site', 'path') . '/file/';
|
||||
} else {
|
||||
$server = $sslserver;
|
||||
$path = common_config('attachments', 'sslpath');
|
||||
if (empty($path)) {
|
||||
$path = common_config('attachments', 'path');
|
||||
}
|
||||
}
|
||||
|
||||
$protocol = 'https';
|
||||
|
||||
} else {
|
||||
|
||||
$path = common_config('attachments', 'path');
|
||||
$server = common_config('attachments', 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
$ssl = common_config('attachments', 'ssl');
|
||||
|
||||
$protocol = ($ssl) ? 'https' : 'http';
|
||||
}
|
||||
|
||||
if ($path[strlen($path)-1] != '/') {
|
||||
$path .= '/';
|
||||
@ -277,28 +315,8 @@ class File extends Memcached_DataObject
|
||||
$path = '/'.$path;
|
||||
}
|
||||
|
||||
$server = common_config('attachments', 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
$ssl = common_config('attachments', 'ssl');
|
||||
|
||||
if (is_null($ssl)) { // null -> guess
|
||||
if (common_config('site', 'ssl') == 'always' &&
|
||||
!common_config('attachments', 'server')) {
|
||||
$ssl = true;
|
||||
} else {
|
||||
$ssl = false;
|
||||
}
|
||||
}
|
||||
|
||||
$protocol = ($ssl) ? 'https' : 'http';
|
||||
|
||||
return $protocol.'://'.$server.$path.$filename;
|
||||
}
|
||||
}
|
||||
|
||||
function getEnclosure(){
|
||||
$enclosure = (object) array();
|
||||
|
@ -559,16 +559,27 @@ class User_group extends Memcached_DataObject
|
||||
function delete()
|
||||
{
|
||||
if ($this->id) {
|
||||
|
||||
// Safe to delete in bulk for now
|
||||
|
||||
$related = array('Group_inbox',
|
||||
'Group_block',
|
||||
'Group_member',
|
||||
'Related_group');
|
||||
|
||||
Event::handle('UserGroupDeleteRelated', array($this, &$related));
|
||||
|
||||
foreach ($related as $cls) {
|
||||
|
||||
$inst = new $cls();
|
||||
$inst->group_id = $this->id;
|
||||
$inst->delete();
|
||||
|
||||
if ($inst->find()) {
|
||||
while ($inst->fetch()) {
|
||||
$dup = clone($inst);
|
||||
$dup->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// And related groups in the other direction...
|
||||
@ -584,6 +595,10 @@ class User_group extends Memcached_DataObject
|
||||
if ($local) {
|
||||
$local->delete();
|
||||
}
|
||||
|
||||
// blow the cached ids
|
||||
self::blow('user_group:notice_ids:%d', $this->id);
|
||||
|
||||
} else {
|
||||
common_log(LOG_WARN, "Ambiguous user_group->delete(); skipping related tables.");
|
||||
}
|
||||
|
880
extlib/OAuth.php
880
extlib/OAuth.php
File diff suppressed because it is too large
Load Diff
@ -175,8 +175,9 @@ class Action extends HTMLOutputter // lawsuit
|
||||
$this->element('link', array('rel' => 'shortcut icon',
|
||||
'href' => Theme::path('favicon.ico')));
|
||||
} else {
|
||||
// favicon.ico should be HTTPS if the rest of the page is
|
||||
$this->element('link', array('rel' => 'shortcut icon',
|
||||
'href' => common_path('favicon.ico')));
|
||||
'href' => common_path('favicon.ico', StatusNet::isHTTPS())));
|
||||
}
|
||||
|
||||
if (common_config('site', 'mobile')) {
|
||||
@ -397,7 +398,10 @@ class Action extends HTMLOutputter // lawsuit
|
||||
Event::handle('EndShowSiteNotice', array($this));
|
||||
}
|
||||
if (common_logged_in()) {
|
||||
if (Event::handle('StartShowNoticeForm', array($this))) {
|
||||
$this->showNoticeForm();
|
||||
Event::handle('EndShowNoticeForm', array($this));
|
||||
}
|
||||
} else {
|
||||
$this->showAnonymousMessage();
|
||||
}
|
||||
@ -422,11 +426,35 @@ class Action extends HTMLOutputter // lawsuit
|
||||
}
|
||||
$this->elementStart('a', array('class' => 'url home bookmark',
|
||||
'href' => $url));
|
||||
if (common_config('site', 'logo') || file_exists(Theme::file('logo.png'))) {
|
||||
|
||||
if (StatusNet::isHTTPS()) {
|
||||
$logoUrl = common_config('site', 'ssllogo');
|
||||
if (empty($logoUrl)) {
|
||||
// if logo is an uploaded file, try to fall back to HTTPS file URL
|
||||
$httpUrl = common_config('site', 'logo');
|
||||
if (!empty($httpUrl)) {
|
||||
$f = File::staticGet('url', $httpUrl);
|
||||
if (!empty($f) && !empty($f->filename)) {
|
||||
// this will handle the HTTPS case
|
||||
$logoUrl = File::url($f->filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$logoUrl = common_config('site', 'logo');
|
||||
}
|
||||
|
||||
if (empty($logoUrl) && file_exists(Theme::file('logo.png'))) {
|
||||
// This should handle the HTTPS case internally
|
||||
$logoUrl = Theme::path('logo.png');
|
||||
}
|
||||
|
||||
if (!empty($logoUrl)) {
|
||||
$this->element('img', array('class' => 'logo photo',
|
||||
'src' => (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png'),
|
||||
'src' => $logoUrl,
|
||||
'alt' => common_config('site', 'name')));
|
||||
}
|
||||
|
||||
$this->text(' ');
|
||||
$this->element('span', array('class' => 'fn org'), common_config('site', 'name'));
|
||||
$this->elementEnd('a');
|
||||
@ -891,8 +919,26 @@ class Action extends HTMLOutputter // lawsuit
|
||||
case 'cc': // fall through
|
||||
default:
|
||||
$this->elementStart('p');
|
||||
|
||||
$image = common_config('license', 'image');
|
||||
$sslimage = common_config('license', 'sslimage');
|
||||
|
||||
if (StatusNet::isHTTPS()) {
|
||||
if (!empty($sslimage)) {
|
||||
$url = $sslimage;
|
||||
} else if (preg_match('#^http://i.creativecommons.org/#', $image)) {
|
||||
// CC support HTTPS on their images
|
||||
$url = preg_replace('/^http/', 'https', $image);
|
||||
} else {
|
||||
// Better to show mixed content than no content
|
||||
$url = $image;
|
||||
}
|
||||
} else {
|
||||
$url = $image;
|
||||
}
|
||||
|
||||
$this->element('img', array('id' => 'license_cc',
|
||||
'src' => common_config('license', 'image'),
|
||||
'src' => $url,
|
||||
'alt' => common_config('license', 'title'),
|
||||
'width' => '80',
|
||||
'height' => '15'));
|
||||
|
@ -1246,23 +1246,29 @@ class ApiAction extends Action
|
||||
|
||||
// Do not emit error header for JSONP
|
||||
if (!isset($this->callback)) {
|
||||
header('HTTP/1.1 '.$code.' '.$status_string);
|
||||
header('HTTP/1.1 ' . $code . ' ' . $status_string);
|
||||
}
|
||||
|
||||
if ($format == 'xml') {
|
||||
switch($format) {
|
||||
case 'xml':
|
||||
$this->initDocument('xml');
|
||||
$this->elementStart('hash');
|
||||
$this->element('error', null, $msg);
|
||||
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
||||
$this->elementEnd('hash');
|
||||
$this->endDocument('xml');
|
||||
} elseif ($format == 'json'){
|
||||
break;
|
||||
case 'json':
|
||||
$this->initDocument('json');
|
||||
$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
|
||||
print(json_encode($error_array));
|
||||
$this->endDocument('json');
|
||||
} else {
|
||||
|
||||
break;
|
||||
case 'text':
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
print $msg;
|
||||
break;
|
||||
default:
|
||||
// If user didn't request a useful format, throw a regular client error
|
||||
throw new ClientException($msg, $code);
|
||||
}
|
||||
|
@ -30,13 +30,12 @@
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiaction.php';
|
||||
require_once INSTALLDIR . '/lib/apioauthstore.php';
|
||||
|
||||
/**
|
||||
* Base action for API OAuth enpoints. Clean up the
|
||||
* the request, and possibly some other common things
|
||||
* here.
|
||||
* request. Some other common functions.
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
@ -44,7 +43,7 @@ require_once INSTALLDIR . '/lib/apioauthstore.php';
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ApiOauthAction extends Action
|
||||
class ApiOauthAction extends ApiAction
|
||||
{
|
||||
/**
|
||||
* Is this a read-only action?
|
||||
@ -77,6 +76,12 @@ class ApiOauthAction extends Action
|
||||
self::cleanRequest();
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up the request so the OAuth library doesn't find
|
||||
* any extra parameters or anything else it's not expecting.
|
||||
* I'm looking at you, p parameter.
|
||||
*/
|
||||
|
||||
static function cleanRequest()
|
||||
{
|
||||
// kill evil effects of magical slashing
|
||||
@ -86,31 +91,19 @@ class ApiOauthAction extends Action
|
||||
}
|
||||
|
||||
// strip out the p param added in index.php
|
||||
|
||||
// XXX: should we strip anything else? Or alternatively
|
||||
// only allow a known list of params?
|
||||
unset($_GET['p']);
|
||||
unset($_POST['p']);
|
||||
unset($_REQUEST['p']);
|
||||
|
||||
$queryArray = explode('&', $_SERVER['QUERY_STRING']);
|
||||
|
||||
for ($i = 0; $i < sizeof($queryArray); $i++) {
|
||||
if (substr($queryArray[$i], 0, 2) == 'p=') {
|
||||
unset($queryArray[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
function getCallback($url, $params)
|
||||
{
|
||||
foreach ($params as $k => $v) {
|
||||
$url = $this->appendQueryVar($url,
|
||||
OAuthUtil::urlencode_rfc3986($k),
|
||||
OAuthUtil::urlencode_rfc3986($v));
|
||||
$_SERVER['QUERY_STRING'] = implode('&', $queryArray);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
function appendQueryVar($url, $k, $v) {
|
||||
$url = preg_replace('/(.*)(\?|&)' . $k . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
|
||||
$url = substr($url, 0, -1);
|
||||
if (strpos($url, '?') === false) {
|
||||
return ($url . '?' . $k . '=' . $v);
|
||||
} else {
|
||||
return ($url . '&' . $k . '=' . $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,33 +71,37 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||
}
|
||||
}
|
||||
|
||||
function new_access_token($token, $consumer)
|
||||
function new_access_token($token, $consumer, $verifier)
|
||||
{
|
||||
common_debug('new_access_token("'.$token->key.'","'.$consumer->key.'")', __FILE__);
|
||||
common_debug(
|
||||
'new_access_token("' . $token->key . '","' . $consumer->key. '","' . $verifier . '")',
|
||||
__FILE__
|
||||
);
|
||||
|
||||
$rt = new Token();
|
||||
|
||||
$rt->consumer_key = $consumer->key;
|
||||
$rt->tok = $token->key;
|
||||
$rt->type = 0; // request
|
||||
|
||||
$app = Oauth_application::getByConsumerKey($consumer->key);
|
||||
assert(!empty($app));
|
||||
|
||||
if (empty($app)) {
|
||||
common_debug("empty app!");
|
||||
}
|
||||
if ($rt->find(true) && $rt->state == 1 && $rt->verifier == $verifier) { // authorized
|
||||
|
||||
if ($rt->find(true) && $rt->state == 1) { // authorized
|
||||
common_debug('request token found.', __FILE__);
|
||||
|
||||
// find the associated user of the app
|
||||
|
||||
$appUser = new Oauth_application_user();
|
||||
|
||||
$appUser->application_id = $app->id;
|
||||
$appUser->token = $rt->tok;
|
||||
|
||||
$result = $appUser->find(true);
|
||||
|
||||
if (!empty($result)) {
|
||||
common_debug("Oath app user found.");
|
||||
common_debug("Ouath app user found.");
|
||||
} else {
|
||||
common_debug("Oauth app user not found. app id $app->id token $rt->tok");
|
||||
return null;
|
||||
@ -110,6 +114,8 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||
$at->tok = common_good_rand(16);
|
||||
$at->secret = common_good_rand(16);
|
||||
$at->type = 1; // access
|
||||
$at->verifier = $verifier;
|
||||
$at->verified_callback = $rt->verified_callback; // 1.0a
|
||||
$at->created = DB_DataObject_Cast::dateTime();
|
||||
|
||||
if (!$at->insert()) {
|
||||
@ -183,4 +189,40 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||
throw new Exception(_('Failed to delete revoked token.'));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new request token. Overrided to support OAuth 1.0a callback
|
||||
*
|
||||
* @param OAuthConsumer $consumer the OAuth Consumer for this token
|
||||
* @param string $callback the verified OAuth callback URL
|
||||
*
|
||||
* @return OAuthToken $token a new unauthorized OAuth request token
|
||||
*/
|
||||
|
||||
function new_request_token($consumer, $callback)
|
||||
{
|
||||
$t = new Token();
|
||||
$t->consumer_key = $consumer->key;
|
||||
$t->tok = common_good_rand(16);
|
||||
$t->secret = common_good_rand(16);
|
||||
$t->type = 0; // request
|
||||
$t->state = 0; // unauthorized
|
||||
$t->verified_callback = $callback;
|
||||
|
||||
if ($callback === 'oob') {
|
||||
// six digit pin
|
||||
$t->verifier = mt_rand(0, 9999999);
|
||||
} else {
|
||||
$t->verifier = common_good_rand(8);
|
||||
}
|
||||
|
||||
$t->created = DB_DataObject_Cast::dateTime();
|
||||
if (!$t->insert()) {
|
||||
return null;
|
||||
} else {
|
||||
return new OAuthToken($t->tok, $t->secret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
* Copyright (C) 2008-2010 StatusNet, Inc.
|
||||
*
|
||||
* 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
|
||||
@ -32,7 +32,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/lib/error.php';
|
||||
require_once INSTALLDIR . '/lib/error.php';
|
||||
|
||||
/**
|
||||
* Class for displaying HTTP client errors
|
||||
@ -90,4 +90,26 @@ class ClientErrorAction extends ErrorAction
|
||||
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* To specify additional HTTP headers for the action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function extraHeaders()
|
||||
{
|
||||
$status_string = @self::$status[$this->code];
|
||||
header('HTTP/1.1 '.$this->code.' '.$status_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page title.
|
||||
*
|
||||
* @return page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
return @self::$status[$this->code];
|
||||
}
|
||||
}
|
||||
|
@ -118,9 +118,9 @@ class ConnectSettingsNav extends Widget
|
||||
}
|
||||
|
||||
$menu['oauthconnectionssettings'] = array(
|
||||
// TRANS: Menu item for OAth connection settings.
|
||||
// TRANS: Menu item for OuAth connection settings.
|
||||
_m('MENU','Connections'),
|
||||
// TRANS: Tooltip for connected applications (Connections through OAth) menu item.
|
||||
// TRANS: Tooltip for connected applications (Connections through OAuth) menu item.
|
||||
_('Authorized connected applications')
|
||||
);
|
||||
|
||||
|
@ -37,6 +37,7 @@ $default =
|
||||
'path' => $_path,
|
||||
'logfile' => null,
|
||||
'logo' => null,
|
||||
'ssllogo' => null,
|
||||
'logdebug' => false,
|
||||
'fancy' => false,
|
||||
'locale_path' => INSTALLDIR.'/locale',
|
||||
@ -210,6 +211,8 @@ $default =
|
||||
array('server' => null,
|
||||
'dir' => INSTALLDIR . '/file/',
|
||||
'path' => $_path . '/file/',
|
||||
'sslserver' => null,
|
||||
'sslpath' => null,
|
||||
'ssl' => null,
|
||||
'supported' => array('image/png',
|
||||
'image/jpeg',
|
||||
|
@ -33,6 +33,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/info.php';
|
||||
|
||||
/**
|
||||
* Base class for displaying HTTP errors
|
||||
*
|
||||
@ -42,7 +44,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
class ErrorAction extends Action
|
||||
class ErrorAction extends InfoAction
|
||||
{
|
||||
static $status = array();
|
||||
|
||||
@ -52,7 +54,7 @@ class ErrorAction extends Action
|
||||
|
||||
function __construct($message, $code, $output='php://output', $indent=null)
|
||||
{
|
||||
parent::__construct($output, $indent);
|
||||
parent::__construct(null, $message, $output, $indent);
|
||||
|
||||
$this->code = $code;
|
||||
$this->message = $message;
|
||||
@ -64,43 +66,6 @@ class ErrorAction extends Action
|
||||
$this->prepare($_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* To specify additional HTTP headers for the action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function extraHeaders()
|
||||
{
|
||||
$status_string = @self::$status[$this->code];
|
||||
header('HTTP/1.1 '.$this->code.' '.$status_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display content.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$this->element('div', array('class' => 'error'), $this->message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page title.
|
||||
*
|
||||
* @return page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
return @self::$status[$this->code];
|
||||
}
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function showPage()
|
||||
{
|
||||
if ($this->minimal) {
|
||||
@ -116,32 +81,16 @@ class ErrorAction extends Action
|
||||
exit();
|
||||
}
|
||||
|
||||
// Overload a bunch of stuff so the page isn't too bloated
|
||||
|
||||
function showBody()
|
||||
/**
|
||||
* Display content.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$this->elementStart('body', array('id' => 'error'));
|
||||
$this->elementStart('div', array('id' => 'wrap'));
|
||||
$this->showHeader();
|
||||
$this->showCore();
|
||||
$this->showFooter();
|
||||
$this->elementEnd('div');
|
||||
$this->elementEnd('body');
|
||||
$this->element('div', array('class' => 'error'), $this->message);
|
||||
}
|
||||
|
||||
function showCore()
|
||||
{
|
||||
$this->elementStart('div', array('id' => 'core'));
|
||||
$this->showContentBlock();
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showHeader()
|
||||
{
|
||||
$this->elementStart('div', array('id' => 'header'));
|
||||
$this->showLogo();
|
||||
$this->showPrimaryNav();
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -352,17 +352,43 @@ class HTMLOutputter extends XMLOutputter
|
||||
*/
|
||||
function script($src, $type='text/javascript')
|
||||
{
|
||||
if(Event::handle('StartScriptElement', array($this,&$src,&$type))) {
|
||||
if (Event::handle('StartScriptElement', array($this,&$src,&$type))) {
|
||||
|
||||
$url = parse_url($src);
|
||||
|
||||
if( empty($url['scheme']) && empty($url['host']) && empty($url['query']) && empty($url['fragment']))
|
||||
{
|
||||
if (empty($url['scheme']) && empty($url['host']) && empty($url['query']) && empty($url['fragment'])) {
|
||||
|
||||
// XXX: this seems like a big assumption
|
||||
|
||||
if (strpos($src, 'plugins/') === 0 || strpos($src, 'local/') === 0) {
|
||||
|
||||
$src = common_path($src) . '?version=' . STATUSNET_VERSION;
|
||||
$src = common_path($src, StatusNet::isHTTPS()) . '?version=' . STATUSNET_VERSION;
|
||||
|
||||
}else{
|
||||
} else {
|
||||
|
||||
if (StatusNet::isHTTPS()) {
|
||||
|
||||
$sslserver = common_config('javascript', 'sslserver');
|
||||
|
||||
if (empty($sslserver)) {
|
||||
if (is_string(common_config('site', 'sslserver')) &&
|
||||
mb_strlen(common_config('site', 'sslserver')) > 0) {
|
||||
$server = common_config('site', 'sslserver');
|
||||
} else if (common_config('site', 'server')) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
$path = common_config('site', 'path') . '/js/';
|
||||
} else {
|
||||
$server = $sslserver;
|
||||
$path = common_config('javascript', 'sslpath');
|
||||
if (empty($path)) {
|
||||
$path = common_config('javascript', 'path');
|
||||
}
|
||||
}
|
||||
|
||||
$protocol = 'https';
|
||||
|
||||
} else {
|
||||
|
||||
$path = common_config('javascript', 'path');
|
||||
|
||||
@ -370,6 +396,15 @@ class HTMLOutputter extends XMLOutputter
|
||||
$path = common_config('site', 'path') . '/js/';
|
||||
}
|
||||
|
||||
$server = common_config('javascript', 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
$protocol = 'http';
|
||||
}
|
||||
|
||||
if ($path[strlen($path)-1] != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
@ -378,25 +413,6 @@ class HTMLOutputter extends XMLOutputter
|
||||
$path = '/'.$path;
|
||||
}
|
||||
|
||||
$server = common_config('javascript', 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
$ssl = common_config('javascript', 'ssl');
|
||||
|
||||
if (is_null($ssl)) { // null -> guess
|
||||
if (common_config('site', 'ssl') == 'always' &&
|
||||
!common_config('javascript', 'server')) {
|
||||
$ssl = true;
|
||||
} else {
|
||||
$ssl = false;
|
||||
}
|
||||
}
|
||||
|
||||
$protocol = ($ssl) ? 'https' : 'http';
|
||||
|
||||
$src = $protocol.'://'.$server.$path.$src . '?version=' . STATUSNET_VERSION;
|
||||
}
|
||||
}
|
||||
@ -453,7 +469,7 @@ class HTMLOutputter extends XMLOutputter
|
||||
if(file_exists(Theme::file($src,$theme))){
|
||||
$src = Theme::path($src, $theme);
|
||||
}else{
|
||||
$src = common_path($src);
|
||||
$src = common_path($src, StatusNet::isHTTPS());
|
||||
}
|
||||
$src.= '?version=' . STATUSNET_VERSION;
|
||||
}
|
||||
|
118
lib/info.php
Normal file
118
lib/info.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Information action
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for displaying dialog box like messages to the user
|
||||
*
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
* @see ErrorAction
|
||||
*/
|
||||
|
||||
class InfoAction extends Action
|
||||
{
|
||||
var $message = null;
|
||||
|
||||
function __construct($title, $message, $output='php://output', $indent=null)
|
||||
{
|
||||
parent::__construct($output, $indent);
|
||||
|
||||
$this->message = $message;
|
||||
$this->title = $title;
|
||||
|
||||
// XXX: hack alert: usually we aren't going to
|
||||
// call this page directly, but because it's
|
||||
// an action it needs an args array anyway
|
||||
$this->prepare($_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page title.
|
||||
*
|
||||
* @return page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
return empty($this->title) ? '' : $this->title;
|
||||
}
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Overload a bunch of stuff so the page isn't too bloated
|
||||
|
||||
function showBody()
|
||||
{
|
||||
$this->elementStart('body', array('id' => 'error'));
|
||||
$this->elementStart('div', array('id' => 'wrap'));
|
||||
$this->showHeader();
|
||||
$this->showCore();
|
||||
$this->showFooter();
|
||||
$this->elementEnd('div');
|
||||
$this->elementEnd('body');
|
||||
}
|
||||
|
||||
function showCore()
|
||||
{
|
||||
$this->elementStart('div', array('id' => 'core'));
|
||||
$this->showContentBlock();
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
function showHeader()
|
||||
{
|
||||
$this->elementStart('div', array('id' => 'header'));
|
||||
$this->showLogo();
|
||||
$this->showPrimaryNav();
|
||||
$this->elementEnd('div');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display content.
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showContent()
|
||||
{
|
||||
$this->element('div', array('class' => 'info'), $this->message);
|
||||
}
|
||||
|
||||
}
|
@ -55,6 +55,17 @@ class StatusNetOAuthDataStore extends OAuthDataStore
|
||||
}
|
||||
}
|
||||
|
||||
function getTokenByKey($token_key)
|
||||
{
|
||||
$t = new Token();
|
||||
$t->tok = $token_key;
|
||||
if ($t->find(true)) {
|
||||
return $t;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// http://oauth.net/core/1.0/#nonce
|
||||
// "The Consumer SHALL then generate a Nonce value that is unique for
|
||||
// all requests with that timestamp."
|
||||
@ -317,6 +328,7 @@ class StatusNetOAuthDataStore extends OAuthDataStore
|
||||
function add_avatar($profile, $url)
|
||||
{
|
||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||
try {
|
||||
copy($url, $temp_filename);
|
||||
$imagefile = new ImageFile($profile->id, $temp_filename);
|
||||
$filename = Avatar::filename($profile->id,
|
||||
@ -324,6 +336,10 @@ class StatusNetOAuthDataStore extends OAuthDataStore
|
||||
null,
|
||||
common_timestamp());
|
||||
rename($temp_filename, Avatar::path($filename));
|
||||
} catch (Exception $e) {
|
||||
unlink($temp_filename);
|
||||
throw $e;
|
||||
}
|
||||
return $profile->setOriginal($filename);
|
||||
}
|
||||
|
||||
|
@ -96,4 +96,27 @@ class ServerErrorAction extends ErrorAction
|
||||
|
||||
$this->showPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* To specify additional HTTP headers for the action
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function extraHeaders()
|
||||
{
|
||||
$status_string = @self::$status[$this->code];
|
||||
header('HTTP/1.1 '.$this->code.' '.$status_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Page title.
|
||||
*
|
||||
* @return page title
|
||||
*/
|
||||
|
||||
function title()
|
||||
{
|
||||
return @self::$status[$this->code];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
* @category Exception
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2008 StatusNet, Inc.
|
||||
* @copyright 2008-2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -169,7 +169,6 @@ class StatusNet
|
||||
return $sites;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fire initialization events for all instantiated plugins.
|
||||
*/
|
||||
@ -387,6 +386,18 @@ class StatusNet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we running from the web with HTTPS?
|
||||
*
|
||||
* @return boolean true if we're running with HTTPS; else false
|
||||
*/
|
||||
|
||||
static function isHTTPS()
|
||||
{
|
||||
// There are some exceptions to this; add them here!
|
||||
return $_SERVER['HTTPS'];
|
||||
}
|
||||
}
|
||||
|
||||
class NoConfigException extends Exception
|
||||
|
@ -116,6 +116,33 @@ class Theme
|
||||
|
||||
protected function relativeThemePath($group, $fallbackSubdir, $name)
|
||||
{
|
||||
if (StatusNet::isHTTPS()) {
|
||||
|
||||
$sslserver = common_config($group, 'sslserver');
|
||||
|
||||
if (empty($sslserver)) {
|
||||
if (is_string(common_config('site', 'sslserver')) &&
|
||||
mb_strlen(common_config('site', 'sslserver')) > 0) {
|
||||
$server = common_config('site', 'sslserver');
|
||||
} else if (common_config('site', 'server')) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
$path = common_config('site', 'path') . '/';
|
||||
if ($fallbackSubdir) {
|
||||
$path .= $fallbackSubdir . '/';
|
||||
}
|
||||
} else {
|
||||
$server = $sslserver;
|
||||
$path = common_config($group, 'sslpath');
|
||||
if (empty($path)) {
|
||||
$path = common_config($group, 'path');
|
||||
}
|
||||
}
|
||||
|
||||
$protocol = 'https';
|
||||
|
||||
} else {
|
||||
|
||||
$path = common_config($group, 'path');
|
||||
|
||||
if (empty($path)) {
|
||||
@ -125,6 +152,15 @@ class Theme
|
||||
}
|
||||
}
|
||||
|
||||
$server = common_config($group, 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
$protocol = 'http';
|
||||
}
|
||||
|
||||
if ($path[strlen($path)-1] != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
@ -133,27 +169,7 @@ class Theme
|
||||
$path = '/'.$path;
|
||||
}
|
||||
|
||||
$server = common_config($group, 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
$ssl = common_config($group, 'ssl');
|
||||
|
||||
if (is_null($ssl)) { // null -> guess
|
||||
if (common_config('site', 'ssl') == 'always' &&
|
||||
!common_config($group, 'server')) {
|
||||
$ssl = true;
|
||||
} else {
|
||||
$ssl = false;
|
||||
}
|
||||
}
|
||||
|
||||
$protocol = ($ssl) ? 'https' : 'http';
|
||||
|
||||
$path = $protocol . '://'.$server.$path.$name;
|
||||
return $path;
|
||||
return $protocol.'://'.$server.$path.$name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@ class ModHelperPlugin extends Plugin
|
||||
|
||||
function onUserRightsCheck($profile, $right, &$result)
|
||||
{
|
||||
if ($right == Right::SILENCEUSER || $right == Right::SANDBOXUSER) {
|
||||
if ($right == Right::SILENCEUSER) {
|
||||
// Hrm.... really we should confirm that the *other* user isn't privleged. :)
|
||||
if ($profile->hasRole('modhelper')) {
|
||||
$result = true;
|
||||
|
@ -46,7 +46,15 @@ class UserxrdAction extends XrdAction
|
||||
}
|
||||
} else {
|
||||
$this->user = User::staticGet('uri', $this->uri);
|
||||
if (empty($this->user)) {
|
||||
// try and get it by profile url
|
||||
$profile = Profile::staticGet('profileurl', $this->uri);
|
||||
if (!empty($profile)) {
|
||||
$this->user = User::staticGet('id', $profile->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->user) {
|
||||
$this->clientError(_m('No such user.'), 404);
|
||||
return false;
|
||||
|
@ -1053,6 +1053,7 @@ class Ostatus_profile extends Memcached_DataObject
|
||||
// @fixme this should be better encapsulated
|
||||
// ripped from oauthstore.php (for old OMB client)
|
||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||
try {
|
||||
if (!copy($url, $temp_filename)) {
|
||||
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
||||
}
|
||||
@ -1069,6 +1070,10 @@ class Ostatus_profile extends Memcached_DataObject
|
||||
null,
|
||||
common_timestamp());
|
||||
rename($temp_filename, Avatar::path($filename));
|
||||
} catch (Exception $e) {
|
||||
unlink($temp_filename);
|
||||
throw $e;
|
||||
}
|
||||
// @fixme hardcoded chmod is lame, but seems to be necessary to
|
||||
// keep from accidentally saving images from command-line (queues)
|
||||
// that can't be read from web server, which causes hard-to-notice
|
||||
|
@ -37,6 +37,7 @@ class XrdAction extends Action
|
||||
function handle()
|
||||
{
|
||||
$nick = $this->user->nickname;
|
||||
$profile = $this->user->getProfile();
|
||||
|
||||
if (empty($this->xrd)) {
|
||||
$xrd = new XRD();
|
||||
@ -47,10 +48,28 @@ class XrdAction extends Action
|
||||
if (empty($xrd->subject)) {
|
||||
$xrd->subject = Discovery::normalize($this->uri);
|
||||
}
|
||||
$xrd->alias[] = $this->user->uri;
|
||||
|
||||
// Possible aliases for the user
|
||||
|
||||
$uris = array($this->user->uri, $profile->profileurl);
|
||||
|
||||
// FIXME: Webfinger generation code should live somewhere on its own
|
||||
|
||||
$path = common_config('site', 'path');
|
||||
|
||||
if (empty($path)) {
|
||||
$uris[] = sprintf('acct:%s@%s', $nick, common_config('site', 'server'));
|
||||
}
|
||||
|
||||
foreach ($uris as $uri) {
|
||||
if ($uri != $xrd->subject) {
|
||||
$xrd->alias[] = $uri;
|
||||
}
|
||||
}
|
||||
|
||||
$xrd->links[] = array('rel' => Discovery::PROFILEPAGE,
|
||||
'type' => 'text/html',
|
||||
'href' => $this->user->uri);
|
||||
'href' => $profile->profileurl);
|
||||
|
||||
$xrd->links[] = array('rel' => Discovery::UPDATESFROM,
|
||||
'href' => common_local_url('ApiTimelineUser',
|
||||
@ -66,7 +85,7 @@ class XrdAction extends Action
|
||||
// XFN
|
||||
$xrd->links[] = array('rel' => 'http://gmpg.org/xfn/11',
|
||||
'type' => 'text/html',
|
||||
'href' => $this->user->uri);
|
||||
'href' => $profile->profileurl);
|
||||
// FOAF
|
||||
$xrd->links[] = array('rel' => 'describedby',
|
||||
'type' => 'application/rdf+xml',
|
||||
|
@ -2,7 +2,8 @@
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Plugin that requires the user to have a validated email address before they can post notices
|
||||
* Plugin that requires the user to have a validated email address before they
|
||||
* can post notices
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
@ -32,44 +33,64 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin for requiring a validated email before posting.
|
||||
*
|
||||
* Enable this plugin using addPlugin('RequireValidatedEmail');
|
||||
*
|
||||
* @category Plugin
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Brion Vibber <brion@status.net>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class RequireValidatedEmailPlugin extends Plugin
|
||||
{
|
||||
// Users created before this time will be grandfathered in
|
||||
// without the validation requirement.
|
||||
public $grandfatherCutoff=null;
|
||||
/**
|
||||
* Users created before this time will be grandfathered in
|
||||
* without the validation requirement.
|
||||
*/
|
||||
|
||||
// If OpenID plugin is installed, users with a verified OpenID
|
||||
// association whose provider URL matches one of these regexes
|
||||
// will be considered to be sufficiently valid for our needs.
|
||||
//
|
||||
// For example, to trust WikiHow and Wikipedia OpenID users:
|
||||
//
|
||||
// addPlugin('RequireValidatedEmailPlugin', array(
|
||||
// 'trustedOpenIDs' => array(
|
||||
// '!^http://\w+\.wikihow\.com/!',
|
||||
// '!^http://\w+\.wikipedia\.org/!',
|
||||
// ),
|
||||
// ));
|
||||
public $trustedOpenIDs=array();
|
||||
public $grandfatherCutoff = null;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
/**
|
||||
* If OpenID plugin is installed, users with a verified OpenID
|
||||
* association whose provider URL matches one of these regexes
|
||||
* will be considered to be sufficiently valid for our needs.
|
||||
*
|
||||
* For example, to trust WikiHow and Wikipedia OpenID users:
|
||||
*
|
||||
* addPlugin('RequireValidatedEmailPlugin', array(
|
||||
* 'trustedOpenIDs' => array(
|
||||
* '!^http://\w+\.wikihow\.com/!',
|
||||
* '!^http://\w+\.wikipedia\.org/!',
|
||||
* ),
|
||||
* ));
|
||||
*/
|
||||
|
||||
public $trustedOpenIDs = array();
|
||||
|
||||
/**
|
||||
* Event handler for notice saves; rejects the notice
|
||||
* if user's address isn't validated.
|
||||
*
|
||||
* @param Notice $notice
|
||||
* @param Notice $notice The notice being saved
|
||||
*
|
||||
* @return bool hook result code
|
||||
*/
|
||||
|
||||
function onStartNoticeSave($notice)
|
||||
{
|
||||
$user = User::staticGet('id', $notice->profile_id);
|
||||
if (!empty($user)) { // it's a remote notice
|
||||
if (!$this->validated($user)) {
|
||||
throw new ClientException(_m("You must validate your email address before posting."));
|
||||
$msg = _m("You must validate your email address before posting.");
|
||||
throw new ClientException($msg);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -79,7 +100,8 @@ class RequireValidatedEmailPlugin extends Plugin
|
||||
* Event handler for registration attempts; rejects the registration
|
||||
* if email field is missing.
|
||||
*
|
||||
* @param RegisterAction $action
|
||||
* @param Action $action Action being executed
|
||||
*
|
||||
* @return bool hook result code
|
||||
*/
|
||||
function onStartRegistrationTry($action)
|
||||
@ -100,7 +122,8 @@ class RequireValidatedEmailPlugin extends Plugin
|
||||
* Check if a user has a validated email address or has been
|
||||
* otherwise grandfathered in.
|
||||
*
|
||||
* @param User $user
|
||||
* @param User $user User to valide
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validated($user)
|
||||
@ -113,7 +136,11 @@ class RequireValidatedEmailPlugin extends Plugin
|
||||
|
||||
// Give other plugins a chance to override, if they can validate
|
||||
// that somebody's ok despite a non-validated email.
|
||||
Event::handle('RequireValidatedEmailPlugin_Override', array($user, &$knownGood));
|
||||
|
||||
// FIXME: This isn't how to do it! Use Start*/End* instead
|
||||
|
||||
Event::handle('RequireValidatedEmailPlugin_Override',
|
||||
array($user, &$knownGood));
|
||||
|
||||
return $knownGood;
|
||||
}
|
||||
@ -122,8 +149,9 @@ class RequireValidatedEmailPlugin extends Plugin
|
||||
* Check if a user was created before the grandfathering cutoff.
|
||||
* If so, we won't need to check for validation.
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
* @param User $user User to check
|
||||
*
|
||||
* @return bool true if user is grandfathered
|
||||
*/
|
||||
protected function grandfathered($user)
|
||||
{
|
||||
@ -141,13 +169,20 @@ class RequireValidatedEmailPlugin extends Plugin
|
||||
* Override for RequireValidatedEmail plugin. If we have a user who's
|
||||
* not validated an e-mail, but did come from a trusted provider,
|
||||
* we'll consider them ok.
|
||||
*
|
||||
* @param User $user User to check
|
||||
*
|
||||
* @return bool true if user has a trusted OpenID.
|
||||
*/
|
||||
|
||||
function hasTrustedOpenID($user)
|
||||
{
|
||||
if ($this->trustedOpenIDs && class_exists('User_openid')) {
|
||||
foreach ($this->trustedOpenIDs as $regex) {
|
||||
$oid = new User_openid();
|
||||
|
||||
$oid->user_id = $user->id;
|
||||
|
||||
$oid->find();
|
||||
while ($oid->fetch()) {
|
||||
if (preg_match($regex, $oid->canonical)) {
|
||||
@ -159,14 +194,45 @@ class RequireValidatedEmailPlugin extends Plugin
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add version information for this plugin.
|
||||
*
|
||||
* @param array &$versions Array of associative arrays of version data
|
||||
*
|
||||
* @return boolean hook value
|
||||
*/
|
||||
|
||||
function onPluginVersion(&$versions)
|
||||
{
|
||||
$versions[] = array('name' => 'Require Validated Email',
|
||||
$versions[] =
|
||||
array('name' => 'Require Validated Email',
|
||||
'version' => STATUSNET_VERSION,
|
||||
'author' => 'Craig Andrews, Evan Prodromou, Brion Vibber',
|
||||
'homepage' => 'http://status.net/wiki/Plugin:RequireValidatedEmail',
|
||||
'author' => 'Craig Andrews, '.
|
||||
'Evan Prodromou, '.
|
||||
'Brion Vibber',
|
||||
'homepage' =>
|
||||
'http://status.net/wiki/Plugin:RequireValidatedEmail',
|
||||
'rawdescription' =>
|
||||
_m('The Require Validated Email plugin disables posting for accounts that do not have a validated email address.'));
|
||||
_m('Disables posting without a validated email address.'));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the notice form if the user isn't able to post.
|
||||
*
|
||||
* @param Action $action action being shown
|
||||
*
|
||||
* @return boolean hook value
|
||||
*/
|
||||
|
||||
function onStartShowNoticeForm($action)
|
||||
{
|
||||
$user = common_current_user();
|
||||
if (!empty($user)) { // it's a remote notice
|
||||
if (!$this->validated($user)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -174,6 +174,7 @@ class WikiHowProfilePlugin extends Plugin
|
||||
// @fixme this should be better encapsulated
|
||||
// ripped from OStatus via oauthstore.php (for old OMB client)
|
||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||
try {
|
||||
if (!copy($url, $temp_filename)) {
|
||||
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
||||
}
|
||||
@ -188,6 +189,10 @@ class WikiHowProfilePlugin extends Plugin
|
||||
null,
|
||||
common_timestamp());
|
||||
rename($temp_filename, Avatar::path($filename));
|
||||
} catch (Exception $e) {
|
||||
unlink($temp_filename);
|
||||
throw $e;
|
||||
}
|
||||
$profile->setOriginal($filename);
|
||||
}
|
||||
}
|
||||
|
@ -436,6 +436,7 @@ class YammerImporter
|
||||
// @fixme this should be better encapsulated
|
||||
// ripped from oauthstore.php (for old OMB client)
|
||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||
try {
|
||||
if (!copy($url, $temp_filename)) {
|
||||
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
||||
}
|
||||
@ -448,6 +449,10 @@ class YammerImporter
|
||||
null,
|
||||
common_timestamp());
|
||||
rename($temp_filename, Avatar::path($filename));
|
||||
} catch (Exception $e) {
|
||||
unlink($temp_filename);
|
||||
throw $e;
|
||||
}
|
||||
// @fixme hardcoded chmod is lame, but seems to be necessary to
|
||||
// keep from accidentally saving images from command-line (queues)
|
||||
// that can't be read from web server, which causes hard-to-notice
|
||||
|
@ -1,22 +1,160 @@
|
||||
Some very rough test scripts for hitting up the OAuth endpoints.
|
||||
|
||||
Note: this works best if you register an OAuth application, leaving
|
||||
the callback URL blank.
|
||||
These instructions assume you understand the basics of how OAuth
|
||||
works. You may want to read up about it first. Here are some good
|
||||
resources for learning about OAuth:
|
||||
|
||||
Put your instance info and consumer key and secret in oauth.ini
|
||||
http://hueniverse.com/oauth/
|
||||
http://tools.ietf.org/html/rfc5849
|
||||
|
||||
Example usage:
|
||||
--------------
|
||||
To use these scripts (and OAuth in general) first you will need to
|
||||
register and OAuth client application with your StatusNet instance:
|
||||
|
||||
php getrequesttoken.php
|
||||
http://example.status.net/settings/oauthapps
|
||||
|
||||
Gets a request token, token secret and a url to authorize it. Once
|
||||
you authorize the request token you can exchange it for an access token...
|
||||
oauth.ini
|
||||
---------
|
||||
|
||||
php exchangetokens.php --oauth_token=b9a79548a88c1aa9a5bea73103c6d41d --token_secret=4a47d9337fc0202a14ab552e17a3b657
|
||||
Using oauth.ini.sample as a guide, put your StatusNet OAuth endpoints
|
||||
and consumer key and secret in a file called oauth.ini and save it
|
||||
in the same directory as these scripts.
|
||||
|
||||
Once you have your access token, go ahead and try a protected API
|
||||
resource:
|
||||
fetch_temp_creds.php
|
||||
--------------------
|
||||
|
||||
php verifycreds.php --oauth_token=cf2de7665f0dda0a82c2dc39b01be7f9 --token_secret=4524c3b712200138e1a4cff2e9ca83d8
|
||||
Will fetch a request token, token secret and a URL to authorize the
|
||||
token. Once you authorize the request token, you can exchange it
|
||||
for an access token.
|
||||
|
||||
example usage:
|
||||
|
||||
$ php fetch_temp_creds.php
|
||||
Request Token
|
||||
- oauth_token = 89d481e376edc622f08da5791e6a4446
|
||||
- oauth_token_secret = 6d028bcd1ea125cbed7da2f254219885
|
||||
Authorize URL
|
||||
http://example.status.net/api/oauth/authorize?oauth_token=89d481e376edc622f08da5791e6a4446
|
||||
|
||||
Now paste the Authorize URL into your browser and authorize your temporary credentials.
|
||||
|
||||
fetch_token_creds.php
|
||||
---------------------
|
||||
|
||||
After you have authorized your request token, you will be presented
|
||||
with a verifier code, or pin, in your browser, which you will need
|
||||
to get an access token. Make sure you copy it into a text buffer
|
||||
or write it down or something. Then call fetch_token_credentials.php
|
||||
to exchange your temporary credentials for real token credentials.
|
||||
|
||||
example usage:
|
||||
|
||||
$ php fetch_token_creds.php -t 89d481e376edc622f08da5791e6a4446 -s 6d028bcd1ea125cbed7da2f254219885 -v 305162
|
||||
Access Token
|
||||
- oauth_token = 9b354df102d8e2b4621122c85d8d045c
|
||||
- oauth_token_secret = 1800a88f1574b47d595214a74e5b1ec5
|
||||
|
||||
|
||||
oauth_verify_credentials.php
|
||||
----------------------------
|
||||
|
||||
Now you should have real token credentials (an OAuth access token)
|
||||
and you can access protected API resources. This is an example
|
||||
script that calls /api/account/verify_credentials.xml.
|
||||
|
||||
example usage:
|
||||
|
||||
$ php oauth_verify_creds.php -t 80305cd15c5c69834364ac02d7f9178c -s 673e3b2978b1b92c8edbfe172505fee1
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<user xmlns:statusnet="http://status.net/schema/api/1/">
|
||||
<id>23</id>
|
||||
<name>zach</name>
|
||||
<screen_name>zach</screen_name>
|
||||
<location></location>
|
||||
<description></description>
|
||||
<profile_image_url>http://example.status.net/theme/default/default-avatar-stream.png</profile_image_url>
|
||||
<url></url>
|
||||
<protected>false</protected>
|
||||
<followers_count>0</followers_count>
|
||||
<profile_background_color></profile_background_color>
|
||||
<profile_text_color></profile_text_color>
|
||||
<profile_link_color></profile_link_color>
|
||||
<profile_sidebar_fill_color></profile_sidebar_fill_color>
|
||||
<profile_sidebar_border_color></profile_sidebar_border_color>
|
||||
<friends_count>0</friends_count>
|
||||
<created_at>Thu Sep 30 23:11:00 +0000 2010</created_at>
|
||||
<favourites_count>0</favourites_count>
|
||||
<utc_offset>0</utc_offset>
|
||||
<time_zone>UTC</time_zone>
|
||||
<profile_background_image_url></profile_background_image_url>
|
||||
<profile_background_tile>false</profile_background_tile>
|
||||
<statuses_count>4</statuses_count>
|
||||
<following>true</following>
|
||||
<statusnet:blocking>false</statusnet:blocking>
|
||||
<notifications>true</notifications>
|
||||
<status>
|
||||
<text>gar</text>
|
||||
<truncated>false</truncated>
|
||||
<created_at>Wed Oct 06 23:40:14 +0000 2010</created_at>
|
||||
<in_reply_to_status_id></in_reply_to_status_id>
|
||||
<source>web</source>
|
||||
<id>7</id>
|
||||
<in_reply_to_user_id></in_reply_to_user_id>
|
||||
<in_reply_to_screen_name></in_reply_to_screen_name>
|
||||
<geo></geo>
|
||||
<favorited>false</favorited>
|
||||
<statusnet:html>gar</statusnet:html>
|
||||
</status>
|
||||
<statusnet:profile_url>http://example.status.net/statusnet/zach</statusnet:profile_url>
|
||||
</user>
|
||||
|
||||
oauth_post_notice.php
|
||||
---------------------
|
||||
|
||||
This is another test script that lets you post a notice via OAuth.
|
||||
|
||||
example usage:
|
||||
|
||||
$ php oauth_post_notice.php -t 80305cd15c5c69834364ac02d7f9178c -s 673e3b2978b1b92c8edbfe172505fee1 -u 'Test test test...'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<status xmlns:statusnet="http://status.net/schema/api/1/">
|
||||
<text>Test test test...</text>
|
||||
<truncated>false</truncated>
|
||||
<created_at>Fri Oct 08 02:37:35 +0000 2010</created_at>
|
||||
<in_reply_to_status_id></in_reply_to_status_id>
|
||||
<source><a href="http://banana.com" rel="nofollow">Banana</a></source>
|
||||
<id>8</id>
|
||||
<in_reply_to_user_id></in_reply_to_user_id>
|
||||
<in_reply_to_screen_name></in_reply_to_screen_name>
|
||||
<geo></geo>
|
||||
<favorited>false</favorited>
|
||||
<user>
|
||||
<id>23</id>
|
||||
<name>zach</name>
|
||||
<screen_name>zach</screen_name>
|
||||
<location></location>
|
||||
<description></description>
|
||||
<profile_image_url>http://example.status.net/statusnet/theme/default/default-avatar-stream.png</profile_image_url>
|
||||
<url></url>
|
||||
<protected>false</protected>
|
||||
<followers_count>0</followers_count>
|
||||
<profile_background_color></profile_background_color>
|
||||
<profile_text_color></profile_text_color>
|
||||
<profile_link_color></profile_link_color>
|
||||
<profile_sidebar_fill_color></profile_sidebar_fill_color>
|
||||
<profile_sidebar_border_color></profile_sidebar_border_color>
|
||||
<friends_count>0</friends_count>
|
||||
<created_at>Thu Sep 30 23:11:00 +0000 2010</created_at>
|
||||
<favourites_count>0</favourites_count>
|
||||
<utc_offset>0</utc_offset>
|
||||
<time_zone>UTC</time_zone>
|
||||
<profile_background_image_url></profile_background_image_url>
|
||||
<profile_background_tile>false</profile_background_tile>
|
||||
<statuses_count>5</statuses_count>
|
||||
<following>true</following>
|
||||
<statusnet:blocking>false</statusnet:blocking>
|
||||
<notifications>true</notifications>
|
||||
<statusnet:profile_url>http://example.status.net/statusnet/zach</statusnet:profile_url>
|
||||
</user>
|
||||
<statusnet:html>Test test test...</statusnet:html>
|
||||
</status>
|
||||
|
||||
|
@ -1,105 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - a distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
|
||||
|
||||
require_once INSTALLDIR . '/extlib/OAuth.php';
|
||||
|
||||
$ini = parse_ini_file("oauth.ini");
|
||||
|
||||
$test_consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||
|
||||
$at_endpoint = $ini['apiroot'] . $ini['access_token_url'];
|
||||
|
||||
$shortoptions = 't:s:';
|
||||
$longoptions = array('oauth_token=', 'token_secret=');
|
||||
|
||||
$helptext = <<<END_OF_ETOKENS_HELP
|
||||
exchangetokens.php [options]
|
||||
Exchange an authorized OAuth request token for an access token
|
||||
|
||||
-t --oauth_token authorized request token
|
||||
-s --token_secret authorized request token secret
|
||||
|
||||
END_OF_ETOKENS_HELP;
|
||||
|
||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||
|
||||
$token = null;
|
||||
$token_secret = null;
|
||||
|
||||
if (have_option('t', 'oauth_token')) {
|
||||
$token = get_option_value('oauth_token');
|
||||
}
|
||||
|
||||
if (have_option('s', 'token_secret')) {
|
||||
$token_secret = get_option_value('s', 'token_secret');
|
||||
}
|
||||
|
||||
if (empty($token)) {
|
||||
print "Please specify a request token.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (empty($token_secret)) {
|
||||
print "Please specify a request token secret.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$rt = new OAuthToken($token, $token_secret);
|
||||
common_debug("Exchange request token = " . var_export($rt, true));
|
||||
|
||||
$parsed = parse_url($at_endpoint);
|
||||
$params = array();
|
||||
parse_str($parsed['query'], $params);
|
||||
|
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
|
||||
$req_req = OAuthRequest::from_consumer_and_token($test_consumer, $rt, "GET", $at_endpoint, $params);
|
||||
$req_req->sign_request($hmac_method, $test_consumer, $rt);
|
||||
|
||||
$r = httpRequest($req_req->to_url());
|
||||
|
||||
common_debug("Exchange request token = " . var_export($rt, true));
|
||||
common_debug("Exchange tokens URL: " . $req_req->to_url());
|
||||
|
||||
$body = $r->getBody();
|
||||
|
||||
$token_stuff = array();
|
||||
parse_str($body, $token_stuff);
|
||||
|
||||
print 'Access token : ' . $token_stuff['oauth_token'] . "\n";
|
||||
print 'Access token secret : ' . $token_stuff['oauth_token_secret'] . "\n";
|
||||
|
||||
function httpRequest($url)
|
||||
{
|
||||
$request = HTTPClient::start();
|
||||
|
||||
$request->setConfig(array(
|
||||
'follow_redirects' => true,
|
||||
'connect_timeout' => 120,
|
||||
'timeout' => 120,
|
||||
'ssl_verify_peer' => false,
|
||||
'ssl_verify_host' => false
|
||||
));
|
||||
|
||||
return $request->get($url);
|
||||
}
|
||||
|
106
tests/oauth/fetch_temp_creds.php
Executable file
106
tests/oauth/fetch_temp_creds.php
Executable file
@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - a distributed open-source microblogging tool
|
||||
* Copyright (C) 2010, StatusNet, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
|
||||
|
||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||
require_once INSTALLDIR . '/extlib/OAuth.php';
|
||||
|
||||
$ini = parse_ini_file("oauth.ini");
|
||||
|
||||
// Check to make sure we have everything we need from the ini file
|
||||
foreach(array('consumer_key', 'consumer_secret', 'apiroot', 'request_token_url') as $inikey) {
|
||||
if (empty($ini[$inikey])) {
|
||||
print "You forgot to specify a $inikey in your oauth.ini file.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
$consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||
$endpoint = $ini['apiroot'] . $ini['request_token_url'];
|
||||
$parsed = parse_url($endpoint);
|
||||
$params = array();
|
||||
|
||||
parse_str($parsed['query'], $params);
|
||||
$params['oauth_callback'] = 'oob'; // out-of-band
|
||||
|
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
|
||||
try {
|
||||
$req = OAuthRequest::from_consumer_and_token(
|
||||
$consumer,
|
||||
null,
|
||||
"POST",
|
||||
$endpoint,
|
||||
$params
|
||||
);
|
||||
$req->sign_request($hmac_method, $consumer, NULL);
|
||||
$r = httpRequest($endpoint, $req->to_postdata());
|
||||
} catch (Exception $e) {
|
||||
// oh noez
|
||||
print $e->getMessage();
|
||||
print "\nOAuth Request:\n";
|
||||
var_dump($req);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$body = $r->getBody();
|
||||
$tokenStuff = array();
|
||||
|
||||
parse_str($body, $tokenStuff);
|
||||
|
||||
$tok = $tokenStuff['oauth_token'];
|
||||
$confirmed = $tokenStuff['oauth_callback_confirmed'];
|
||||
|
||||
if (empty($tokenStuff['oauth_token'])
|
||||
|| empty($tokenStuff['oauth_token_secret'])
|
||||
|| empty($confirmed)
|
||||
|| $confirmed != 'true')
|
||||
{
|
||||
print "Error! HTTP response body: $body\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$authurl = $ini['apiroot'] . $ini['authorize_url'] . '?oauth_token=' . $tok;
|
||||
|
||||
print "Request Token\n";
|
||||
print ' - oauth_token = ' . $tokenStuff['oauth_token'] . "\n";
|
||||
print ' - oauth_token_secret = ' . $tokenStuff['oauth_token_secret'] . "\n";
|
||||
print "Authorize URL\n $authurl\n\n";
|
||||
print "Now paste the Authorize URL into your browser and authorize your temporary credentials.\n";
|
||||
|
||||
function httpRequest($endpoint, $poststr)
|
||||
{
|
||||
$request = HTTPClient::start();
|
||||
|
||||
$request->setConfig(
|
||||
array(
|
||||
'follow_redirects' => true,
|
||||
'connect_timeout' => 120,
|
||||
'timeout' => 120,
|
||||
'ssl_verify_peer' => false,
|
||||
'ssl_verify_host' => false
|
||||
)
|
||||
);
|
||||
|
||||
// Turn signed request query string back into an array
|
||||
parse_str($poststr, $postdata);
|
||||
return $request->post($endpoint, null, $postdata);
|
||||
}
|
146
tests/oauth/fetch_token_creds.php
Executable file
146
tests/oauth/fetch_token_creds.php
Executable file
@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - a distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
|
||||
|
||||
require_once INSTALLDIR . '/extlib/OAuth.php';
|
||||
|
||||
$ini = parse_ini_file("oauth.ini");
|
||||
|
||||
// Check to make sure we have everything we need from the ini file
|
||||
foreach(array('consumer_key', 'consumer_secret', 'apiroot', 'access_token_url') as $inikey) {
|
||||
if (empty($ini[$inikey])) {
|
||||
print "You forgot to specify a $inikey in your oauth.ini file.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
$consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||
|
||||
$endpoint = $ini['apiroot'] . $ini['access_token_url'];
|
||||
|
||||
$shortoptions = 't:s:v:';
|
||||
$longoptions = array('oauth_token=', 'oauth_token_secret=', 'oauth_verifier=');
|
||||
|
||||
$helptext = <<<END_OF_ETOKENS_HELP
|
||||
fetch_token_creds.php [options]
|
||||
|
||||
Exchange authorized OAuth temporary credentials for token credentials
|
||||
(an authorized request token for an access token)
|
||||
|
||||
-t --oauth_token authorized request token
|
||||
-s --oauth_token_secret authorized request token secret
|
||||
-v --oauth_verifier authorized request token verifier
|
||||
|
||||
|
||||
END_OF_ETOKENS_HELP;
|
||||
|
||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||
|
||||
$token = $secret = $verifier = null;
|
||||
|
||||
if (have_option('t', 'oauth_token')) {
|
||||
$token = get_option_value('t', 'oauth_token');
|
||||
}
|
||||
|
||||
if (have_option('s', 'oauth_token_secret')) {
|
||||
$secret = get_option_value('s', 'oauth_token_secret');
|
||||
}
|
||||
|
||||
if (have_option('v', 'oauth_verifier')) {
|
||||
$verifier = get_option_value('v', 'oauth_verifier');
|
||||
}
|
||||
|
||||
if (empty($token)) {
|
||||
print "Please specify the request token (--help for help).\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (empty($secret)) {
|
||||
print "Please specify the request token secret (--help for help).\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (empty($verifier)) {
|
||||
print "Please specify the request token verifier (--help for help).\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$rtok = new OAuthToken($token, $secret);
|
||||
$parsed = parse_url($endpoint);
|
||||
parse_str($parsed['query'], $params);
|
||||
|
||||
$params['oauth_verifier'] = $verifier; // 1.0a
|
||||
|
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
|
||||
try {
|
||||
|
||||
$oauthReq = OAuthRequest::from_consumer_and_token(
|
||||
$consumer,
|
||||
$rtok,
|
||||
"POST",
|
||||
$endpoint,
|
||||
$params
|
||||
);
|
||||
|
||||
$oauthReq->sign_request($hmac_method, $consumer, $rtok);
|
||||
|
||||
$httpReq = httpRequest($endpoint, $oauthReq->to_postdata());
|
||||
$body = $httpReq->getBody();
|
||||
|
||||
} catch (Exception $e) {
|
||||
// oh noez
|
||||
print $e->getMessage();
|
||||
print "\nOAuth Request:\n";
|
||||
var_dump($oauthReq);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$tokenStuff = array();
|
||||
parse_str($body, $tokenStuff);
|
||||
|
||||
if (empty($tokenStuff['oauth_token']) || empty($tokenStuff['oauth_token_secret'])) {
|
||||
print "Error! HTTP response body: $body\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print "Access Token\n";
|
||||
print ' - oauth_token = ' . $tokenStuff['oauth_token'] . "\n";
|
||||
print ' - oauth_token_secret = ' . $tokenStuff['oauth_token_secret'] . "\n";
|
||||
|
||||
function httpRequest($endpoint, $poststr)
|
||||
{
|
||||
$request = HTTPClient::start();
|
||||
|
||||
$request->setConfig(
|
||||
array(
|
||||
'follow_redirects' => true,
|
||||
'connect_timeout' => 120,
|
||||
'timeout' => 120,
|
||||
'ssl_verify_peer' => false,
|
||||
'ssl_verify_host' => false
|
||||
)
|
||||
);
|
||||
|
||||
parse_str($poststr, $postdata);
|
||||
return $request->post($endpoint, null, $postdata);
|
||||
}
|
||||
|
@ -1,71 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
* StatusNet - a distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
|
||||
|
||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||
require_once INSTALLDIR . '/extlib/OAuth.php';
|
||||
|
||||
$ini = parse_ini_file("oauth.ini");
|
||||
|
||||
$test_consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||
|
||||
$rt_endpoint = $ini['apiroot'] . $ini['request_token_url'];
|
||||
|
||||
$parsed = parse_url($rt_endpoint);
|
||||
$params = array();
|
||||
|
||||
parse_str($parsed['query'], $params);
|
||||
|
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
|
||||
$req_req = OAuthRequest::from_consumer_and_token($test_consumer, NULL, "GET", $rt_endpoint, $params);
|
||||
$req_req->sign_request($hmac_method, $test_consumer, NULL);
|
||||
|
||||
$r = httpRequest($req_req->to_url());
|
||||
|
||||
$body = $r->getBody();
|
||||
|
||||
$token_stuff = array();
|
||||
parse_str($body, $token_stuff);
|
||||
|
||||
$authurl = $ini['apiroot'] . $ini['authorize_url'] . '?oauth_token=' . $token_stuff['oauth_token'];
|
||||
|
||||
print 'Request token : ' . $token_stuff['oauth_token'] . "\n";
|
||||
print 'Request token secret : ' . $token_stuff['oauth_token_secret'] . "\n";
|
||||
print "Authorize URL : $authurl\n";
|
||||
|
||||
//var_dump($req_req);
|
||||
|
||||
function httpRequest($url)
|
||||
{
|
||||
$request = HTTPClient::start();
|
||||
|
||||
$request->setConfig(array(
|
||||
'follow_redirects' => true,
|
||||
'connect_timeout' => 120,
|
||||
'timeout' => 120,
|
||||
'ssl_verify_peer' => false,
|
||||
'ssl_verify_host' => false
|
||||
));
|
||||
|
||||
return $request->get($url);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
; Setup OAuth info here
|
||||
apiroot = "http://YOURSTATUSNET/api"
|
||||
apiroot = "https://YOURSTATUSNET/api"
|
||||
|
||||
request_token_url = "/oauth/request_token"
|
||||
authorize_url = "/oauth/authorize"
|
@ -22,15 +22,15 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
|
||||
|
||||
require_once INSTALLDIR . '/extlib/OAuth.php';
|
||||
|
||||
$shortoptions = 'o:s:u:';
|
||||
$shortoptions = 't:s:u:';
|
||||
$longoptions = array('oauth_token=', 'token_secret=', 'update=');
|
||||
|
||||
$helptext = <<<END_OF_VERIFY_HELP
|
||||
statusupdate.php [options]
|
||||
Update your status using OAuth
|
||||
oauth_post_notice.php [options]
|
||||
Update your status via OAuth
|
||||
|
||||
-o --oauth_token access token
|
||||
-s --token_secret access token secret
|
||||
-t --oauth_token access token
|
||||
-s --oauth_token_secret access token secret
|
||||
-u --update status update
|
||||
|
||||
|
||||
@ -42,12 +42,12 @@ $update = null;
|
||||
|
||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||
|
||||
if (have_option('o', 'oauth_token')) {
|
||||
$token = get_option_value('oauth_token');
|
||||
if (have_option('t', 'oauth_token')) {
|
||||
$token = get_option_value('t', 'oauth_token');
|
||||
}
|
||||
|
||||
if (have_option('s', 'token_secret')) {
|
||||
$token_secret = get_option_value('s', 'token_secret');
|
||||
if (have_option('s', 'oauth_token_secret')) {
|
||||
$token_secret = get_option_value('s', 'oauth_token_secret');
|
||||
}
|
||||
|
||||
if (have_option('u', 'update')) {
|
||||
@ -70,46 +70,55 @@ if (empty($update)) {
|
||||
}
|
||||
|
||||
$ini = parse_ini_file("oauth.ini");
|
||||
|
||||
$test_consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||
|
||||
$consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||
$endpoint = $ini['apiroot'] . '/statuses/update.xml';
|
||||
|
||||
print "$endpoint\n";
|
||||
|
||||
$at = new OAuthToken($token, $token_secret);
|
||||
$atok = new OAuthToken($token, $token_secret);
|
||||
|
||||
$parsed = parse_url($endpoint);
|
||||
$params = array();
|
||||
parse_str($parsed['query'], $params);
|
||||
|
||||
$params['status'] = $update;
|
||||
|
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
|
||||
$req_req = OAuthRequest::from_consumer_and_token($test_consumer, $at, 'POST', $endpoint, $params);
|
||||
$req_req->sign_request($hmac_method, $test_consumer, $at);
|
||||
try {
|
||||
|
||||
$r = httpRequest($req_req->to_url());
|
||||
$oauthReq = OAuthRequest::from_consumer_and_token(
|
||||
$consumer,
|
||||
$atok,
|
||||
'POST',
|
||||
$endpoint,
|
||||
$params
|
||||
);
|
||||
|
||||
$body = $r->getBody();
|
||||
$oauthReq->sign_request($hmac_method, $consumer, $atok);
|
||||
|
||||
print "$body\n";
|
||||
$httpReq = httpRequest($endpoint, $oauthReq->to_postdata());
|
||||
|
||||
//print $req_req->to_url() . "\n\n";
|
||||
print $httpReq->getBody();
|
||||
|
||||
function httpRequest($url)
|
||||
} catch (Exception $e) {
|
||||
print "Error! . $e->getMessage() . 'HTTP reponse body: " . $httpReq->getBody();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function httpRequest($endpoint, $poststr)
|
||||
{
|
||||
$request = HTTPClient::start();
|
||||
|
||||
$request->setConfig(array(
|
||||
$request->setConfig(
|
||||
array(
|
||||
'follow_redirects' => true,
|
||||
'connect_timeout' => 120,
|
||||
'timeout' => 120,
|
||||
'ssl_verify_peer' => false,
|
||||
'ssl_verify_host' => false
|
||||
));
|
||||
)
|
||||
);
|
||||
|
||||
return $request->post($url);
|
||||
// Turn signed request query string back into an array
|
||||
parse_str($poststr, $postdata);
|
||||
return $request->post($endpoint, null, $postdata);
|
||||
}
|
||||
|
@ -22,15 +22,15 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
|
||||
|
||||
require_once INSTALLDIR . '/extlib/OAuth.php';
|
||||
|
||||
$shortoptions = 'o:s:';
|
||||
$longoptions = array('oauth_token=', 'token_secret=');
|
||||
$shortoptions = 't:s:';
|
||||
$longoptions = array('oauth_token=', 'oauth_token_secret=');
|
||||
|
||||
$helptext = <<<END_OF_VERIFY_HELP
|
||||
verifycreds.php [options]
|
||||
Use an access token to verify credentials thru the api
|
||||
oauth_verify_creds.php [options]
|
||||
Access /api/account/verify_credentials.xml with OAuth
|
||||
|
||||
-o --oauth_token access token
|
||||
-s --token_secret access token secret
|
||||
-t --oauth_token access token
|
||||
-s --oauth_token_secret access token secret
|
||||
|
||||
END_OF_VERIFY_HELP;
|
||||
|
||||
@ -39,63 +39,69 @@ $token_secret = null;
|
||||
|
||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||
|
||||
if (have_option('o', 'oauth_token')) {
|
||||
$token = get_option_value('oauth_token');
|
||||
if (have_option('t', 'oauth_token')) {
|
||||
$token = get_option_value('t', 'oauth_token');
|
||||
}
|
||||
|
||||
if (have_option('s', 'token_secret')) {
|
||||
$token_secret = get_option_value('s', 'token_secret');
|
||||
$token_secret = get_option_value('s', 'oauth_token_secret');
|
||||
}
|
||||
|
||||
if (empty($token)) {
|
||||
print "Please specify an access token.\n";
|
||||
print "Please specify an access token (--help for help).\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (empty($token_secret)) {
|
||||
print "Please specify an access token secret.\n";
|
||||
print "Please specify an access token secret (--help for help).\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$ini = parse_ini_file("oauth.ini");
|
||||
|
||||
$test_consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||
|
||||
$consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||
$endpoint = $ini['apiroot'] . '/account/verify_credentials.xml';
|
||||
|
||||
print "$endpoint\n";
|
||||
|
||||
$at = new OAuthToken($token, $token_secret);
|
||||
|
||||
$atok = new OAuthToken($token, $token_secret);
|
||||
$parsed = parse_url($endpoint);
|
||||
$params = array();
|
||||
|
||||
parse_str($parsed['query'], $params);
|
||||
|
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
try {
|
||||
|
||||
$req_req = OAuthRequest::from_consumer_and_token($test_consumer, $at, "GET", $endpoint, $params);
|
||||
$req_req->sign_request($hmac_method, $test_consumer, $at);
|
||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
|
||||
$r = httpRequest($req_req->to_url());
|
||||
$oauthReq = OAuthRequest::from_consumer_and_token(
|
||||
$consumer,
|
||||
$atok,
|
||||
"GET",
|
||||
$endpoint,
|
||||
$params
|
||||
);
|
||||
|
||||
$body = $r->getBody();
|
||||
$oauthReq->sign_request($hmac_method, $consumer, $atok);
|
||||
|
||||
print "$body\n";
|
||||
$httpReq = httpRequest($oauthReq->to_url());
|
||||
|
||||
//print $req_req->to_url() . "\n\n";
|
||||
} catch (Exception $e) {
|
||||
print "Error! HTTP response body: " . $httpReq->getBody();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print $httpReq->getBody();
|
||||
|
||||
function httpRequest($url)
|
||||
{
|
||||
$request = HTTPClient::start();
|
||||
|
||||
$request->setConfig(array(
|
||||
$request->setConfig(
|
||||
array(
|
||||
'follow_redirects' => true,
|
||||
'connect_timeout' => 120,
|
||||
'timeout' => 120,
|
||||
'ssl_verify_peer' => false,
|
||||
'ssl_verify_host' => false
|
||||
));
|
||||
)
|
||||
);
|
||||
|
||||
return $request->get($url);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user