diff --git a/src/plone/restapi/locales/de/LC_MESSAGES/plone.restapi.po b/src/plone/restapi/locales/de/LC_MESSAGES/plone.restapi.po index 4c6904f6db..0a4c1ec545 100644 --- a/src/plone/restapi/locales/de/LC_MESSAGES/plone.restapi.po +++ b/src/plone/restapi/locales/de/LC_MESSAGES/plone.restapi.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-09-21 15:17+0000\n" +"POT-Creation-Date: 2023-09-25 20:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: Timo Stollenwerk \n" "Language-Team: German \n" @@ -147,7 +147,7 @@ msgstr "" msgid "Volto Blocks" msgstr "" -#: plone/restapi/services/users/update.py:139 +#: plone/restapi/services/users/update.py:151 msgid "You are not authorized to perform this action" msgstr "" @@ -163,14 +163,18 @@ msgstr "" msgid "You can't set a password without a password reset token." msgstr "" -#: plone/restapi/services/users/update.py:108 +#: plone/restapi/services/users/update.py:120 msgid "You can't update roles of this user" msgstr "" -#: plone/restapi/services/users/update.py:145 +#: plone/restapi/services/users/update.py:157 msgid "You can't update the properties of this user" msgstr "" +#: plone/restapi/services/users/update.py:94 +msgid "You can't update this user" +msgstr "" + #: plone/restapi/services/users/add.py:284 msgid "You can't use 'reset_token' and 'old_password' together." msgstr "" diff --git a/src/plone/restapi/locales/es/LC_MESSAGES/plone.restapi.po b/src/plone/restapi/locales/es/LC_MESSAGES/plone.restapi.po index 23e64c683c..6510309a30 100644 --- a/src/plone/restapi/locales/es/LC_MESSAGES/plone.restapi.po +++ b/src/plone/restapi/locales/es/LC_MESSAGES/plone.restapi.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" -"POT-Creation-Date: 2023-09-21 15:17+0000\n" +"POT-Creation-Date: 2023-09-25 20:32+0000\n" "PO-Revision-Date: 2023-08-23 21:19-0400\n" "Last-Translator: Leonardo J. Caballero G. \n" "Language-Team: ES \n" @@ -153,7 +153,7 @@ msgstr "El reset_token es desconocido/no válido." msgid "Volto Blocks" msgstr "Bloques Volto" -#: plone/restapi/services/users/update.py:139 +#: plone/restapi/services/users/update.py:151 msgid "You are not authorized to perform this action" msgstr "No está autorizado a realizar esta acción." @@ -169,14 +169,18 @@ msgstr "No puede enviar la contraseña y 'Enviar un correo electrónico de confi msgid "You can't set a password without a password reset token." msgstr "No puede establecer una contraseña sin un token de restablecimiento de contraseña." -#: plone/restapi/services/users/update.py:108 +#: plone/restapi/services/users/update.py:120 msgid "You can't update roles of this user" msgstr "" -#: plone/restapi/services/users/update.py:145 +#: plone/restapi/services/users/update.py:157 msgid "You can't update the properties of this user" msgstr "No puede actualizar las propiedades de este usuario." +#: plone/restapi/services/users/update.py:94 +msgid "You can't update this user" +msgstr "" + #: plone/restapi/services/users/add.py:284 msgid "You can't use 'reset_token' and 'old_password' together." msgstr "No puede utilizar 'Restablecer token' y 'Contraseña anterior' juntas." diff --git a/src/plone/restapi/locales/fr/LC_MESSAGES/plone.restapi.po b/src/plone/restapi/locales/fr/LC_MESSAGES/plone.restapi.po index 958226088e..9d25934588 100644 --- a/src/plone/restapi/locales/fr/LC_MESSAGES/plone.restapi.po +++ b/src/plone/restapi/locales/fr/LC_MESSAGES/plone.restapi.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-09-21 15:17+0000\n" +"POT-Creation-Date: 2023-09-25 20:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: Julien Chandelle \n" "Language-Team: French \n" @@ -147,7 +147,7 @@ msgstr "Le reset_token est inconnu/non valide." msgid "Volto Blocks" msgstr "Blocs Volto" -#: plone/restapi/services/users/update.py:139 +#: plone/restapi/services/users/update.py:151 msgid "You are not authorized to perform this action" msgstr "Vous n'êtes pas autorisé à effectuer cette action" @@ -163,14 +163,18 @@ msgstr "Vous ne pouvez pas envoyer à la fois le password et sendPasswordReset" msgid "You can't set a password without a password reset token." msgstr "Vous ne pouvez pas définir de mot de passe sans un jeton de réinitialisation de mot de passe." -#: plone/restapi/services/users/update.py:108 +#: plone/restapi/services/users/update.py:120 msgid "You can't update roles of this user" msgstr "" -#: plone/restapi/services/users/update.py:145 +#: plone/restapi/services/users/update.py:157 msgid "You can't update the properties of this user" msgstr "Vous ne pouvez pas mettre à jour les propriétés de cet utilisateur" +#: plone/restapi/services/users/update.py:94 +msgid "You can't update this user" +msgstr "" + #: plone/restapi/services/users/add.py:284 msgid "You can't use 'reset_token' and 'old_password' together." msgstr "Vous ne pouvez pas utiliser 'reset_token' et 'old_password' ensemble." diff --git a/src/plone/restapi/locales/plone.restapi.pot b/src/plone/restapi/locales/plone.restapi.pot index 1b5dc2428e..d1d2abf57a 100644 --- a/src/plone/restapi/locales/plone.restapi.pot +++ b/src/plone/restapi/locales/plone.restapi.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-09-21 15:17+0000\n" +"POT-Creation-Date: 2023-09-25 20:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -150,7 +150,7 @@ msgstr "" msgid "Volto Blocks" msgstr "" -#: plone/restapi/services/users/update.py:139 +#: plone/restapi/services/users/update.py:151 msgid "You are not authorized to perform this action" msgstr "" @@ -166,14 +166,18 @@ msgstr "" msgid "You can't set a password without a password reset token." msgstr "" -#: plone/restapi/services/users/update.py:108 +#: plone/restapi/services/users/update.py:120 msgid "You can't update roles of this user" msgstr "" -#: plone/restapi/services/users/update.py:145 +#: plone/restapi/services/users/update.py:157 msgid "You can't update the properties of this user" msgstr "" +#: plone/restapi/services/users/update.py:94 +msgid "You can't update this user" +msgstr "" + #: plone/restapi/services/users/add.py:284 msgid "You can't use 'reset_token' and 'old_password' together." msgstr "" diff --git a/src/plone/restapi/locales/pt_BR/LC_MESSAGES/plone.restapi.po b/src/plone/restapi/locales/pt_BR/LC_MESSAGES/plone.restapi.po index 79eb245a07..dd921dca1f 100644 --- a/src/plone/restapi/locales/pt_BR/LC_MESSAGES/plone.restapi.po +++ b/src/plone/restapi/locales/pt_BR/LC_MESSAGES/plone.restapi.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: plone.restapi\n" -"POT-Creation-Date: 2023-09-21 15:17+0000\n" +"POT-Creation-Date: 2023-09-25 20:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: Wesley Barroso Lopes\n" "Language-Team: \n" @@ -147,7 +147,7 @@ msgstr "O reset_token é desconhecido/inválido." msgid "Volto Blocks" msgstr "Blocos Volto" -#: plone/restapi/services/users/update.py:139 +#: plone/restapi/services/users/update.py:151 msgid "You are not authorized to perform this action" msgstr "Você não está autorizado a realizar esta ação" @@ -163,14 +163,18 @@ msgstr "Você não pode informar Senha e 'Envie um e-mail de confirmação com u msgid "You can't set a password without a password reset token." msgstr "Você não pode definir uma senha sem um token de redefinição de senha." -#: plone/restapi/services/users/update.py:108 +#: plone/restapi/services/users/update.py:120 msgid "You can't update roles of this user" msgstr "Você não pode atualizar os papéis deste usuário" -#: plone/restapi/services/users/update.py:145 +#: plone/restapi/services/users/update.py:157 msgid "You can't update the properties of this user" msgstr "Você não pode atualizar as propriedades deste usuário" +#: plone/restapi/services/users/update.py:94 +msgid "You can't update this user" +msgstr "Você não pode atualizar este usuário" + #: plone/restapi/services/users/add.py:284 msgid "You can't use 'reset_token' and 'old_password' together." msgstr "Você não pode usar 'Redefinir Token' e 'Senha Antiga' juntos." diff --git a/src/plone/restapi/services/users/update.py b/src/plone/restapi/services/users/update.py index 284cb3ff2e..b97a1504d7 100644 --- a/src/plone/restapi/services/users/update.py +++ b/src/plone/restapi/services/users/update.py @@ -42,6 +42,11 @@ def can_change_manager_role(self, target_roles, current_roles): return "Manager" not in list(target_roles) return "Manager" in list(target_roles) + def can_change(self, current_roles): + if self.is_zope_manager: + return True + return "Manager" not in current_roles + def publishTraverse(self, request, name): # Consume any path segments after /@users as parameters self.params.append(name) @@ -79,7 +84,15 @@ def reply(self): security = getAdapter(self.context, ISecuritySchema) if self.can_manage_users: + current_roles = user.getRoles() for key, value in user_settings_to_update.items(): + if key in ["password", "email"]: + if not self.can_change(current_roles): + return self._error( + 403, + "Forbidden", + _("You can't update this user"), + ) if key == "password": self._change_user_password(user, value) elif key == "username": @@ -97,7 +110,6 @@ def reply(self): to_add = [key for key, enabled in roles.items() if enabled] to_remove = [key for key, enabled in roles.items() if not enabled] - current_roles = user.getRoles() target_roles = set(current_roles) - set(to_remove) target_roles = target_roles | set(to_add) diff --git a/src/plone/restapi/tests/test_services_users.py b/src/plone/restapi/tests/test_services_users.py index 626f85f2e9..9d158dc2b7 100644 --- a/src/plone/restapi/tests/test_services_users.py +++ b/src/plone/restapi/tests/test_services_users.py @@ -105,6 +105,15 @@ def set_siteadm(self): self.api_session.auth = (siteadm_username, siteadm_password) transaction.commit() + def create_manager(self): + api.user.create( + email="manager@example.com", + roles=["Manager"], + username="manager", + password="managerpassword", + ) + transaction.commit() + def test_list_users(self): response = self.api_session.get("/@users") @@ -1394,3 +1403,41 @@ def test_siteadm_not_add_manager(self): transaction.commit() self.assertIsNone(api.user.get(userid="howard")) + + def test_siteadm_not_change_manager_password(self): + self.set_siteadm() + self.create_manager() + self.api_session.patch( + "/@users/manager", + json={ + "password": "newmanagerpassword", + }, + ) + transaction.commit() + + response = self.api_session.post( + "/@login", + json={ + "login": "manager", + "password": "newmanagerpassword", + }, + ) + + self.assertEqual( + "Wrong login and/or password.", response.json()["error"]["message"] + ) + + def test_siteadm_not_change_manager_email(self): + self.set_siteadm() + self.create_manager() + self.api_session.patch( + "/@users/manager", + json={ + "email": "newmanageremail@test.com", + }, + ) + transaction.commit() + + self.assertEqual( + "manager@example.com", api.user.get(userid="manager").getProperty("email") + )