Merge remote branch 'gitorious/0.9.x' into 0.9.x
This commit is contained in:
commit
ddb60a8191
|
@ -2,7 +2,8 @@
|
||||||
/**
|
/**
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
* 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
|
* PHP version 5
|
||||||
*
|
*
|
||||||
|
@ -34,7 +35,8 @@ if (!defined('STATUSNET')) {
|
||||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
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
|
* @category API
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
|
@ -45,6 +47,8 @@ require_once INSTALLDIR . '/lib/apioauth.php';
|
||||||
|
|
||||||
class ApiOauthAccessTokenAction extends ApiOauthAction
|
class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||||
{
|
{
|
||||||
|
protected $reqToken = null;
|
||||||
|
protected $verifier = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class handler.
|
* Class handler.
|
||||||
|
@ -65,30 +69,58 @@ class ApiOauthAccessTokenAction extends ApiOauthAction
|
||||||
|
|
||||||
$atok = null;
|
$atok = null;
|
||||||
|
|
||||||
|
// XXX: Insist that oauth_token and oauth_verifier be populated?
|
||||||
|
// Spec doesn't say they MUST be.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$req = OAuthRequest::from_request();
|
$req = OAuthRequest::from_request();
|
||||||
|
|
||||||
|
$this->reqToken = $req->get_parameter('oauth_token');
|
||||||
|
$this->verifier = $req->get_parameter('oauth_verifier');
|
||||||
|
|
||||||
$atok = $server->fetch_access_token($req);
|
$atok = $server->fetch_access_token($req);
|
||||||
|
|
||||||
} catch (OAuthException $e) {
|
} catch (OAuthException $e) {
|
||||||
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
||||||
common_debug(var_export($req, true));
|
common_debug(var_export($req, true));
|
||||||
$this->outputError($e->getMessage());
|
$code = $e->getCode();
|
||||||
return;
|
$this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($atok)) {
|
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 {
|
} 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: application/x-www-form-urlencoded');
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
print $token;
|
||||||
print $msg . "\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ if (!defined('STATUSNET')) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
require_once INSTALLDIR . '/lib/apioauth.php';
|
||||||
|
require_once INSTALLDIR . '/lib/info.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authorize an OAuth request token
|
* Authorize an OAuth request token
|
||||||
|
@ -43,9 +44,10 @@ require_once INSTALLDIR . '/lib/apioauth.php';
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ApiOauthAuthorizeAction extends ApiOauthAction
|
class ApiOauthAuthorizeAction extends Action
|
||||||
{
|
{
|
||||||
var $oauth_token;
|
var $oauthTokenParam;
|
||||||
|
var $reqToken;
|
||||||
var $callback;
|
var $callback;
|
||||||
var $app;
|
var $app;
|
||||||
var $nickname;
|
var $nickname;
|
||||||
|
@ -67,12 +69,17 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
$this->nickname = $this->trimmed('nickname');
|
$this->nickname = $this->trimmed('nickname');
|
||||||
$this->password = $this->arg('password');
|
$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->callback = $this->arg('oauth_callback');
|
||||||
$this->store = new ApiStatusNetOAuthDataStore();
|
$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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -97,14 +104,30 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
|
|
||||||
} else {
|
} 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.'));
|
$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)) {
|
if (empty($this->app)) {
|
||||||
$this->clientError(_('Invalid token.'));
|
$this->clientError(_('Invalid request token.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = $this->app->name;
|
$name = $this->app->name;
|
||||||
|
@ -120,8 +143,8 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
$token = $this->trimmed('token');
|
$token = $this->trimmed('token');
|
||||||
|
|
||||||
if (!$token || $token != common_session_token()) {
|
if (!$token || $token != common_session_token()) {
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
$this->showForm(
|
||||||
'Try again, please.'));
|
_('There was a problem with your session token. Try again, please.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +153,11 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
$user = null;
|
$user = null;
|
||||||
|
|
||||||
if (!common_logged_in()) {
|
if (!common_logged_in()) {
|
||||||
|
|
||||||
|
// XXX Force credentials check?
|
||||||
|
|
||||||
|
// XXX OpenID
|
||||||
|
|
||||||
$user = common_check_user($this->nickname, $this->password);
|
$user = common_check_user($this->nickname, $this->password);
|
||||||
if (empty($user)) {
|
if (empty($user)) {
|
||||||
$this->showForm(_("Invalid nickname / password!"));
|
$this->showForm(_("Invalid nickname / password!"));
|
||||||
|
@ -141,9 +169,15 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
|
|
||||||
if ($this->arg('allow')) {
|
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
|
// Check to see if there was a previous token associated
|
||||||
// with this user/app and kill it. If the user is doing this she
|
// with this user/app and kill it. If the user is doing this she
|
||||||
|
@ -156,8 +190,7 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
common_log_db_error($appUser, 'DELETE', __FILE__);
|
common_log_db_error($appUser, 'DELETE', __FILE__);
|
||||||
throw new ServerException(_('Database error deleting OAuth application user.'));
|
$this->serverError(_('Database error deleting OAuth application user.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,20 +208,19 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
// granted. The OAuth app user record then gets updated
|
// granted. The OAuth app user record then gets updated
|
||||||
// with the new access token and access type.
|
// with the new access token and access type.
|
||||||
|
|
||||||
$appUser->token = $this->oauth_token;
|
$appUser->token = $this->oauthTokenParam;
|
||||||
$appUser->created = common_sql_now();
|
$appUser->created = common_sql_now();
|
||||||
|
|
||||||
$result = $appUser->insert();
|
$result = $appUser->insert();
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
common_log_db_error($appUser, 'INSERT', __FILE__);
|
common_log_db_error($appUser, 'INSERT', __FILE__);
|
||||||
throw new ServerException(_('Database error inserting OAuth application user.'));
|
$this->serverError(_('Database error inserting OAuth application user.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
// is passed in with the request.
|
||||||
|
|
||||||
if (!empty($this->app->callback_url)) {
|
if (!empty($this->app->callback_url)) {
|
||||||
|
@ -197,40 +229,40 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
|
|
||||||
if (!empty($this->callback)) {
|
if (!empty($this->callback)) {
|
||||||
|
|
||||||
$target_url = $this->getCallback($this->callback,
|
$targetUrl = $this->getCallback(
|
||||||
array('oauth_token' => $this->oauth_token));
|
$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 {
|
} 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 {
|
} else {
|
||||||
$this->clientError(_('Unexpected form submission.'));
|
$this->clientError(_('Unexpected form submission.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +308,7 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
_('Allow or deny access'));
|
_('Allow or deny access'));
|
||||||
|
|
||||||
$this->hidden('token', common_session_token());
|
$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->hidden('oauth_callback', $this->callback);
|
||||||
|
|
||||||
$this->elementStart('ul', 'form_data');
|
$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',
|
'class' => 'submit submit form_action-primary',
|
||||||
'name' => 'deny',
|
'name' => 'cancel',
|
||||||
'type' => 'submit',
|
'type' => 'submit',
|
||||||
'value' => _('Deny')));
|
'value' => _('Cancel')));
|
||||||
|
|
||||||
$this->element('input', array('id' => 'allow_submit',
|
$this->element('input', array('id' => 'allow_submit',
|
||||||
'class' => 'submit submit form_action-secondary',
|
'class' => 'submit submit form_action-secondary',
|
||||||
|
@ -348,7 +380,7 @@ class ApiOauthAuthorizeAction extends ApiOauthAction
|
||||||
|
|
||||||
function getInstructions()
|
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
|
// 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
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
*
|
*
|
||||||
* Get an OAuth request token
|
* Issue temporary OAuth credentials (a request token)
|
||||||
*
|
*
|
||||||
* PHP version 5
|
* PHP version 5
|
||||||
*
|
*
|
||||||
|
@ -34,7 +34,7 @@ if (!defined('STATUSNET')) {
|
||||||
require_once INSTALLDIR . '/lib/apioauth.php';
|
require_once INSTALLDIR . '/lib/apioauth.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an OAuth request token
|
* Issue temporary OAuth credentials (a request token)
|
||||||
*
|
*
|
||||||
* @category API
|
* @category API
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
|
@ -58,22 +58,23 @@ class ApiOauthRequestTokenAction extends ApiOauthAction
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
$this->callback = $this->arg('oauth_callback');
|
// XXX: support "force_login" parameter like Twitter? (Forces the user to enter
|
||||||
|
// their credentials to ensure the correct users account is authorized.)
|
||||||
if (!empty($this->callback)) {
|
|
||||||
common_debug("callback: $this->callback");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
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
|
* @param array $args array of arguments
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
@ -85,14 +86,78 @@ class ApiOauthRequestTokenAction extends ApiOauthAction
|
||||||
$server->add_signature_method($hmac_method);
|
$server->add_signature_method($hmac_method);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$req = OAuthRequest::from_request();
|
|
||||||
|
$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);
|
$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) {
|
} catch (OAuthException $e) {
|
||||||
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage());
|
||||||
header('HTTP/1.1 401 Unauthorized');
|
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
// Return 401 for for bad credentials or signature problems,
|
||||||
print $e->getMessage() . "\n";
|
// 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'))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
226
actions/deletegroup.php
Normal file
226
actions/deletegroup.php
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Delete a group
|
||||||
|
*
|
||||||
|
* 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 Group
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Brion Vibber <brion@status.net>
|
||||||
|
* @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/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a group
|
||||||
|
*
|
||||||
|
* This is the action for deleting a group.
|
||||||
|
*
|
||||||
|
* @category Group
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Brion Vibber <brion@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/
|
||||||
|
* @fixme merge more of this code with related variants
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DeletegroupAction extends RedirectingAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare to run
|
||||||
|
*
|
||||||
|
* @fixme merge common setup code with other group actions
|
||||||
|
* @fixme allow group admins to delete their own groups
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
if (!common_logged_in()) {
|
||||||
|
$this->clientError(_('You must be logged in to delete a group.'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nickname_arg = $this->trimmed('nickname');
|
||||||
|
$id = intval($this->arg('id'));
|
||||||
|
if ($id) {
|
||||||
|
$this->group = User_group::staticGet('id', $id);
|
||||||
|
} else if ($nickname_arg) {
|
||||||
|
$nickname = common_canonical_nickname($nickname_arg);
|
||||||
|
|
||||||
|
// Permanent redirect on non-canonical nickname
|
||||||
|
|
||||||
|
if ($nickname_arg != $nickname) {
|
||||||
|
$args = array('nickname' => $nickname);
|
||||||
|
common_redirect(common_local_url('leavegroup', $args), 301);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$local = Local_group::staticGet('nickname', $nickname);
|
||||||
|
|
||||||
|
if (!$local) {
|
||||||
|
$this->clientError(_('No such group.'), 404);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->group = User_group::staticGet('id', $local->group_id);
|
||||||
|
} else {
|
||||||
|
$this->clientError(_('No nickname or ID.'), 404);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->group) {
|
||||||
|
$this->clientError(_('No such group.'), 404);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cur = common_current_user();
|
||||||
|
if (!$cur->hasRight(Right::DELETEGROUP)) {
|
||||||
|
$this->clientError(_('You are not allowed to delete this group.'), 403);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* On POST, delete the group.
|
||||||
|
*
|
||||||
|
* @param array $args unused
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
if ($this->arg('no')) {
|
||||||
|
$this->returnToPrevious();
|
||||||
|
return;
|
||||||
|
} elseif ($this->arg('yes')) {
|
||||||
|
$this->handlePost();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->showPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePost()
|
||||||
|
{
|
||||||
|
$cur = common_current_user();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (Event::handle('StartDeleteGroup', array($this->group))) {
|
||||||
|
$this->group->delete();
|
||||||
|
Event::handle('EndDeleteGroup', array($this->group));
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->serverError(sprintf(_('Could not delete group %2$s.'),
|
||||||
|
$this->group->nickname));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->boolean('ajax')) {
|
||||||
|
$this->startHTML('text/xml;charset=utf-8');
|
||||||
|
$this->elementStart('head');
|
||||||
|
$this->element('title', null, sprintf(_('Deleted group %2$s'),
|
||||||
|
$this->group->nickname));
|
||||||
|
$this->elementEnd('head');
|
||||||
|
$this->elementStart('body');
|
||||||
|
// @fixme add a sensible AJAX response form!
|
||||||
|
$this->elementEnd('body');
|
||||||
|
$this->elementEnd('html');
|
||||||
|
} else {
|
||||||
|
// @fixme if we could direct to the page on which this group
|
||||||
|
// would have shown... that would be awesome
|
||||||
|
common_redirect(common_local_url('groups'),
|
||||||
|
303);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function title() {
|
||||||
|
return _('Delete group');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showContent() {
|
||||||
|
$this->areYouSureForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm with user.
|
||||||
|
* Ripped from DeleteuserAction
|
||||||
|
*
|
||||||
|
* Shows a confirmation form.
|
||||||
|
*
|
||||||
|
* @fixme refactor common code for things like this
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function areYouSureForm()
|
||||||
|
{
|
||||||
|
$id = $this->group->id;
|
||||||
|
$this->elementStart('form', array('id' => 'deletegroup-' . $id,
|
||||||
|
'method' => 'post',
|
||||||
|
'class' => 'form_settings form_entity_block',
|
||||||
|
'action' => common_local_url('deletegroup', array('id' => $this->group->id))));
|
||||||
|
$this->elementStart('fieldset');
|
||||||
|
$this->hidden('token', common_session_token());
|
||||||
|
$this->element('legend', _('Delete group'));
|
||||||
|
if (Event::handle('StartDeleteGroupForm', array($this, $this->group))) {
|
||||||
|
$this->element('p', null,
|
||||||
|
_('Are you sure you want to delete this group? '.
|
||||||
|
'This will clear all data about the group from the '.
|
||||||
|
'database, without a backup. ' .
|
||||||
|
'Public posts to this group will still appear in ' .
|
||||||
|
'individual timelines.'));
|
||||||
|
foreach ($this->args as $k => $v) {
|
||||||
|
if (substr($k, 0, 9) == 'returnto-') {
|
||||||
|
$this->hidden($k, $v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::handle('EndDeleteGroupForm', array($this, $this->group));
|
||||||
|
}
|
||||||
|
$this->submit('form_action-no',
|
||||||
|
// TRANS: Button label on the delete group form.
|
||||||
|
_m('BUTTON','No'),
|
||||||
|
'submit form_action-primary',
|
||||||
|
'no',
|
||||||
|
// TRANS: Submit button title for 'No' when deleting a group.
|
||||||
|
_('Do not delete this group'));
|
||||||
|
$this->submit('form_action-yes',
|
||||||
|
// TRANS: Button label on the delete group form.
|
||||||
|
_m('BUTTON','Yes'),
|
||||||
|
'submit form_action-secondary',
|
||||||
|
'yes',
|
||||||
|
// TRANS: Submit button title for 'Yes' when deleting a group.
|
||||||
|
_('Delete this group'));
|
||||||
|
$this->elementEnd('fieldset');
|
||||||
|
$this->elementEnd('form');
|
||||||
|
}
|
||||||
|
}
|
|
@ -316,6 +316,12 @@ class ShowgroupAction extends GroupDesignAction
|
||||||
Event::handle('EndGroupSubscribe', array($this, $this->group));
|
Event::handle('EndGroupSubscribe', array($this, $this->group));
|
||||||
}
|
}
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
|
if ($cur->hasRight(Right::DELETEGROUP)) {
|
||||||
|
$this->elementStart('li', 'entity_delete');
|
||||||
|
$df = new DeleteGroupForm($this, $this->group);
|
||||||
|
$df->show();
|
||||||
|
$this->elementEnd('li');
|
||||||
|
}
|
||||||
$this->elementEnd('ul');
|
$this->elementEnd('ul');
|
||||||
$this->elementEnd('div');
|
$this->elementEnd('div');
|
||||||
}
|
}
|
||||||
|
|
|
@ -854,6 +854,7 @@ class Profile extends Memcached_DataObject
|
||||||
case Right::SANDBOXUSER:
|
case Right::SANDBOXUSER:
|
||||||
case Right::SILENCEUSER:
|
case Right::SILENCEUSER:
|
||||||
case Right::DELETEUSER:
|
case Right::DELETEUSER:
|
||||||
|
case Right::DELETEGROUP:
|
||||||
$result = $this->hasRole(Profile_role::MODERATOR);
|
$result = $this->hasRole(Profile_role::MODERATOR);
|
||||||
break;
|
break;
|
||||||
case Right::CONFIGURESITE:
|
case Right::CONFIGURESITE:
|
||||||
|
|
|
@ -547,4 +547,46 @@ class User_group extends Memcached_DataObject
|
||||||
$group->query('COMMIT');
|
$group->query('COMMIT');
|
||||||
return $group;
|
return $group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle cascading deletion, on the model of notice and profile.
|
||||||
|
*
|
||||||
|
* This should handle freeing up cached entries for the group's
|
||||||
|
* id, nickname, URI, and aliases. There may be other areas that
|
||||||
|
* are not de-cached in the UI, including the sidebar lists on
|
||||||
|
* GroupsAction
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// And related groups in the other direction...
|
||||||
|
$inst = new Related_group();
|
||||||
|
$inst->related_group_id = $this->id;
|
||||||
|
$inst->delete();
|
||||||
|
|
||||||
|
// Aliases and the local_group entry need to be cleared explicitly
|
||||||
|
// or we'll miss clearing some cache keys; that can make it hard
|
||||||
|
// to create a new group with one of those names or aliases.
|
||||||
|
$this->setAliases(array());
|
||||||
|
$local = Local_group::staticGet('group_id', $this->id);
|
||||||
|
if ($local) {
|
||||||
|
$local->delete();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
common_log(LOG_WARN, "Ambiguous user_group->delete(); skipping related tables.");
|
||||||
|
}
|
||||||
|
parent::delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
912
extlib/OAuth.php
912
extlib/OAuth.php
File diff suppressed because it is too large
Load Diff
|
@ -1244,23 +1244,29 @@ class ApiAction extends Action
|
||||||
|
|
||||||
// Do not emit error header for JSONP
|
// Do not emit error header for JSONP
|
||||||
if (!isset($this->callback)) {
|
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->initDocument('xml');
|
||||||
$this->elementStart('hash');
|
$this->elementStart('hash');
|
||||||
$this->element('error', null, $msg);
|
$this->element('error', null, $msg);
|
||||||
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
||||||
$this->elementEnd('hash');
|
$this->elementEnd('hash');
|
||||||
$this->endDocument('xml');
|
$this->endDocument('xml');
|
||||||
} elseif ($format == 'json'){
|
break;
|
||||||
|
case 'json':
|
||||||
$this->initDocument('json');
|
$this->initDocument('json');
|
||||||
$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
|
$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
|
||||||
print(json_encode($error_array));
|
print(json_encode($error_array));
|
||||||
$this->endDocument('json');
|
$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
|
// If user didn't request a useful format, throw a regular client error
|
||||||
throw new ClientException($msg, $code);
|
throw new ClientException($msg, $code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,13 +30,12 @@
|
||||||
if (!defined('STATUSNET')) {
|
if (!defined('STATUSNET')) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
require_once INSTALLDIR . '/lib/apiaction.php';
|
||||||
require_once INSTALLDIR . '/lib/apioauthstore.php';
|
require_once INSTALLDIR . '/lib/apioauthstore.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base action for API OAuth enpoints. Clean up the
|
* Base action for API OAuth enpoints. Clean up the
|
||||||
* the request, and possibly some other common things
|
* request. Some other common functions.
|
||||||
* here.
|
|
||||||
*
|
*
|
||||||
* @category API
|
* @category API
|
||||||
* @package StatusNet
|
* @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
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class ApiOauthAction extends Action
|
class ApiOauthAction extends ApiAction
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Is this a read-only action?
|
* Is this a read-only action?
|
||||||
|
@ -77,6 +76,12 @@ class ApiOauthAction extends Action
|
||||||
self::cleanRequest();
|
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()
|
static function cleanRequest()
|
||||||
{
|
{
|
||||||
// kill evil effects of magical slashing
|
// kill evil effects of magical slashing
|
||||||
|
@ -86,31 +91,19 @@ class ApiOauthAction extends Action
|
||||||
}
|
}
|
||||||
|
|
||||||
// strip out the p param added in index.php
|
// 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($_GET['p']);
|
||||||
unset($_POST['p']);
|
unset($_POST['p']);
|
||||||
}
|
unset($_REQUEST['p']);
|
||||||
|
|
||||||
function getCallback($url, $params)
|
$queryArray = explode('&', $_SERVER['QUERY_STRING']);
|
||||||
{
|
|
||||||
foreach ($params as $k => $v) {
|
for ($i = 0; $i < sizeof($queryArray); $i++) {
|
||||||
$url = $this->appendQueryVar($url,
|
if (substr($queryArray[$i], 0, 2) == 'p=') {
|
||||||
OAuthUtil::urlencode_rfc3986($k),
|
unset($queryArray[$i]);
|
||||||
OAuthUtil::urlencode_rfc3986($v));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $url;
|
$_SERVER['QUERY_STRING'] = implode('&', $queryArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = new Token();
|
||||||
|
|
||||||
$rt->consumer_key = $consumer->key;
|
$rt->consumer_key = $consumer->key;
|
||||||
$rt->tok = $token->key;
|
$rt->tok = $token->key;
|
||||||
$rt->type = 0; // request
|
$rt->type = 0; // request
|
||||||
|
|
||||||
$app = Oauth_application::getByConsumerKey($consumer->key);
|
$app = Oauth_application::getByConsumerKey($consumer->key);
|
||||||
|
assert(!empty($app));
|
||||||
|
|
||||||
if (empty($app)) {
|
if ($rt->find(true) && $rt->state == 1 && $rt->verifier == $verifier) { // authorized
|
||||||
common_debug("empty app!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($rt->find(true) && $rt->state == 1) { // authorized
|
|
||||||
common_debug('request token found.', __FILE__);
|
common_debug('request token found.', __FILE__);
|
||||||
|
|
||||||
// find the associated user of the app
|
// find the associated user of the app
|
||||||
|
|
||||||
$appUser = new Oauth_application_user();
|
$appUser = new Oauth_application_user();
|
||||||
|
|
||||||
$appUser->application_id = $app->id;
|
$appUser->application_id = $app->id;
|
||||||
$appUser->token = $rt->tok;
|
$appUser->token = $rt->tok;
|
||||||
|
|
||||||
$result = $appUser->find(true);
|
$result = $appUser->find(true);
|
||||||
|
|
||||||
if (!empty($result)) {
|
if (!empty($result)) {
|
||||||
common_debug("Oath app user found.");
|
common_debug("Ouath app user found.");
|
||||||
} else {
|
} else {
|
||||||
common_debug("Oauth app user not found. app id $app->id token $rt->tok");
|
common_debug("Oauth app user not found. app id $app->id token $rt->tok");
|
||||||
return null;
|
return null;
|
||||||
|
@ -106,10 +110,12 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||||
// go ahead and make the access token
|
// go ahead and make the access token
|
||||||
|
|
||||||
$at = new Token();
|
$at = new Token();
|
||||||
$at->consumer_key = $consumer->key;
|
$at->consumer_key = $consumer->key;
|
||||||
$at->tok = common_good_rand(16);
|
$at->tok = common_good_rand(16);
|
||||||
$at->secret = common_good_rand(16);
|
$at->secret = common_good_rand(16);
|
||||||
$at->type = 1; // access
|
$at->type = 1; // access
|
||||||
|
$at->verifier = $verifier;
|
||||||
|
$at->verified_callback = $rt->verified_callback; // 1.0a
|
||||||
$at->created = DB_DataObject_Cast::dateTime();
|
$at->created = DB_DataObject_Cast::dateTime();
|
||||||
|
|
||||||
if (!$at->insert()) {
|
if (!$at->insert()) {
|
||||||
|
@ -183,4 +189,40 @@ class ApiStatusNetOAuthDataStore extends StatusNetOAuthDataStore
|
||||||
throw new Exception(_('Failed to delete revoked token.'));
|
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/
|
* @link http://status.net/
|
||||||
*
|
*
|
||||||
* StatusNet - the distributed open-source microblogging tool
|
* 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
|
* 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
|
* 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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/error.php';
|
require_once INSTALLDIR . '/lib/error.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for displaying HTTP client errors
|
* Class for displaying HTTP client errors
|
||||||
|
@ -90,4 +90,26 @@ class ClientErrorAction extends ErrorAction
|
||||||
|
|
||||||
$this->showPage();
|
$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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,9 +116,9 @@ class ConnectSettingsNav extends Widget
|
||||||
}
|
}
|
||||||
|
|
||||||
$menu['oauthconnectionssettings'] = array(
|
$menu['oauthconnectionssettings'] = array(
|
||||||
// TRANS: Menu item for OAth connection settings.
|
// TRANS: Menu item for OuAth connection settings.
|
||||||
_m('MENU','Connections'),
|
_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')
|
_('Authorized connected applications')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
123
lib/deletegroupform.php
Normal file
123
lib/deletegroupform.php
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Form for joining a group
|
||||||
|
*
|
||||||
|
* 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 Form
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @author Brion Vibber <brion@status.net>
|
||||||
|
* @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/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form for deleting a group
|
||||||
|
*
|
||||||
|
* @category Form
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @author Brion Vibber <brion@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/
|
||||||
|
*
|
||||||
|
* @see UnsubscribeForm
|
||||||
|
* @fixme merge a bunch of this stuff with similar form types to reduce boilerplate
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DeleteGroupForm extends Form
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* group for user to delete
|
||||||
|
*/
|
||||||
|
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param HTMLOutputter $out output channel
|
||||||
|
* @param group $group group to join
|
||||||
|
*/
|
||||||
|
|
||||||
|
function __construct($out=null, $group=null)
|
||||||
|
{
|
||||||
|
parent::__construct($out);
|
||||||
|
|
||||||
|
$this->group = $group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID of the form
|
||||||
|
*
|
||||||
|
* @return string ID of the form
|
||||||
|
*/
|
||||||
|
|
||||||
|
function id()
|
||||||
|
{
|
||||||
|
return 'group-delete-' . $this->group->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class of the form
|
||||||
|
*
|
||||||
|
* @return string of the form class
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formClass()
|
||||||
|
{
|
||||||
|
return 'form_group_delete';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action of the form
|
||||||
|
*
|
||||||
|
* @return string URL of the action
|
||||||
|
*/
|
||||||
|
|
||||||
|
function action()
|
||||||
|
{
|
||||||
|
return common_local_url('deletegroup',
|
||||||
|
array('id' => $this->group->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
function formData()
|
||||||
|
{
|
||||||
|
$this->out->hidden($this->id() . '-returnto-action', 'groupbyid', 'returnto-action');
|
||||||
|
$this->out->hidden($this->id() . '-returnto-id', $this->group->id, 'returnto-id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action elements
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formActions()
|
||||||
|
{
|
||||||
|
$this->out->submit('submit', _('Delete'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/info.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for displaying HTTP errors
|
* 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
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class ErrorAction extends Action
|
class ErrorAction extends InfoAction
|
||||||
{
|
{
|
||||||
static $status = array();
|
static $status = array();
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ class ErrorAction extends Action
|
||||||
|
|
||||||
function __construct($message, $code, $output='php://output', $indent=null)
|
function __construct($message, $code, $output='php://output', $indent=null)
|
||||||
{
|
{
|
||||||
parent::__construct($output, $indent);
|
parent::__construct(null, $message, $output, $indent);
|
||||||
|
|
||||||
$this->code = $code;
|
$this->code = $code;
|
||||||
$this->message = $message;
|
$this->message = $message;
|
||||||
|
@ -64,43 +66,6 @@ class ErrorAction extends Action
|
||||||
$this->prepare($_REQUEST);
|
$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()
|
function showPage()
|
||||||
{
|
{
|
||||||
if ($this->minimal) {
|
if ($this->minimal) {
|
||||||
|
@ -116,32 +81,16 @@ class ErrorAction extends Action
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overload a bunch of stuff so the page isn't too bloated
|
/**
|
||||||
|
* Display content.
|
||||||
function showBody()
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
function showContent()
|
||||||
{
|
{
|
||||||
$this->elementStart('body', array('id' => 'error'));
|
$this->element('div', array('class' => 'error'), $this->message);
|
||||||
$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');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -85,7 +85,11 @@ abstract class Installer
|
||||||
$config = INSTALLDIR.'/config.php';
|
$config = INSTALLDIR.'/config.php';
|
||||||
if (file_exists($config)) {
|
if (file_exists($config)) {
|
||||||
if (!is_writable($config) || filesize($config) > 0) {
|
if (!is_writable($config) || filesize($config) > 0) {
|
||||||
$this->warning('Config file "config.php" already exists.');
|
if (filesize($config) == 0) {
|
||||||
|
$this->warning('Config file "config.php" already exists and is empty, but is not writable.');
|
||||||
|
} else {
|
||||||
|
$this->warning('Config file "config.php" already exists.');
|
||||||
|
}
|
||||||
$pass = false;
|
$pass = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// http://oauth.net/core/1.0/#nonce
|
||||||
// "The Consumer SHALL then generate a Nonce value that is unique for
|
// "The Consumer SHALL then generate a Nonce value that is unique for
|
||||||
// all requests with that timestamp."
|
// all requests with that timestamp."
|
||||||
|
@ -317,13 +328,18 @@ class StatusNetOAuthDataStore extends OAuthDataStore
|
||||||
function add_avatar($profile, $url)
|
function add_avatar($profile, $url)
|
||||||
{
|
{
|
||||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||||
copy($url, $temp_filename);
|
try {
|
||||||
$imagefile = new ImageFile($profile->id, $temp_filename);
|
copy($url, $temp_filename);
|
||||||
$filename = Avatar::filename($profile->id,
|
$imagefile = new ImageFile($profile->id, $temp_filename);
|
||||||
image_type_to_extension($imagefile->type),
|
$filename = Avatar::filename($profile->id,
|
||||||
null,
|
image_type_to_extension($imagefile->type),
|
||||||
common_timestamp());
|
null,
|
||||||
rename($temp_filename, Avatar::path($filename));
|
common_timestamp());
|
||||||
|
rename($temp_filename, Avatar::path($filename));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
unlink($temp_filename);
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
return $profile->setOriginal($filename);
|
return $profile->setOriginal($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,5 +60,6 @@ class Right
|
||||||
const MAKEGROUPADMIN = 'makegroupadmin';
|
const MAKEGROUPADMIN = 'makegroupadmin';
|
||||||
const GRANTROLE = 'grantrole';
|
const GRANTROLE = 'grantrole';
|
||||||
const REVOKEROLE = 'revokerole';
|
const REVOKEROLE = 'revokerole';
|
||||||
|
const DELETEGROUP = 'deletegroup';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,7 @@ class Router
|
||||||
|
|
||||||
$m->connect('group/new', array('action' => 'newgroup'));
|
$m->connect('group/new', array('action' => 'newgroup'));
|
||||||
|
|
||||||
foreach (array('edit', 'join', 'leave') as $v) {
|
foreach (array('edit', 'join', 'leave', 'delete') as $v) {
|
||||||
$m->connect('group/:nickname/'.$v,
|
$m->connect('group/:nickname/'.$v,
|
||||||
array('action' => $v.'group'),
|
array('action' => $v.'group'),
|
||||||
array('nickname' => '[a-zA-Z0-9]+'));
|
array('nickname' => '[a-zA-Z0-9]+'));
|
||||||
|
|
|
@ -96,4 +96,27 @@ class ServerErrorAction extends ErrorAction
|
||||||
|
|
||||||
$this->showPage();
|
$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
|
* @category Exception
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @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
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -336,8 +336,11 @@ class StatusNet
|
||||||
|
|
||||||
foreach ($config_files as $_config_file) {
|
foreach ($config_files as $_config_file) {
|
||||||
if (@file_exists($_config_file)) {
|
if (@file_exists($_config_file)) {
|
||||||
include($_config_file);
|
// Ignore 0-byte config files
|
||||||
self::$have_config = true;
|
if (filesize($_config_file) > 0) {
|
||||||
|
include($_config_file);
|
||||||
|
self::$have_config = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
54
plugins/ModHelper/ModHelperPlugin.php
Normal file
54
plugins/ModHelper/ModHelperPlugin.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* 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')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package ModHelperPlugin
|
||||||
|
* @maintainer Brion Vibber <brion@status.net>
|
||||||
|
*/
|
||||||
|
class ModHelperPlugin extends Plugin
|
||||||
|
{
|
||||||
|
function onPluginVersion(&$versions)
|
||||||
|
{
|
||||||
|
$versions[] = array('name' => 'ModHelper',
|
||||||
|
'version' => STATUSNET_VERSION,
|
||||||
|
'author' => 'Brion Vibber',
|
||||||
|
'homepage' => 'http://status.net/wiki/Plugin:ModHelper',
|
||||||
|
'rawdescription' =>
|
||||||
|
_m('Lets users who have been manually marked as "modhelper"s silence accounts.'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUserRightsCheck($profile, $right, &$result)
|
||||||
|
{
|
||||||
|
if ($right == Right::SILENCEUSER) {
|
||||||
|
// Hrm.... really we should confirm that the *other* user isn't privleged. :)
|
||||||
|
if ($profile->hasRole('modhelper')) {
|
||||||
|
$result = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1053,22 +1053,27 @@ class Ostatus_profile extends Memcached_DataObject
|
||||||
// @fixme this should be better encapsulated
|
// @fixme this should be better encapsulated
|
||||||
// ripped from oauthstore.php (for old OMB client)
|
// ripped from oauthstore.php (for old OMB client)
|
||||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||||
if (!copy($url, $temp_filename)) {
|
try {
|
||||||
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
if (!copy($url, $temp_filename)) {
|
||||||
}
|
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->isGroup()) {
|
if ($this->isGroup()) {
|
||||||
$id = $this->group_id;
|
$id = $this->group_id;
|
||||||
} else {
|
} else {
|
||||||
$id = $this->profile_id;
|
$id = $this->profile_id;
|
||||||
|
}
|
||||||
|
// @fixme should we be using different ids?
|
||||||
|
$imagefile = new ImageFile($id, $temp_filename);
|
||||||
|
$filename = Avatar::filename($id,
|
||||||
|
image_type_to_extension($imagefile->type),
|
||||||
|
null,
|
||||||
|
common_timestamp());
|
||||||
|
rename($temp_filename, Avatar::path($filename));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
unlink($temp_filename);
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
// @fixme should we be using different ids?
|
|
||||||
$imagefile = new ImageFile($id, $temp_filename);
|
|
||||||
$filename = Avatar::filename($id,
|
|
||||||
image_type_to_extension($imagefile->type),
|
|
||||||
null,
|
|
||||||
common_timestamp());
|
|
||||||
rename($temp_filename, Avatar::path($filename));
|
|
||||||
// @fixme hardcoded chmod is lame, but seems to be necessary to
|
// @fixme hardcoded chmod is lame, but seems to be necessary to
|
||||||
// keep from accidentally saving images from command-line (queues)
|
// keep from accidentally saving images from command-line (queues)
|
||||||
// that can't be read from web server, which causes hard-to-notice
|
// that can't be read from web server, which causes hard-to-notice
|
||||||
|
|
|
@ -174,20 +174,25 @@ class WikiHowProfilePlugin extends Plugin
|
||||||
// @fixme this should be better encapsulated
|
// @fixme this should be better encapsulated
|
||||||
// ripped from OStatus via oauthstore.php (for old OMB client)
|
// ripped from OStatus via oauthstore.php (for old OMB client)
|
||||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||||
if (!copy($url, $temp_filename)) {
|
try {
|
||||||
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
if (!copy($url, $temp_filename)) {
|
||||||
|
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $user->getProfile();
|
||||||
|
$id = $profile->id;
|
||||||
|
// @fixme should we be using different ids?
|
||||||
|
|
||||||
|
$imagefile = new ImageFile($id, $temp_filename);
|
||||||
|
$filename = Avatar::filename($id,
|
||||||
|
image_type_to_extension($imagefile->type),
|
||||||
|
null,
|
||||||
|
common_timestamp());
|
||||||
|
rename($temp_filename, Avatar::path($filename));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
unlink($temp_filename);
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
$id = $profile->id;
|
|
||||||
// @fixme should we be using different ids?
|
|
||||||
|
|
||||||
$imagefile = new ImageFile($id, $temp_filename);
|
|
||||||
$filename = Avatar::filename($id,
|
|
||||||
image_type_to_extension($imagefile->type),
|
|
||||||
null,
|
|
||||||
common_timestamp());
|
|
||||||
rename($temp_filename, Avatar::path($filename));
|
|
||||||
$profile->setOriginal($filename);
|
$profile->setOriginal($filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,18 +436,23 @@ class YammerImporter
|
||||||
// @fixme this should be better encapsulated
|
// @fixme this should be better encapsulated
|
||||||
// ripped from oauthstore.php (for old OMB client)
|
// ripped from oauthstore.php (for old OMB client)
|
||||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||||
if (!copy($url, $temp_filename)) {
|
try {
|
||||||
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
if (!copy($url, $temp_filename)) {
|
||||||
}
|
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
||||||
|
}
|
||||||
|
|
||||||
$id = $dest->id;
|
$id = $dest->id;
|
||||||
// @fixme should we be using different ids?
|
// @fixme should we be using different ids?
|
||||||
$imagefile = new ImageFile($id, $temp_filename);
|
$imagefile = new ImageFile($id, $temp_filename);
|
||||||
$filename = Avatar::filename($id,
|
$filename = Avatar::filename($id,
|
||||||
image_type_to_extension($imagefile->type),
|
image_type_to_extension($imagefile->type),
|
||||||
null,
|
null,
|
||||||
common_timestamp());
|
common_timestamp());
|
||||||
rename($temp_filename, Avatar::path($filename));
|
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
|
// @fixme hardcoded chmod is lame, but seems to be necessary to
|
||||||
// keep from accidentally saving images from command-line (queues)
|
// keep from accidentally saving images from command-line (queues)
|
||||||
// that can't be read from web server, which causes hard-to-notice
|
// 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.
|
Some very rough test scripts for hitting up the OAuth endpoints.
|
||||||
|
|
||||||
Note: this works best if you register an OAuth application, leaving
|
These instructions assume you understand the basics of how OAuth
|
||||||
the callback URL blank.
|
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
|
oauth.ini
|
||||||
you authorize the request token you can exchange it for an access token...
|
---------
|
||||||
|
|
||||||
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
|
fetch_temp_creds.php
|
||||||
resource:
|
--------------------
|
||||||
|
|
||||||
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
|
; Setup OAuth info here
|
||||||
apiroot = "http://YOURSTATUSNET/api"
|
apiroot = "https://YOURSTATUSNET/api"
|
||||||
|
|
||||||
request_token_url = "/oauth/request_token"
|
request_token_url = "/oauth/request_token"
|
||||||
authorize_url = "/oauth/authorize"
|
authorize_url = "/oauth/authorize"
|
|
@ -22,16 +22,16 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..'));
|
||||||
|
|
||||||
require_once INSTALLDIR . '/extlib/OAuth.php';
|
require_once INSTALLDIR . '/extlib/OAuth.php';
|
||||||
|
|
||||||
$shortoptions = 'o:s:u:';
|
$shortoptions = 't:s:u:';
|
||||||
$longoptions = array('oauth_token=', 'token_secret=', 'update=');
|
$longoptions = array('oauth_token=', 'token_secret=', 'update=');
|
||||||
|
|
||||||
$helptext = <<<END_OF_VERIFY_HELP
|
$helptext = <<<END_OF_VERIFY_HELP
|
||||||
statusupdate.php [options]
|
oauth_post_notice.php [options]
|
||||||
Update your status using OAuth
|
Update your status via OAuth
|
||||||
|
|
||||||
-o --oauth_token access token
|
-t --oauth_token access token
|
||||||
-s --token_secret access token secret
|
-s --oauth_token_secret access token secret
|
||||||
-u --update status update
|
-u --update status update
|
||||||
|
|
||||||
|
|
||||||
END_OF_VERIFY_HELP;
|
END_OF_VERIFY_HELP;
|
||||||
|
@ -42,12 +42,12 @@ $update = null;
|
||||||
|
|
||||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||||
|
|
||||||
if (have_option('o', 'oauth_token')) {
|
if (have_option('t', 'oauth_token')) {
|
||||||
$token = get_option_value('oauth_token');
|
$token = get_option_value('t', 'oauth_token');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_option('s', 'token_secret')) {
|
if (have_option('s', 'oauth_token_secret')) {
|
||||||
$token_secret = get_option_value('s', 'token_secret');
|
$token_secret = get_option_value('s', 'oauth_token_secret');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_option('u', 'update')) {
|
if (have_option('u', 'update')) {
|
||||||
|
@ -69,47 +69,56 @@ if (empty($update)) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$ini = parse_ini_file("oauth.ini");
|
$ini = parse_ini_file("oauth.ini");
|
||||||
|
$consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||||
$test_consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
|
||||||
|
|
||||||
$endpoint = $ini['apiroot'] . '/statuses/update.xml';
|
$endpoint = $ini['apiroot'] . '/statuses/update.xml';
|
||||||
|
|
||||||
print "$endpoint\n";
|
$atok = new OAuthToken($token, $token_secret);
|
||||||
|
|
||||||
$at = new OAuthToken($token, $token_secret);
|
|
||||||
|
|
||||||
$parsed = parse_url($endpoint);
|
$parsed = parse_url($endpoint);
|
||||||
$params = array();
|
|
||||||
parse_str($parsed['query'], $params);
|
parse_str($parsed['query'], $params);
|
||||||
|
|
||||||
$params['status'] = $update;
|
$params['status'] = $update;
|
||||||
|
|
||||||
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||||
|
|
||||||
$req_req = OAuthRequest::from_consumer_and_token($test_consumer, $at, 'POST', $endpoint, $params);
|
try {
|
||||||
$req_req->sign_request($hmac_method, $test_consumer, $at);
|
|
||||||
|
|
||||||
$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 = HTTPClient::start();
|
||||||
|
|
||||||
$request->setConfig(array(
|
$request->setConfig(
|
||||||
'follow_redirects' => true,
|
array(
|
||||||
'connect_timeout' => 120,
|
'follow_redirects' => true,
|
||||||
'timeout' => 120,
|
'connect_timeout' => 120,
|
||||||
'ssl_verify_peer' => false,
|
'timeout' => 120,
|
||||||
'ssl_verify_host' => false
|
'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';
|
require_once INSTALLDIR . '/extlib/OAuth.php';
|
||||||
|
|
||||||
$shortoptions = 'o:s:';
|
$shortoptions = 't:s:';
|
||||||
$longoptions = array('oauth_token=', 'token_secret=');
|
$longoptions = array('oauth_token=', 'oauth_token_secret=');
|
||||||
|
|
||||||
$helptext = <<<END_OF_VERIFY_HELP
|
$helptext = <<<END_OF_VERIFY_HELP
|
||||||
verifycreds.php [options]
|
oauth_verify_creds.php [options]
|
||||||
Use an access token to verify credentials thru the api
|
Access /api/account/verify_credentials.xml with OAuth
|
||||||
|
|
||||||
-o --oauth_token access token
|
-t --oauth_token access token
|
||||||
-s --token_secret access token secret
|
-s --oauth_token_secret access token secret
|
||||||
|
|
||||||
END_OF_VERIFY_HELP;
|
END_OF_VERIFY_HELP;
|
||||||
|
|
||||||
|
@ -39,63 +39,69 @@ $token_secret = null;
|
||||||
|
|
||||||
require_once INSTALLDIR . '/scripts/commandline.inc';
|
require_once INSTALLDIR . '/scripts/commandline.inc';
|
||||||
|
|
||||||
if (have_option('o', 'oauth_token')) {
|
if (have_option('t', 'oauth_token')) {
|
||||||
$token = get_option_value('oauth_token');
|
$token = get_option_value('t', 'oauth_token');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_option('s', 'token_secret')) {
|
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)) {
|
if (empty($token)) {
|
||||||
print "Please specify an access token.\n";
|
print "Please specify an access token (--help for help).\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($token_secret)) {
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$ini = parse_ini_file("oauth.ini");
|
$ini = parse_ini_file("oauth.ini");
|
||||||
|
$consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
||||||
$test_consumer = new OAuthConsumer($ini['consumer_key'], $ini['consumer_secret']);
|
|
||||||
|
|
||||||
$endpoint = $ini['apiroot'] . '/account/verify_credentials.xml';
|
$endpoint = $ini['apiroot'] . '/account/verify_credentials.xml';
|
||||||
|
|
||||||
print "$endpoint\n";
|
$atok = new OAuthToken($token, $token_secret);
|
||||||
|
|
||||||
$at = new OAuthToken($token, $token_secret);
|
|
||||||
|
|
||||||
$parsed = parse_url($endpoint);
|
$parsed = parse_url($endpoint);
|
||||||
$params = array();
|
|
||||||
parse_str($parsed['query'], $params);
|
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);
|
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||||
$req_req->sign_request($hmac_method, $test_consumer, $at);
|
|
||||||
|
|
||||||
$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)
|
function httpRequest($url)
|
||||||
{
|
{
|
||||||
$request = HTTPClient::start();
|
$request = HTTPClient::start();
|
||||||
|
|
||||||
$request->setConfig(array(
|
$request->setConfig(
|
||||||
'follow_redirects' => true,
|
array(
|
||||||
'connect_timeout' => 120,
|
'follow_redirects' => true,
|
||||||
'timeout' => 120,
|
'connect_timeout' => 120,
|
||||||
'ssl_verify_peer' => false,
|
'timeout' => 120,
|
||||||
'ssl_verify_host' => false
|
'ssl_verify_peer' => false,
|
||||||
));
|
'ssl_verify_host' => false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return $request->get($url);
|
return $request->get($url);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user