mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-05-06 13:32:52 +02:00
Merge branch 'master' into issue-2362-add-filters-options-in-admin
This commit is contained in:
@@ -460,6 +460,34 @@ $conf['session_use_ip_address'] = true;
|
||||
// session").
|
||||
$conf['session_gc_probability'] = 1;
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | api key |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
// api_key_duration: available duration options (in days) for API key creation.
|
||||
// Array of predefined durations that will be displayed in the select dropdown
|
||||
// when creating a new API key. Use 'custom' to allow users to set a specific
|
||||
// expiration date with a date picker input.
|
||||
$conf['api_key_duration'] = ['30', '90', '180', '365', 'custom'];
|
||||
|
||||
// The following API methods are prohibited when making requests with an API key.
|
||||
// These restrictions are in place for security reasons and to prevent unauthorized
|
||||
// access to sensitive operations that require higher-level authentication.
|
||||
$conf['api_key_forbidden_methods'] = array(
|
||||
// users
|
||||
'pwg.users.generatePasswordLink',
|
||||
'pwg.users.getAuthKey',
|
||||
'pwg.users.setMainUser',
|
||||
'pwg.users.setInfo',
|
||||
// plugins
|
||||
'pwg.plugins.performAction',
|
||||
// themes
|
||||
'pwg.themes.performAction',
|
||||
// extensions
|
||||
'pwg.extensions.ignoreUpdate',
|
||||
'pwg.extensions.update',
|
||||
);
|
||||
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | debug/performance |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
@@ -20,6 +20,8 @@ define('IMG_MEDIUM', 'medium');
|
||||
define('IMG_LARGE', 'large');
|
||||
define('IMG_XLARGE', 'xlarge');
|
||||
define('IMG_XXLARGE', 'xxlarge');
|
||||
define('IMG_3XLARGE', '3xlarge');
|
||||
define('IMG_4XLARGE', '4xlarge');
|
||||
define('IMG_CUSTOM', 'custom');
|
||||
|
||||
|
||||
@@ -53,7 +55,7 @@ final class ImageStdParams
|
||||
/** @var string[] */
|
||||
private static $all_types = array(
|
||||
IMG_SQUARE, IMG_THUMB, IMG_XXSMALL, IMG_XSMALL, IMG_SMALL,
|
||||
IMG_MEDIUM, IMG_LARGE, IMG_XLARGE, IMG_XXLARGE
|
||||
IMG_MEDIUM, IMG_LARGE, IMG_XLARGE, IMG_XXLARGE, IMG_3XLARGE, IMG_4XLARGE
|
||||
);
|
||||
/** @var DerivativeParams[] */
|
||||
private static $all_type_map = array();
|
||||
@@ -214,6 +216,8 @@ final class ImageStdParams
|
||||
IMG_LARGE => new DerivativeParams( SizingParams::classic(1008,756) ),
|
||||
IMG_XLARGE => new DerivativeParams( SizingParams::classic(1224,918) ),
|
||||
IMG_XXLARGE => new DerivativeParams( SizingParams::classic(1656,1242) ),
|
||||
IMG_3XLARGE => new DerivativeParams( SizingParams::classic(2232,1674) ),
|
||||
IMG_4XLARGE => new DerivativeParams( SizingParams::classic(3000,2250) ),
|
||||
);
|
||||
$now = time();
|
||||
foreach($arr as $params)
|
||||
|
||||
@@ -153,6 +153,13 @@ SELECT data
|
||||
*/
|
||||
function pwg_session_write($session_id, $data)
|
||||
{
|
||||
// when the request is authenticated via api_key (PWG_API_KEY_REQUEST),
|
||||
// you do not want the session to be written to the database (no user session persistence)
|
||||
// this avoids polluting the session table with stateless API accesses
|
||||
if (defined('PWG_API_KEY_REQUEST'))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
$query = '
|
||||
REPLACE INTO '.SESSIONS_TABLE.'
|
||||
(id,data,expiration)
|
||||
|
||||
@@ -1661,14 +1661,28 @@ function get_recent_photos_sql($db_field)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function auth_key_login($auth_key)
|
||||
function auth_key_login($auth_key, $connection_by_header=false)
|
||||
{
|
||||
global $conf, $user, $page;
|
||||
|
||||
if (!preg_match('/^[a-z0-9]{30}$/i', $auth_key))
|
||||
$valid_key = false;
|
||||
$secret_key = null;
|
||||
if (preg_match('/^[a-z0-9]{30}$/i', $auth_key))
|
||||
{
|
||||
return false;
|
||||
$valid_key = 'auth_key';
|
||||
}
|
||||
else if (
|
||||
preg_match('/^pkid-\d{8}-[a-z0-9]{20}:[a-z0-9]{40}$/i', $auth_key)
|
||||
and $connection_by_header
|
||||
)
|
||||
{
|
||||
$valid_key = 'api_key';
|
||||
$tmp_key = explode(':', $auth_key);
|
||||
$auth_key = $tmp_key[0];
|
||||
$secret_key = $tmp_key[1];
|
||||
}
|
||||
|
||||
if (!$valid_key) return false;
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
@@ -1689,6 +1703,22 @@ SELECT
|
||||
|
||||
$key = $keys[0];
|
||||
|
||||
// the key is an api_key
|
||||
if ('api_key' === $valid_key)
|
||||
{
|
||||
// check secret
|
||||
if (!pwg_password_verify($secret_key, $key['apikey_secret']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// is the key is revoked?
|
||||
if (null != $key['revoked_on'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// is the key still valid?
|
||||
if (strtotime($key['expired_on']) < strtotime($key['dbnow']))
|
||||
{
|
||||
@@ -1697,12 +1727,34 @@ SELECT
|
||||
}
|
||||
|
||||
// admin/webmaster/guest can't get connected with authentication keys
|
||||
if (!in_array($key['status'], array('normal','generic')))
|
||||
if ('auth_key' === $valid_key and !in_array($key['status'], array('normal','generic')))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$user['id'] = $key['user_id'];
|
||||
|
||||
// update last used key
|
||||
single_update(
|
||||
USER_AUTH_KEYS_TABLE,
|
||||
array('last_used_on' => $key['dbnow']),
|
||||
array(
|
||||
'user_id' => $user['id'],
|
||||
'auth_key' => $key['auth_key']
|
||||
),
|
||||
);
|
||||
|
||||
// set the type of connection
|
||||
$_SESSION['connected_with'] = $valid_key;
|
||||
|
||||
// if the connection is made via an API key in the header,
|
||||
// access is authenticated without creating a persistent user session
|
||||
// this enables stateless authentication for API calls
|
||||
if ($connection_by_header)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
log_user($user['id'], false);
|
||||
trigger_notify('login_success', $key['username']);
|
||||
|
||||
@@ -1771,6 +1823,7 @@ SELECT
|
||||
'created_on' => $now,
|
||||
'duration' => $conf['auth_key_duration'],
|
||||
'expired_on' => $expiration,
|
||||
'key_type' => 'auth_key',
|
||||
);
|
||||
|
||||
single_insert(USER_AUTH_KEYS_TABLE, $key);
|
||||
@@ -1799,6 +1852,7 @@ UPDATE '.USER_AUTH_KEYS_TABLE.'
|
||||
SET expired_on = NOW()
|
||||
WHERE user_id = '.$user_id.'
|
||||
AND expired_on > NOW()
|
||||
AND key_type = \'auth_key\'
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
@@ -2028,4 +2082,555 @@ SELECT COUNT(*)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all user infos and save parameters
|
||||
*
|
||||
* @since 16
|
||||
* @param mixed[] $params
|
||||
* @option string username (optional)
|
||||
* @option string password (optional)
|
||||
* @option string email (optional)
|
||||
* @option string status (optional)
|
||||
* @option int level (optional)
|
||||
* @option string language (optional)
|
||||
* @option string theme (optional)
|
||||
* @option int nb_image_page (optional)
|
||||
* @option int recent_period (optional)
|
||||
* @option bool expand (optional)
|
||||
* @option bool show_nb_comments (optional)
|
||||
* @option bool show_nb_hits (optional)
|
||||
* @option bool enabled_high (optional)
|
||||
*/
|
||||
function check_and_save_user_infos($params)
|
||||
{
|
||||
if (isset($params['username']) and strlen(str_replace( " ", "", $params['username'])) == 0)
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, 'Name field must not be empty');
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => 'Name field must not be empty'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
global $conf, $user, $service;
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
$updates = $updates_infos = array();
|
||||
$update_status = null;
|
||||
|
||||
if (count($params['user_id']) == 1)
|
||||
{
|
||||
if (get_username($params['user_id'][0]) === false)
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, 'This user does not exist.');
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => 'This user does not exist.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($params['username']))
|
||||
{
|
||||
$user_id = get_userid($params['username']);
|
||||
if ($user_id and $user_id != $params['user_id'][0])
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, l10n('this login is already used'));
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => l10n('this login is already used')
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($params['username'] != strip_tags($params['username']))
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, l10n('html tags are not allowed in login'));
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => l10n('html tags are not allowed in login')
|
||||
)
|
||||
);
|
||||
}
|
||||
$updates[ $conf['user_fields']['username'] ] = $params['username'];
|
||||
}
|
||||
|
||||
if (!empty($params['email']))
|
||||
{
|
||||
if ( ($error = validate_mail_address($params['user_id'][0], $params['email'])) != '')
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, $error);
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => $error
|
||||
)
|
||||
);
|
||||
}
|
||||
$updates[ $conf['user_fields']['email'] ] = $params['email'];
|
||||
}
|
||||
|
||||
if (!empty($params['password']))
|
||||
{
|
||||
if (!is_webmaster())
|
||||
{
|
||||
$password_protected_users = array($conf['guest_id']);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
user_id
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE status IN (\'webmaster\', \'admin\')
|
||||
;';
|
||||
$admin_ids = query2array($query, null, 'user_id');
|
||||
|
||||
// we add all admin+webmaster users BUT the user herself
|
||||
$password_protected_users = array_merge($password_protected_users, array_diff($admin_ids, array($user['id'])));
|
||||
|
||||
if (in_array($params['user_id'][0], $password_protected_users))
|
||||
{
|
||||
// return new PwgError(403, 'Only webmasters can change password of other "webmaster/admin" users');
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => 403,
|
||||
'message' => 'Only webmasters can change password of other "webmaster/admin" users'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$updates[ $conf['user_fields']['password'] ] = $conf['password_hash']($params['password']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($params['status']))
|
||||
{
|
||||
if (in_array($params['status'], array('webmaster', 'admin')) and !is_webmaster() )
|
||||
{
|
||||
// return new PwgError(403, 'Only webmasters can grant "webmaster/admin" status');
|
||||
return array(
|
||||
'error' => array(
|
||||
'code '=> 403,
|
||||
'message' => 'Only webmasters can grant "webmaster/admin" status'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( !in_array($params['status'], array('guest','generic','normal','admin','webmaster')) )
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid status');
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => 'Invalid status'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$protected_users = array(
|
||||
$user['id'],
|
||||
$conf['guest_id'],
|
||||
$conf['webmaster_id'],
|
||||
);
|
||||
|
||||
// an admin can't change status of other admin/webmaster
|
||||
if ('admin' == $user['status'])
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
user_id
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE status IN (\'webmaster\', \'admin\')
|
||||
;';
|
||||
$protected_users = array_merge($protected_users, query2array($query, null, 'user_id'));
|
||||
}
|
||||
|
||||
// status update query is separated from the rest as not applying to the same
|
||||
// set of users (current, guest and webmaster can't be changed)
|
||||
$params['user_id_for_status'] = array_diff($params['user_id'], $protected_users);
|
||||
|
||||
$update_status = $params['status'];
|
||||
}
|
||||
|
||||
if (!empty($params['level']) or @$params['level']===0)
|
||||
{
|
||||
if ( !in_array($params['level'], $conf['available_permission_levels']) )
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid level');
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => 'Invalid level'
|
||||
)
|
||||
);
|
||||
}
|
||||
$updates_infos['level'] = $params['level'];
|
||||
}
|
||||
|
||||
if (!empty($params['language']))
|
||||
{
|
||||
if ( !in_array($params['language'], array_keys(get_languages())) )
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid language');
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => 'Invalid language'
|
||||
)
|
||||
);
|
||||
}
|
||||
$updates_infos['language'] = $params['language'];
|
||||
}
|
||||
|
||||
if (!empty($params['theme']))
|
||||
{
|
||||
if ( !in_array($params['theme'], array_keys(get_pwg_themes())) )
|
||||
{
|
||||
// return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid theme');
|
||||
return array(
|
||||
'error' => array(
|
||||
'code' => WS_ERR_INVALID_PARAM,
|
||||
'message' => 'Invalid theme'
|
||||
)
|
||||
);
|
||||
}
|
||||
$updates_infos['theme'] = $params['theme'];
|
||||
}
|
||||
|
||||
if (!empty($params['nb_image_page']))
|
||||
{
|
||||
$updates_infos['nb_image_page'] = $params['nb_image_page'];
|
||||
}
|
||||
|
||||
if (!empty($params['recent_period']) or @$params['recent_period']===0)
|
||||
{
|
||||
$updates_infos['recent_period'] = $params['recent_period'];
|
||||
}
|
||||
|
||||
if (!empty($params['expand']) or @$params['expand']===false)
|
||||
{
|
||||
$updates_infos['expand'] = boolean_to_string($params['expand']);
|
||||
}
|
||||
|
||||
if (!empty($params['show_nb_comments']) or @$params['show_nb_comments']===false)
|
||||
{
|
||||
$updates_infos['show_nb_comments'] = boolean_to_string($params['show_nb_comments']);
|
||||
}
|
||||
|
||||
if (!empty($params['show_nb_hits']) or @$params['show_nb_hits']===false)
|
||||
{
|
||||
$updates_infos['show_nb_hits'] = boolean_to_string($params['show_nb_hits']);
|
||||
}
|
||||
|
||||
if (!empty($params['enabled_high']) or @$params['enabled_high']===false)
|
||||
{
|
||||
$updates_infos['enabled_high'] = boolean_to_string($params['enabled_high']);
|
||||
}
|
||||
|
||||
// perform updates
|
||||
single_update(
|
||||
USERS_TABLE,
|
||||
$updates,
|
||||
array($conf['user_fields']['id'] => $params['user_id'][0])
|
||||
);
|
||||
|
||||
if (isset($updates[ $conf['user_fields']['password'] ]))
|
||||
{
|
||||
deactivate_user_auth_keys($params['user_id'][0]);
|
||||
}
|
||||
|
||||
if (isset($updates[ $conf['user_fields']['email'] ]))
|
||||
{
|
||||
deactivate_password_reset_key($params['user_id'][0]);
|
||||
}
|
||||
|
||||
if (isset($update_status) and count($params['user_id_for_status']) > 0)
|
||||
{
|
||||
$query = '
|
||||
UPDATE '. USER_INFOS_TABLE .' SET
|
||||
status = "'. $update_status .'"
|
||||
WHERE user_id IN('. implode(',', $params['user_id_for_status']) .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
// we delete sessions, ie disconnect, for users if status becomes "guest".
|
||||
// It's like deactivating the user.
|
||||
if ('guest' == $update_status)
|
||||
{
|
||||
foreach ($params['user_id_for_status'] as $user_id_for_status)
|
||||
{
|
||||
delete_user_sessions($user_id_for_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($updates_infos) > 0)
|
||||
{
|
||||
$query = '
|
||||
UPDATE '. USER_INFOS_TABLE .' SET ';
|
||||
|
||||
$first = true;
|
||||
foreach ($updates_infos as $field => $value)
|
||||
{
|
||||
if (!$first) $query.= ', ';
|
||||
else $first = false;
|
||||
$query.= $field .' = "'. $value .'"';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
WHERE user_id IN('. implode(',', $params['user_id']) .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
// manage association to groups
|
||||
if (!empty($params['group_id']))
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.USER_GROUP_TABLE.'
|
||||
WHERE user_id IN ('.implode(',', $params['user_id']).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
// we remove all provided groups that do not really exist
|
||||
$query = '
|
||||
SELECT
|
||||
id
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
WHERE id IN ('.implode(',', $params['group_id']).')
|
||||
;';
|
||||
$group_ids = array_from_query($query, 'id');
|
||||
|
||||
// if only -1 (a group id that can't exist) is in the list, then no
|
||||
// group is associated
|
||||
|
||||
if (count($group_ids) > 0)
|
||||
{
|
||||
$inserts = array();
|
||||
|
||||
foreach ($group_ids as $group_id)
|
||||
{
|
||||
foreach ($params['user_id'] as $user_id)
|
||||
{
|
||||
$inserts[] = array('user_id' => $user_id, 'group_id' => $group_id);
|
||||
}
|
||||
}
|
||||
|
||||
mass_inserts(USER_GROUP_TABLE, array_keys($inserts[0]), $inserts);
|
||||
}
|
||||
}
|
||||
|
||||
invalidate_user_cache();
|
||||
|
||||
pwg_activity('user', $params['user_id'], 'edit');
|
||||
|
||||
return array(
|
||||
'user_id' => $params['user_id'],
|
||||
'infos' => $updates_infos,
|
||||
'account' => $updates
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new api_key
|
||||
*
|
||||
* @since 16
|
||||
* @param int $user_id
|
||||
* @param int|null $duration
|
||||
* @param string $key_name
|
||||
* @return array auth_key / apikey_secret / apikey_name /
|
||||
* user_id / created_on / duration / expired_on / key_type
|
||||
*/
|
||||
function create_api_key($user_id, $duration, $key_name)
|
||||
{
|
||||
$key_id = 'pkid-'.date('Ymd').'-'.generate_key(20);
|
||||
$key_secret = generate_key(40);
|
||||
|
||||
list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
|
||||
|
||||
$key = array(
|
||||
'auth_key' => $key_id,
|
||||
'apikey_secret' => pwg_password_hash($key_secret),
|
||||
'apikey_name' => $key_name,
|
||||
'user_id' => $user_id,
|
||||
'created_on' => $dbnow,
|
||||
'key_type' => 'api_key'
|
||||
);
|
||||
|
||||
if (!empty($duration))
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
ADDDATE(NOW(), INTERVAL '.($duration * 60 * 60 * 24).' SECOND)
|
||||
;';
|
||||
list($expiration) = pwg_db_fetch_row(pwg_query($query));
|
||||
$key['duration'] = $duration;
|
||||
}
|
||||
$key['expired_on'] = $expiration;
|
||||
|
||||
single_insert(USER_AUTH_KEYS_TABLE, $key);
|
||||
|
||||
$key['apikey_secret'] = $key_secret;
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke a api_key
|
||||
*
|
||||
* @since 16
|
||||
* @param int $user_id
|
||||
* @param string $pkid
|
||||
* @return string|bool
|
||||
*/
|
||||
function revoke_api_key($user_id, $pkid)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*),
|
||||
NOW()
|
||||
FROM `'.USER_AUTH_KEYS_TABLE.'`
|
||||
WHERE auth_key = "'.$pkid.'"
|
||||
AND user_id = '.$user_id.'
|
||||
;';
|
||||
|
||||
list($key, $now) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ($key == 0)
|
||||
{
|
||||
return l10n('API Key not found');
|
||||
}
|
||||
|
||||
single_update(
|
||||
USER_AUTH_KEYS_TABLE,
|
||||
array('revoked_on' => $now),
|
||||
array(
|
||||
'auth_key' => $pkid,
|
||||
'user_id' => $user_id
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a api_key
|
||||
*
|
||||
* @since 16
|
||||
* @param int $user_id
|
||||
* @param string $pkid
|
||||
* @return string|bool
|
||||
*/
|
||||
function edit_api_key($user_id, $pkid, $api_name)
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM `'.USER_AUTH_KEYS_TABLE.'`
|
||||
WHERE auth_key = "'.$pkid.'"
|
||||
AND user_id = '.$user_id.'
|
||||
;';
|
||||
|
||||
list($key) = pwg_db_fetch_row(pwg_query($query));
|
||||
if ($key == 0)
|
||||
{
|
||||
return l10n('API Key not found');
|
||||
}
|
||||
|
||||
single_update(
|
||||
USER_AUTH_KEYS_TABLE,
|
||||
array('apikey_name' => $api_name),
|
||||
array(
|
||||
'auth_key' => $pkid,
|
||||
'user_id' => $user_id
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all api_key
|
||||
*
|
||||
* @since 16
|
||||
* @param string $user_id
|
||||
* @return array|false
|
||||
*/
|
||||
function get_api_key($user_id)
|
||||
{
|
||||
$query = '
|
||||
SELECT *
|
||||
FROM `'.USER_AUTH_KEYS_TABLE.'`
|
||||
WHERE user_id = '.$user_id.'
|
||||
AND key_type = "api_key"
|
||||
;';
|
||||
|
||||
$api_keys = query2array($query);
|
||||
if (!$api_keys) return false;
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
NOW()
|
||||
;';
|
||||
list($now) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
foreach ($api_keys as $i => $api_key)
|
||||
{
|
||||
$api_key['apikey_secret'] = str_repeat("*", 40);
|
||||
unset($api_key['auth_key_id'], $api_key['user_id'], $api_key['key_type']);
|
||||
|
||||
$api_key['created_on_format'] = format_date($api_key['created_on'], array('day', 'month', 'year'));
|
||||
$api_key['expired_on_format'] = format_date($api_key['expired_on'], array('day', 'month', 'year'));
|
||||
$api_key['last_used_on_since'] =
|
||||
$api_key['last_used_on']
|
||||
? time_since($api_key['last_used_on'], 'day')
|
||||
: l10n('Never');
|
||||
|
||||
$expired_on = str2DateTime($api_key['expired_on']);
|
||||
$now = str2DateTime($now);
|
||||
|
||||
$api_key['is_expired'] = $expired_on < $now;
|
||||
if ($api_key['is_expired'])
|
||||
{
|
||||
$api_key['expiration'] = l10n('Expired');
|
||||
}
|
||||
else
|
||||
{
|
||||
$diff = dateDiff($now, $expired_on);
|
||||
if ($diff->days > 0)
|
||||
{
|
||||
$api_key['expiration'] = l10n('%d days', $diff->days);
|
||||
}
|
||||
elseif ($diff->h > 0)
|
||||
{
|
||||
$api_key['expiration'] = l10n('%d hours', $diff->h);
|
||||
}
|
||||
else
|
||||
{
|
||||
$api_key['expiration'] = l10n('%d minutes', $diff->i);
|
||||
}
|
||||
}
|
||||
|
||||
$api_key['expired_on_since'] = time_since($api_key['expired_on'], 'day');
|
||||
|
||||
$api_key['revoked_on_since'] =
|
||||
$api_key['revoked_on']
|
||||
? time_since($api_key['revoked_on'], 'day')
|
||||
: null;
|
||||
|
||||
$api_key['revoked_on_message'] =
|
||||
$api_key['revoked_on']
|
||||
? l10n('This API key was manually revoked on %s', format_date($api_key['revoked_on'], array('day', 'month', 'year')))
|
||||
: null;
|
||||
|
||||
$api_keys[$i] = $api_key;
|
||||
}
|
||||
|
||||
return $api_keys;
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -187,7 +187,7 @@ class Template
|
||||
// standard pages can't get the header to load the html header
|
||||
if (
|
||||
'default' != $theme
|
||||
and in_array(script_basename(), array('identification', 'register', 'password'))
|
||||
and in_array(script_basename(), array('identification', 'register', 'password', 'profile'))
|
||||
and (($themeconf['use_standard_pages'] ?? false) or conf_get_param('use_standard_pages', false))
|
||||
)
|
||||
{
|
||||
|
||||
@@ -56,6 +56,44 @@ if (isset($_GET['auth']))
|
||||
auth_key_login($_GET['auth']);
|
||||
}
|
||||
|
||||
// HTTP_AUTHORIZATION api_key
|
||||
if (
|
||||
defined('IN_WS')
|
||||
and isset($_SERVER['HTTP_AUTHORIZATION'])
|
||||
and !empty($_SERVER['HTTP_AUTHORIZATION'])
|
||||
and isset($_REQUEST['method'])
|
||||
)
|
||||
{
|
||||
$auth_header = pwg_db_real_escape_string($_SERVER['HTTP_AUTHORIZATION']) ?? null;
|
||||
|
||||
if ($auth_header)
|
||||
{
|
||||
$authenticate = auth_key_login($auth_header, true);
|
||||
if (!$authenticate)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'include/ws_init.inc.php');
|
||||
$service->sendResponse(new PwgError(401, 'Invalid api_key'));
|
||||
exit;
|
||||
}
|
||||
define('PWG_API_KEY_REQUEST', true);
|
||||
|
||||
// set pwg_token for api_key request
|
||||
if (isset($_POST['pwg_token']))
|
||||
{
|
||||
$_POST['pwg_token'] = get_pwg_token();
|
||||
}
|
||||
|
||||
if (isset($_GET['pwg_token']))
|
||||
{
|
||||
$_GET['pwg_token'] = get_pwg_token();
|
||||
}
|
||||
|
||||
// logger
|
||||
global $logger;
|
||||
$logger->info('[api_key][pkid='.explode(':', $auth_header)[0].'][method='.$_REQUEST['method'].']');
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
defined('IN_WS')
|
||||
and isset($_REQUEST['method'])
|
||||
@@ -70,6 +108,7 @@ if (
|
||||
$service->sendResponse(new PwgError(999, 'Invalid username/password'));
|
||||
exit();
|
||||
}
|
||||
$_SESSION['connected_with'] = 'pwg.images.uploadAsync';
|
||||
}
|
||||
|
||||
$page['user_use_cache'] = true;
|
||||
|
||||
@@ -517,6 +517,11 @@ Request format: ".@$this->_requestFormat." Response format: ".@$this->_responseF
|
||||
return new PwgError(401, 'Access denied');
|
||||
}
|
||||
|
||||
if (!$this->isAuthorizedMethodForAPIKEY())
|
||||
{
|
||||
return new PwgError(401, 'Access denied');
|
||||
}
|
||||
|
||||
// parameter check and data correction
|
||||
$signature = $method['signature'];
|
||||
$missing_params = array();
|
||||
@@ -679,5 +684,27 @@ Request format: ".@$this->_requestFormat." Response format: ".@$this->_responseF
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
function isAuthorizedMethodForAPIKEY()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
// if the request is made with an API key (via header or session API key),
|
||||
// we check whether the requested method is on the
|
||||
// list of prohibited methods ($conf['api_key_forbidden_methods']) for API keys
|
||||
// if it is, access is refused (false)
|
||||
if (
|
||||
defined('PWG_API_KEY_REQUEST')
|
||||
OR (isset($_SESSION['connected_with']) AND 'ws_session_login_api_key' === $_SESSION['connected_with'])
|
||||
)
|
||||
{
|
||||
if (in_array($_REQUEST['method'], $conf['api_key_forbidden_methods']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -347,8 +347,24 @@ DELETE FROM '. RATE_TABLE .'
|
||||
*/
|
||||
function ws_session_login($params, &$service)
|
||||
{
|
||||
if (try_log_user($params['username'], $params['password'], false))
|
||||
if (defined('PWG_API_KEY_REQUEST'))
|
||||
{
|
||||
return new PwgError(401, 'Cannot use this method with an api key');
|
||||
}
|
||||
|
||||
if (preg_match('/^pkid-\d{8}-[a-z0-9]{20}$/i', $params['username']))
|
||||
{
|
||||
$secret = pwg_db_real_escape_string($params['password']);
|
||||
$authenticate = auth_key_login($params['username'].':'.$secret);
|
||||
if ($authenticate)
|
||||
{
|
||||
$_SESSION['connected_with'] = 'ws_session_login_api_key';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (try_log_user($params['username'], $params['password'], false))
|
||||
{
|
||||
$_SESSION['connected_with'] = 'ws_session_login';
|
||||
return true;
|
||||
}
|
||||
return new PwgError(999, 'Invalid username/password');
|
||||
@@ -362,6 +378,11 @@ function ws_session_login($params, &$service)
|
||||
*/
|
||||
function ws_session_logout($params, &$service)
|
||||
{
|
||||
if (defined('PWG_API_KEY_REQUEST'))
|
||||
{
|
||||
return new PwgError(401, 'Cannot use this method with an api key');
|
||||
}
|
||||
|
||||
if (!is_a_guest())
|
||||
{
|
||||
logout_user();
|
||||
@@ -390,11 +411,13 @@ function ws_session_getStatus($params, &$service)
|
||||
$res['current_datetime'] = $dbnow;
|
||||
$res['version'] = PHPWG_VERSION;
|
||||
$res['save_visits'] = do_log();
|
||||
$res['connected_with'] = $_SESSION['connected_with'] ?? null;
|
||||
|
||||
// Piwigo Remote Sync does not support receiving the new (version 14) output "save_visits"
|
||||
if (isset($_SERVER['HTTP_USER_AGENT']) and preg_match('/^PiwigoRemoteSync/', $_SERVER['HTTP_USER_AGENT']))
|
||||
{
|
||||
unset($res['save_visits']);
|
||||
unset($res['connected_with']);
|
||||
}
|
||||
|
||||
// Piwigo Remote Sync does not support receiving the available sizes
|
||||
@@ -1151,4 +1174,5 @@ SELECT
|
||||
'summary' => $search_summary
|
||||
);
|
||||
}
|
||||
?>
|
||||
|
||||
?>
|
||||
@@ -532,270 +532,124 @@ function ws_users_setInfo($params, &$service)
|
||||
return new PwgError(403, 'Invalid security token');
|
||||
}
|
||||
|
||||
if (isset($params['username']) and strlen(str_replace( " ", "", $params['username'])) == 0) {
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'Name field must not be empty');
|
||||
}
|
||||
$updated_users = check_and_save_user_infos($params);
|
||||
|
||||
global $conf, $user;
|
||||
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
$updates = $updates_infos = array();
|
||||
$update_status = null;
|
||||
|
||||
if (count($params['user_id']) == 1)
|
||||
if (isset($updated_users['error']))
|
||||
{
|
||||
if (get_username($params['user_id'][0]) === false)
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'This user does not exist.');
|
||||
}
|
||||
|
||||
if (!empty($params['username']))
|
||||
{
|
||||
$user_id = get_userid($params['username']);
|
||||
if ($user_id and $user_id != $params['user_id'][0])
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, l10n('this login is already used'));
|
||||
}
|
||||
if ($params['username'] != strip_tags($params['username']))
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, l10n('html tags are not allowed in login'));
|
||||
}
|
||||
$updates[ $conf['user_fields']['username'] ] = $params['username'];
|
||||
}
|
||||
|
||||
if (!empty($params['email']))
|
||||
{
|
||||
if ( ($error = validate_mail_address($params['user_id'][0], $params['email'])) != '')
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, $error);
|
||||
}
|
||||
$updates[ $conf['user_fields']['email'] ] = $params['email'];
|
||||
}
|
||||
|
||||
if (!empty($params['password']))
|
||||
{
|
||||
if (!is_webmaster())
|
||||
{
|
||||
$password_protected_users = array($conf['guest_id']);
|
||||
|
||||
$query = '
|
||||
SELECT
|
||||
user_id
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE status IN (\'webmaster\', \'admin\')
|
||||
;';
|
||||
$admin_ids = query2array($query, null, 'user_id');
|
||||
|
||||
// we add all admin+webmaster users BUT the user herself
|
||||
$password_protected_users = array_merge($password_protected_users, array_diff($admin_ids, array($user['id'])));
|
||||
|
||||
if (in_array($params['user_id'][0], $password_protected_users))
|
||||
{
|
||||
return new PwgError(403, 'Only webmasters can change password of other "webmaster/admin" users');
|
||||
}
|
||||
}
|
||||
|
||||
$updates[ $conf['user_fields']['password'] ] = $conf['password_hash']($params['password']);
|
||||
}
|
||||
return new PwgError($updated_users[ 'error' ][ 'code' ], $updated_users[ 'error' ][ 'message' ]);
|
||||
}
|
||||
|
||||
if (!empty($params['status']))
|
||||
{
|
||||
if (in_array($params['status'], array('webmaster', 'admin')) and !is_webmaster() )
|
||||
{
|
||||
return new PwgError(403, 'Only webmasters can grant "webmaster/admin" status');
|
||||
}
|
||||
|
||||
if ( !in_array($params['status'], array('guest','generic','normal','admin','webmaster')) )
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid status');
|
||||
}
|
||||
|
||||
$protected_users = array(
|
||||
$user['id'],
|
||||
$conf['guest_id'],
|
||||
$conf['webmaster_id'],
|
||||
);
|
||||
|
||||
// an admin can't change status of other admin/webmaster
|
||||
if ('admin' == $user['status'])
|
||||
{
|
||||
$query = '
|
||||
SELECT
|
||||
user_id
|
||||
FROM '.USER_INFOS_TABLE.'
|
||||
WHERE status IN (\'webmaster\', \'admin\')
|
||||
;';
|
||||
$protected_users = array_merge($protected_users, query2array($query, null, 'user_id'));
|
||||
}
|
||||
|
||||
// status update query is separated from the rest as not applying to the same
|
||||
// set of users (current, guest and webmaster can't be changed)
|
||||
$params['user_id_for_status'] = array_diff($params['user_id'], $protected_users);
|
||||
|
||||
$update_status = $params['status'];
|
||||
}
|
||||
|
||||
if (!empty($params['level']) or @$params['level']===0)
|
||||
{
|
||||
if ( !in_array($params['level'], $conf['available_permission_levels']) )
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid level');
|
||||
}
|
||||
$updates_infos['level'] = $params['level'];
|
||||
}
|
||||
|
||||
if (!empty($params['language']))
|
||||
{
|
||||
if ( !in_array($params['language'], array_keys(get_languages())) )
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid language');
|
||||
}
|
||||
$updates_infos['language'] = $params['language'];
|
||||
}
|
||||
|
||||
if (!empty($params['theme']))
|
||||
{
|
||||
if ( !in_array($params['theme'], array_keys(get_pwg_themes())) )
|
||||
{
|
||||
return new PwgError(WS_ERR_INVALID_PARAM, 'Invalid theme');
|
||||
}
|
||||
$updates_infos['theme'] = $params['theme'];
|
||||
}
|
||||
|
||||
if (!empty($params['nb_image_page']))
|
||||
{
|
||||
$updates_infos['nb_image_page'] = $params['nb_image_page'];
|
||||
}
|
||||
|
||||
if (!empty($params['recent_period']) or @$params['recent_period']===0)
|
||||
{
|
||||
$updates_infos['recent_period'] = $params['recent_period'];
|
||||
}
|
||||
|
||||
if (!empty($params['expand']) or @$params['expand']===false)
|
||||
{
|
||||
$updates_infos['expand'] = boolean_to_string($params['expand']);
|
||||
}
|
||||
|
||||
if (!empty($params['show_nb_comments']) or @$params['show_nb_comments']===false)
|
||||
{
|
||||
$updates_infos['show_nb_comments'] = boolean_to_string($params['show_nb_comments']);
|
||||
}
|
||||
|
||||
if (!empty($params['show_nb_hits']) or @$params['show_nb_hits']===false)
|
||||
{
|
||||
$updates_infos['show_nb_hits'] = boolean_to_string($params['show_nb_hits']);
|
||||
}
|
||||
|
||||
if (!empty($params['enabled_high']) or @$params['enabled_high']===false)
|
||||
{
|
||||
$updates_infos['enabled_high'] = boolean_to_string($params['enabled_high']);
|
||||
}
|
||||
|
||||
// perform updates
|
||||
single_update(
|
||||
USERS_TABLE,
|
||||
$updates,
|
||||
array($conf['user_fields']['id'] => $params['user_id'][0])
|
||||
);
|
||||
|
||||
if (isset($updates[ $conf['user_fields']['password'] ]))
|
||||
{
|
||||
deactivate_user_auth_keys($params['user_id'][0]);
|
||||
}
|
||||
|
||||
if (isset($updates[ $conf['user_fields']['email'] ]))
|
||||
{
|
||||
deactivate_password_reset_key($params['user_id'][0]);
|
||||
}
|
||||
|
||||
if (isset($update_status) and count($params['user_id_for_status']) > 0)
|
||||
{
|
||||
$query = '
|
||||
UPDATE '. USER_INFOS_TABLE .' SET
|
||||
status = "'. $update_status .'"
|
||||
WHERE user_id IN('. implode(',', $params['user_id_for_status']) .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
// we delete sessions, ie disconnect, for users if status becomes "guest".
|
||||
// It's like deactivating the user.
|
||||
if ('guest' == $update_status)
|
||||
{
|
||||
foreach ($params['user_id_for_status'] as $user_id_for_status)
|
||||
{
|
||||
delete_user_sessions($user_id_for_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($updates_infos) > 0)
|
||||
{
|
||||
$query = '
|
||||
UPDATE '. USER_INFOS_TABLE .' SET ';
|
||||
|
||||
$first = true;
|
||||
foreach ($updates_infos as $field => $value)
|
||||
{
|
||||
if (!$first) $query.= ', ';
|
||||
else $first = false;
|
||||
$query.= $field .' = "'. $value .'"';
|
||||
}
|
||||
|
||||
$query.= '
|
||||
WHERE user_id IN('. implode(',', $params['user_id']) .')
|
||||
;';
|
||||
pwg_query($query);
|
||||
}
|
||||
|
||||
// manage association to groups
|
||||
if (!empty($params['group_id']))
|
||||
{
|
||||
$query = '
|
||||
DELETE
|
||||
FROM '.USER_GROUP_TABLE.'
|
||||
WHERE user_id IN ('.implode(',', $params['user_id']).')
|
||||
;';
|
||||
pwg_query($query);
|
||||
|
||||
// we remove all provided groups that do not really exist
|
||||
$query = '
|
||||
SELECT
|
||||
id
|
||||
FROM `'.GROUPS_TABLE.'`
|
||||
WHERE id IN ('.implode(',', $params['group_id']).')
|
||||
;';
|
||||
$group_ids = array_from_query($query, 'id');
|
||||
|
||||
// if only -1 (a group id that can't exist) is in the list, then no
|
||||
// group is associated
|
||||
|
||||
if (count($group_ids) > 0)
|
||||
{
|
||||
$inserts = array();
|
||||
|
||||
foreach ($group_ids as $group_id)
|
||||
{
|
||||
foreach ($params['user_id'] as $user_id)
|
||||
{
|
||||
$inserts[] = array('user_id' => $user_id, 'group_id' => $group_id);
|
||||
}
|
||||
}
|
||||
|
||||
mass_inserts(USER_GROUP_TABLE, array_keys($inserts[0]), $inserts);
|
||||
}
|
||||
}
|
||||
|
||||
invalidate_user_cache();
|
||||
|
||||
pwg_activity('user', $params['user_id'], 'edit');
|
||||
|
||||
return $service->invoke('pwg.users.getList', array(
|
||||
'user_id' => $params['user_id'],
|
||||
'display' => 'basics,'.implode(',', array_keys($updates_infos)),
|
||||
));
|
||||
'user_id' => $updated_users['user_id'],
|
||||
'display' => 'basics,'.implode(',', array_keys($updated_users['infos'])),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Update user
|
||||
* @since 16
|
||||
* @param mixed[] $params
|
||||
* @option string email (optional)
|
||||
* @option int nb_image_page (optional)
|
||||
* @option string theme (optional)
|
||||
* @option string language (optional)
|
||||
* @option int recent_period (optional)
|
||||
* @option bool expand (optional)
|
||||
* @option bool show_nb_comments (optional)
|
||||
* @option bool show_nb_hits (optional)
|
||||
* @option string password (optional)
|
||||
* @option string new_password (optional)
|
||||
* @option string conf_new_password (optional)
|
||||
*/
|
||||
function ws_users_setMyInfo($params, &$service)
|
||||
{
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
return new PwgError(403, 'Invalid security token');
|
||||
}
|
||||
|
||||
if (is_a_guest())
|
||||
{
|
||||
return new PwgError(401, 'Access Denied');
|
||||
}
|
||||
|
||||
global $user, $conf;
|
||||
|
||||
// ACTIVATE_COMMENTS
|
||||
if (!$conf['activate_comments'])
|
||||
{
|
||||
unset($params['show_nb_comments']);
|
||||
}
|
||||
|
||||
// ALLOW_USER_CUSTOMIZATION
|
||||
if (!$conf['allow_user_customization'])
|
||||
{
|
||||
unset(
|
||||
$params['nb_image_page'],
|
||||
$params['theme'],
|
||||
$params['language'],
|
||||
$params['recent_period'],
|
||||
$params['expand'],
|
||||
$params['show_nb_comments'],
|
||||
$params['show_nb_hits']
|
||||
);
|
||||
}
|
||||
|
||||
// SPECIAL_USER
|
||||
$special_user = in_array($user['id'], array($conf['guest_id'], $conf['default_user_id']));
|
||||
if ($special_user)
|
||||
{
|
||||
unset(
|
||||
$params['password'],
|
||||
$params['theme'],
|
||||
$params['language']
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($params['password']))
|
||||
{
|
||||
if ($params['new_password'] != $params['conf_new_password'])
|
||||
{
|
||||
return new PwgError(403, l10n('The passwords do not match'));
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT '.$conf['user_fields']['password'].' AS password
|
||||
FROM '.USERS_TABLE.'
|
||||
WHERE '.$conf['user_fields']['id'].' = \''.$user['id'].'\'
|
||||
;';
|
||||
list($current_password) = pwg_db_fetch_row(pwg_query($query));
|
||||
|
||||
if (!$conf['password_verify']($params['password'], $current_password))
|
||||
{
|
||||
return new PwgError(403, l10n('Current password is wrong'));
|
||||
}
|
||||
|
||||
$params['password'] = $params['new_password'];
|
||||
}
|
||||
|
||||
|
||||
// Unset admin field also new and conf password
|
||||
unset(
|
||||
$params['new_password'],
|
||||
$params['conf_new_password'],
|
||||
$params['username'],
|
||||
$params['status'],
|
||||
$params['level'],
|
||||
$params['group_id'],
|
||||
$params['enabled_high']
|
||||
);
|
||||
|
||||
$params['user_id'] = [$user['id']];
|
||||
$updated_users = check_and_save_user_infos($params);
|
||||
|
||||
if (isset($updated_users['error']))
|
||||
{
|
||||
return new PwgError($updated_users[ 'error' ][ 'code' ], $updated_users[ 'error' ][ 'message' ]);
|
||||
}
|
||||
|
||||
return l10n('Your changes have been applied.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1097,4 +951,158 @@ function ws_set_main_user($params, &$service)
|
||||
conf_update_param('webmaster_id', $params['user_id']);
|
||||
return 'The main user has been changed.';
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Create a new api key for the current user
|
||||
* @since 15
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
function ws_create_api_key($params, &$service)
|
||||
{
|
||||
global $user, $logger;
|
||||
|
||||
if (is_a_guest() OR !can_manage_api_key()) return new PwgError(401, 'Acces Denied');
|
||||
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
return new PwgError(403, 'Invalid security token');
|
||||
}
|
||||
|
||||
if ($params['duration'] < 1 OR $params['duration'] > 999999)
|
||||
{
|
||||
return new PwgError(400, 'Invalid duration max days is 999999');
|
||||
}
|
||||
|
||||
if (strlen($params['key_name']) > 100)
|
||||
{
|
||||
return new PwgError(400, 'Key name is too long');
|
||||
}
|
||||
|
||||
$key_name = pwg_db_real_escape_string($params['key_name']);
|
||||
$duration = 0 == $params['duration'] ? 1 : $params['duration'];
|
||||
|
||||
$secret = create_api_key($user['id'], $duration, $key_name);
|
||||
|
||||
$logger->info('[api_key][user_id='.$user['id'].'][action=create][key_name='.$params['key_name'].']');
|
||||
|
||||
return $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Revoke a api key for the current user
|
||||
* @since 15
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
function ws_revoke_api_key($params, &$service)
|
||||
{
|
||||
global $user, $logger;
|
||||
|
||||
if (is_a_guest() OR !can_manage_api_key()) return new PwgError(401, 'Acces Denied');
|
||||
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
return new PwgError(403, l10n('Invalid security token'));
|
||||
}
|
||||
|
||||
if (!preg_match('/^pkid-\d{8}-[a-z0-9]{20}$/i', $params['pkid']))
|
||||
{
|
||||
return new PwgError(403, l10n('Invalid pkid format'));
|
||||
}
|
||||
|
||||
$revoked_key = revoke_api_key($user['id'], $params['pkid']);
|
||||
|
||||
if (true !== $revoked_key)
|
||||
{
|
||||
return new PwgError(403, $revoked_key);
|
||||
}
|
||||
|
||||
$logger->info('[api_key][user_id='.$user['id'].'][action=revoke][pkid='.$params['pkid'].']');
|
||||
|
||||
return l10n('API Key has been successfully revoked.');
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Edit a api key for the current user
|
||||
* @since 15
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
function ws_edit_api_key($params, &$service)
|
||||
{
|
||||
global $user, $logger;
|
||||
|
||||
if (is_a_guest())
|
||||
{
|
||||
return new PwgError(401, 'Acces Denied');
|
||||
}
|
||||
|
||||
if (!can_manage_api_key())
|
||||
{
|
||||
return new PwgError(401, 'Acces Denied');
|
||||
}
|
||||
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
return new PwgError(403, l10n('Invalid security token'));
|
||||
}
|
||||
|
||||
if (!preg_match('/^pkid-\d{8}-[a-z0-9]{20}$/i', $params['pkid']))
|
||||
{
|
||||
return new PwgError(403, l10n('Invalid pkid format'));
|
||||
}
|
||||
|
||||
$key_name = pwg_db_real_escape_string($params['key_name']);
|
||||
$edited_key = edit_api_key($user['id'], $params['pkid'], $key_name);
|
||||
|
||||
if (true !== $edited_key)
|
||||
{
|
||||
return new PwgError(403, $edited_key);
|
||||
}
|
||||
|
||||
$logger->info('[api_key][user_id='.$user['id'].'][action=edit][pkid='.$params['pkid'].'][new_name='.$key_name.']');
|
||||
|
||||
return l10n('API Key has been successfully edited.');
|
||||
}
|
||||
|
||||
/**
|
||||
* API method
|
||||
* Get all api key for the current user
|
||||
* @since 15
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
function ws_get_api_key($params, &$service)
|
||||
{
|
||||
global $user;
|
||||
|
||||
if (is_a_guest())
|
||||
{
|
||||
return new PwgError(401, 'Acces Denied');
|
||||
}
|
||||
|
||||
if (!can_manage_api_key())
|
||||
{
|
||||
return new PwgError(401, 'Acces Denied');
|
||||
}
|
||||
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
return new PwgError(403, 'Invalid security token');
|
||||
}
|
||||
|
||||
$api_keys = get_api_key($user['id']);
|
||||
|
||||
return $api_keys ?? l10n('No API key found');
|
||||
}
|
||||
|
||||
function can_manage_api_key()
|
||||
{
|
||||
// You can manage your api key only if you are connected via identification.php
|
||||
if (isset($_SESSION['connected_with']) and 'pwg_ui' === $_SESSION['connected_with'])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user