mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #56393 from nextcloud/backport/52012/stable32-fix-user-collaborators-returned-when-searching-for-mail-collaborators
[stable32] Fix user collaborators returned when searching for mail collaborators
This commit is contained in:
commit
14aef68eaf
13 changed files with 1060 additions and 116 deletions
|
|
@ -41,30 +41,39 @@ Feature: autocomplete
|
|||
Then get autocomplete for "autocomplete"
|
||||
| id | source |
|
||||
|
||||
Scenario: getting autocomplete emails from address book with enumeration
|
||||
Scenario: getting autocomplete from address book with enumeration
|
||||
Given As an "admin"
|
||||
And sending "PUT" to "/cloud/users/autocomplete" with
|
||||
| key | email |
|
||||
| value | autocomplete@example.com |
|
||||
And there is a contact in an addressbook
|
||||
Then get email autocomplete for "example"
|
||||
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "no"
|
||||
Then get autocomplete for "auto"
|
||||
| id | source |
|
||||
| auto | users |
|
||||
| autocomplete | users |
|
||||
| autocomplete2 | users |
|
||||
Then get autocomplete for "example"
|
||||
| id | source |
|
||||
| autocomplete | users |
|
||||
| leon@example.com | emails |
|
||||
| user@example.com | emails |
|
||||
Then get email autocomplete for "auto"
|
||||
Then get autocomplete for "autocomplete@example.com"
|
||||
| id | source |
|
||||
| autocomplete | users |
|
||||
Then get email autocomplete for "example"
|
||||
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "yes"
|
||||
Then get autocomplete for "auto"
|
||||
| id | source |
|
||||
| auto | users |
|
||||
| autocomplete | users |
|
||||
| autocomplete2 | users |
|
||||
Then get autocomplete for "example"
|
||||
| id | source |
|
||||
| autocomplete | users |
|
||||
| leon@example.com | emails |
|
||||
| user@example.com | emails |
|
||||
Then get email autocomplete for "autocomplete@example.com"
|
||||
Then get autocomplete for "autocomplete@example.com"
|
||||
| id | source |
|
||||
| autocomplete | users |
|
||||
| autocomplete | users |
|
||||
|
||||
Scenario: getting autocomplete emails from address book without enumeration
|
||||
Scenario: getting autocomplete from address book without enumeration
|
||||
Given As an "admin"
|
||||
And sending "PUT" to "/cloud/users/autocomplete" with
|
||||
| key | email |
|
||||
|
|
@ -72,10 +81,66 @@ Feature: autocomplete
|
|||
And there is a contact in an addressbook
|
||||
And parameter "shareapi_allow_share_dialog_user_enumeration" of app "core" is set to "no"
|
||||
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "no"
|
||||
Then get autocomplete for "auto"
|
||||
| id | source |
|
||||
Then get autocomplete for "example"
|
||||
| id | source |
|
||||
Then get autocomplete for "autocomplete@example.com"
|
||||
| id | source |
|
||||
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "yes"
|
||||
Then get autocomplete for "auto"
|
||||
| id | source |
|
||||
| auto | users |
|
||||
Then get autocomplete for "example"
|
||||
| id | source |
|
||||
Then get autocomplete for "autocomplete@example.com"
|
||||
| id | source |
|
||||
| autocomplete | users |
|
||||
| autocomplete | users |
|
||||
|
||||
Scenario: getting autocomplete emails from address book with enumeration
|
||||
Given As an "admin"
|
||||
And sending "PUT" to "/cloud/users/autocomplete" with
|
||||
| key | email |
|
||||
| value | autocomplete@example.com |
|
||||
And there is a contact in an addressbook
|
||||
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "no"
|
||||
Then get email autocomplete for "auto"
|
||||
| id | source |
|
||||
Then get email autocomplete for "example"
|
||||
| id | source |
|
||||
| leon@example.com | emails |
|
||||
| user@example.com | emails |
|
||||
Then get email autocomplete for "autocomplete@example.com"
|
||||
| id | source |
|
||||
| autocomplete@example.com | emails |
|
||||
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "yes"
|
||||
Then get email autocomplete for "auto"
|
||||
| id | source |
|
||||
Then get email autocomplete for "example"
|
||||
| id | source |
|
||||
| leon@example.com | emails |
|
||||
| user@example.com | emails |
|
||||
Then get email autocomplete for "autocomplete@example.com"
|
||||
| id | source |
|
||||
|
||||
Scenario: getting autocomplete emails from address book without enumeration
|
||||
Given As an "admin"
|
||||
And sending "PUT" to "/cloud/users/autocomplete" with
|
||||
| key | email |
|
||||
| value | autocomplete@example.com |
|
||||
And there is a contact in an addressbook
|
||||
And parameter "shareapi_allow_share_dialog_user_enumeration" of app "core" is set to "no"
|
||||
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "no"
|
||||
Then get email autocomplete for "auto"
|
||||
| id | source |
|
||||
Then get email autocomplete for "example"
|
||||
| id | source |
|
||||
| leon@example.com | emails |
|
||||
| user@example.com | emails |
|
||||
Then get email autocomplete for "autocomplete@example.com"
|
||||
| id | source |
|
||||
| autocomplete@example.com | emails |
|
||||
When parameter "shareapi_restrict_user_enumeration_full_match" of app "core" is set to "yes"
|
||||
Then get email autocomplete for "auto"
|
||||
| id | source |
|
||||
|
|
@ -85,7 +150,6 @@ Feature: autocomplete
|
|||
| user@example.com | emails |
|
||||
Then get email autocomplete for "autocomplete@example.com"
|
||||
| id | source |
|
||||
| autocomplete | users |
|
||||
|
||||
Scenario: getting autocomplete with limited enumeration by group
|
||||
Given As an "admin"
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@ require __DIR__ . '/../../vendor/autoload.php';
|
|||
trait Provisioning {
|
||||
use BasicStructure;
|
||||
|
||||
/** @var array */
|
||||
private $appsToEnableAfterScenario = [];
|
||||
|
||||
/** @var array */
|
||||
private $appsToDisableAfterScenario = [];
|
||||
|
||||
/** @var array */
|
||||
private $createdUsers = [];
|
||||
|
||||
|
|
@ -28,6 +34,19 @@ trait Provisioning {
|
|||
/** @var array */
|
||||
private $createdGroups = [];
|
||||
|
||||
/** @AfterScenario */
|
||||
public function restoreAppsEnabledStateAfterScenario() {
|
||||
$this->asAn('admin');
|
||||
|
||||
foreach ($this->appsToEnableAfterScenario as $app) {
|
||||
$this->sendingTo('POST', '/cloud/apps/' . $app);
|
||||
}
|
||||
|
||||
foreach ($this->appsToDisableAfterScenario as $app) {
|
||||
$this->sendingTo('DELETE', '/cloud/apps/' . $app);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^user "([^"]*)" exists$/
|
||||
* @param string $user
|
||||
|
|
@ -803,13 +822,23 @@ trait Provisioning {
|
|||
return $extractedElementsArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Given /^app "([^"]*)" is disabled$/
|
||||
* @Given /^app "([^"]*)" enabled state will be restored once the scenario finishes$/
|
||||
* @param string $app
|
||||
*/
|
||||
public function appIsDisabled($app) {
|
||||
$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=disabled';
|
||||
public function appEnabledStateWillBeRestoredOnceTheScenarioFinishes($app) {
|
||||
if (in_array($app, $this->getAppsWithFilter('enabled'))) {
|
||||
$this->appsToEnableAfterScenario[] = $app;
|
||||
} elseif (in_array($app, $this->getAppsWithFilter('disabled'))) {
|
||||
$this->appsToDisableAfterScenario[] = $app;
|
||||
}
|
||||
|
||||
// Apps that were not installed before the scenario will not be
|
||||
// disabled nor uninstalled after the scenario.
|
||||
}
|
||||
|
||||
private function getAppsWithFilter($filter) {
|
||||
$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=' . $filter;
|
||||
$client = new Client();
|
||||
$options = [];
|
||||
if ($this->currentUser === 'admin') {
|
||||
|
|
@ -820,7 +849,15 @@ trait Provisioning {
|
|||
];
|
||||
|
||||
$this->response = $client->get($fullUrl, $options);
|
||||
$respondedArray = $this->getArrayOfAppsResponded($this->response);
|
||||
return $this->getArrayOfAppsResponded($this->response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^app "([^"]*)" is disabled$/
|
||||
* @param string $app
|
||||
*/
|
||||
public function appIsDisabled($app) {
|
||||
$respondedArray = $this->getAppsWithFilter('disabled');
|
||||
Assert::assertContains($app, $respondedArray);
|
||||
Assert::assertEquals(200, $this->response->getStatusCode());
|
||||
}
|
||||
|
|
@ -830,18 +867,7 @@ trait Provisioning {
|
|||
* @param string $app
|
||||
*/
|
||||
public function appIsEnabled($app) {
|
||||
$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=enabled';
|
||||
$client = new Client();
|
||||
$options = [];
|
||||
if ($this->currentUser === 'admin') {
|
||||
$options['auth'] = $this->adminUser;
|
||||
}
|
||||
$options['headers'] = [
|
||||
'OCS-APIREQUEST' => 'true',
|
||||
];
|
||||
|
||||
$this->response = $client->get($fullUrl, $options);
|
||||
$respondedArray = $this->getArrayOfAppsResponded($this->response);
|
||||
$respondedArray = $this->getAppsWithFilter('enabled');
|
||||
Assert::assertContains($app, $respondedArray);
|
||||
Assert::assertEquals(200, $this->response->getStatusCode());
|
||||
}
|
||||
|
|
@ -854,18 +880,7 @@ trait Provisioning {
|
|||
* @param string $app
|
||||
*/
|
||||
public function appIsNotEnabled($app) {
|
||||
$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=enabled';
|
||||
$client = new Client();
|
||||
$options = [];
|
||||
if ($this->currentUser === 'admin') {
|
||||
$options['auth'] = $this->adminUser;
|
||||
}
|
||||
$options['headers'] = [
|
||||
'OCS-APIREQUEST' => 'true',
|
||||
];
|
||||
|
||||
$this->response = $client->get($fullUrl, $options);
|
||||
$respondedArray = $this->getArrayOfAppsResponded($this->response);
|
||||
$respondedArray = $this->getAppsWithFilter('enabled');
|
||||
Assert::assertNotContains($app, $respondedArray);
|
||||
Assert::assertEquals(200, $this->response->getStatusCode());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -697,7 +697,13 @@ trait Sharing {
|
|||
if ($body instanceof TableNode) {
|
||||
$parameters = [];
|
||||
foreach ($body->getRowsHash() as $key => $value) {
|
||||
$parameters[] = $key . '=' . $value;
|
||||
if ($key === 'shareTypes') {
|
||||
foreach (explode(' ', $value) as $shareType) {
|
||||
$parameters[] = 'shareType[]=' . $shareType;
|
||||
}
|
||||
} else {
|
||||
$parameters[] = $key . '=' . $value;
|
||||
}
|
||||
}
|
||||
if (!empty($parameters)) {
|
||||
$url .= '?' . implode('&', $parameters);
|
||||
|
|
@ -732,9 +738,46 @@ trait Sharing {
|
|||
$shareeType = substr($shareeType, 6);
|
||||
}
|
||||
|
||||
// "simplexml_load_string" creates a SimpleXMLElement object for each
|
||||
// XML element with child elements. In turn, each child is indexed by
|
||||
// its tag in the SimpleXMLElement object. However, when there are
|
||||
// several child XML elements with the same tag, an array with all the
|
||||
// children with the same tag is indexed instead. Therefore, when the
|
||||
// XML contains
|
||||
// <XXX>
|
||||
// <element>
|
||||
// <label>...</label>
|
||||
// <value>...</value>
|
||||
// </element>
|
||||
// </XXX>
|
||||
// the "$elements[$shareeType]" variable contains an "element" key which
|
||||
// in turn contains "label" and "value" keys, but when the XML contains
|
||||
// <XXX>
|
||||
// <element>
|
||||
// <label>...</label>
|
||||
// <value>...</value>
|
||||
// </element>
|
||||
// <element>
|
||||
// <label>...</label>
|
||||
// <value>...</value>
|
||||
// </element>
|
||||
// </XXX>
|
||||
// the "$elements[$shareeType]" variable contains an "element" key which
|
||||
// in turn contains "0" and "1" keys, and in turn each one contains
|
||||
// "label" and "value" keys.
|
||||
if (array_key_exists('element', $elements[$shareeType]) && is_int(array_keys($elements[$shareeType]['element'])[0])) {
|
||||
$elements[$shareeType] = $elements[$shareeType]['element'];
|
||||
}
|
||||
|
||||
$sharees = [];
|
||||
foreach ($elements[$shareeType] as $element) {
|
||||
$sharees[] = [$element['label'], $element['value']['shareType'], $element['value']['shareWith']];
|
||||
$sharee = [$element['label'], $element['value']['shareType'], $element['value']['shareWith']];
|
||||
|
||||
if (array_key_exists('shareWithDisplayNameUnique', $element)) {
|
||||
$sharee[] = $element['shareWithDisplayNameUnique'];
|
||||
}
|
||||
|
||||
$sharees[] = $sharee;
|
||||
}
|
||||
return $sharees;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,5 +161,5 @@ Feature: LDAP
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Elisa | 0 | elisa |
|
||||
| Elisa | 0 | elisa | elisa@nextcloud.ci |
|
||||
And "exact groups" sharees returned is empty
|
||||
|
|
|
|||
|
|
@ -8,6 +8,14 @@ Feature: sharees
|
|||
And user "Sharee1" exists
|
||||
And group "ShareeGroup" exists
|
||||
And user "test" belongs to group "ShareeGroup"
|
||||
And user "Sharee2" exists
|
||||
And As an "admin"
|
||||
And sending "PUT" to "/cloud/users/Sharee2" with
|
||||
| key | email |
|
||||
| value | sharee2@system.com |
|
||||
And sending "PUT" to "/cloud/users/Sharee2" with
|
||||
| key | additional_mail |
|
||||
| value | sharee2@secondary.com |
|
||||
|
||||
Scenario: Search without exact match
|
||||
Given As an "test"
|
||||
|
|
@ -18,7 +26,8 @@ Feature: sharees
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned are
|
||||
| ShareeGroup | 1 | ShareeGroup |
|
||||
|
|
@ -34,7 +43,8 @@ Feature: sharees
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned are
|
||||
| ShareeGroup | 1 | ShareeGroup |
|
||||
|
|
@ -68,7 +78,7 @@ Feature: sharees
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned are
|
||||
| ShareeGroup | 1 | ShareeGroup |
|
||||
|
|
@ -85,7 +95,7 @@ Feature: sharees
|
|||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
|
|
@ -131,7 +141,7 @@ Feature: sharees
|
|||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
|
|
@ -162,7 +172,7 @@ Feature: sharees
|
|||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
Then "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
Then "users" sharees returned is empty
|
||||
Then "exact groups" sharees returned is empty
|
||||
Then "groups" sharees returned is empty
|
||||
|
|
@ -177,7 +187,7 @@ Feature: sharees
|
|||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
Then "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
Then "users" sharees returned is empty
|
||||
Then "exact groups" sharees returned is empty
|
||||
Then "groups" sharees returned is empty
|
||||
|
|
@ -207,7 +217,7 @@ Feature: sharees
|
|||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
Then "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
Then "users" sharees returned is empty
|
||||
Then "exact groups" sharees returned is empty
|
||||
Then "groups" sharees returned is empty
|
||||
|
|
@ -254,8 +264,285 @@ Feature: sharees
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
|
||||
Scenario: Search user by system e-mail address
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@system.com |
|
||||
| itemType | file |
|
||||
| shareType | 0 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
# UserPlugin provides two identical results (except for the field order, but
|
||||
# that is hidden by the check).
|
||||
# MailPlugin does not add a result if there is already one for that user.
|
||||
And "exact users" sharees returned are
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search user by system e-mail address without exact match
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@system.c |
|
||||
| itemType | file |
|
||||
| shareType | 0 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
# MailPlugin does not add a result if there is already one for that user.
|
||||
And "users" sharees returned are
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search user by secondary e-mail address
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@secondary.com |
|
||||
| itemType | file |
|
||||
| shareType | 0 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
# UserPlugin only searches in the system e-mail address, but not in
|
||||
# secondary addresses.
|
||||
And "exact users" sharees returned are
|
||||
| Sharee2 (sharee2@secondary.com) | 0 | Sharee2 | sharee2@secondary.com |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search user by secondary e-mail address without exact match
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@secondary.c |
|
||||
| itemType | file |
|
||||
| shareType | 0 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
# UserPlugin only searches in the system e-mail address, but not in
|
||||
# secondary addresses.
|
||||
# MailPlugin adds a result for every e-mail address of the contact unless
|
||||
# there is an exact match.
|
||||
And "users" sharees returned are
|
||||
| Sharee2 (sharee2@system.com) | 0 | Sharee2 | sharee2@system.com |
|
||||
| Sharee2 (sharee2@secondary.com) | 0 | Sharee2 | sharee2@secondary.com |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search e-mail
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@unknown.com |
|
||||
| itemType | file |
|
||||
| shareType | 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned are
|
||||
| sharee2@unknown.com | 4 | sharee2@unknown.com |
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search e-mail when sharebymail app is disabled
|
||||
Given app "sharebymail" enabled state will be restored once the scenario finishes
|
||||
And sending "DELETE" to "/cloud/apps/sharebymail"
|
||||
And app "sharebymail" is disabled
|
||||
And As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@unknown.com |
|
||||
| itemType | file |
|
||||
| shareType | 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search e-mail matching system e-mail address of user
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@system.com |
|
||||
| itemType | file |
|
||||
| shareType | 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search e-mail partially matching system e-mail address of user
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@system.c |
|
||||
| itemType | file |
|
||||
| shareType | 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned are
|
||||
| sharee2@system.c | 4 | sharee2@system.c |
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search e-mail matching secondary e-mail address of user
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@secondary.com |
|
||||
| itemType | file |
|
||||
| shareType | 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search e-mail partially matching secondary e-mail address of user
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@secondary.c |
|
||||
| itemType | file |
|
||||
| shareType | 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned are
|
||||
| sharee2@secondary.c | 4 | sharee2@secondary.c |
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search user and e-mail matching system e-mail address of user
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@system.com |
|
||||
| itemType | file |
|
||||
| shareTypes | 0 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
# UserPlugin provides two identical results (except for the field order, but
|
||||
# that is hidden by the check)
|
||||
And "exact users" sharees returned are
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search user and e-mail matching system e-mail address of user when sharebymail app is disabled
|
||||
Given app "sharebymail" enabled state will be restored once the scenario finishes
|
||||
And sending "DELETE" to "/cloud/apps/sharebymail"
|
||||
And app "sharebymail" is disabled
|
||||
And As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@system.com |
|
||||
| itemType | file |
|
||||
| shareTypes | 0 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
# UserPlugin provides two identical results (except for the field order, but
|
||||
# that is hidden by the check)
|
||||
And "exact users" sharees returned are
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
| Sharee2 | 0 | Sharee2 | sharee2@system.com |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search user and e-mail matching secondary e-mail address of user
|
||||
Given As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@secondary.com |
|
||||
| itemType | file |
|
||||
| shareTypes | 0 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned are
|
||||
| Sharee2 (sharee2@secondary.com) | 0 | Sharee2 | sharee2@secondary.com |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
||||
Scenario: Search user and e-mail matching secondary e-mail address of user when sharebymail app is disabled
|
||||
Given app "sharebymail" enabled state will be restored once the scenario finishes
|
||||
And sending "DELETE" to "/cloud/apps/sharebymail"
|
||||
And app "sharebymail" is disabled
|
||||
And As an "test"
|
||||
When getting sharees for
|
||||
| search | sharee2@secondary.com |
|
||||
| itemType | file |
|
||||
| shareTypes | 0 4 |
|
||||
Then the OCS status code should be "100"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned are
|
||||
| Sharee2 (sharee2@secondary.com) | 0 | Sharee2 | sharee2@secondary.com |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
And "remotes" sharees returned is empty
|
||||
And "exact emails" sharees returned is empty
|
||||
And "emails" sharees returned is empty
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Feature: sharees_provisioningapiv2
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned are
|
||||
| ShareeGroup | 1 | ShareeGroup |
|
||||
|
|
@ -34,7 +34,7 @@ Feature: sharees_provisioningapiv2
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned are
|
||||
| ShareeGroup | 1 | ShareeGroup |
|
||||
|
|
@ -68,7 +68,7 @@ Feature: sharees_provisioningapiv2
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned are
|
||||
| ShareeGroup | 1 | ShareeGroup |
|
||||
|
|
@ -114,7 +114,7 @@ Feature: sharees_provisioningapiv2
|
|||
Then the OCS status code should be "200"
|
||||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
And "users" sharees returned is empty
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
|
|
@ -145,7 +145,7 @@ Feature: sharees_provisioningapiv2
|
|||
Then the OCS status code should be "200"
|
||||
And the HTTP status code should be "200"
|
||||
Then "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
Then "users" sharees returned is empty
|
||||
Then "exact groups" sharees returned is empty
|
||||
Then "groups" sharees returned is empty
|
||||
|
|
@ -160,7 +160,7 @@ Feature: sharees_provisioningapiv2
|
|||
Then the OCS status code should be "200"
|
||||
And the HTTP status code should be "200"
|
||||
Then "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
Then "users" sharees returned is empty
|
||||
Then "exact groups" sharees returned is empty
|
||||
Then "groups" sharees returned is empty
|
||||
|
|
@ -190,7 +190,7 @@ Feature: sharees_provisioningapiv2
|
|||
Then the OCS status code should be "200"
|
||||
And the HTTP status code should be "200"
|
||||
Then "exact users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
Then "users" sharees returned is empty
|
||||
Then "exact groups" sharees returned is empty
|
||||
Then "groups" sharees returned is empty
|
||||
|
|
@ -237,7 +237,7 @@ Feature: sharees_provisioningapiv2
|
|||
And the HTTP status code should be "200"
|
||||
And "exact users" sharees returned is empty
|
||||
And "users" sharees returned are
|
||||
| Sharee1 | 0 | Sharee1 |
|
||||
| Sharee1 | 0 | Sharee1 | Sharee1 |
|
||||
And "exact groups" sharees returned is empty
|
||||
And "groups" sharees returned is empty
|
||||
And "exact remotes" sharees returned is empty
|
||||
|
|
|
|||
|
|
@ -1201,11 +1201,13 @@ return array(
|
|||
'OC\\Collaboration\\AutoComplete\\Manager' => $baseDir . '/lib/private/Collaboration/AutoComplete/Manager.php',
|
||||
'OC\\Collaboration\\Collaborators\\GroupPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/GroupPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\LookupPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/LookupPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\MailByMailPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/MailByMailPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\MailPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/MailPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\RemoteGroupPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/RemoteGroupPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\RemotePlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/RemotePlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\Search' => $baseDir . '/lib/private/Collaboration/Collaborators/Search.php',
|
||||
'OC\\Collaboration\\Collaborators\\SearchResult' => $baseDir . '/lib/private/Collaboration/Collaborators/SearchResult.php',
|
||||
'OC\\Collaboration\\Collaborators\\UserByMailPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/UserByMailPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\UserPlugin' => $baseDir . '/lib/private/Collaboration/Collaborators/UserPlugin.php',
|
||||
'OC\\Collaboration\\Reference\\File\\FileReferenceEventListener' => $baseDir . '/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php',
|
||||
'OC\\Collaboration\\Reference\\File\\FileReferenceProvider' => $baseDir . '/lib/private/Collaboration/Reference/File/FileReferenceProvider.php',
|
||||
|
|
|
|||
|
|
@ -1242,11 +1242,13 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Collaboration\\AutoComplete\\Manager' => __DIR__ . '/../../..' . '/lib/private/Collaboration/AutoComplete/Manager.php',
|
||||
'OC\\Collaboration\\Collaborators\\GroupPlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/GroupPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\LookupPlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/LookupPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\MailByMailPlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/MailByMailPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\MailPlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/MailPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\RemoteGroupPlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/RemoteGroupPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\RemotePlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/RemotePlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\Search' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/Search.php',
|
||||
'OC\\Collaboration\\Collaborators\\SearchResult' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/SearchResult.php',
|
||||
'OC\\Collaboration\\Collaborators\\UserByMailPlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/UserByMailPlugin.php',
|
||||
'OC\\Collaboration\\Collaborators\\UserPlugin' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Collaborators/UserPlugin.php',
|
||||
'OC\\Collaboration\\Reference\\File\\FileReferenceEventListener' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php',
|
||||
'OC\\Collaboration\\Reference\\File\\FileReferenceProvider' => __DIR__ . '/../../..' . '/lib/private/Collaboration/Reference/File/FileReferenceProvider.php',
|
||||
|
|
|
|||
45
lib/private/Collaboration/Collaborators/MailByMailPlugin.php
Normal file
45
lib/private/Collaboration/Collaborators/MailByMailPlugin.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OC\Collaboration\Collaborators;
|
||||
|
||||
use OC\KnownUser\KnownUserService;
|
||||
use OCP\Contacts\IManager;
|
||||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Mail\IMailer;
|
||||
use OCP\Share\IShare;
|
||||
|
||||
/**
|
||||
* Dummy subclass to initialize a MailPlugin with a specific share type.
|
||||
*/
|
||||
class MailByMailPlugin extends MailPlugin {
|
||||
|
||||
public function __construct(
|
||||
IManager $contactsManager,
|
||||
ICloudIdManager $cloudIdManager,
|
||||
IConfig $config,
|
||||
IGroupManager $groupManager,
|
||||
KnownUserService $knownUserService,
|
||||
IUserSession $userSession,
|
||||
IMailer $mailer,
|
||||
mixed $shareWithGroupOnlyExcludeGroupsList = [],
|
||||
) {
|
||||
parent::__construct(
|
||||
$contactsManager,
|
||||
$cloudIdManager,
|
||||
$config,
|
||||
$groupManager,
|
||||
$knownUserService,
|
||||
$userSession,
|
||||
$mailer,
|
||||
$shareWithGroupOnlyExcludeGroupsList,
|
||||
IShare::TYPE_EMAIL,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +41,8 @@ class MailPlugin implements ISearchPlugin {
|
|||
private KnownUserService $knownUserService,
|
||||
private IUserSession $userSession,
|
||||
private IMailer $mailer,
|
||||
private mixed $shareWithGroupOnlyExcludeGroupsList = [],
|
||||
private mixed $shareWithGroupOnlyExcludeGroupsList,
|
||||
private int $shareType,
|
||||
) {
|
||||
$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
|
||||
$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
|
||||
|
|
@ -139,7 +140,7 @@ class MailPlugin implements ISearchPlugin {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!$this->isCurrentUser($cloud) && !$searchResult->hasResult($userType, $cloud->getUser())) {
|
||||
if ($this->shareType === IShare::TYPE_USER && !$this->isCurrentUser($cloud) && !$searchResult->hasResult($userType, $cloud->getUser())) {
|
||||
$singleResult = [[
|
||||
'label' => $displayName,
|
||||
'uuid' => $contact['UID'] ?? $emailAddress,
|
||||
|
|
@ -180,22 +181,28 @@ class MailPlugin implements ISearchPlugin {
|
|||
}
|
||||
}
|
||||
if ($addToWide && !$this->isCurrentUser($cloud) && !$searchResult->hasResult($userType, $cloud->getUser())) {
|
||||
$userResults['wide'][] = [
|
||||
'label' => $displayName,
|
||||
'uuid' => $contact['UID'] ?? $emailAddress,
|
||||
'name' => $contact['FN'] ?? $displayName,
|
||||
'value' => [
|
||||
'shareType' => IShare::TYPE_USER,
|
||||
'shareWith' => $cloud->getUser(),
|
||||
],
|
||||
'shareWithDisplayNameUnique' => !empty($emailAddress) ? $emailAddress : $cloud->getUser()
|
||||
];
|
||||
if ($this->shareType === IShare::TYPE_USER) {
|
||||
$userResults['wide'][] = [
|
||||
'label' => $displayName,
|
||||
'uuid' => $contact['UID'] ?? $emailAddress,
|
||||
'name' => $contact['FN'] ?? $displayName,
|
||||
'value' => [
|
||||
'shareType' => IShare::TYPE_USER,
|
||||
'shareWith' => $cloud->getUser(),
|
||||
],
|
||||
'shareWithDisplayNameUnique' => !empty($emailAddress) ? $emailAddress : $cloud->getUser()
|
||||
];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->shareType !== IShare::TYPE_EMAIL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($exactEmailMatch
|
||||
|| (isset($contact['FN']) && strtolower($contact['FN']) === $lowerSearch)) {
|
||||
if ($exactEmailMatch) {
|
||||
|
|
@ -236,7 +243,8 @@ class MailPlugin implements ISearchPlugin {
|
|||
$userResults['wide'] = array_slice($userResults['wide'], $offset, $limit);
|
||||
}
|
||||
|
||||
if (!$searchResult->hasExactIdMatch($emailType) && $this->mailer->validateMailAddress($search)) {
|
||||
if ($this->shareType === IShare::TYPE_EMAIL
|
||||
&& !$searchResult->hasExactIdMatch($emailType) && $this->mailer->validateMailAddress($search)) {
|
||||
$result['exact'][] = [
|
||||
'label' => $search,
|
||||
'uuid' => $search,
|
||||
|
|
@ -247,10 +255,12 @@ class MailPlugin implements ISearchPlugin {
|
|||
];
|
||||
}
|
||||
|
||||
if (!empty($userResults['wide'])) {
|
||||
if ($this->shareType === IShare::TYPE_USER && !empty($userResults['wide'])) {
|
||||
$searchResult->addResultSet($userType, $userResults['wide'], []);
|
||||
}
|
||||
$searchResult->addResultSet($emailType, $result['wide'], $result['exact']);
|
||||
if ($this->shareType === IShare::TYPE_EMAIL) {
|
||||
$searchResult->addResultSet($emailType, $result['wide'], $result['exact']);
|
||||
}
|
||||
|
||||
return !$reachedEnd;
|
||||
}
|
||||
|
|
|
|||
45
lib/private/Collaboration/Collaborators/UserByMailPlugin.php
Normal file
45
lib/private/Collaboration/Collaborators/UserByMailPlugin.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OC\Collaboration\Collaborators;
|
||||
|
||||
use OC\KnownUser\KnownUserService;
|
||||
use OCP\Contacts\IManager;
|
||||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Mail\IMailer;
|
||||
use OCP\Share\IShare;
|
||||
|
||||
/**
|
||||
* Dummy subclass to initialize a MailPlugin with a specific share type.
|
||||
*/
|
||||
class UserByMailPlugin extends MailPlugin {
|
||||
|
||||
public function __construct(
|
||||
IManager $contactsManager,
|
||||
ICloudIdManager $cloudIdManager,
|
||||
IConfig $config,
|
||||
IGroupManager $groupManager,
|
||||
KnownUserService $knownUserService,
|
||||
IUserSession $userSession,
|
||||
IMailer $mailer,
|
||||
mixed $shareWithGroupOnlyExcludeGroupsList = [],
|
||||
) {
|
||||
parent::__construct(
|
||||
$contactsManager,
|
||||
$cloudIdManager,
|
||||
$config,
|
||||
$groupManager,
|
||||
$knownUserService,
|
||||
$userSession,
|
||||
$mailer,
|
||||
$shareWithGroupOnlyExcludeGroupsList,
|
||||
IShare::TYPE_USER,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -25,9 +25,10 @@ use OC\Authentication\Token\IProvider;
|
|||
use OC\Avatar\AvatarManager;
|
||||
use OC\Blurhash\Listener\GenerateBlurhashMetadata;
|
||||
use OC\Collaboration\Collaborators\GroupPlugin;
|
||||
use OC\Collaboration\Collaborators\MailPlugin;
|
||||
use OC\Collaboration\Collaborators\MailByMailPlugin;
|
||||
use OC\Collaboration\Collaborators\RemoteGroupPlugin;
|
||||
use OC\Collaboration\Collaborators\RemotePlugin;
|
||||
use OC\Collaboration\Collaborators\UserByMailPlugin;
|
||||
use OC\Collaboration\Collaborators\UserPlugin;
|
||||
use OC\Collaboration\Reference\ReferenceManager;
|
||||
use OC\Command\CronBus;
|
||||
|
|
@ -1109,8 +1110,9 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
|
||||
// register default plugins
|
||||
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => UserPlugin::class]);
|
||||
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => UserByMailPlugin::class]);
|
||||
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_GROUP', 'class' => GroupPlugin::class]);
|
||||
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => MailPlugin::class]);
|
||||
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => MailByMailPlugin::class]);
|
||||
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE', 'class' => RemotePlugin::class]);
|
||||
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE_GROUP', 'class' => RemoteGroupPlugin::class]);
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class MailPluginTest extends TestCase {
|
|||
$this->searchResult = new SearchResult();
|
||||
}
|
||||
|
||||
public function instantiatePlugin() {
|
||||
public function instantiatePlugin(int $shareType) {
|
||||
$this->plugin = new MailPlugin(
|
||||
$this->contactsManager,
|
||||
$this->cloudIdManager,
|
||||
|
|
@ -82,7 +82,9 @@ class MailPluginTest extends TestCase {
|
|||
$this->groupManager,
|
||||
$this->knownUserService,
|
||||
$this->userSession,
|
||||
$this->mailer
|
||||
$this->mailer,
|
||||
[],
|
||||
$shareType,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -91,11 +93,13 @@ class MailPluginTest extends TestCase {
|
|||
* @param string $searchTerm
|
||||
* @param array $contacts
|
||||
* @param bool $shareeEnumeration
|
||||
* @param array $expected
|
||||
* @param bool $reachedEnd
|
||||
* @param array $expectedResult
|
||||
* @param bool $expectedExactIdMatch
|
||||
* @param bool $expectedMoreResults
|
||||
* @param bool $validEmail
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataGetEmail')]
|
||||
public function testSearch($searchTerm, $contacts, $shareeEnumeration, $expected, $exactIdMatch, $reachedEnd, $validEmail): void {
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataSearchEmail')]
|
||||
public function testSearchEmail($searchTerm, $contacts, $shareeEnumeration, $expectedResult, $expectedExactIdMatch, $expectedMoreResults, $validEmail): void {
|
||||
$this->config->expects($this->any())
|
||||
->method('getAppValue')
|
||||
->willReturnCallback(
|
||||
|
|
@ -107,7 +111,7 @@ class MailPluginTest extends TestCase {
|
|||
}
|
||||
);
|
||||
|
||||
$this->instantiatePlugin();
|
||||
$this->instantiatePlugin(IShare::TYPE_EMAIL);
|
||||
|
||||
$currentUser = $this->createMock(IUser::class);
|
||||
$currentUser->method('getUID')
|
||||
|
|
@ -130,12 +134,12 @@ class MailPluginTest extends TestCase {
|
|||
$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
|
||||
$result = $this->searchResult->asArray();
|
||||
|
||||
$this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
|
||||
$this->assertEquals($expected, $result);
|
||||
$this->assertSame($reachedEnd, $moreResults);
|
||||
$this->assertSame($expectedExactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
|
||||
$this->assertEquals($expectedResult, $result);
|
||||
$this->assertSame($expectedMoreResults, $moreResults);
|
||||
}
|
||||
|
||||
public static function dataGetEmail(): array {
|
||||
public static function dataSearchEmail(): array {
|
||||
return [
|
||||
// data set 0
|
||||
['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, false, false],
|
||||
|
|
@ -401,7 +405,7 @@ class MailPluginTest extends TestCase {
|
|||
false,
|
||||
],
|
||||
// data set 13
|
||||
// Local user found by email
|
||||
// Local user found by email => no result
|
||||
[
|
||||
'test@example.com',
|
||||
[
|
||||
|
|
@ -414,8 +418,8 @@ class MailPluginTest extends TestCase {
|
|||
]
|
||||
],
|
||||
false,
|
||||
['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User (test@example.com)','value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => 'test@example.com']]]],
|
||||
true,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
],
|
||||
|
|
@ -439,7 +443,7 @@ class MailPluginTest extends TestCase {
|
|||
true,
|
||||
],
|
||||
// data set 15
|
||||
// Pagination and "more results" for user matches byyyyyyy emails
|
||||
// Several local users found by email => no result nor pagination
|
||||
[
|
||||
'test@example',
|
||||
[
|
||||
|
|
@ -473,12 +477,9 @@ class MailPluginTest extends TestCase {
|
|||
],
|
||||
],
|
||||
true,
|
||||
['users' => [
|
||||
['uuid' => 'uid1', 'name' => 'User1', 'label' => 'User1 (test@example.com)', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'shareWithDisplayNameUnique' => 'test@example.com'],
|
||||
['uuid' => 'uid2', 'name' => 'User2', 'label' => 'User2 (test@example.de)', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'shareWithDisplayNameUnique' => 'test@example.de'],
|
||||
], 'emails' => [], 'exact' => ['users' => [], 'emails' => []]],
|
||||
['emails' => [], 'exact' => ['emails' => []]],
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
],
|
||||
// data set 16
|
||||
|
|
@ -572,13 +573,310 @@ class MailPluginTest extends TestCase {
|
|||
*
|
||||
* @param string $searchTerm
|
||||
* @param array $contacts
|
||||
* @param array $expected
|
||||
* @param bool $exactIdMatch
|
||||
* @param bool $reachedEnd
|
||||
* @param array groups
|
||||
* @param bool $shareeEnumeration
|
||||
* @param array $expectedResult
|
||||
* @param bool $expectedExactIdMatch
|
||||
* @param bool $expectedMoreResults
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataGetEmailGroupsOnly')]
|
||||
public function testSearchGroupsOnly($searchTerm, $contacts, $expected, $exactIdMatch, $reachedEnd, $userToGroupMapping, $validEmail): void {
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataSearchUser')]
|
||||
public function testSearchUser($searchTerm, $contacts, $shareeEnumeration, $expectedResult, $expectedExactIdMatch, $expectedMoreResults): void {
|
||||
$this->config->expects($this->any())
|
||||
->method('getAppValue')
|
||||
->willReturnCallback(
|
||||
function ($appName, $key, $default) use ($shareeEnumeration) {
|
||||
if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
|
||||
return $shareeEnumeration ? 'yes' : 'no';
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
);
|
||||
|
||||
$this->instantiatePlugin(IShare::TYPE_USER);
|
||||
|
||||
$currentUser = $this->createMock(IUser::class);
|
||||
$currentUser->method('getUID')
|
||||
->willReturn('current');
|
||||
$this->userSession->method('getUser')
|
||||
->willReturn($currentUser);
|
||||
|
||||
$this->contactsManager->expects($this->any())
|
||||
->method('search')
|
||||
->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
|
||||
if ($search === $searchTerm) {
|
||||
return $contacts;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
|
||||
$result = $this->searchResult->asArray();
|
||||
|
||||
$this->assertSame($expectedExactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
|
||||
$this->assertEquals($expectedResult, $result);
|
||||
$this->assertSame($expectedMoreResults, $moreResults);
|
||||
}
|
||||
|
||||
public static function dataSearchUser(): array {
|
||||
return [
|
||||
// data set 0
|
||||
['test', [], true, ['exact' => []], false, false],
|
||||
// data set 1
|
||||
['test', [], false, ['exact' => []], false, false],
|
||||
// data set 2
|
||||
[
|
||||
'test@remote.com',
|
||||
[],
|
||||
true,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
],
|
||||
// data set 3
|
||||
[
|
||||
'test@remote.com',
|
||||
[],
|
||||
false,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
],
|
||||
// data set 4
|
||||
[
|
||||
'test',
|
||||
[
|
||||
[
|
||||
'UID' => 'uid3',
|
||||
'FN' => 'User3 @ Localhost',
|
||||
],
|
||||
[
|
||||
'UID' => 'uid2',
|
||||
'FN' => 'User2 @ Localhost',
|
||||
'EMAIL' => [
|
||||
],
|
||||
],
|
||||
[
|
||||
'UID' => 'uid1',
|
||||
'FN' => 'User @ Localhost',
|
||||
'EMAIL' => [
|
||||
'username@localhost',
|
||||
],
|
||||
],
|
||||
],
|
||||
true,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
],
|
||||
// data set 5
|
||||
[
|
||||
'test',
|
||||
[
|
||||
[
|
||||
'UID' => 'uid3',
|
||||
'FN' => 'User3 @ Localhost',
|
||||
],
|
||||
[
|
||||
'UID' => 'uid2',
|
||||
'FN' => 'User2 @ Localhost',
|
||||
'EMAIL' => [
|
||||
],
|
||||
],
|
||||
[
|
||||
'isLocalSystemBook' => true,
|
||||
'UID' => 'uid1',
|
||||
'FN' => 'User @ Localhost',
|
||||
'EMAIL' => [
|
||||
'username@localhost',
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
],
|
||||
// data set 6
|
||||
[
|
||||
'test@remote.com',
|
||||
[
|
||||
[
|
||||
'UID' => 'uid3',
|
||||
'FN' => 'User3 @ Localhost',
|
||||
],
|
||||
[
|
||||
'UID' => 'uid2',
|
||||
'FN' => 'User2 @ Localhost',
|
||||
'EMAIL' => [
|
||||
],
|
||||
],
|
||||
[
|
||||
'UID' => 'uid1',
|
||||
'FN' => 'User @ Localhost',
|
||||
'EMAIL' => [
|
||||
'username@localhost',
|
||||
],
|
||||
],
|
||||
],
|
||||
true,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
],
|
||||
// data set 7
|
||||
[
|
||||
'username@localhost',
|
||||
[
|
||||
[
|
||||
'UID' => 'uid3',
|
||||
'FN' => 'User3 @ Localhost',
|
||||
],
|
||||
[
|
||||
'UID' => 'uid2',
|
||||
'FN' => 'User2 @ Localhost',
|
||||
'EMAIL' => [
|
||||
],
|
||||
],
|
||||
[
|
||||
'UID' => 'uid1',
|
||||
'FN' => 'User @ Localhost',
|
||||
'EMAIL' => [
|
||||
'username@localhost',
|
||||
],
|
||||
],
|
||||
],
|
||||
true,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
],
|
||||
// data set 8
|
||||
// Local user found by email
|
||||
[
|
||||
'test@example.com',
|
||||
[
|
||||
[
|
||||
'UID' => 'uid1',
|
||||
'FN' => 'User',
|
||||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
]
|
||||
],
|
||||
false,
|
||||
['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User (test@example.com)','value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => 'test@example.com']]]],
|
||||
true,
|
||||
false,
|
||||
],
|
||||
// data set 9
|
||||
// Current local user found by email => no result
|
||||
[
|
||||
'test@example.com',
|
||||
[
|
||||
[
|
||||
'UID' => 'uid1',
|
||||
'FN' => 'User',
|
||||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['current@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
]
|
||||
],
|
||||
true,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
],
|
||||
// data set 10
|
||||
// Pagination and "more results" for user matches by emails
|
||||
[
|
||||
'test@example',
|
||||
[
|
||||
[
|
||||
'UID' => 'uid1',
|
||||
'FN' => 'User1',
|
||||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test1@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
],
|
||||
[
|
||||
'UID' => 'uid2',
|
||||
'FN' => 'User2',
|
||||
'EMAIL' => ['test@example.de'],
|
||||
'CLOUD' => ['test2@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
],
|
||||
[
|
||||
'UID' => 'uid3',
|
||||
'FN' => 'User3',
|
||||
'EMAIL' => ['test@example.org'],
|
||||
'CLOUD' => ['test3@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
],
|
||||
[
|
||||
'UID' => 'uid4',
|
||||
'FN' => 'User4',
|
||||
'EMAIL' => ['test@example.net'],
|
||||
'CLOUD' => ['test4@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
],
|
||||
],
|
||||
true,
|
||||
['users' => [
|
||||
['uuid' => 'uid1', 'name' => 'User1', 'label' => 'User1 (test@example.com)', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'shareWithDisplayNameUnique' => 'test@example.com'],
|
||||
['uuid' => 'uid2', 'name' => 'User2', 'label' => 'User2 (test@example.de)', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'shareWithDisplayNameUnique' => 'test@example.de'],
|
||||
], 'exact' => ['users' => []]],
|
||||
false,
|
||||
true,
|
||||
],
|
||||
// data set 11
|
||||
// Pagination and "more results" for normal emails
|
||||
[
|
||||
'test@example',
|
||||
[
|
||||
[
|
||||
'UID' => 'uid1',
|
||||
'FN' => 'User1',
|
||||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test1@localhost'],
|
||||
],
|
||||
[
|
||||
'UID' => 'uid2',
|
||||
'FN' => 'User2',
|
||||
'EMAIL' => ['test@example.de'],
|
||||
'CLOUD' => ['test2@localhost'],
|
||||
],
|
||||
[
|
||||
'UID' => 'uid3',
|
||||
'FN' => 'User3',
|
||||
'EMAIL' => ['test@example.org'],
|
||||
'CLOUD' => ['test3@localhost'],
|
||||
],
|
||||
[
|
||||
'UID' => 'uid4',
|
||||
'FN' => 'User4',
|
||||
'EMAIL' => ['test@example.net'],
|
||||
'CLOUD' => ['test4@localhost'],
|
||||
],
|
||||
],
|
||||
true,
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $searchTerm
|
||||
* @param array $contacts
|
||||
* @param array $expectedResult
|
||||
* @param bool $expectedExactIdMatch
|
||||
* @param bool $expectedMoreResults
|
||||
* @param array $userToGroupMapping
|
||||
* @param bool $validEmail
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataSearchEmailGroupsOnly')]
|
||||
public function testSearchEmailGroupsOnly($searchTerm, $contacts, $expectedResult, $expectedExactIdMatch, $expectedMoreResults, $userToGroupMapping, $validEmail): void {
|
||||
$this->config->expects($this->any())
|
||||
->method('getAppValue')
|
||||
->willReturnCallback(
|
||||
|
|
@ -592,7 +890,7 @@ class MailPluginTest extends TestCase {
|
|||
}
|
||||
);
|
||||
|
||||
$this->instantiatePlugin();
|
||||
$this->instantiatePlugin(IShare::TYPE_EMAIL);
|
||||
|
||||
/** @var IUser|\PHPUnit\Framework\MockObject\MockObject */
|
||||
$currentUser = $this->createMock('\OCP\IUser');
|
||||
|
|
@ -632,12 +930,12 @@ class MailPluginTest extends TestCase {
|
|||
$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
|
||||
$result = $this->searchResult->asArray();
|
||||
|
||||
$this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
|
||||
$this->assertEquals($expected, $result);
|
||||
$this->assertSame($reachedEnd, $moreResults);
|
||||
$this->assertSame($expectedExactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
|
||||
$this->assertEquals($expectedResult, $result);
|
||||
$this->assertSame($expectedMoreResults, $moreResults);
|
||||
}
|
||||
|
||||
public static function dataGetEmailGroupsOnly(): array {
|
||||
public static function dataSearchEmailGroupsOnly(): array {
|
||||
return [
|
||||
// The user `User` can share with the current user
|
||||
[
|
||||
|
|
@ -648,15 +946,15 @@ class MailPluginTest extends TestCase {
|
|||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
'UID' => 'User'
|
||||
'UID' => 'User',
|
||||
]
|
||||
],
|
||||
['users' => [['label' => 'User (test@example.com)', 'uuid' => 'User', 'name' => 'User', 'value' => ['shareType' => 0, 'shareWith' => 'test'],'shareWithDisplayNameUnique' => 'test@example.com',]], 'emails' => [], 'exact' => ['emails' => [], 'users' => []]],
|
||||
['emails' => [], 'exact' => ['emails' => []]],
|
||||
false,
|
||||
false,
|
||||
[
|
||||
'currentUser' => ['group1'],
|
||||
'User' => ['group1']
|
||||
'User' => ['group1'],
|
||||
],
|
||||
false,
|
||||
],
|
||||
|
|
@ -669,7 +967,7 @@ class MailPluginTest extends TestCase {
|
|||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
'UID' => 'User'
|
||||
'UID' => 'User',
|
||||
]
|
||||
],
|
||||
['emails' => [], 'exact' => ['emails' => []]],
|
||||
|
|
@ -677,7 +975,7 @@ class MailPluginTest extends TestCase {
|
|||
false,
|
||||
[
|
||||
'currentUser' => ['group1'],
|
||||
'User' => ['group2']
|
||||
'User' => ['group2'],
|
||||
],
|
||||
false,
|
||||
],
|
||||
|
|
@ -690,18 +988,149 @@ class MailPluginTest extends TestCase {
|
|||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
'UID' => 'User'
|
||||
'UID' => 'User',
|
||||
]
|
||||
],
|
||||
['emails' => [], 'exact' => ['emails' => [['label' => 'test@example.com', 'uuid' => 'test@example.com', 'value' => ['shareType' => 4,'shareWith' => 'test@example.com']]]]],
|
||||
['emails' => [], 'exact' => ['emails' => [['label' => 'test@example.com', 'uuid' => 'test@example.com', 'value' => ['shareType' => IShare::TYPE_EMAIL,'shareWith' => 'test@example.com']]]]],
|
||||
false,
|
||||
false,
|
||||
[
|
||||
'currentUser' => ['group1'],
|
||||
'User' => ['group2']
|
||||
'User' => ['group2'],
|
||||
],
|
||||
true,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $searchTerm
|
||||
* @param array $contacts
|
||||
* @param array $expectedResult
|
||||
* @param bool $expectedExactIdMatch
|
||||
* @param bool $expectedMoreResults
|
||||
* @param array $userToGroupMapping
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('dataSearchUserGroupsOnly')]
|
||||
public function testSearchUserGroupsOnly($searchTerm, $contacts, $expectedResult, $expectedExactIdMatch, $expectedMoreResults, $userToGroupMapping): void {
|
||||
$this->config->expects($this->any())
|
||||
->method('getAppValue')
|
||||
->willReturnCallback(
|
||||
function ($appName, $key, $default) {
|
||||
if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
|
||||
return 'yes';
|
||||
} elseif ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') {
|
||||
return 'yes';
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
);
|
||||
|
||||
$this->instantiatePlugin(IShare::TYPE_USER);
|
||||
|
||||
/** @var \OCP\IUser | \PHPUnit\Framework\MockObject\MockObject */
|
||||
$currentUser = $this->createMock('\OCP\IUser');
|
||||
|
||||
$currentUser->expects($this->any())
|
||||
->method('getUID')
|
||||
->willReturn('currentUser');
|
||||
|
||||
$this->contactsManager->expects($this->any())
|
||||
->method('search')
|
||||
->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
|
||||
if ($search === $searchTerm) {
|
||||
return $contacts;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
$this->userSession->expects($this->any())
|
||||
->method('getUser')
|
||||
->willReturn($currentUser);
|
||||
|
||||
$this->groupManager->expects($this->any())
|
||||
->method('getUserGroupIds')
|
||||
->willReturnCallback(function (\OCP\IUser $user) use ($userToGroupMapping) {
|
||||
return $userToGroupMapping[$user->getUID()];
|
||||
});
|
||||
|
||||
$this->groupManager->expects($this->any())
|
||||
->method('isInGroup')
|
||||
->willReturnCallback(function ($userId, $group) use ($userToGroupMapping) {
|
||||
return in_array($group, $userToGroupMapping[$userId]);
|
||||
});
|
||||
|
||||
$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
|
||||
$result = $this->searchResult->asArray();
|
||||
|
||||
$this->assertSame($expectedExactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
|
||||
$this->assertEquals($expectedResult, $result);
|
||||
$this->assertSame($expectedMoreResults, $moreResults);
|
||||
}
|
||||
|
||||
public static function dataSearchUserGroupsOnly(): array {
|
||||
return [
|
||||
// The user `User` can share with the current user
|
||||
[
|
||||
'test',
|
||||
[
|
||||
[
|
||||
'FN' => 'User',
|
||||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
'UID' => 'User',
|
||||
]
|
||||
],
|
||||
['users' => [['label' => 'User (test@example.com)', 'uuid' => 'User', 'name' => 'User', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'],'shareWithDisplayNameUnique' => 'test@example.com',]], 'exact' => ['users' => []]],
|
||||
false,
|
||||
false,
|
||||
[
|
||||
'currentUser' => ['group1'],
|
||||
'User' => ['group1'],
|
||||
],
|
||||
],
|
||||
// The user `User` cannot share with the current user
|
||||
[
|
||||
'test',
|
||||
[
|
||||
[
|
||||
'FN' => 'User',
|
||||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
'UID' => 'User',
|
||||
]
|
||||
],
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
[
|
||||
'currentUser' => ['group1'],
|
||||
'User' => ['group2'],
|
||||
],
|
||||
],
|
||||
// The user `User` cannot share with the current user, but there is an exact match on the e-mail address -> share by e-mail
|
||||
[
|
||||
'test@example.com',
|
||||
[
|
||||
[
|
||||
'FN' => 'User',
|
||||
'EMAIL' => ['test@example.com'],
|
||||
'CLOUD' => ['test@localhost'],
|
||||
'isLocalSystemBook' => true,
|
||||
'UID' => 'User',
|
||||
]
|
||||
],
|
||||
['exact' => []],
|
||||
false,
|
||||
false,
|
||||
[
|
||||
'currentUser' => ['group1'],
|
||||
'User' => ['group2'],
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue