issue #2354 update pwg.users.setInfo

and add pwg.users.setMyInfo method
This commit is contained in:
Linty
2025-05-05 20:24:05 +02:00
parent 6c609e5da6
commit 7f850c2938
3 changed files with 493 additions and 259 deletions

View File

@@ -2028,4 +2028,359 @@ 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
);
}
?>

View File

@@ -532,270 +532,122 @@ 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(
$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.');
}
/**

27
ws.php
View File

@@ -1238,6 +1238,33 @@ enabled_high, registration_date, registration_date_string, registration_date_sin
$ws_functions_root . 'pwg.users.php',
array('admin_only'=>true, 'post_only'=>true)
);
$service->addMethod(
'pwg.users.setMyInfo',
'ws_users_setMyInfo',
array(
'email' => array('flags'=>WS_PARAM_OPTIONAL),
'nb_image_page' => array('flags'=>WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE|WS_TYPE_NOTNULL),
'theme' => array('flags'=>WS_PARAM_OPTIONAL),
'language' => array('flags'=>WS_PARAM_OPTIONAL),
'recent_period' => array('flags'=>WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_INT|WS_TYPE_POSITIVE),
'expand' => array('flags'=>WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_BOOL),
'show_nb_comments' => array('flags'=>WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_BOOL),
'show_nb_hits' => array('flags'=>WS_PARAM_OPTIONAL,
'type'=>WS_TYPE_BOOL),
'password' => array('flags'=>WS_PARAM_OPTIONAL),
'new_password' => array('flags'=>WS_PARAM_OPTIONAL),
'conf_new_password' => array('flags'=>WS_PARAM_OPTIONAL),
'pwg_token' => array(),
),
'',
$ws_functions_root . 'pwg.users.php',
array('admin_only'=>false, 'post_only'=>true)
);
$service->addMethod(
'pwg.permissions.getList',