mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-06-02 04:15:05 +02:00
fixes #2355 implement API key management system
- Added API key get, creation, editing, and revocation methods. - Updated the profile template to include API key management features. - Updated the database schema to support the new API key system, including additional fields for key management. - Added client-side JavaScript functionality to handle API key operations and display responses. - Update tools/htm.ws with the new way to authenticate. - Restriction of certain api methods when used with an api key - Backward compatibility with older apps
This commit is contained in:
@@ -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
|
||||
);
|
||||
}
|
||||
?>
|
||||
|
||||
?>
|
||||
@@ -629,6 +629,8 @@ SELECT '.$conf['user_fields']['password'].' AS password
|
||||
$params['password'] = $params['new_password'];
|
||||
}
|
||||
|
||||
|
||||
// Unset admin field also new and conf password
|
||||
unset(
|
||||
$params['new_password'],
|
||||
$params['conf_new_password'],
|
||||
@@ -949,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