Skip to content

Commit 626d3d7

Browse files
committed
Merge branch 'feature/PB-45554_52-Publish-production-API' into 'master'
PB-45554 Release v5.5.2 See merge request passbolt/passbolt-ce-api!443
2 parents b3001ff + 3e5def9 commit 626d3d7

File tree

10 files changed

+141
-109
lines changed

10 files changed

+141
-109
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

5+
## [5.5.2] - 2025-09-29
6+
### Fixed
7+
- PB-45439 As an administrator I can edit the metadata key settings when not editing zero-knowledge mode
8+
9+
## [5.5.2-test.1] - 2025-09-29
10+
### Fixed
11+
- PB-45439 As an administrator I can edit the metadata key settings when not editing zero-knowledge mode when not editing zero-knowledge mode
12+
513
## [5.5.0] - 2025-09-15
614
### Added
715
- PB-44639 As an administrator, when updating metadata settings from friendly mode to zero knowledge, I should see the server key dropped in DB

RELEASE_NOTES.md

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,9 @@
1-
Release song: https://youtu.be/L3Wo8jcNrkQ
1+
Release song: https://youtu.be/RyP8hGuyknA
22

3-
Passbolt 5.5.0 is a feature release introducing encrypted metadata in zero-knowledge mode and SCIM provisioning (beta) for automated user management.
3+
Passbolt 5.5.2 resolves an issue introduced in the previous version that affected the editing of encrypted metadata settings. Due to zero-knowledge mode being required in some conditions, administrators were unable to edit the metadata key settings. This has now been fixed, restoring the ability to customize these settings.
44

5-
## Encrypted Metadata Zero-Knowledge Mode
6-
7-
This mode is designed for organizations that prioritize privacy over server-side auditability. In this setup, the server never has access to the shared metadata private key.
8-
9-
* __Key distribution__: When a new user joins, the server does not distribute the metadata key.
10-
Administrators are notified by email and can review which users are missing the key in the __Users & Groups workspace__. Keys must then be shared manually.
11-
* __User experience__: Until the key is received, the user’s actions are limited. Operations that depend on metadata, such as sharing a resource, moving a private item into a shared folder or creating resources intended to be shared are blocked.
12-
* __Guidance in UI__: If a restricted action is attempted, the interface provides an explanation and steps to resolve the issue.
13-
14-
More details are available in the dedicated [blog post](https://www.passbolt.com/blog/the-road-to-passbolt-v5-encrypted-metadata-and-other-core-security-changes-2) on encrypted metadata and zero-knowledge.
15-
16-
Several bugs reported by the community have also been fixed. As always, thank you to everyone who took the time to file issues and suggest improvements. Checkout the changelog for more information.
17-
18-
## [5.5.0] - 2025-09-15
19-
### Added
20-
- PB-44639 As an administrator, when updating metadata settings from friendly mode to zero knowledge, I should see the server key dropped in DB
21-
- PB-44756 Updates metadata keys settings endpoint to accept server metadata private key
22-
- PB-44752 Adds a new data check for existing resources v5 encrypted with hard or soft deleted shared metadata key
5+
We thank the community for reporting this issue!
236

7+
## [5.5.2] - 2025-09-29
248
### Fixed
25-
- PB-45060 Fixes custom fields json schema properties type
26-
- PB-45062 Fixes user_setup_complete.php template in LU folder instead of AD
27-
- PB-44760 Fixes health check "record not found in table organization_settings" issue (GITHUB #563)
28-
29-
### Maintenance
30-
- PB-44915 Changes DDEV containers names and URLs from passbolt-ce-api to passbolt-api
31-
- PB-44813 Updates ddev config
32-
- PB-44772 Speeds up continuous integration by splitting pipelines in two distinct test suites
9+
- PB-45439 As an administrator I can edit the metadata key settings when not editing zero-knowledge mode

config/version.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22
return [
33
'passbolt' => [
4-
'version' => '5.5.0',
5-
'name' => "Katip Arzuhalim",
4+
'version' => '5.5.2',
5+
'name' => 'Hey Boy Hey Girl',
66
],
77
'php' => [
88
'minVersion' => '8.2',

plugins/PassboltCe/Metadata/src/Form/MetadataKeysSettingsForm.php

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,12 @@
1616
*/
1717
namespace Passbolt\Metadata\Form;
1818

19-
use Cake\Event\EventManager;
2019
use Cake\Form\Form;
2120
use Cake\Form\Schema;
2221
use Cake\Validation\Validator;
2322

2423
class MetadataKeysSettingsForm extends Form
2524
{
26-
private string $mode;
27-
28-
/**
29-
* @inheritDoc
30-
*/
31-
public function __construct(string $mode = 'create', ?EventManager $eventManager = null)
32-
{
33-
parent::__construct($eventManager);
34-
35-
$this->mode = $mode;
36-
}
37-
3825
/**
3926
* Email configuration schema.
4027
*
@@ -64,23 +51,27 @@ public function validationDefault(Validator $validator): Validator
6451
->boolean('zero_knowledge_key_share', __('The setting should be a valid boolean.'))
6552
->requirePresence('zero_knowledge_key_share', true, __('The setting is required.'));
6653

67-
if ($this->mode === 'update') {
68-
$onZeroKnowledgeDisabled = function ($context) {
69-
return !$context['data']['zero_knowledge_key_share'];
70-
};
71-
72-
$validator
73-
->requirePresence('metadata_private_keys', true, __('The metadata private keys is required.')) // phpcs:ignore;
74-
->notEmptyArray('metadata_private_keys', __('The metadata private keys should not be empty.'), $onZeroKnowledgeDisabled) // phpcs:ignore;
75-
->hasAtLeast('metadata_private_keys', 1, __('Need at least one metadata private key.'), $onZeroKnowledgeDisabled) // phpcs:ignore;
76-
// TODO: Accept multiple metadata private keys?
77-
->hasAtMost('metadata_private_keys', 1, __('Need at least one metadata private key.'), $onZeroKnowledgeDisabled) // phpcs:ignore;
78-
->addNestedMany('metadata_private_keys', $this->getServerMetadataPrivateKeysValidator(), null, $onZeroKnowledgeDisabled); // phpcs:ignore;
79-
}
80-
8154
return $validator;
8255
}
8356

57+
/**
58+
* Default validation rules + validation for metadata private keys
59+
*
60+
* @param \Cake\Validation\Validator $validator validator
61+
* @return \Cake\Validation\Validator
62+
*/
63+
public function validationWithMetadataPrivateKeys(Validator $validator): Validator
64+
{
65+
return $this
66+
->validationDefault($validator)
67+
->requirePresence('metadata_private_keys', true, __('The metadata private keys is required.')) // phpcs:ignore;
68+
->notEmptyArray('metadata_private_keys', __('The metadata private keys should not be empty.')) // phpcs:ignore;
69+
->hasAtLeast('metadata_private_keys', 1, __('Need at least one metadata private key.')) // phpcs:ignore;
70+
// TODO: Accept multiple metadata private keys?
71+
->hasAtMost('metadata_private_keys', 1, __('Need at most one metadata private key.')) // phpcs:ignore;
72+
->addNestedMany('metadata_private_keys', $this->getServerMetadataPrivateKeysValidator()); // phpcs:ignore;
73+
}
74+
8475
/**
8576
* @return \Cake\Validation\Validator
8677
*/

plugins/PassboltCe/Metadata/src/Service/MetadataKeysSettingsAssertService.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ class MetadataKeysSettingsAssertService
2626
* Validates the setting and return them
2727
*
2828
* @param array $data untrusted input
29-
* @param string $mode Mode for form to know if settings are being created or modified.
29+
* @param bool $validateWithMetadataPrivateKeys flag to know if metadata private key validation should be performed
3030
* @return \Passbolt\Metadata\Model\Dto\MetadataKeysSettingsDto dto
3131
* @throws \App\Error\Exception\FormValidationException if the data does not validate
3232
*/
33-
public function assert(array $data, string $mode = 'create'): MetadataKeysSettingsDto
33+
public function assert(array $data, bool $validateWithMetadataPrivateKeys = false): MetadataKeysSettingsDto
3434
{
35-
$form = new MetadataKeysSettingsForm($mode);
36-
if (!$form->execute($data)) {
35+
$form = new MetadataKeysSettingsForm();
36+
$validate = $validateWithMetadataPrivateKeys ? 'withMetadataPrivateKeys' : 'default';
37+
if (!$form->execute($data, compact('validate'))) {
3738
throw new FormValidationException(__('Could not validate the settings.'), $form);
3839
}
3940

plugins/PassboltCe/Metadata/src/Service/MetadataKeysSettingsSetService.php

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,11 @@ public function saveSettings(UserAccessControl $uac, array $data): MetadataKeysS
4646
{
4747
$uac->assertIsAdmin();
4848

49-
/** @var \App\Model\Table\OrganizationSettingsTable $orgSettingsTable */
50-
$orgSettingsTable = $this->fetchTable('OrganizationSettings');
51-
$mode = is_null($orgSettingsTable->getByProperty(MetadataKeysSettingsGetService::ORG_SETTING_PROPERTY)) ? 'create' : 'update'; // phpcs:ignore
49+
$settingsInDB = MetadataKeysSettingsGetService::getSettings();
50+
$isDisablingZeroKnowledge = $this->isDisablingZeroKnowledge($data, $settingsInDB);
51+
$dto = (new MetadataKeysSettingsAssertService())->assert($data, $isDisablingZeroKnowledge);
5252

53-
$dto = (new MetadataKeysSettingsAssertService())->assert($data, $mode);
54-
55-
if ($mode == 'update' && $this->shouldCreateMetadataPrivateKey($dto, $data)) {
53+
if ($isDisablingZeroKnowledge && $this->shouldCreateMetadataPrivateKey($dto, $data)) {
5654
$service = new MetadataPrivateKeysCreateService();
5755
foreach ($data['metadata_private_keys'] as $i => $key) {
5856
try {
@@ -65,6 +63,8 @@ public function saveSettings(UserAccessControl $uac, array $data): MetadataKeysS
6563
}
6664
}
6765

66+
/** @var \App\Model\Table\OrganizationSettingsTable $orgSettingsTable */
67+
$orgSettingsTable = $this->fetchTable('OrganizationSettings');
6868
$updatedEntity = $orgSettingsTable->createOrUpdateSetting(
6969
MetadataKeysSettingsGetService::ORG_SETTING_PROPERTY,
7070
$dto->toJson(),
@@ -117,4 +117,26 @@ private function shouldCreateMetadataPrivateKey(MetadataKeysSettingsDto $setting
117117

118118
return false;
119119
}
120+
121+
/**
122+
* When updating the settings, we want to know if the zero knowledge mode is being disabled.
123+
* If so, metadata private keys will be requested in the payload at a later stage.
124+
*
125+
* @param array $data payload
126+
* @param \Passbolt\Metadata\Model\Dto\MetadataKeysSettingsDto $organizationSetting DTO of the settings currently in DB
127+
* @return bool
128+
*/
129+
private function isDisablingZeroKnowledge(array $data, MetadataKeysSettingsDto $organizationSetting): bool
130+
{
131+
if ($organizationSetting->isUserFriendlyMode()) {
132+
// The setting is already in user-friendly mode, potentially because falling back on the default settings
133+
return false;
134+
}
135+
if (!isset($data['zero_knowledge_key_share'])) {
136+
// If not set in payload, will fail validation at a later stage
137+
return false;
138+
}
139+
140+
return !$data['zero_knowledge_key_share'];
141+
}
120142
}

plugins/PassboltCe/Metadata/tests/TestCase/Form/MetadataKeysSettingsFormTest.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use App\Test\Lib\Model\FormatValidationTrait;
2222
use App\Utility\UuidFactory;
2323
use Cake\Event\EventDispatcherTrait;
24+
use Cake\Validation\Validator;
2425
use Passbolt\Metadata\Form\MetadataKeysSettingsForm;
2526
use Passbolt\Metadata\Model\Dto\MetadataKeysSettingsDto;
2627
use Passbolt\Metadata\Service\Migration\MigrateAllV4ToV5ServiceCollector;
@@ -111,8 +112,8 @@ public function testMetadataKeysSettingsForm_Error_NotBool(): void
111112
public function testMetadataKeysSettingsForm_Error_MetadataPrivateKeys_Empty(): void
112113
{
113114
$data = self::getDefaultData([], []);
114-
$form = new MetadataKeysSettingsForm('update');
115-
$result = $form->execute($data);
115+
$form = new MetadataKeysSettingsForm();
116+
$result = $form->execute($data, ['validate' => 'withMetadataPrivateKeys']);
116117
$errors = $form->getErrors();
117118
$this->assertFalse($result);
118119
$this->assertArrayHasKey('_empty', $errors['metadata_private_keys']);
@@ -136,8 +137,8 @@ public static function metadataPrivateKeysFieldsRequired(): array
136137
public function testMetadataKeysSettingsForm_Error_MetadataPrivateKeys_FieldsRequired(array $privateKeyData): void
137138
{
138139
$data = self::getDefaultData([], $privateKeyData);
139-
$form = new MetadataKeysSettingsForm('update');
140-
$result = $form->execute($data);
140+
$form = new MetadataKeysSettingsForm();
141+
$result = $form->execute($data, ['validate' => 'withMetadataPrivateKeys']);
141142
$errors = $form->getErrors();
142143
$this->assertFalse($result);
143144
$requiredFields = ['metadata_key_id', 'user_id', 'data'];
@@ -154,8 +155,8 @@ public function testMetadataKeysSettingsForm_Error_MetadataPrivateKeys_InvalidId
154155
'data' => $this->getEncryptedMetadataPrivateKeyForServerKey(),
155156
]]);
156157

157-
$form = new MetadataKeysSettingsForm('update');
158-
$result = $form->execute($data);
158+
$form = new MetadataKeysSettingsForm();
159+
$result = $form->execute($data, ['validate' => 'withMetadataPrivateKeys']);
159160
$errors = $form->getErrors();
160161

161162
$this->assertFalse($result);
@@ -178,7 +179,10 @@ public function testMetadataKeysSettingsForm_Error_MetadataPrivateKeys_Data(): v
178179
'ascii' => self::getAsciiTestCases(),
179180
];
180181

181-
$form = new MetadataKeysSettingsForm('update');
182+
$form = new MetadataKeysSettingsForm();
183+
$validator = new Validator();
184+
$withMetadataPrivateKeysValidator = $form->validationWithMetadataPrivateKeys($validator);
185+
$form->setValidator('default', $withMetadataPrivateKeysValidator);
182186
$this->assertFormFieldFormatValidation(
183187
$form,
184188
'metadata_private_keys.0.data',

plugins/PassboltCe/Metadata/tests/TestCase/Service/MetadataKeysSettingsSetServiceTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,20 @@ public function testMetadataKeysSettingsSetService_Success_CreateUserFriendlyMod
7878
$this->assertEquals($data, $dto->toArray());
7979
}
8080

81+
public function testMetadataKeysSettingsSetService_Success_UpdateFromUserFriendlyMode_To_UserFriendlyMode(): void
82+
{
83+
$user = UserFactory::make()->admin()->persist();
84+
MetadataKeysSettingsFactory::make()->persist();
85+
$data = MetadataKeysSettingsFormTest::getDefaultData([
86+
MetadataKeysSettingsDto::ALLOW_USAGE_OF_PERSONAL_KEYS => true,
87+
MetadataKeysSettingsDto::ZERO_KNOWLEDGE_KEY_SHARE => false,
88+
]);
89+
$uac = new UserAccessControl(Role::ADMIN, $user->get('id'));
90+
$sut = new MetadataKeysSettingsSetService();
91+
$dto = $sut->saveSettings($uac, $data);
92+
$this->assertEquals($data, $dto->toArray());
93+
}
94+
8195
public function testMetadataKeysSettingsSetService_Success_EditAllowUsageOfPersonalKeys(): void
8296
{
8397
$user = UserFactory::make()->admin()->persist();

0 commit comments

Comments
 (0)