mirror of
https://github.com/nextcloud/server.git
synced 2026-04-21 14:23:17 -04:00
Merge pull request #55311 from nextcloud/fix/sharing-results-collaboration
fix: add missing sharing options to ui and add full-match results
This commit is contained in:
commit
3d97549a74
7 changed files with 94 additions and 48 deletions
|
|
@ -53,10 +53,10 @@ class Sharing implements IDelegatedSettings {
|
|||
'allowFederationOnPublicShares' => $this->appConfig->getValueBool('core', ConfigLexicon::SHAREAPI_ALLOW_FEDERATION_ON_PUBLIC_SHARES),
|
||||
'restrictUserEnumerationToGroup' => $this->getHumanBooleanConfig('core', 'shareapi_restrict_user_enumeration_to_group'),
|
||||
'restrictUserEnumerationToPhone' => $this->getHumanBooleanConfig('core', 'shareapi_restrict_user_enumeration_to_phone'),
|
||||
'restrictUserEnumerationFullMatch' => $this->getHumanBooleanConfig('core', 'shareapi_restrict_user_enumeration_full_match', true),
|
||||
'restrictUserEnumerationFullMatchUserId' => $this->getHumanBooleanConfig('core', 'shareapi_restrict_user_enumeration_full_match_userid', true),
|
||||
'restrictUserEnumerationFullMatchEmail' => $this->getHumanBooleanConfig('core', 'shareapi_restrict_user_enumeration_full_match_email', true),
|
||||
'restrictUserEnumerationFullMatchIgnoreSecondDN' => $this->getHumanBooleanConfig('core', 'shareapi_restrict_user_enumeration_full_match_ignore_second_dn'),
|
||||
'restrictUserEnumerationFullMatch' => $this->shareManager->allowEnumerationFullMatch(),
|
||||
'restrictUserEnumerationFullMatchUserId' => $this->shareManager->matchUserId(),
|
||||
'restrictUserEnumerationFullMatchEmail' => $this->shareManager->matchEmail(),
|
||||
'restrictUserEnumerationFullMatchIgnoreSecondDN' => $this->shareManager->ignoreSecondDisplayName(),
|
||||
'enforceLinksPassword' => Util::isPublicLinkPasswordRequired(false),
|
||||
'enforceLinksPasswordExcludedGroups' => json_decode($excludedPasswordGroups) ?? [],
|
||||
'enforceLinksPasswordExcludedGroupsEnabled' => $this->config->getSystemValueBool('sharing.allow_disabled_password_enforcement_groups', false),
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
-->
|
||||
<template>
|
||||
<form class="sharing">
|
||||
<NcCheckboxRadioSwitch aria-controls="settings-sharing-api settings-sharing-api-settings settings-sharing-default-permissions settings-sharing-privary-related"
|
||||
<NcCheckboxRadioSwitch aria-controls="settings-sharing-api settings-sharing-api-settings settings-sharing-default-permissions settings-sharing-privacy-related"
|
||||
type="switch"
|
||||
:checked.sync="settings.enabled">
|
||||
{{ t('settings', 'Allow apps to use the Share API') }}
|
||||
|
|
@ -174,7 +174,7 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div v-show="settings.enabled" id="settings-sharing-privary-related" class="sharing__section">
|
||||
<div v-show="settings.enabled" id="settings-sharing-privacy-related" class="sharing__section">
|
||||
<h3>{{ t('settings', 'Privacy settings for sharing') }}</h3>
|
||||
|
||||
<NcCheckboxRadioSwitch type="switch"
|
||||
|
|
@ -183,33 +183,52 @@
|
|||
{{ t('settings', 'Allow account name autocompletion in share dialog and allow access to the system address book') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<fieldset v-show="settings.allowShareDialogUserEnumeration" id="settings-sharing-privacy-user-enumeration" class="sharing__sub-section">
|
||||
<legend class="hidden-visually">
|
||||
{{ t('settings', 'Sharing autocompletion restrictions') }}
|
||||
</legend>
|
||||
<em>
|
||||
{{ t('settings', 'If autocompletion "same group" and "phone number integration" are enabled a match in either is enough to show the user.') }}
|
||||
{{ t('settings', 'If autocompletion restrictions for both "same group" and "phonebook integration" are enabled, a match in either is enough to show the user.') }}
|
||||
</em>
|
||||
<NcCheckboxRadioSwitch :checked.sync="settings.restrictUserEnumerationToGroup">
|
||||
{{ t('settings', 'Restrict account name autocompletion and system address book access to users within the same groups') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch :checked.sync="settings.restrictUserEnumerationToPhone">
|
||||
{{ t('settings', 'Restrict account name autocompletion to users based on phone number integration') }}
|
||||
{{ t('settings', 'Restrict account name autocompletion to users based on their phonebook') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
</fieldset>
|
||||
|
||||
<NcCheckboxRadioSwitch type="switch" :checked.sync="settings.restrictUserEnumerationFullMatch">
|
||||
{{ t('settings', 'Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)') }}
|
||||
<NcCheckboxRadioSwitch v-model="settings.restrictUserEnumerationFullMatch"
|
||||
type="switch"
|
||||
aria-controls="settings-sharing-privacy-autocomplete">
|
||||
{{ t('settings', 'Allow autocompletion to full match when entering the full name (ignoring restrictions like group membership or missing phonebook match)') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<fieldset v-show="settings.restrictUserEnumerationFullMatch" id="settings-sharing-privacy-autocomplete" class="sharing__sub-section">
|
||||
<legend class="hidden-visually">
|
||||
{{ t('settings', 'Full match autocompletion restrictions') }}
|
||||
</legend>
|
||||
<NcCheckboxRadioSwitch :checked.sync="settings.restrictUserEnumerationFullMatchUserId">
|
||||
{{ t('settings', 'Also allow autocompletion on full match of the user id') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch :checked.sync="settings.restrictUserEnumerationFullMatchEmail">
|
||||
{{ t('settings', 'Also allow autocompletion on full match of the user email') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch :checked.sync="settings.restrictUserEnumerationFullMatchIgnoreSecondDN">
|
||||
{{ t('settings', 'Do not use second user displayname for full match') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
</fieldset>
|
||||
|
||||
<NcCheckboxRadioSwitch type="switch" :checked.sync="publicShareDisclaimerEnabled">
|
||||
{{ t('settings', 'Show disclaimer text on the public link upload page (only shown when the file list is hidden)') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<div v-if="publicShareDisclaimerEnabled"
|
||||
aria-describedby="settings-sharing-privary-related-disclaimer-hint"
|
||||
aria-describedby="settings-sharing-privacy-related-disclaimer-hint"
|
||||
class="sharing__sub-section">
|
||||
<NcTextArea class="sharing__input"
|
||||
:label="t('settings', 'Disclaimer text')"
|
||||
aria-describedby="settings-sharing-privary-related-disclaimer-hint"
|
||||
aria-describedby="settings-sharing-privacy-related-disclaimer-hint"
|
||||
:value="settings.publicShareDisclaimerText"
|
||||
@update:value="onUpdateDisclaimer" />
|
||||
<em id="settings-sharing-privary-related-disclaimer-hint" class="sharing__input">
|
||||
<em id="settings-sharing-privacy-related-disclaimer-hint" class="sharing__input">
|
||||
{{ t('settings', 'This text will be shown on the public link upload page when the file list is hidden.') }}
|
||||
</em>
|
||||
</div>
|
||||
|
|
|
|||
4
dist/settings-vue-settings-admin-sharing.js
vendored
4
dist/settings-vue-settings-admin-sharing.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -63,8 +63,10 @@ class UserPlugin implements ISearchPlugin {
|
|||
$users = [];
|
||||
$hasMoreResults = false;
|
||||
|
||||
$currentUserId = $this->userSession->getUser()->getUID();
|
||||
$currentUserGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
|
||||
/** @var IUser */
|
||||
$currentUser = $this->userSession->getUser();
|
||||
$currentUserId = $currentUser->getUID();
|
||||
$currentUserGroups = $this->groupManager->getUserGroupIds($currentUser);
|
||||
|
||||
// ShareWithGroupOnly filtering
|
||||
$currentUserGroups = array_diff($currentUserGroups, $this->shareWithGroupOnlyExcludeGroupsList);
|
||||
|
|
@ -76,7 +78,7 @@ class UserPlugin implements ISearchPlugin {
|
|||
foreach ($usersInGroup as $userId => $displayName) {
|
||||
$userId = (string)$userId;
|
||||
$user = $this->userManager->get($userId);
|
||||
if (!$user->isEnabled()) {
|
||||
if (!$user?->isEnabled()) {
|
||||
// Ignore disabled users
|
||||
continue;
|
||||
}
|
||||
|
|
@ -86,37 +88,43 @@ class UserPlugin implements ISearchPlugin {
|
|||
$hasMoreResults = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->shareWithGroupOnly && $this->shareeEnumerationPhone) {
|
||||
$usersTmp = $this->userManager->searchKnownUsersByDisplayName($currentUserId, $search, $limit, $offset);
|
||||
if (!empty($usersTmp)) {
|
||||
// not limited to group only sharing
|
||||
if (!$this->shareWithGroupOnly) {
|
||||
if (!$this->shareeEnumerationPhone && !$this->shareeEnumerationInGroupOnly) {
|
||||
// no restrictions, add everything
|
||||
$usersTmp = $this->userManager->searchDisplayName($search, $limit, $offset);
|
||||
foreach ($usersTmp as $user) {
|
||||
if ($user->isEnabled()) { // Don't keep deactivated users
|
||||
$users[$user->getUID()] = $user;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// make sure to add phonebook matches if configured
|
||||
if ($this->shareeEnumerationPhone) {
|
||||
$usersTmp = $this->userManager->searchKnownUsersByDisplayName($currentUserId, $search, $limit, $offset);
|
||||
foreach ($usersTmp as $user) {
|
||||
if ($user->isEnabled()) { // Don't keep deactivated users
|
||||
$users[$user->getUID()] = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uasort($users, function ($a, $b) {
|
||||
/**
|
||||
* @var \OC\User\User $a
|
||||
* @var \OC\User\User $b
|
||||
*/
|
||||
return strcasecmp($a->getDisplayName(), $b->getDisplayName());
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Search in all users
|
||||
if ($this->shareeEnumerationPhone) {
|
||||
$usersTmp = $this->userManager->searchKnownUsersByDisplayName($currentUserId, $search, $limit, $offset);
|
||||
} else {
|
||||
$usersTmp = $this->userManager->searchDisplayName($search, $limit, $offset);
|
||||
}
|
||||
foreach ($usersTmp as $user) {
|
||||
if ($user->isEnabled()) { // Don't keep deactivated users
|
||||
$users[$user->getUID()] = $user;
|
||||
// additionally we need to add full matches
|
||||
if ($this->shareeEnumerationFullMatch) {
|
||||
$usersTmp = $this->userManager->searchDisplayName($search, $limit, $offset);
|
||||
foreach ($usersTmp as $user) {
|
||||
if ($user->isEnabled() && mb_strtolower($user->getDisplayName()) === mb_strtolower($search)) {
|
||||
$users[$user->getUID()] = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uasort($users, function (IUser $a, IUser $b) {
|
||||
return strcasecmp($a->getDisplayName(), $b->getDisplayName());
|
||||
});
|
||||
}
|
||||
|
||||
$this->takeOutCurrentUser($users);
|
||||
|
|
@ -149,10 +157,13 @@ class UserPlugin implements ISearchPlugin {
|
|||
|
||||
if (
|
||||
$this->shareeEnumerationFullMatch
|
||||
&& $lowerSearch !== '' && (strtolower($uid) === $lowerSearch
|
||||
|| strtolower($userDisplayName) === $lowerSearch
|
||||
|| ($this->shareeEnumerationFullMatchIgnoreSecondDisplayName && trim(strtolower(preg_replace('/ \(.*\)$/', '', $userDisplayName))) === $lowerSearch)
|
||||
|| ($this->shareeEnumerationFullMatchEmail && strtolower($userEmail ?? '') === $lowerSearch))
|
||||
&& $lowerSearch !== ''
|
||||
&& (
|
||||
strtolower($uid) === $lowerSearch
|
||||
|| strtolower($userDisplayName) === $lowerSearch
|
||||
|| ($this->shareeEnumerationFullMatchIgnoreSecondDisplayName && trim(strtolower(preg_replace('/ \(.*\)$/', '', $userDisplayName))) === $lowerSearch)
|
||||
|| ($this->shareeEnumerationFullMatchEmail && strtolower($userEmail ?? '') === $lowerSearch)
|
||||
)
|
||||
) {
|
||||
if (strtolower($uid) === $lowerSearch) {
|
||||
$foundUserById = true;
|
||||
|
|
|
|||
|
|
@ -1931,6 +1931,10 @@ class Manager implements IManager {
|
|||
return $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_email', 'yes') === 'yes';
|
||||
}
|
||||
|
||||
public function matchUserId(): bool {
|
||||
return $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_userid', 'yes') === 'yes';
|
||||
}
|
||||
|
||||
public function ignoreSecondDisplayName(): bool {
|
||||
return $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_ignore_second_dn', 'no') === 'yes';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -441,7 +441,8 @@ interface IManager {
|
|||
public function limitEnumerationToPhone(): bool;
|
||||
|
||||
/**
|
||||
* Check if user enumeration is allowed to return on full match
|
||||
* Check if user enumeration is allowed to return also on full match
|
||||
* and ignore limitations to phonebook or groups.
|
||||
*
|
||||
* @return bool
|
||||
* @since 21.0.1
|
||||
|
|
@ -449,7 +450,8 @@ interface IManager {
|
|||
public function allowEnumerationFullMatch(): bool;
|
||||
|
||||
/**
|
||||
* Check if the search should match the email
|
||||
* When `allowEnumerationFullMatch` is enabled and `matchEmail` is set,
|
||||
* then also return results for full email matches.
|
||||
*
|
||||
* @return bool
|
||||
* @since 25.0.0
|
||||
|
|
@ -457,7 +459,17 @@ interface IManager {
|
|||
public function matchEmail(): bool;
|
||||
|
||||
/**
|
||||
* Check if the search should ignore the second in parentheses display name if there is any
|
||||
* When `allowEnumerationFullMatch` is enabled and `matchUserId` is set,
|
||||
* then also return results for full user id matches.
|
||||
*
|
||||
* @return bool
|
||||
* @since 33.0.0
|
||||
*/
|
||||
public function matchUserId(): bool;
|
||||
|
||||
/**
|
||||
* When `allowEnumerationFullMatch` is enabled and `ignoreSecondDisplayName` is set,
|
||||
* then the search should ignore matches on the second displayname and only use the first.
|
||||
*
|
||||
* @return bool
|
||||
* @since 25.0.0
|
||||
|
|
|
|||
Loading…
Reference in a new issue