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