mirror of
https://github.com/nextcloud/server.git
synced 2025-02-28 02:26:32 +00:00
feat(files_sharing): allow to specify allowed groups to share instead of excluded groups
Relates to #3387 Signed-off-by: Corentin Damman <c.damman@intopix.com>
This commit is contained in:
parent
a0913739c6
commit
0fa9f3049f
8 changed files with 74 additions and 27 deletions
apps/settings
lib/Settings/Admin
src/components
tests/Settings/Admin
dist
lib/private
tests/lib/Share20
|
@ -88,7 +88,7 @@ class Sharing implements IDelegatedSettings {
|
|||
'defaultExpireDate' => $this->getHumanBooleanConfig('core', 'shareapi_default_expire_date'),
|
||||
'expireAfterNDays' => $this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7'),
|
||||
'enforceExpireDate' => $this->getHumanBooleanConfig('core', 'shareapi_enforce_expire_date'),
|
||||
'excludeGroups' => $this->getHumanBooleanConfig('core', 'shareapi_exclude_groups'),
|
||||
'excludeGroups' => $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no'),
|
||||
'excludeGroupsList' => json_decode($excludedGroups, true) ?? [],
|
||||
'publicShareDisclaimerText' => $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null),
|
||||
'enableLinkPasswordByDefault' => $this->getHumanBooleanConfig('core', 'shareapi_enable_link_password_by_default'),
|
||||
|
|
|
@ -76,19 +76,31 @@
|
|||
</label>
|
||||
</fieldset>
|
||||
|
||||
<NcCheckboxRadioSwitch type="switch" :checked.sync="settings.excludeGroups">
|
||||
{{ t('settings', 'Exclude groups from sharing') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<div v-show="settings.excludeGroups" class="sharing__sub-section">
|
||||
<div class="sharing__labeled-entry sharing__input">
|
||||
<label for="settings-sharing-excluded-groups">{{ t('settings', 'Groups excluded from sharing') }}</label>
|
||||
<label>{{ t('settings', 'Limit sharing based on groups') }}</label>
|
||||
<div class="sharing__sub-section">
|
||||
<NcCheckboxRadioSwitch :checked.sync="settings.excludeGroups"
|
||||
name="excludeGroups" value="no"
|
||||
type="radio" @update:checked="onUpdateExcludeGroups">
|
||||
{{ t('settings', 'Allow sharing for everyone (default)') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch :checked.sync="settings.excludeGroups"
|
||||
name="excludeGroups" value="yes"
|
||||
type="radio" @update:checked="onUpdateExcludeGroups">
|
||||
{{ t('settings', 'Exclude some groups from sharing') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch :checked.sync="settings.excludeGroups"
|
||||
name="excludeGroups" value="allow"
|
||||
type="radio" @update:checked="onUpdateExcludeGroups">
|
||||
{{ t('settings', 'Limit sharing to some groups') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<div v-show="settings.excludeGroups !== 'no'" class="sharing__labeled-entry sharing__input">
|
||||
<NcSettingsSelectGroup id="settings-sharing-excluded-groups"
|
||||
v-model="settings.excludeGroupsList"
|
||||
aria-describedby="settings-sharing-excluded-groups-desc"
|
||||
:label="t('settings', 'Groups excluded from sharing')"
|
||||
:disabled="!settings.excludeGroups"
|
||||
:label="settings.excludeGroups === 'allow' ? t('settings', 'Groups allowed to share') : t('settings', 'Groups excluded from sharing')"
|
||||
:disabled="settings.excludeGroups === 'no'"
|
||||
style="width: 100%" />
|
||||
<em id="settings-sharing-excluded-groups-desc">{{ t('settings', 'These groups will still be able to receive shares, but not to initiate them.') }}</em>
|
||||
<em id="settings-sharing-excluded-groups-desc">{{ t('settings', 'Not allowed groups will still be able to receive shares, but not to initiate them.') }}</em>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -227,7 +239,7 @@ interface IShareSettings {
|
|||
defaultExpireDate: boolean
|
||||
expireAfterNDays: string
|
||||
enforceExpireDate: boolean
|
||||
excludeGroups: boolean
|
||||
excludeGroups: string
|
||||
excludeGroupsList: string[]
|
||||
publicShareDisclaimerText?: string
|
||||
enableLinkPasswordByDefault: boolean
|
||||
|
@ -306,6 +318,10 @@ export default defineComponent({
|
|||
}
|
||||
this.settingsData.publicShareDisclaimerText = value
|
||||
}, 500) as (v?: string) => void,
|
||||
onUpdateExcludeGroups: debounce(function(value: string) {
|
||||
window.OCP.AppConfig.setValue('core', 'excludeGroups', value)
|
||||
this.settings.excludeGroups = value
|
||||
}, 500) as (v?: string) => void
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -150,7 +150,7 @@ class SharingTest extends TestCase {
|
|||
'defaultExpireDate' => false,
|
||||
'expireAfterNDays' => '7',
|
||||
'enforceExpireDate' => false,
|
||||
'excludeGroups' => false,
|
||||
'excludeGroups' => 'no',
|
||||
'excludeGroupsList' => [],
|
||||
'publicShareDisclaimerText' => 'Lorem ipsum',
|
||||
'enableLinkPasswordByDefault' => true,
|
||||
|
@ -243,7 +243,7 @@ class SharingTest extends TestCase {
|
|||
'defaultExpireDate' => false,
|
||||
'expireAfterNDays' => '7',
|
||||
'enforceExpireDate' => false,
|
||||
'excludeGroups' => true,
|
||||
'excludeGroups' => 'yes',
|
||||
'excludeGroupsList' => ['NoSharers','OtherNoSharers'],
|
||||
'publicShareDisclaimerText' => 'Lorem ipsum',
|
||||
'enableLinkPasswordByDefault' => true,
|
||||
|
|
BIN
dist/settings-vue-settings-admin-sharing.js
vendored
BIN
dist/settings-vue-settings-admin-sharing.js
vendored
Binary file not shown.
BIN
dist/settings-vue-settings-admin-sharing.js.map
vendored
BIN
dist/settings-vue-settings-admin-sharing.js.map
vendored
Binary file not shown.
|
@ -193,7 +193,7 @@ class ContactsStore implements IContactsStore {
|
|||
$restrictEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
|
||||
$restrictEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
|
||||
$allowEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes';
|
||||
$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes';
|
||||
$excludeGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no');
|
||||
|
||||
// whether to filter out local users
|
||||
$skipLocal = false;
|
||||
|
@ -202,14 +202,22 @@ class ContactsStore implements IContactsStore {
|
|||
|
||||
$selfGroups = $this->groupManager->getUserGroupIds($self);
|
||||
|
||||
if ($excludedGroups) {
|
||||
if ($excludeGroups && $excludeGroups !== 'no') {
|
||||
$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
|
||||
$decodedExcludeGroups = json_decode($excludedGroups, true);
|
||||
$excludeGroupsList = $decodedExcludeGroups ?? [];
|
||||
|
||||
if (count(array_intersect($excludeGroupsList, $selfGroups)) !== 0) {
|
||||
// a group of the current user is excluded -> filter all local users
|
||||
if ($excludeGroups != 'allow') {
|
||||
if (count(array_intersect($excludeGroupsList, $selfGroups)) !== 0) {
|
||||
// a group of the current user is excluded -> filter all local users
|
||||
$skipLocal = true;
|
||||
}
|
||||
} else {
|
||||
$skipLocal = true;
|
||||
if (count(array_intersect($excludeGroupsList, $selfGroups)) !== 0) {
|
||||
// a group of the current user is allowed -> do not filter all local users
|
||||
$skipLocal = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,9 @@ class ShareDisableChecker {
|
|||
return $this->sharingDisabledForUsersCache[$userId];
|
||||
}
|
||||
|
||||
if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
|
||||
$excludeGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no');
|
||||
|
||||
if ($excludeGroups && $excludeGroups !== 'no') {
|
||||
$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
|
||||
$excludedGroups = json_decode($groupsList);
|
||||
if (is_null($excludedGroups)) {
|
||||
|
@ -48,14 +50,28 @@ class ShareDisableChecker {
|
|||
return false;
|
||||
}
|
||||
$usersGroups = $this->groupManager->getUserGroupIds($user);
|
||||
if (!empty($usersGroups)) {
|
||||
$remainingGroups = array_diff($usersGroups, $excludedGroups);
|
||||
// if the user is only in groups which are disabled for sharing then
|
||||
// sharing is also disabled for the user
|
||||
if (empty($remainingGroups)) {
|
||||
$this->sharingDisabledForUsersCache[$userId] = true;
|
||||
return true;
|
||||
if ($excludeGroups !== 'allow') {
|
||||
if (!empty($usersGroups)) {
|
||||
$remainingGroups = array_diff($usersGroups, $excludedGroups);
|
||||
// if the user is only in groups which are disabled for sharing then
|
||||
// sharing is also disabled for the user
|
||||
if (empty($remainingGroups)) {
|
||||
$this->sharingDisabledForUsersCache[$userId] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!empty($usersGroups)) {
|
||||
$remainingGroups = array_intersect($usersGroups, $excludedGroups);
|
||||
// if the user is in any group which is allowed for sharing then
|
||||
// sharing is also allowed for the user
|
||||
if (!empty($remainingGroups)) {
|
||||
$this->sharingDisabledForUsersCache[$userId] = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->sharingDisabledForUsersCache[$userId] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2099,26 +2099,33 @@ class ManagerTest extends \Test\TestCase {
|
|||
// No exclude groups
|
||||
$data[] = ['no', null, null, [], false];
|
||||
|
||||
// empty exclude list, user no groups
|
||||
// empty exclude / allow list, user no groups
|
||||
$data[] = ['yes', '', json_encode(['']), [], false];
|
||||
$data[] = ['allow', '', json_encode(['']), [], true];
|
||||
|
||||
// empty exclude list, user groups
|
||||
// empty exclude / allow list, user groups
|
||||
$data[] = ['yes', '', json_encode(['']), ['group1', 'group2'], false];
|
||||
$data[] = ['allow', '', json_encode(['']), ['group1', 'group2'], true];
|
||||
|
||||
// Convert old list to json
|
||||
$data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), [], false];
|
||||
$data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), [], true];
|
||||
|
||||
// Old list partly groups in common
|
||||
$data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), ['group1', 'group3'], false];
|
||||
$data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), ['group1', 'group3'], false];
|
||||
|
||||
// Old list only groups in common
|
||||
$data[] = ['yes', 'group1,group2', json_encode(['group1', 'group2']), ['group1'], true];
|
||||
$data[] = ['allow', 'group1,group2', json_encode(['group1', 'group2']), ['group1'], false];
|
||||
|
||||
// New list partly in common
|
||||
$data[] = ['yes', json_encode(['group1', 'group2']), null, ['group1', 'group3'], false];
|
||||
$data[] = ['allow', json_encode(['group1', 'group2']), null, ['group1', 'group3'], false];
|
||||
|
||||
// New list only groups in common
|
||||
$data[] = ['yes', json_encode(['group1', 'group2']), null, ['group2'], true];
|
||||
$data[] = ['allow', json_encode(['group1', 'group2']), null, ['group2'], false];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue