- revert feature 564: log the login of each user; but add the possibility to be
done by a plugin - create a "standard" way to define PHP functions that we use but might not be available in the current php version - when a comment is rejected (spam, anti-flood etc), put the content back to the browser in case there is a real user behind it - now a comment can be entered only if the page was retrieved between 2 seconds ago and 1 hour ago git-svn-id: http://piwigo.org/svn/trunk@1744 68402e56-0260-453c-a942-63ccdbb3a9ee
This commit is contained in:
parent
767064c9fe
commit
e90aaffbd5
18 changed files with 174 additions and 98 deletions
admin
identification.phpinclude
common.inc.phpfunctions_html.inc.phpfunctions_search.inc.phpfunctions_user.inc.php
php_compat
picture_comment.inc.phpws_functions.inc.phpinstall
language
en_UK.iso-8859-1
fr_FR.iso-8859-1
template/yoga
|
@ -51,7 +51,6 @@ $general_checkboxes = array(
|
|||
'log',
|
||||
'history_admin',
|
||||
'history_guest',
|
||||
'login_history',
|
||||
'email_admin_on_new_user',
|
||||
'allow_user_registration',
|
||||
);
|
||||
|
|
|
@ -45,24 +45,9 @@ if ( !empty($_GET['redirect']) )
|
|||
if (isset($_POST['login']))
|
||||
{
|
||||
$redirect_to = isset($_POST['redirect']) ? $_POST['redirect'] : '';
|
||||
$username = mysql_escape_string($_POST['username']);
|
||||
// retrieving the encrypted password of the login submitted
|
||||
$query = '
|
||||
SELECT '.$conf['user_fields']['id'].' AS id,
|
||||
'.$conf['user_fields']['password'].' AS password
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
|
||||
;';
|
||||
$row = mysql_fetch_array(pwg_query($query));
|
||||
if ($row['password'] == $conf['pass_convert']($_POST['password']))
|
||||
$remember_me = isset($_POST['remember_me']) and $_POST['remember_me']==1;
|
||||
if ( try_log_user($_POST['username'], $_POST['password'], $remember_me) )
|
||||
{
|
||||
$remember_me = false;
|
||||
if (isset($_POST['remember_me'])
|
||||
and $_POST['remember_me'] == 1)
|
||||
{
|
||||
$remember_me = true;
|
||||
}
|
||||
log_user($row['id'], $remember_me);
|
||||
redirect(empty($redirect_to) ? make_index_url() : $redirect_to);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -121,6 +121,17 @@ if (!defined('PHPWG_INSTALLED'))
|
|||
exit;
|
||||
}
|
||||
|
||||
foreach( array(
|
||||
'array_intersect_key', //PHP 5 >= 5.1.0RC1
|
||||
'hash_hmac', //(hash) - enabled by default as of PHP 5.1.2
|
||||
) as $func)
|
||||
{
|
||||
if (!function_exists($func))
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH . 'include/php_compat/'.$func.'.php');
|
||||
}
|
||||
}
|
||||
|
||||
include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
|
||||
@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
|
||||
include(PHPWG_ROOT_PATH . 'include/constants.php');
|
||||
|
|
|
@ -717,5 +717,6 @@ function set_status_header($code, $text='')
|
|||
}
|
||||
header("HTTP/1.1 $code $text");
|
||||
header("Status: $code $text");
|
||||
trigger_action('set_status_header', $code, $text);
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -252,23 +252,6 @@ SELECT DISTINCT(id)
|
|||
return $items;
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('array_intersect_key')) {
|
||||
function array_intersect_key()
|
||||
{
|
||||
$arrs = func_get_args();
|
||||
$result = array_shift($arrs);
|
||||
foreach ($arrs as $array) {
|
||||
foreach ($result as $key => $v) {
|
||||
if (!array_key_exists($key, $array)) {
|
||||
unset($result[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the LIKE sql clause corresponding to the quick search query $q
|
||||
* and the field $field. example q="john bill", field="file" will return
|
||||
|
|
|
@ -858,8 +858,9 @@ function get_language_filepath($filename, $dirname = '')
|
|||
/**
|
||||
* returns the auto login key or false on error
|
||||
* @param int user_id
|
||||
* @param string [out] username
|
||||
*/
|
||||
function calculate_auto_login_key($user_id)
|
||||
function calculate_auto_login_key($user_id, &$username)
|
||||
{
|
||||
global $conf;
|
||||
$query = '
|
||||
|
@ -871,7 +872,12 @@ WHERE '.$conf['user_fields']['id'].' = '.$user_id;
|
|||
if (mysql_num_rows($result) > 0)
|
||||
{
|
||||
$row = mysql_fetch_assoc($result);
|
||||
$key = sha1( $row['username'].$row['password'] );
|
||||
$username = $row['username'];
|
||||
$data = $row['username'].$row['password'];
|
||||
$key = base64_encode(
|
||||
pack('H*', sha1($data))
|
||||
.hash_hmac('md5', $data, $conf['secret_key'],true)
|
||||
);
|
||||
return $key;
|
||||
}
|
||||
return false;
|
||||
|
@ -889,7 +895,7 @@ function log_user($user_id, $remember_me)
|
|||
|
||||
if ($remember_me and $conf['authorize_remembering'])
|
||||
{
|
||||
$key = calculate_auto_login_key($user_id);
|
||||
$key = calculate_auto_login_key($user_id, $username);
|
||||
if ($key!==false)
|
||||
{
|
||||
$cookie = array('id' => (int)$user_id, 'key' => $key);
|
||||
|
@ -928,12 +934,13 @@ function auto_login() {
|
|||
if ( isset( $_COOKIE[$conf['remember_me_name']] ) )
|
||||
{
|
||||
$cookie = unserialize(stripslashes($_COOKIE[$conf['remember_me_name']]));
|
||||
if ($cookie!==false)
|
||||
if ($cookie!==false and is_numeric(@$cookie['id']) )
|
||||
{
|
||||
$key = calculate_auto_login_key($cookie['id']);
|
||||
$key = calculate_auto_login_key( $cookie['id'], $username );
|
||||
if ($key!==false and $key===$cookie['key'])
|
||||
{
|
||||
log_user($cookie['id'], true);
|
||||
trigger_action('login_success', $username);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -942,6 +949,31 @@ function auto_login() {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to login a user given username and password (must be MySql escaped)
|
||||
* return true on success
|
||||
*/
|
||||
function try_log_user($username, $password, $remember_me)
|
||||
{
|
||||
global $conf;
|
||||
// retrieving the encrypted password of the login submitted
|
||||
$query = '
|
||||
SELECT '.$conf['user_fields']['id'].' AS id,
|
||||
'.$conf['user_fields']['password'].' AS password
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
|
||||
;';
|
||||
$row = mysql_fetch_assoc(pwg_query($query));
|
||||
if ($row['password'] == $conf['pass_convert']($password))
|
||||
{
|
||||
log_user($row['id'], $remember_me);
|
||||
trigger_action('login_success', $username);
|
||||
return true;
|
||||
}
|
||||
trigger_action('login_failure', $username);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return access_type definition of uuser
|
||||
* Test does with user status
|
||||
|
|
35
include/php_compat/array_intersect_key.php
Normal file
35
include/php_compat/array_intersect_key.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
// http://www.php.net/manual/en/function.array-intersect-key.php
|
||||
// PHP 5 >= 5.1.0RC1
|
||||
function array_intersect_key()
|
||||
{
|
||||
$args = func_get_args();
|
||||
if (count($args) < 2) {
|
||||
trigger_error('Wrong parameter count for array_intersect_key()', E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check arrays
|
||||
$array_count = count($args);
|
||||
for ($i = 0; $i !== $array_count; $i++) {
|
||||
if (!is_array($args[$i])) {
|
||||
trigger_error('array_intersect_key() Argument #' . ($i + 1) . ' is not an array', E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare entries
|
||||
$result = array();
|
||||
foreach ($args[0] as $key1 => $value1) {
|
||||
for ($i = 1; $i !== $array_count; $i++) {
|
||||
foreach ($args[$i] as $key2 => $value2) {
|
||||
if ((string) $key1 === (string) $key2) {
|
||||
$result[$key1] = $value1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
?>
|
25
include/php_compat/hash_hmac.php
Normal file
25
include/php_compat/hash_hmac.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
//(hash) - enabled by default as of PHP 5.1.2
|
||||
function hash_hmac($algo, $data, $key, $raw_output=false)
|
||||
{
|
||||
/* md5 and sha1 only */
|
||||
$algo=strtolower($algo);
|
||||
$p=array('md5'=>'H32','sha1'=>'H40');
|
||||
if ( !isset($p[$algo]) or !function_exists($algo) )
|
||||
{
|
||||
$algo = 'md5';
|
||||
}
|
||||
if(strlen($key)>64) $key=pack($p[$algo],$algo($key));
|
||||
if(strlen($key)<64) $key=str_pad($key,64,chr(0));
|
||||
|
||||
$ipad=substr($key,0,64) ^ str_repeat(chr(0x36),64);
|
||||
$opad=substr($key,0,64) ^ str_repeat(chr(0x5C),64);
|
||||
|
||||
$ret = $algo($opad.pack($p[$algo],$algo($ipad.$data)));
|
||||
if ($raw_output)
|
||||
{
|
||||
$ret = pack('H*', $ret);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
?>
|
|
@ -30,32 +30,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
if (!function_exists('hash_hmac'))
|
||||
{
|
||||
function hash_hmac($algo, $data, $key, $raw_output=false)
|
||||
{
|
||||
/* md5 and sha1 only */
|
||||
$algo=strtolower($algo);
|
||||
$p=array('md5'=>'H32','sha1'=>'H40');
|
||||
if ( !isset($p[$algo]) or !function_exists($algo) )
|
||||
{
|
||||
$algo = 'md5';
|
||||
}
|
||||
if(strlen($key)>64) $key=pack($p[$algo],$algo($key));
|
||||
if(strlen($key)<64) $key=str_pad($key,64,chr(0));
|
||||
|
||||
$ipad=substr($key,0,64) ^ str_repeat(chr(0x36),64);
|
||||
$opad=substr($key,0,64) ^ str_repeat(chr(0x5C),64);
|
||||
|
||||
$ret = $algo($opad.pack($p[$algo],$algo($ipad.$data)));
|
||||
if ($raw_output)
|
||||
{
|
||||
$ret = pack('H*', $ret);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
//returns string action to perform on a new comment: validate, moderate, reject
|
||||
function user_comment_check($action, $comment, $picture)
|
||||
{
|
||||
|
@ -166,7 +140,8 @@ if ( $page['show_comments'] and isset( $_POST['content'] ) )
|
|||
|
||||
$key = explode(':', @$_POST['key']);
|
||||
if ( count($key)!=2
|
||||
or $key[0]>time() or $key[0]<time()-1800 // 30 minutes expiration
|
||||
or $key[0]>time()-2 // page must have been retrieved more than 2 sec ago
|
||||
or $key[0]<time()-3600 // 60 minutes expiration
|
||||
or hash_hmac('md5', $key[0], $conf['secret_key'])!=$key[1]
|
||||
)
|
||||
{
|
||||
|
@ -257,6 +232,7 @@ if ( $page['show_comments'] and isset( $_POST['content'] ) )
|
|||
}
|
||||
else
|
||||
{
|
||||
set_status_header(403);
|
||||
$template->assign_block_vars('information',
|
||||
array('INFORMATION'=>l10n('comment_not_added') )
|
||||
);
|
||||
|
@ -354,9 +330,15 @@ SELECT id,author,date,image_id,content
|
|||
{
|
||||
$key = time();
|
||||
$key .= ':'.hash_hmac('md5', $key, $conf['secret_key']);
|
||||
$content = '';
|
||||
if ('reject'===@$comment_action)
|
||||
{
|
||||
$content = htmlspecialchars($comm['content']);
|
||||
}
|
||||
$template->assign_block_vars('comments.add_comment',
|
||||
array(
|
||||
'key' => $key
|
||||
'KEY' => $key,
|
||||
'CONTENT' => $content
|
||||
));
|
||||
// display author field if the user is not logged in
|
||||
if ($user['is_the_guest'])
|
||||
|
|
|
@ -494,20 +494,8 @@ function ws_session_login($params, &$service)
|
|||
{
|
||||
return new PwgError(400, "This method requires POST");
|
||||
}
|
||||
|
||||
$username = $params['username'];
|
||||
// retrieving the encrypted password of the login submitted
|
||||
$query = '
|
||||
SELECT '.$conf['user_fields']['id'].' AS id,
|
||||
'.$conf['user_fields']['password'].' AS password
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
|
||||
;';
|
||||
$row = mysql_fetch_assoc(pwg_query($query));
|
||||
|
||||
if ($row['password'] == $conf['pass_convert']($params['password']))
|
||||
if (try_log_user($params['username'], $params['password'],false))
|
||||
{
|
||||
log_user($row['id'], false);
|
||||
return true;
|
||||
}
|
||||
return new PwgError(999, 'Invalid username/password');
|
||||
|
|
|
@ -21,7 +21,6 @@ INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('rate_anonymous',
|
|||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('page_banner','<h1>PhpWebGallery demonstration site</h1><p>My photos web site</p>','html displayed on the top each page of your gallery');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('history_admin','false','keep a history of administrator visits on your website');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('history_guest','true','keep a history of guest visits on your website');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('login_history','true','keep a history of user logins on your website');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('allow_user_registration','true','allow visitors to register?');
|
||||
INSERT INTO phpwebgallery_config (param,value,comment) VALUES ('secret_key', MD5(RAND()), 'a secret key specific to the gallery for internal use');
|
||||
-- Notification by mail
|
||||
|
|
50
install/db/46-database.php
Normal file
50
install/db/46-database.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | PhpWebGallery - a PHP based picture gallery |
|
||||
// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
|
||||
// | Copyright (C) 2003-2005 PhpWebGallery Team - http://phpwebgallery.net |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | branch : BSF (Best So Far)
|
||||
// | file : $Id$
|
||||
// | last update : $Date$
|
||||
// | last modifier : $Author$
|
||||
// | revision : $Revision$
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | This program is free software; you can redistribute it and/or modify |
|
||||
// | it under the terms of the GNU General Public License as published by |
|
||||
// | the Free Software Foundation |
|
||||
// | |
|
||||
// | 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 |
|
||||
// | General Public License for more details. |
|
||||
// | |
|
||||
// | You should have received a copy of the GNU General Public License |
|
||||
// | along with this program; if not, write to the Free Software |
|
||||
// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
|
||||
// | USA. |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
if (!defined('PHPWG_ROOT_PATH'))
|
||||
{
|
||||
die('Hacking attempt!');
|
||||
}
|
||||
|
||||
$upgrade_description = 'remove login_history from #config (partial revert 30-database.php)';
|
||||
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Upgrade content |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
$query = '
|
||||
DELETE FROM '.PREFIX_TABLE.'config WHERE param="login_history"';
|
||||
pwg_query($query);
|
||||
|
||||
echo
|
||||
"\n"
|
||||
.'"'.$upgrade_description.'"'.' ended'
|
||||
."\n"
|
||||
;
|
||||
|
||||
?>
|
|
@ -106,7 +106,6 @@ $lang['Link all category elements to a new category'] = 'Link all category eleme
|
|||
$lang['Link all category elements to some existing categories'] = 'Link all category elements to some existing categories';
|
||||
$lang['Linked categories'] = 'Linked categories';
|
||||
$lang['Lock gallery'] = 'Lock gallery';
|
||||
$lang['Login history'] = 'User login history';
|
||||
$lang['Maintenance'] = 'Maintenance';
|
||||
$lang['Manage permissions for a category'] = 'Manage permissions for a category';
|
||||
$lang['Manage permissions for group "%s"'] = 'Manage permissions for group "%s"';
|
||||
|
|
|
@ -40,10 +40,6 @@ rate images.</li>
|
|||
will be saved.</li>
|
||||
|
||||
<li><strong>History Guests</strong>: page visits by guests will be saved.</li>
|
||||
|
||||
<li><strong>User login history</strong>: when a user logs in, it will be
|
||||
logged in the <code>history</code> table.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
|
@ -106,7 +106,6 @@ $lang['Link all category elements to a new category'] = 'Associer tous les
|
|||
$lang['Link all category elements to some existing categories'] = 'Associer tous les éléments de la catégorie à des catégories existantes';
|
||||
$lang['Linked categories'] = 'Catégories associées';
|
||||
$lang['Lock gallery'] = 'Verrouiller la galerie';
|
||||
$lang['Login history'] = 'Historique des connexions';
|
||||
$lang['Maintenance'] = 'Maintenance';
|
||||
$lang['Manage permissions for a category'] = 'Gérer les permissions pour une catégorie';
|
||||
$lang['Manage permissions for group "%s"'] = 'Gérer les permissions pour le groupe "%s"';
|
||||
|
|
|
@ -41,10 +41,6 @@ dans l'
|
|||
|
||||
<li><strong>Historique Invités</strong>: les visites des pages
|
||||
par les invités sont enregistrées.</li>
|
||||
|
||||
<li><strong>Historique des connexions</strong>: chaque connexion
|
||||
utilisateur, est enregistrée dans la table <code>history</code>.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
|
@ -82,10 +82,6 @@
|
|||
<li>
|
||||
<label><span class="property">{lang:Guests}</span><input type="checkbox" name="history_guest" {general.HISTORY_GUEST} /></label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<label><span class="property">{lang:Login history}</span><input type="checkbox" name="login_history" {general.LOGIN_HISTORY} /></label>
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</li>
|
||||
|
|
|
@ -190,8 +190,8 @@
|
|||
<!-- BEGIN author_field -->
|
||||
<label>{lang:upload_author}<input type="text" name="author"></label>
|
||||
<!-- END author_field -->
|
||||
<label>{lang:comment}<textarea name="content" rows="5" cols="80"></textarea></label>
|
||||
<input type="hidden" name="key" value="{comments.add_comment.key}" />
|
||||
<label>{lang:comment}<textarea name="content" rows="5" cols="80">{comments.add_comment.CONTENT}</textarea></label>
|
||||
<input type="hidden" name="key" value="{comments.add_comment.KEY}" />
|
||||
<input type="submit" value="{lang:submit}">
|
||||
</fieldset>
|
||||
</form>
|
||||
|
|
Loading…
Add table
Reference in a new issue