Merge branch '0.9.x' into userflag

This commit is contained in:
Evan Prodromou
2009-11-07 13:03:52 -05:00
168 changed files with 110975 additions and 26613 deletions

View File

@@ -98,11 +98,10 @@ class AutocompleteAction extends Action
$user = new User();
$user->limit($limit);
$user->whereAdd('nickname like \'' . trim($user->escape($q), '\'') . '%\'');
$user->find();
while($user->fetch()) {
$profile = Profile::staticGet($user->id);
$user->profile=$profile;
$this->users[]=$user;
if($user->find()){
while($user->fetch()) {
$this->users[]=clone($user);
}
}
}
if(substr($q,0,1)=='!'){
@@ -111,9 +110,10 @@ class AutocompleteAction extends Action
$group = new User_group();
$group->limit($limit);
$group->whereAdd('nickname like \'' . trim($group->escape($q), '\'') . '%\'');
$group->find();
while($group->fetch()) {
$this->groups[]=$group;
if($group->find()){
while($group->fetch()) {
$this->groups[]=clone($group);
}
}
}
return true;
@@ -124,7 +124,8 @@ class AutocompleteAction extends Action
parent::handle($args);
$results = array();
foreach($this->users as $user){
$results[]=array('nickname' => $user->nickname, 'fullname'=> $user->profile->fullname, 'type'=>'user');
$profile = $user->getProfile();
$results[]=array('nickname' => $user->nickname, 'fullname'=> $profile->fullname, 'type'=>'user');
}
foreach($this->groups as $group){
$results[]=array('nickname' => $group->nickname, 'fullname'=> $group->fullname, 'type'=>'group');

View File

@@ -0,0 +1,61 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Plugin to push RSS/Atom updates to a PubSubHubBub hub
*
* 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 Plugin
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2009 Craig Andrews http://candrews.integralblue.com
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
exit(1);
}
class BitlyUrlPlugin extends Plugin
{
function __construct()
{
parent::__construct();
}
function onInitializePlugin(){
$this->registerUrlShortener(
'bit.ly',
array(),
array('BitlyUrl',array('http://bit.ly/api?method=shorten&long_url='))
);
}
}
class BitlyUrl extends ShortUrlApi
{
protected function shorten_imp($url) {
$response = $this->http_get($url);
if(!$response){
return $url;
}else{
return current(json_decode($response)->results)->hashUrl;
}
}
}

View File

@@ -22,6 +22,7 @@
* @category Plugin
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Brion Vibber <brion@status.net>
* @copyright 2009 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/
@@ -69,14 +70,12 @@ class BlogspamNetPlugin extends Plugin
{
$args = $this->testArgs($notice);
common_debug("Blogspamnet args = " . print_r($args, TRUE));
$request = xmlrpc_encode_request('testComment', array($args));
$context = stream_context_create(array('http' => array('method' => "POST",
'header' =>
"Content-Type: text/xml\r\n".
"User-Agent: " . $this->userAgent(),
'content' => $request)));
$file = file_get_contents($this->baseUrl, false, $context);
$response = xmlrpc_decode($file);
$requestBody = xmlrpc_encode_request('testComment', array($args));
$request = HTTPClient::start();
$httpResponse = $request->post($this->baseUrl, array('Content-Type: text/xml'), $requestBody);
$response = xmlrpc_decode($httpResponse->getBody());
if (xmlrpc_is_fault($response)) {
throw new ServerException("$response[faultString] ($response[faultCode])", 500);
} else {

View File

@@ -74,8 +74,8 @@ class GeonamesPlugin extends Plugin
$result = $client->get('http://ws.geonames.org/search?'.$str);
if ($result->code == "200") {
$rj = json_decode($result->body);
if ($result->isOk()) {
$rj = json_decode($result->getBody());
if (count($rj->geonames) > 0) {
$n = $rj->geonames[0];
@@ -121,9 +121,9 @@ class GeonamesPlugin extends Plugin
$result = $client->get('http://ws.geonames.org/hierarchyJSON?'.$str);
if ($result->code == "200") {
if ($result->isOk()) {
$rj = json_decode($result->body);
$rj = json_decode($result->getBody());
if (count($rj->geonames) > 0) {
@@ -182,9 +182,9 @@ class GeonamesPlugin extends Plugin
$result =
$client->get('http://ws.geonames.org/findNearbyPlaceNameJSON?'.$str);
if ($result->code == "200") {
if ($result->isOk()) {
$rj = json_decode($result->body);
$rj = json_decode($result->getBody());
if (count($rj->geonames) > 0) {
@@ -249,9 +249,9 @@ class GeonamesPlugin extends Plugin
$result = $client->get('http://ws.geonames.org/hierarchyJSON?'.$str);
if ($result->code == "200") {
if ($result->isOk()) {
$rj = json_decode($result->body);
$rj = json_decode($result->getBody());
if (count($rj->geonames) > 0) {

105
plugins/Ldap/LdapPlugin.php Normal file
View File

@@ -0,0 +1,105 @@
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Plugin to enable LDAP Authentication and Authorization
*
* 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 Plugin
* @package StatusNet
* @author Craig Andrews <candrews@integralblue.com>
* @copyright 2009 Craig Andrews http://candrews.integralblue.com
* @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.'/plugins/Ldap/ldap.php';
class LdapPlugin extends Plugin
{
private $config = array();
function __construct()
{
parent::__construct();
}
function onCheckPassword($nickname, $password, &$authenticated)
{
if(ldap_check_password($nickname, $password)){
$authenticated = true;
//stop handling of other events, because we have an answer
return false;
}
if(common_config('ldap','authoritative')){
//a false return stops handler processing
return false;
}
}
function onAutoRegister($nickname)
{
$user = User::staticGet('nickname', $nickname);
if (! is_null($user) && $user !== false) {
common_log(LOG_WARNING, "An attempt was made to autoregister an existing user with nickname: $nickname");
return;
}
$attributes=array();
$config_attributes = array('nickname','email','fullname','homepage','location');
foreach($config_attributes as $config_attribute){
$value = common_config('ldap', $config_attribute.'_attribute');
if($value!==false){
array_push($attributes,$value);
}
}
$entry = ldap_get_user($nickname,$attributes);
if($entry){
$registration_data = array();
foreach($config_attributes as $config_attribute){
$value = common_config('ldap', $config_attribute.'_attribute');
if($value!==false){
if($config_attribute=='email'){
$registration_data[$config_attribute]=common_canonical_email($entry->getValue($value,'single'));
}else if($config_attribute=='nickname'){
$registration_data[$config_attribute]=common_canonical_nickname($entry->getValue($value,'single'));
}else{
$registration_data[$config_attribute]=$entry->getValue($value,'single');
}
}
}
//set the database saved password to a random string.
$registration_data['password']=common_good_rand(16);
$user = User::register($registration_data);
//prevent other handlers from running, as we have registered the user
return false;
}
}
function onChangePassword($nickname,$oldpassword,$newpassword,&$errormsg)
{
//TODO implement this
$errormsg = _('Sorry, changing LDAP passwords is not supported at this time');
//return false, indicating that the event has been handled
return false;
}
}

23
plugins/Ldap/README Normal file
View File

@@ -0,0 +1,23 @@
The LDAP plugin allows for StatusNet to handle authentication, authorization, and user information through LDAP.
Installation
============
Add configuration entries to config.php. These entries are:
The following are documented at http://pear.php.net/manual/en/package.networking.net-ldap2.connecting.php
$config['ldap']['binddn']
$config['ldap']['bindpw']
$config['ldap']['basedn']
$config['ldap']['host']
$config['ldap']['nickname_attribute'] Set this to the name of the ldap attribute that holds the username. For example, on Microsoft's Active Directory, this should be set to 'sAMAccountName'
$config['ldap']['nickname_email'] Set this to the name of the ldap attribute that holds the user's email address. For example, on Microsoft's Active Directory, this should be set to 'mail'
$config['ldap']['nickname_fullname'] Set this to the name of the ldap attribute that holds the user's full name. For example, on Microsoft's Active Directory, this should be set to 'displayName'
$config['ldap']['nickname_homepage'] Set this to the name of the ldap attribute that holds the the url of the user's home page.
$config['ldap']['nickname_location'] Set this to the name of the ldap attribute that holds the user's location.
$config['ldap']['authoritative'] Set to true if LDAP's responses are authoritative (meaning if LDAP fails, do check the any other plugins or the internal password database)
$config['ldap']['autoregister'] Set to true if users should be automatically created when they attempt to login
Finally, add "addPlugin('ldap');" to the bottom of your config.php

108
plugins/Ldap/ldap.php Normal file
View File

@@ -0,0 +1,108 @@
<?php
/*
* StatusNet - the 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/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
require_once 'Net/LDAP2.php';
function ldap_get_config(){
static $config = null;
if($config == null){
$config = array();
$keys = array('host','port','version','starttls','binddn','bindpw','basedn','options','scope');
foreach($keys as $key){
$value = common_config('ldap', $key);
if($value!==false){
$config[$key]=$value;
}
}
}
return $config;
}
function ldap_get_connection($config = null){
if($config == null){
$config = ldap_get_config();
}
//cannot use Net_LDAP2::connect() as StatusNet uses
//PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'handleError');
//PEAR handling can be overridden on instance objects, so we do that.
$ldap = new Net_LDAP2($config);
$ldap->setErrorHandling(PEAR_ERROR_RETURN);
$err=$ldap->bind();
if (Net_LDAP2::isError($err)) {
common_log(LOG_WARNING, 'Could not connect to LDAP server: '.$err->getMessage());
return false;
}
return $ldap;
}
function ldap_check_password($username, $password){
$ldap = ldap_get_connection();
if(!$ldap){
return false;
}
$entry = ldap_get_user($username);
if(!$entry){
return false;
}else{
$config = ldap_get_config();
$config['binddn']=$entry->dn();
$config['bindpw']=$password;
if(ldap_get_connection($config)){
return true;
}else{
return false;
}
}
}
/**
* get an LDAP entry for a user with a given username
*
* @param string $username
* $param array $attributes LDAP attributes to retrieve
* @return string DN
*/
function ldap_get_user($username,$attributes=array()){
$ldap = ldap_get_connection();
$filter = Net_LDAP2_Filter::create(common_config('ldap','nickname_attribute'), 'equals', $username);
$options = array(
'scope' => 'sub',
'attributes' => $attributes
);
$search = $ldap->search(null,$filter,$options);
if (PEAR::isError($search)) {
common_log(LOG_WARNING, 'Error while getting DN for user: '.$search->getMessage());
return false;
}
if($search->count()==0){
return false;
}else if($search->count()==1){
$entry = $search->shiftEntry();
return $entry;
}else{
common_log(LOG_WARNING, 'Found ' . $search->count() . ' ldap user with the username: ' . $username);
return false;
}
}

View File

@@ -58,7 +58,10 @@ class LilUrl extends ShortUrlApi
$y = @simplexml_load_string($response);
if (!isset($y->body)) return $url;
$x = $y->body->p[0]->a->attributes();
if (isset($x['href'])) return $x['href'];
if (isset($x['href'])) {
common_log(LOG_INFO, __CLASS__ . ": shortened $url to $x[href]");
return $x['href'];
}
return $url;
}
}

View File

@@ -129,18 +129,12 @@ class LinkbackPlugin extends Plugin
}
}
$request = xmlrpc_encode_request('pingback.ping', $args);
$context = stream_context_create(array('http' => array('method' => "POST",
'header' =>
"Content-Type: text/xml\r\n".
"User-Agent: " . $this->userAgent(),
'content' => $request)));
$file = file_get_contents($endpoint, false, $context);
if (!$file) {
common_log(LOG_WARNING,
"Pingback request failed for '$url' ($endpoint)");
} else {
$response = xmlrpc_decode($file);
$request = HTTPClient::start();
try {
$response = $request->post($endpoint,
array('Content-Type: text/xml'),
xmlrpc_encode_request('pingback.ping', $args));
$response = xmlrpc_decode($response->getBody());
if (xmlrpc_is_fault($response)) {
common_log(LOG_WARNING,
"Pingback error for '$url' ($endpoint): ".
@@ -150,6 +144,9 @@ class LinkbackPlugin extends Plugin
"Pingback success for '$url' ($endpoint): ".
"'$response'");
}
} catch (HTTP_Request2_Exception $e) {
common_log(LOG_WARNING,
"Pingback request failed for '$url' ($endpoint)");
}
}

View File

@@ -1,5 +1,31 @@
// add a notice encoded as JSON into the current timeline
//
/*
* StatusNet - a distributed open-source microblogging tool
* Copyright (C) 2008, StatusNet, Inc.
*
* Add a notice encoded as JSON into the current timeline
*
* 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 Plugin
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @author Sarven Capadisli <csarven@status.net>
* @copyright 2009 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/
*/
// TODO: i18n
RealtimeUpdate = {

View File

@@ -65,15 +65,6 @@ class SimpleUrlPlugin extends Plugin
class SimpleUrl extends ShortUrlApi
{
protected function shorten_imp($url) {
$curlh = curl_init();
curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait
curl_setopt($curlh, CURLOPT_USERAGENT, 'StatusNet');
curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlh, CURLOPT_URL, $this->service_url.urlencode($url));
$short_url = curl_exec($curlh);
curl_close($curlh);
return $short_url;
return $this->http_get($url);
}
}

View File

@@ -152,8 +152,8 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon
$friends_ids = $client->friendsIds();
} catch (Exception $e) {
common_log(LOG_WARNING, $this->name() .
' - cURL error getting friend ids ' .
$e->getCode() . ' - ' . $e->getMessage());
' - error getting friend ids: ' .
$e->getMessage());
return $friends;
}

View File

@@ -109,12 +109,16 @@ class TwitterStatusFetcher extends ParallelizingDaemon
$flink->find();
$flinks = array();
common_log(LOG_INFO, "hello");
while ($flink->fetch()) {
if (($flink->noticesync & FOREIGN_NOTICE_RECV) ==
FOREIGN_NOTICE_RECV) {
$flinks[] = clone($flink);
common_log(LOG_INFO, "sync: foreign id $flink->foreign_id");
} else {
common_log(LOG_INFO, "nothing to sync");
}
}
@@ -515,31 +519,32 @@ class TwitterStatusFetcher extends ParallelizingDaemon
return $id;
}
/**
* Fetch a remote avatar image and save to local storage.
*
* @param string $url avatar source URL
* @param string $filename bare local filename for download
* @return bool true on success, false on failure
*/
function fetchAvatar($url, $filename)
{
$avatarfile = Avatar::path($filename);
common_debug($this->name() . " - Fetching Twitter avatar: $url");
$out = fopen($avatarfile, 'wb');
if (!$out) {
common_log(LOG_WARNING, $this->name() .
" - Couldn't open file $filename");
$request = HTTPClient::start();
$response = $request->get($url);
if ($response->isOk()) {
$avatarfile = Avatar::path($filename);
$ok = file_put_contents($avatarfile, $response->getBody());
if (!$ok) {
common_log(LOG_WARNING, $this->name() .
" - Couldn't open file $filename");
return false;
}
} else {
return false;
}
common_debug($this->name() . " - Fetching Twitter avatar: $url");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FILE, $out);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
$result = curl_exec($ch);
curl_close($ch);
fclose($out);
return $result;
return true;
}
}

View File

@@ -215,7 +215,7 @@ function broadcast_basicauth($notice, $flink)
try {
$status = $client->statusesUpdate($statustxt);
} catch (BasicAuthCurlException $e) {
} catch (HTTP_Request2_Exception $e) {
return process_error($e, $flink);
}

View File

@@ -125,7 +125,7 @@ class TwitterauthorizationAction extends Action
$auth_link = $client->getAuthorizeLink($req_tok);
} catch (TwitterOAuthClientException $e) {
} catch (OAuthClientException $e) {
$msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s',
$e->getCode(), $e->getMessage());
$this->serverError(_('Couldn\'t link your Twitter account.'));

View File

@@ -31,26 +31,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1);
}
/**
* Exception wrapper for cURL errors
*
* @category Integration
* @package StatusNet
* @author Adrian Lang <mail@adrianlang.de>
* @author Brenda Wallace <shiny@cpan.org>
* @author Craig Andrews <candrews@integralblue.com>
* @author Dan Moore <dan@moore.cx>
* @author Evan Prodromou <evan@status.net>
* @author mEDI <medi@milaro.net>
* @author Sarven Capadisli <csarven@status.net>
* @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 BasicAuthCurlException extends Exception
{
}
/**
* Class for talking to the Twitter API with HTTP Basic Auth.
*
@@ -198,45 +178,27 @@ class TwitterBasicAuthClient
*/
function httpRequest($url, $params = null, $auth = true)
{
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FAILONERROR => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => 'StatusNet',
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_SSL_VERIFYPEER => false,
// Twitter is strict about accepting invalid "Expect" headers
CURLOPT_HTTPHEADER => array('Expect:')
);
if (isset($params)) {
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = $params;
}
$request = HTTPClient::start();
$request->setConfig(array(
'follow_redirects' => true,
'connect_timeout' => 120,
'timeout' => 120,
'ssl_verifypeer' => false,
));
if ($auth) {
$options[CURLOPT_USERPWD] = $this->screen_name .
':' . $this->password;
$request->setAuth($this->screen_name, $this->password);
}
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
if ($response === false) {
$msg = curl_error($ch);
$code = curl_errno($ch);
throw new BasicAuthCurlException($msg, $code);
if (isset($params)) {
// Twitter is strict about accepting invalid "Expect" headers
$headers = array('Expect:');
$response = $request->post($url, $headers, $params);
} else {
$response = $request->get($url);
}
curl_close($ch);
return $response;
return $response->getBody();
}
}

View File

@@ -68,14 +68,13 @@ class WikiHashtagsPlugin extends Plugin
$editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit',
urlencode($tag));
$context = stream_context_create(array('http' => array('method' => "GET",
'header' =>
"User-Agent: " . $this->userAgent())));
$html = @file_get_contents($url, false, $context);
$request = HTTPClient::start();
$response = $request->get($url);
$html = $response->getBody();
$action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section'));
if (!empty($html)) {
if ($response->isOk() && !empty($html)) {
$action->element('style', null,
"span.editsection { display: none }\n".
"table.toc { display: none }");
@@ -100,10 +99,4 @@ class WikiHashtagsPlugin extends Plugin
return true;
}
function userAgent()
{
return 'WikiHashtagsPlugin/'.WIKIHASHTAGSPLUGIN_VERSION .
' StatusNet/' . STATUSNET_VERSION;
}
}