Skip to content

Commit a1efa39

Browse files
authored
Merge pull request #48864 from nextcloud/fix/invalid-app-config
fix(settings): Do not use `null` on `string` parameter for sharing disclaimer
2 parents 8bdf8bc + e058820 commit a1efa39

File tree

6 files changed

+115
-114
lines changed

6 files changed

+115
-114
lines changed

apps/settings/lib/Settings/Admin/Sharing.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function getForm() {
6262
'enforceExpireDate' => $this->getHumanBooleanConfig('core', 'shareapi_enforce_expire_date'),
6363
'excludeGroups' => $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no'),
6464
'excludeGroupsList' => json_decode($excludedGroups, true) ?? [],
65-
'publicShareDisclaimerText' => $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null),
65+
'publicShareDisclaimerText' => $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext'),
6666
'enableLinkPasswordByDefault' => $this->getHumanBooleanConfig('core', 'shareapi_enable_link_password_by_default'),
6767
'defaultPermissions' => (int)$this->config->getAppValue('core', 'shareapi_default_permissions', (string)Constants::PERMISSION_ALL),
6868
'defaultInternalExpireDate' => $this->getHumanBooleanConfig('core', 'shareapi_default_internal_expire_date'),

apps/settings/src/components/AdminSettingsSharingForm.vue

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@
170170
<NcCheckboxRadioSwitch type="switch" :checked.sync="publicShareDisclaimerEnabled">
171171
{{ t('settings', 'Show disclaimer text on the public link upload page (only shown when the file list is hidden)') }}
172172
</NcCheckboxRadioSwitch>
173-
<div v-if="typeof settings.publicShareDisclaimerText === 'string'"
173+
<div v-if="publicShareDisclaimerEnabled"
174174
aria-describedby="settings-sharing-privary-related-disclaimer-hint"
175175
class="sharing__sub-section">
176176
<NcTextArea class="sharing__input"
@@ -231,7 +231,7 @@ interface IShareSettings {
231231
enforceExpireDate: boolean
232232
excludeGroups: string
233233
excludeGroupsList: string[]
234-
publicShareDisclaimerText?: string
234+
publicShareDisclaimerText: string
235235
enableLinkPasswordByDefault: boolean
236236
defaultPermissions: number
237237
defaultInternalExpireDate: boolean
@@ -252,8 +252,10 @@ export default defineComponent({
252252
SelectSharingPermissions,
253253
},
254254
data() {
255+
const settingsData = loadState<IShareSettings>('settings', 'sharingSettings')
255256
return {
256-
settingsData: loadState<IShareSettings>('settings', 'sharingSettings'),
257+
settingsData,
258+
publicShareDisclaimerEnabled: settingsData.publicShareDisclaimerText !== '',
257259
}
258260
},
259261
computed: {
@@ -272,26 +274,24 @@ export default defineComponent({
272274
},
273275
})
274276
},
275-
publicShareDisclaimerEnabled: {
276-
get() {
277-
return typeof this.settingsData.publicShareDisclaimerText === 'string'
278-
},
279-
set(value) {
280-
if (value) {
281-
this.settingsData.publicShareDisclaimerText = ''
282-
} else {
283-
this.onUpdateDisclaimer()
284-
}
285-
},
277+
},
278+
279+
watch: {
280+
publicShareDisclaimerEnabled() {
281+
// When disabled we just remove the disclaimer content
282+
if (this.publicShareDisclaimerEnabled === false) {
283+
this.onUpdateDisclaimer('')
284+
}
286285
},
287286
},
287+
288288
methods: {
289289
t,
290290
291-
onUpdateDisclaimer: debounce(function(value?: string) {
291+
onUpdateDisclaimer: debounce(function(value: string) {
292292
const options = {
293293
success() {
294-
if (value) {
294+
if (value !== '') {
295295
showSuccess(t('settings', 'Changed disclaimer text'))
296296
} else {
297297
showSuccess(t('settings', 'Deleted disclaimer text'))
@@ -301,7 +301,7 @@ export default defineComponent({
301301
showError(t('settings', 'Could not set disclaimer text'))
302302
},
303303
}
304-
if (!value) {
304+
if (value === '') {
305305
window.OCP.AppConfig.deleteKey('core', 'shareapi_public_link_disclaimertext', options)
306306
} else {
307307
window.OCP.AppConfig.setValue('core', 'shareapi_public_link_disclaimertext', value, options)

apps/settings/tests/Settings/Admin/SharingTest.php

Lines changed: 94 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
class SharingTest extends TestCase {
2121
/** @var Sharing */
2222
private $admin;
23-
/** @var IConfig */
23+
/** @var IConfig&MockObject */
2424
private $config;
25-
/** @var IL10N|MockObject */
25+
/** @var IL10N&MockObject */
2626
private $l10n;
2727
/** @var IManager|MockObject */
2828
private $shareManager;
@@ -35,9 +35,7 @@ class SharingTest extends TestCase {
3535

3636
protected function setUp(): void {
3737
parent::setUp();
38-
/** @var IConfig|MockObject */
3938
$this->config = $this->getMockBuilder(IConfig::class)->getMock();
40-
/** @var IL10N|MockObject */
4139
$this->l10n = $this->getMockBuilder(IL10N::class)->getMock();
4240

4341
/** @var IManager|MockObject */
@@ -82,7 +80,7 @@ public function testGetFormWithoutExcludedGroups(): void {
8280
['core', 'shareapi_expire_after_n_days', '7', '7'],
8381
['core', 'shareapi_enforce_expire_date', 'no', 'no'],
8482
['core', 'shareapi_exclude_groups', 'no', 'no'],
85-
['core', 'shareapi_public_link_disclaimertext', null, 'Lorem ipsum'],
83+
['core', 'shareapi_public_link_disclaimertext', '', 'Lorem ipsum'],
8684
['core', 'shareapi_enable_link_password_by_default', 'no', 'yes'],
8785
['core', 'shareapi_default_permissions', (string)Constants::PERMISSION_ALL, Constants::PERMISSION_ALL],
8886
['core', 'shareapi_default_internal_expire_date', 'no', 'no'],
@@ -98,50 +96,53 @@ public function testGetFormWithoutExcludedGroups(): void {
9896
->willReturn(false);
9997

10098
$this->appManager->method('isEnabledForUser')->with('files_sharing')->willReturn(false);
99+
100+
$initialStateCalls = [];
101101
$this->initialState
102102
->expects($this->exactly(3))
103103
->method('provideInitialState')
104-
->withConsecutive(
105-
['sharingAppEnabled', false],
106-
['sharingDocumentation', ''],
107-
[
108-
'sharingSettings',
109-
[
110-
'allowGroupSharing' => true,
111-
'allowLinks' => true,
112-
'allowPublicUpload' => true,
113-
'allowResharing' => true,
114-
'allowShareDialogUserEnumeration' => true,
115-
'restrictUserEnumerationToGroup' => false,
116-
'restrictUserEnumerationToPhone' => false,
117-
'restrictUserEnumerationFullMatch' => true,
118-
'restrictUserEnumerationFullMatchUserId' => true,
119-
'restrictUserEnumerationFullMatchEmail' => true,
120-
'restrictUserEnumerationFullMatchIgnoreSecondDN' => false,
121-
'enforceLinksPassword' => false,
122-
'onlyShareWithGroupMembers' => false,
123-
'enabled' => true,
124-
'defaultExpireDate' => false,
125-
'expireAfterNDays' => '7',
126-
'enforceExpireDate' => false,
127-
'excludeGroups' => 'no',
128-
'excludeGroupsList' => [],
129-
'publicShareDisclaimerText' => 'Lorem ipsum',
130-
'enableLinkPasswordByDefault' => true,
131-
'defaultPermissions' => Constants::PERMISSION_ALL,
132-
'defaultInternalExpireDate' => false,
133-
'internalExpireAfterNDays' => '7',
134-
'enforceInternalExpireDate' => false,
135-
'defaultRemoteExpireDate' => false,
136-
'remoteExpireAfterNDays' => '7',
137-
'enforceRemoteExpireDate' => false,
138-
'allowLinksExcludeGroups' => [],
139-
'onlyShareWithGroupMembersExcludeGroupList' => [],
140-
'enforceLinksPasswordExcludedGroups' => [],
141-
'enforceLinksPasswordExcludedGroupsEnabled' => false,
142-
]
143-
],
144-
);
104+
->willReturnCallback(function (string $key) use (&$initialStateCalls) {
105+
$initialStateCalls[$key] = func_get_args();
106+
});
107+
108+
$expectedInitialStateCalls = [
109+
'sharingAppEnabled' => false,
110+
'sharingDocumentation' => '',
111+
'sharingSettings' => [
112+
'allowGroupSharing' => true,
113+
'allowLinks' => true,
114+
'allowPublicUpload' => true,
115+
'allowResharing' => true,
116+
'allowShareDialogUserEnumeration' => true,
117+
'restrictUserEnumerationToGroup' => false,
118+
'restrictUserEnumerationToPhone' => false,
119+
'restrictUserEnumerationFullMatch' => true,
120+
'restrictUserEnumerationFullMatchUserId' => true,
121+
'restrictUserEnumerationFullMatchEmail' => true,
122+
'restrictUserEnumerationFullMatchIgnoreSecondDN' => false,
123+
'enforceLinksPassword' => false,
124+
'onlyShareWithGroupMembers' => false,
125+
'enabled' => true,
126+
'defaultExpireDate' => false,
127+
'expireAfterNDays' => '7',
128+
'enforceExpireDate' => false,
129+
'excludeGroups' => 'no',
130+
'excludeGroupsList' => [],
131+
'publicShareDisclaimerText' => 'Lorem ipsum',
132+
'enableLinkPasswordByDefault' => true,
133+
'defaultPermissions' => Constants::PERMISSION_ALL,
134+
'defaultInternalExpireDate' => false,
135+
'internalExpireAfterNDays' => '7',
136+
'enforceInternalExpireDate' => false,
137+
'defaultRemoteExpireDate' => false,
138+
'remoteExpireAfterNDays' => '7',
139+
'enforceRemoteExpireDate' => false,
140+
'allowLinksExcludeGroups' => [],
141+
'onlyShareWithGroupMembersExcludeGroupList' => [],
142+
'enforceLinksPasswordExcludedGroups' => [],
143+
'enforceLinksPasswordExcludedGroupsEnabled' => false,
144+
]
145+
];
145146

146147
$expected = new TemplateResponse(
147148
'settings',
@@ -151,6 +152,7 @@ public function testGetFormWithoutExcludedGroups(): void {
151152
);
152153

153154
$this->assertEquals($expected, $this->admin->getForm());
155+
$this->assertEquals(sort($expectedInitialStateCalls), sort($initialStateCalls), 'Provided initial state does not match');
154156
}
155157

156158
public function testGetFormWithExcludedGroups(): void {
@@ -175,7 +177,7 @@ public function testGetFormWithExcludedGroups(): void {
175177
['core', 'shareapi_expire_after_n_days', '7', '7'],
176178
['core', 'shareapi_enforce_expire_date', 'no', 'no'],
177179
['core', 'shareapi_exclude_groups', 'no', 'yes'],
178-
['core', 'shareapi_public_link_disclaimertext', null, 'Lorem ipsum'],
180+
['core', 'shareapi_public_link_disclaimertext', '', 'Lorem ipsum'],
179181
['core', 'shareapi_enable_link_password_by_default', 'no', 'yes'],
180182
['core', 'shareapi_default_permissions', (string)Constants::PERMISSION_ALL, Constants::PERMISSION_ALL],
181183
['core', 'shareapi_default_internal_expire_date', 'no', 'no'],
@@ -191,50 +193,53 @@ public function testGetFormWithExcludedGroups(): void {
191193
->willReturn(false);
192194

193195
$this->appManager->method('isEnabledForUser')->with('files_sharing')->willReturn(true);
196+
197+
$initialStateCalls = [];
194198
$this->initialState
195199
->expects($this->exactly(3))
196200
->method('provideInitialState')
197-
->withConsecutive(
198-
['sharingAppEnabled', true],
199-
['sharingDocumentation', ''],
200-
[
201-
'sharingSettings',
202-
[
203-
'allowGroupSharing' => true,
204-
'allowLinks' => true,
205-
'allowPublicUpload' => true,
206-
'allowResharing' => true,
207-
'allowShareDialogUserEnumeration' => true,
208-
'restrictUserEnumerationToGroup' => false,
209-
'restrictUserEnumerationToPhone' => false,
210-
'restrictUserEnumerationFullMatch' => true,
211-
'restrictUserEnumerationFullMatchUserId' => true,
212-
'restrictUserEnumerationFullMatchEmail' => true,
213-
'restrictUserEnumerationFullMatchIgnoreSecondDN' => false,
214-
'enforceLinksPassword' => false,
215-
'onlyShareWithGroupMembers' => false,
216-
'enabled' => true,
217-
'defaultExpireDate' => false,
218-
'expireAfterNDays' => '7',
219-
'enforceExpireDate' => false,
220-
'excludeGroups' => 'yes',
221-
'excludeGroupsList' => ['NoSharers','OtherNoSharers'],
222-
'publicShareDisclaimerText' => 'Lorem ipsum',
223-
'enableLinkPasswordByDefault' => true,
224-
'defaultPermissions' => Constants::PERMISSION_ALL,
225-
'defaultInternalExpireDate' => false,
226-
'internalExpireAfterNDays' => '7',
227-
'enforceInternalExpireDate' => false,
228-
'defaultRemoteExpireDate' => false,
229-
'remoteExpireAfterNDays' => '7',
230-
'enforceRemoteExpireDate' => false,
231-
'allowLinksExcludeGroups' => [],
232-
'onlyShareWithGroupMembersExcludeGroupList' => [],
233-
'enforceLinksPasswordExcludedGroups' => [],
234-
'enforceLinksPasswordExcludedGroupsEnabled' => false,
235-
]
236-
],
237-
);
201+
->willReturnCallback(function (string $key) use (&$initialStateCalls) {
202+
$initialStateCalls[$key] = func_get_args();
203+
});
204+
205+
$expectedInitialStateCalls = [
206+
'sharingAppEnabled' => true,
207+
'sharingDocumentation' => '',
208+
'sharingSettings' => [
209+
'allowGroupSharing' => true,
210+
'allowLinks' => true,
211+
'allowPublicUpload' => true,
212+
'allowResharing' => true,
213+
'allowShareDialogUserEnumeration' => true,
214+
'restrictUserEnumerationToGroup' => false,
215+
'restrictUserEnumerationToPhone' => false,
216+
'restrictUserEnumerationFullMatch' => true,
217+
'restrictUserEnumerationFullMatchUserId' => true,
218+
'restrictUserEnumerationFullMatchEmail' => true,
219+
'restrictUserEnumerationFullMatchIgnoreSecondDN' => false,
220+
'enforceLinksPassword' => false,
221+
'onlyShareWithGroupMembers' => false,
222+
'enabled' => true,
223+
'defaultExpireDate' => false,
224+
'expireAfterNDays' => '7',
225+
'enforceExpireDate' => false,
226+
'excludeGroups' => 'yes',
227+
'excludeGroupsList' => ['NoSharers','OtherNoSharers'],
228+
'publicShareDisclaimerText' => 'Lorem ipsum',
229+
'enableLinkPasswordByDefault' => true,
230+
'defaultPermissions' => Constants::PERMISSION_ALL,
231+
'defaultInternalExpireDate' => false,
232+
'internalExpireAfterNDays' => '7',
233+
'enforceInternalExpireDate' => false,
234+
'defaultRemoteExpireDate' => false,
235+
'remoteExpireAfterNDays' => '7',
236+
'enforceRemoteExpireDate' => false,
237+
'allowLinksExcludeGroups' => [],
238+
'onlyShareWithGroupMembersExcludeGroupList' => [],
239+
'enforceLinksPasswordExcludedGroups' => [],
240+
'enforceLinksPasswordExcludedGroupsEnabled' => false,
241+
],
242+
];
238243

239244
$expected = new TemplateResponse(
240245
'settings',
@@ -244,6 +249,7 @@ public function testGetFormWithExcludedGroups(): void {
244249
);
245250

246251
$this->assertEquals($expected, $this->admin->getForm());
252+
$this->assertEquals(sort($expectedInitialStateCalls), sort($initialStateCalls), 'Provided initial state does not match');
247253
}
248254

249255
public function testGetSection(): void {

build/psalm-baseline.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,11 +1041,6 @@
10411041
<code><![CDATA[isReady]]></code>
10421042
</UndefinedInterfaceMethod>
10431043
</file>
1044-
<file src="apps/settings/lib/Settings/Admin/Sharing.php">
1045-
<NullArgument>
1046-
<code><![CDATA[null]]></code>
1047-
</NullArgument>
1048-
</file>
10491044
<file src="apps/sharebymail/lib/ShareByMailProvider.php">
10501045
<InvalidArgument>
10511046
<code><![CDATA[$share->getId()]]></code>

dist/settings-vue-settings-admin-sharing.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/settings-vue-settings-admin-sharing.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)