diff --git a/changes/4193.feature b/changes/4193.feature new file mode 100644 index 00000000000..325ec5b7db3 --- /dev/null +++ b/changes/4193.feature @@ -0,0 +1 @@ +Allow sysadmins to change usernames of other accounts diff --git a/ckan/logic/action/update.py b/ckan/logic/action/update.py index 418f42398f7..c68e02de6db 100644 --- a/ckan/logic/action/update.py +++ b/ckan/logic/action/update.py @@ -774,7 +774,7 @@ def user_update(context: Context, data_dict: DataDict) -> ActionResult.UserUpdat '''Update a user account. Normal users can only update their own user accounts. Sysadmins can update - any user account. Can not modify exisiting user's name. + any user account and modify existing usernames. .. note:: Update methods may delete parameters not explicitly provided in the data_dict. If you want to edit only a specific attribute use `user_patch` diff --git a/ckan/logic/validators.py b/ckan/logic/validators.py index b8c9f409e99..55209751091 100644 --- a/ckan/logic/validators.py +++ b/ckan/logic/validators.py @@ -14,7 +14,7 @@ from sqlalchemy.orm.exc import NoResultFound import ckan.lib.navl.dictization_functions as df -import ckan.logic as logic +from ckan import authz, logic import ckan.logic.converters as converters import ckan.lib.helpers as h from ckan.model import (MAX_TAG_LENGTH, MIN_TAG_LENGTH, @@ -22,7 +22,6 @@ PACKAGE_VERSION_MAX_LENGTH, VOCABULARY_NAME_MAX_LENGTH, VOCABULARY_NAME_MIN_LENGTH) -import ckan.authz as authz from ckan.model.core import State from ckan.common import _ @@ -615,10 +614,13 @@ def user_name_validator(key: FlattenKey, data: FlattenDataDict, return else: # Otherwise return an error: there's already another user with that - # name, so you can create a new user with that name or update an + # name, so you can't create a new user with that name or update an # existing user's name to that name. errors[key].append(_('That login name is not available.')) elif user_obj_from_context: + requester = context.get('auth_user_obj', None) + if requester and authz.is_sysadmin(requester.name): + return old_user = model.User.get(user_obj_from_context.id) if old_user is not None and old_user.state != model.State.PENDING: errors[key].append(_('That login name can not be modified.')) diff --git a/ckan/templates/user/edit_user_form.html b/ckan/templates/user/edit_user_form.html index 3b1a3331888..01e68715288 100644 --- a/ckan/templates/user/edit_user_form.html +++ b/ckan/templates/user/edit_user_form.html @@ -8,7 +8,11 @@ {% block core_fields %}