feature #392, authentication keys, album notification

* On album notification (for a group), sends one distinct email for each user
  with a new authentication key.

* When someone clicks the link with auth=<key> in URL, if the user is not
  already connected, Piwigo will automatically connect the user.
This commit is contained in:
plegall
2015-12-31 19:59:08 +01:00
parent eee57a5d2e
commit 4aeedb5a2e
7 changed files with 181 additions and 21 deletions
+4
View File
@@ -646,6 +646,10 @@ $conf['recent_post_dates'] = array(
// the author shown in the RSS feed <author> element
$conf['rss_feed_author'] = 'Piwigo notifier';
// how long does the authentication key stays valid, in seconds. 3 days by
// default. 0 to disable.
$conf['auth_key_duration'] = 3*24*60*60;
// +-----------------------------------------------------------------------+
// | Set admin layout |
// +-----------------------------------------------------------------------+
+2
View File
@@ -81,6 +81,8 @@ if (!defined('USER_FEED_TABLE'))
define('USER_FEED_TABLE', $prefixeTable.'user_feed');
if (!defined('RATE_TABLE'))
define('RATE_TABLE', $prefixeTable.'rate');
if (!defined('USER_AUTH_KEYS_TABLE'))
define('USER_AUTH_KEYS_TABLE', $prefixeTable.'user_auth_keys');
if (!defined('USER_CACHE_TABLE'))
define('USER_CACHE_TABLE', $prefixeTable.'user_cache');
if (!defined('USER_CACHE_CATEGORIES_TABLE'))
+23 -7
View File
@@ -514,6 +514,8 @@ SELECT DISTINCT language
// get subset of users in this group for a specific language
$query = '
SELECT
ui.user_id,
ui.status,
u.'.$conf['user_fields']['username'].' AS name,
u.'.$conf['user_fields']['email'].' AS email
FROM '.USER_GROUP_TABLE.' AS ug
@@ -534,13 +536,27 @@ SELECT
switch_lang_to($language);
$return&= pwg_mail(null,
array_merge(
$args,
array('Bcc' => $users)
),
$tpl
);
foreach ($users as $u)
{
$authkey = create_user_auth_key($u['user_id'], $u['status']);
$user_tpl = $tpl;
if ($authkey !== false)
{
$user_tpl['assign']['LINK'] = add_url_params($tpl['assign']['LINK'], array('auth' => $authkey['auth_key']));
if (isset($user_tpl['assign']['IMG']['link']))
{
$user_tpl['assign']['IMG']['link'] = add_url_params(
$user_tpl['assign']['IMG']['link'],
array('auth' => $authkey['auth_key'])
);
}
}
$return &= pwg_mail($u['email'], $args, $user_tpl);
}
switch_lang_back();
}
+132
View File
@@ -1462,4 +1462,136 @@ function get_recent_photos_sql($db_field)
.pwg_db_get_recent_period_expression($user['recent_period'])
.','.pwg_db_get_recent_period_expression(1,$user['last_photo_date']).')';
}
/**
* Performs auto-connection if authentication key is valid.
*
* @since 2.8
*
* @return bool
*/
function auth_key_login($auth_key)
{
global $conf, $user;
if ($user['id'] != $conf['guest_id'])
{
return false;
}
if (!preg_match('/^[a-z0-9]{30}$/i', $auth_key))
{
return false;
}
$query = '
SELECT
*,
'.$conf['user_fields']['username'].' AS username,
NOW() AS dbnow
FROM '.USER_AUTH_KEYS_TABLE.' AS uak
JOIN '.USER_INFOS_TABLE.' AS ui ON uak.user_id = ui.user_id
JOIN '.USERS_TABLE.' AS u ON u.'.$conf['user_fields']['id'].' = ui.user_id
WHERE auth_key = \''.$auth_key.'\'
;';
$keys = query2array($query);
if (count($keys) == 0)
{
return false;
}
$key = $keys[0];
// is the key still valid?
if (strtotime($key['expired_on']) < strtotime($key['dbnow']))
{
return false;
}
// admin/webmaster/guest can't get connected with authentication keys
if (!in_array($key['status'], array('normal','generic')))
{
return false;
}
$user['id'] = $key['user_id'];
log_user($user['id'], false);
trigger_notify('login_success', stripslashes($key['username']));
return true;
}
/**
* Creates an authentication key.
*
* @since 2.8
* @param int $user_id
* @return array
*/
function create_user_auth_key($user_id, $user_status=null)
{
global $conf;
if (0 == $conf['auth_key_duration'])
{
return false;
}
if (!isset($user_status))
{
// we have to find the user status
$query = '
SELECT
status
FROM '.USER_INFOS_TABLE.'
WHERE user_id = '.$user_id.'
;';
$user_infos = query2array($query);
if (count($user_infos) == 0)
{
return false;
}
$user_status = $user_infos[0]['status'];
}
if (!in_array($user_status, array('normal','generic')))
{
return false;
}
$candidate = generate_key(30);
$query = '
SELECT
COUNT(*),
NOW(),
ADDDATE(NOW(), INTERVAL '.$conf['auth_key_duration'].' SECOND)
FROM '.USER_AUTH_KEYS_TABLE.'
WHERE auth_key = \''.$candidate.'\'
;';
list($counter, $now, $expiration) = pwg_db_fetch_row(pwg_query($query));
if (0 == $counter)
{
$key = array(
'auth_key' => $candidate,
'user_id' => $user_id,
'created_on' => $now,
'duration' => $conf['auth_key_duration'],
'expired_on' => $expiration,
);
single_insert(USER_AUTH_KEYS_TABLE, $key);
$key['auth_key_id'] = pwg_db_insert_id();
return $key;
}
else
{
return create_user_auth_key($user_id);
}
}
?>
+6
View File
@@ -65,6 +65,12 @@ if ($conf['apache_authentication'])
}
}
// automatic login by authentication key
if (isset($_GET['auth']))
{
auth_key_login($_GET['auth']);
}
$user = build_user( $user['id'],
( defined('IN_ADMIN') and IN_ADMIN ) ? false : true // use cache ?
);