diff --git a/CHANGELOG.md b/CHANGELOG.md index d1ed70e713..546e40738e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [4.6.1] - 2024-03-27 +### Fixed +- PB-32354 As an admin, I can re-enable a suspended user (GITHUB #512) + +## [4.6.1-test.1] - 2024-03-26 +### Fixed +- PB-32354 As an admin, I can re-enable a suspended user (GITHUB #512) + ## [4.6.0] - 2024-03-14 ### Added - PB-24485 As an administrator I can view the API healthcheck in the administration section diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index aa761ea74f..f2c1b943ed 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,35 +1,11 @@ -Release song: https://youtu.be/Ub0NtPOj7es?si=3IL4HKS4-g17uPal +Release song: https://www.youtube.com/watch?v=b8-tXG8KrWs -The Passbolt Community Edition 4.6.0 release "Purple Haze", brings enhancements that focus primarily on the administrative aspect and overall system health. +Passbolt is pleased to announce the immediate availability of version 4.6.1. This is a maintenance update that contains an important fix for the API, addressing the issue reported by the community since version 4.6.0. -This update introduces the Health Check feature within the Admin workspace, designed to offer administrators a comprehensive tool for system assessment and upkeep. -In addition, this version addresses a range of minor bugs and delivers the awaited PHP 8.3 support. +Most notably this update fixes a problem when an administrator is not able to re-enable a suspended user. -This version furthermore lays the foundations for successive performance gains by refining data verification processes and reducing memory usage, particularly when browsing. Expect more significant improvements with the next releases. - -## [4.6.0] - 2024-03-14 -### Added -- PB-24485 As an administrator I can view the API healthcheck in the administration section -- PB-29396 As an administrator I can hide the share folder capability with a RBAC -- PB-25463 As an administrator I can disable the healthcheck index endpoint with a flag -- PB-29397 As an administrator I can disable the healthcheck administration panel with a flag - -### Improved -- PB-29009 As an administrator completing my setup I should not receive a notification that I completed my setup -- PB-26152 The API should identify openpgpjs v5.10 revoked key as revoked -- PB-29437 As an administrator I can log internal errors with the complete trace in Json format - -### Security -- PB-30155 Update phpseclib/phpseclib to fix composer security vulnerability +We would like to express our sincere thanks to the community members who brought issues to our attention and helped the team to make passbolt better. +## [4.6.1] - 2024-03-27 ### Fixed -- PB-30019 As a user I should not get a 500 when editing a user with payload containing integers as fields -- PB-29964 As an administrator disabling a user I should not get a 500 if the disabled date is not valid -- PB-29970 As a group manager I should receive an accurate summary in my notifications on group permission changes -- PB-29054 As an administrator I should not get an error when running the cleanup command and the users table does not exist -- PB-28719 As an administrator sending emails the timezone displayed in the emails should be in the correct time zone -- PB-30266 As an administrator sending emails with the email digest the message ID should be defined -- PB-30182 Build the styleguide on version 4.6.1 - -### Maintenance -- PB-28247 Update cakephp/cakephp to version 4.5 +- PB-32354 As an admin, I can re-enable a suspended user (GITHUB #512) diff --git a/config/version.php b/config/version.php index db2a22e11b..80c9e33f85 100644 --- a/config/version.php +++ b/config/version.php @@ -1,8 +1,8 @@ [ - 'version' => '4.6.0', - 'name' => 'Purple Haze', + 'version' => '4.6.1', + 'name' => 'Reptillia', ], 'php' => [ 'minVersion' => '7.4', diff --git a/resources/locales/es_ES/default.po b/resources/locales/es_ES/default.po index ebaae25fdf..fc000b1d17 100644 --- a/resources/locales/es_ES/default.po +++ b/resources/locales/es_ES/default.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" "POT-Creation-Date: 2024-03-07 13:12+0000\n" -"PO-Revision-Date: 2024-03-07 13:51\n" +"PO-Revision-Date: 2024-03-19 12:27\n" "Last-Translator: NAME \n" "Language-Team: Spanish\n" "MIME-Version: 1.0\n" @@ -245,7 +245,7 @@ msgid "All checks ran successfully!" msgstr "¡Todas las comprobaciones se han ejecutado con éxito!" msgid "Healthcheck security index endpoint disabled." -msgstr "" +msgstr "Endpoint del índice de seguridad del chequeo de salud deshabilitado." msgid "OK" msgstr "OK" diff --git a/resources/locales/ko_KR/default.po b/resources/locales/ko_KR/default.po index c44f4af96b..5c63bd52ee 100644 --- a/resources/locales/ko_KR/default.po +++ b/resources/locales/ko_KR/default.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" "POT-Creation-Date: 2024-03-07 13:12+0000\n" -"PO-Revision-Date: 2024-03-11 07:27\n" +"PO-Revision-Date: 2024-03-25 06:25\n" "Last-Translator: NAME \n" "Language-Team: Korean\n" "MIME-Version: 1.0\n" @@ -1073,7 +1073,7 @@ msgid "{0} has been suspended" msgstr "{0} 이(가) 중지되었습니다." msgid "Welcome to passbolt, {0}!" -msgstr "패스볼트에 어서 오세요, {0}!" +msgstr "패스볼트에 오신 것을 환영합니다, {0}!" msgid "The purify subject setting should be a boolean." msgstr "정화된 제목 설정은 부울이어야 합니다." @@ -2477,7 +2477,7 @@ msgid "When logging in from a new device you will need to enter a unique verific msgstr "새 기기에서 로그인할 때 모바일의 앱에서 생성된 고유한 인증 코드를 입력해야 합니다." msgid "Remember this device for a month." -msgstr "이 기기를 한달 동안 기억." +msgstr "이 기기를 한달 동안 기억하기" msgid "Yubikey One Time Password" msgstr "Yubikey 일회성 암호" diff --git a/resources/locales/pt_BR/default.po b/resources/locales/pt_BR/default.po index 72a1652368..0b6d827d8a 100644 --- a/resources/locales/pt_BR/default.po +++ b/resources/locales/pt_BR/default.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: 41c2572bd9bd4cc908d3e09e0cbed6e5\n" "POT-Creation-Date: 2024-03-07 13:12+0000\n" -"PO-Revision-Date: 2024-03-07 13:51\n" +"PO-Revision-Date: 2024-03-17 15:03\n" "Last-Translator: NAME \n" "Language-Team: Portuguese, Brazilian\n" "MIME-Version: 1.0\n" @@ -245,7 +245,7 @@ msgid "All checks ran successfully!" msgstr "Todas as verificações foram executadas com sucesso!" msgid "Healthcheck security index endpoint disabled." -msgstr "" +msgstr "Endpoint do índice de segurança Healthcheck desativado." msgid "OK" msgstr "OK" @@ -956,7 +956,7 @@ msgid "The key should not already be expired." msgstr "A chave não deve estar expirada." msgid "The date could not be parsed." -msgstr "" +msgstr "A data não pôde ser analisada." msgid "The email should be a valid email address." msgstr "O e-mail deve ser um endereço de e-mail válido." @@ -983,10 +983,10 @@ msgid "{0} updated your memberships in several groups" msgstr "{0} atualizou sua participação em diversos grupos" msgid "{0} deleted several group memberships" -msgstr "" +msgstr "{0} excluiu vários membros de grupo" msgid "You made changes on several resources" -msgstr "" +msgstr "Você fez mudanças em vários recursos" msgid "{0} has made changes on several resources" msgstr "{0} fez alterações em vários recursos" @@ -1013,7 +1013,7 @@ msgid "{0} requested you to add members to {1}" msgstr "{0} solicitou que você adicione membros a {1}" msgid "You have been requested to add members to {0}" -msgstr "" +msgstr "Você foi solicitado a adicionar membros a {0}" msgid "{0} removed you from the group {1}" msgstr "{0} removeu você do grupo {1}" @@ -1037,7 +1037,7 @@ msgid "{0} deleted the password {1}" msgstr "{0} excluiu a senha {1}" msgid "You edited the password {0}" -msgstr "" +msgstr "Você editou a senha {0}" msgid "{0} edited the password {1}" msgstr "{0} editou a senha {1}" @@ -1049,22 +1049,22 @@ msgid "{0} shared the password {1}" msgstr "{0} compartilhou a senha {1}" msgid "You deleted administrator {0}" -msgstr "" +msgstr "Você excluiu o administrador {0}" msgid "{0} deleted your account" -msgstr "" +msgstr "{0} excluiu a sua conta" msgid "{0} deleted administrator {1}" -msgstr "" +msgstr "{0} excluiu o administrador {1}" msgid "Your account has been suspended" msgstr "" msgid "Your admin role has been revoked" -msgstr "" +msgstr "Sua função de administrador foi revogada" msgid "{0}'s admin role has been revoked" -msgstr "" +msgstr "{0} sua função de administrador foi revogada" msgid "{0} deleted user {1}" msgstr "{0} excluiu o usuário {1}" @@ -1124,7 +1124,7 @@ msgid "The send on group manager updated setting should be a boolean." msgstr "A configuração de atualização do envio no gerente de grupo deve ser um booleano." msgid "The send on group manager request add user should be a boolean." -msgstr "" +msgstr "O envio de solicitação do gerente de grupo adicionar usuário deve ser um valor booleano." msgid "The send on password created setting should be a boolean." msgstr "A configuração enviar na senha criada deve ser um booleano." @@ -1364,10 +1364,10 @@ msgid "Could not validate secret data." msgstr "Não foi possível validar dados secretos." msgid "The group id should be a valid UUID." -msgstr "" +msgstr "O identificador do grupo deve ser um UUID válido." msgid "The users ids array should contain only valid UUIDs." -msgstr "" +msgstr "A matriz de ID's de usuários deve conter apenas UUID's válidos." msgid "Validation failed for secret {0}. {1}" msgstr "Falha na validação do segredo {0}. {1}" @@ -1439,7 +1439,7 @@ msgid "This user has been disabled." msgstr "" msgid "The username {0} is a duplicate." -msgstr "" +msgstr "O nome de usuário {0} é uma cópia." msgid "Validation failed for user {0}. {1}" msgstr "Validação falhou para o usuário {0}. {1}" @@ -1901,7 +1901,7 @@ msgid "This is not a valid {0}." msgstr "Este não é um {0} válido." msgid "The locale should be a string." -msgstr "" +msgstr "A localidade deve ser uma string." msgid "The strategy should extend the class: {0}" msgstr "A estratégia deve estender a classe {0}" @@ -2519,43 +2519,43 @@ msgid "Log in passbolt" msgstr "Senha de login" msgid "The automatic_expiry field must be true." -msgstr "" +msgstr "O campo de expiração automático deve ser verdadeiro." msgid "The automatic_update field must be true." -msgstr "" +msgstr "O campo de atualização automática deve ser verdadeiro." msgid "The value should be an array." msgstr "" msgid "{0} marked several passwords as expired" -msgstr "" +msgstr "{0} marcou várias senhas como expiradas" msgid "Some of your passwords expired" -msgstr "" +msgstr "Algumas de suas senhas expiradas." msgid "{0} marked the password {1} as expired" -msgstr "" +msgstr "{0} marcou a senha {1} como expirada" msgid "You edited the password expiry settings" -msgstr "" +msgstr "Você editou as configurações de expiração da senha" msgid "{0} edited the password expiry settings" -msgstr "" +msgstr "{0} editou as configurações de expiração da senha" msgid "The send password expire setting should be a boolean." -msgstr "" +msgstr "O envio de configuração de expiração da senha deve ser booleana." msgid "The password expiry setting does not exist." -msgstr "" +msgstr "A configuração de expiração de senha não existe." msgid "Could not validate the password expiry settings." -msgstr "" +msgstr "Não é possível validar as configurações de política de senhas." msgid "The password expiry settings have been updated." -msgstr "" +msgstr "As configurações de expiração da senha foram atualizadas." msgid "View them in passbolt" -msgstr "" +msgstr "Visualize no passbolt" msgid "{0} resources were affected." msgstr "{0} recursos foram afetados." @@ -2564,25 +2564,25 @@ msgid "It would be too much to list them here, but you can go check them on pass msgstr "Seria exagerado enumerá-los aqui, mas pode verificá-los de passagem." msgid "Change them in passbolt" -msgstr "" +msgstr "Altere no passbolt" msgid "You have been requested to change them" -msgstr "" +msgstr "Você foi solicitado para alterá-los" msgid "Access for users to your shared passwords have been revoked." -msgstr "" +msgstr "O acesso dos usuários às suas senhas compartilhadas foi revogado." msgid "These passwords are now marked as expired." -msgstr "" +msgstr "Estas senhas agora estão marcadas como expiradas." msgid "Please rotate them to ensure continued security." -msgstr "" +msgstr "Por favor, rotacione para garantir segurança contínua." msgid "Please rotate it to ensure continued security." -msgstr "" +msgstr "Por favor, rotacione para garantir a segurança contínua." msgid "Change it in passbolt " -msgstr "" +msgstr "Altere isto no passbolt " msgid "Could not retrieve the password policies." msgstr "Não foi possível recuperar as políticas de senha." @@ -2786,7 +2786,7 @@ msgid "An entry already exists for the given role and action ids." msgstr "Já existe uma entrada para a função e IDs de ação fornecidos." msgid "The control function is not allowed for this UI Action." -msgstr "" +msgstr "A função de controle não é permitida para esta ação de UI." msgid "An action already exists for the given name." msgstr "Uma ação já existe com o nome fornecido." @@ -3578,13 +3578,13 @@ msgid "login" msgstr "login" msgid "The administrator {0} ({1}) is now deleted from the passbolt organisation." -msgstr "" +msgstr "O administrador {0} ({1}) foi removido da organização do passbolt." msgid "{0} deleted you from the passbolt organisation." -msgstr "" +msgstr "{0} excluiu você da organização do passbolt." msgid "Feel free to get in touch with the administrator at the origin of the operation if you feel this action looks suspicious." -msgstr "" +msgstr "Sinta-se à vontade para entrar em contato com o administrador na origem da operação, se você achar que essa ação parece suspeita." msgid "Account suspended" msgstr "" @@ -3602,13 +3602,13 @@ msgid "Contact your admin" msgstr "" msgid "{0} changed your role to user." -msgstr "" +msgstr "{0} mudou sua função para o usuário." msgid "{0} changed the role of {1} to user." -msgstr "" +msgstr "{0} alterou a função de {1} para o usuário." msgid "{0} can no longer perform administration tasks." -msgstr "" +msgstr "{0} não pode mais executar tarefas administrativas." msgid "You" msgstr "Você" @@ -3701,10 +3701,10 @@ msgid "You just opened an account on passbolt at {0}." msgstr "Você acabou de abrir uma conta no passaporte em {0}." msgid "There was a change in the user directory." -msgstr "" +msgstr "Houve uma alteração no diretório de usuários." msgid "You have been requested to add members to a group." -msgstr "" +msgstr "Você foi solicitado a adicionar membros a um grupo." msgid "{0} requested you to add members to a group" msgstr "{0} solicitou que você adicione membros a um grupo" diff --git a/src/Controller/Users/UsersEditController.php b/src/Controller/Users/UsersEditController.php index 6e381ded68..6678b87df4 100644 --- a/src/Controller/Users/UsersEditController.php +++ b/src/Controller/Users/UsersEditController.php @@ -163,22 +163,35 @@ protected function _validateRequestData(string $id): array if ($this->User->role() !== Role::ADMIN && (isset($data['role']) || isset($data['role_id']))) { throw new ForbiddenException(__('You are not authorized to edit the role.')); } + // Sanitize data as the marshaller will throw a type error if the payload has integers as fields $sanitizedData = []; - if (isset($data['role_id'])) { - $sanitizedData['role_id'] = $data['role_id']; - } - if (isset($data['disabled'])) { - $sanitizedData['disabled'] = $data['disabled']; - } - if (isset($data['profile']['first_name'])) { - $sanitizedData['profile']['first_name'] = $data['profile']['first_name']; - } - if (isset($data['profile']['last_name'])) { - $sanitizedData['profile']['last_name'] = $data['profile']['last_name']; - } - if (isset($data['profile']['avatar'])) { - $sanitizedData['profile']['avatar'] = $data['profile']['avatar']; + $allowedKeys = [ + 'role_id', + 'disabled', + 'profile' => [ + 'first_name', + 'last_name', + 'avatar', + ], + ]; + + foreach ($allowedKeys as $allowedMainKey => $allowedKey) { + if (!is_array($allowedKey)) { + if (array_key_exists($allowedKey, $data)) { + $sanitizedData[$allowedKey] = $data[$allowedKey]; + } + } else { + foreach ($allowedKey as $allowedNestedKey) { + if (!array_key_exists($allowedMainKey, $data)) { + break; + } + + if (array_key_exists($allowedNestedKey, $data[$allowedMainKey])) { + $sanitizedData[$allowedMainKey][$allowedNestedKey] = $data[$allowedMainKey][$allowedNestedKey]; + } + } + } } return $sanitizedData; diff --git a/tests/TestCase/Controller/Users/UsersEditDisableControllerTest.php b/tests/TestCase/Controller/Users/UsersEditDisableControllerTest.php index d121a47488..b6572e57d2 100644 --- a/tests/TestCase/Controller/Users/UsersEditDisableControllerTest.php +++ b/tests/TestCase/Controller/Users/UsersEditDisableControllerTest.php @@ -141,4 +141,24 @@ public function testUsersEditDisableController_Success_AdminDisableAlreadyDisabl $this->assertTrue($user->isDisabled()); $this->assertEmailQueueCount(0); } + + public function testUsersEditDisableController_Success_EnableDisabledUser(): void + { + $user = UserFactory::make()->user()->disabled()->persist(); + $this->logInAsAdmin(); + + $data = [ + 'id' => $user->id, + 'disabled' => null, + 'username' => $user->username, + 'role_id' => $user->role_id, + ]; + $this->postJson('/users/' . $user->id . '.json', $data); + + $this->assertSuccess(); + $this->assertNull($this->_responseJsonBody->disabled); + $user = UserFactory::get($user->id); + $this->assertFalse($user->isDisabled()); + $this->assertEmailQueueCount(0); + } }