diff --git a/lib/Controller/ContactIntegrationController.php b/lib/Controller/ContactIntegrationController.php index 9847f4f6d3..67088fe202 100644 --- a/lib/Controller/ContactIntegrationController.php +++ b/lib/Controller/ContactIntegrationController.php @@ -46,7 +46,7 @@ public function __construct(string $appName, */ #[TrapError] public function match(string $mail): JSONResponse { - return (new JSONResponse($this->service->findMatches($mail)))->cacheFor(60 * 60, false, true); + return (new JSONResponse($this->service->findMatches($this->uid, $mail)))->cacheFor(60 * 60, false, true); } /** @@ -92,7 +92,7 @@ public function autoComplete(string $term): JSONResponse { return new JSONResponse($decoded); } } - $res = $this->service->autoComplete($term); + $res = $this->service->autoComplete($this->uid, $term); $this->cache->set("{$this->uid}:$term", json_encode($res), 24 * 3600); return new JSONResponse($res); } diff --git a/lib/IMAP/ImapMessageFetcher.php b/lib/IMAP/ImapMessageFetcher.php index 8ae03cee31..9ab62207bf 100644 --- a/lib/IMAP/ImapMessageFetcher.php +++ b/lib/IMAP/ImapMessageFetcher.php @@ -549,7 +549,7 @@ private function parseHeaders(Horde_Imap_Client_Data_Fetch $fetch): void { $this->hasDkimSignature = $dkimSignatureHeader !== null; if ($this->runPhishingCheck) { - $this->phishingDetails = $this->phishingDetectionService->checkHeadersForPhishing($parsedHeaders, $fetch->getFlags(), $this->hasHtmlMessage, $this->htmlMessage); + $this->phishingDetails = $this->phishingDetectionService->checkHeadersForPhishing($this->userId, $parsedHeaders, $fetch->getFlags(), $this->hasHtmlMessage, $this->htmlMessage); } $listUnsubscribeHeader = $parsedHeaders->getHeader('list-unsubscribe'); diff --git a/lib/Service/ContactIntegration/ContactIntegrationService.php b/lib/Service/ContactIntegration/ContactIntegrationService.php index 3a8babb3b3..20ecc74b97 100644 --- a/lib/Service/ContactIntegration/ContactIntegrationService.php +++ b/lib/Service/ContactIntegration/ContactIntegrationService.php @@ -19,8 +19,8 @@ public function __construct(ContactsIntegration $ci) { $this->contactsIntegration = $ci; } - public function findMatches(string $mail): array { - $matches = $this->contactsIntegration->getContactsWithMail($mail); + public function findMatches(string $uid, string $mail): array { + $matches = $this->contactsIntegration->getContactsWithMail($uid, $mail); return $matches; } @@ -32,7 +32,7 @@ public function newContact(string $name, string $mail): ?array { return $this->contactsIntegration->newContact($name, $mail); } - public function autoComplete(string $term): array { - return $this->contactsIntegration->getContactsWithName($term); + public function autoComplete(string $uid, string $term): array { + return $this->contactsIntegration->getContactsWithName($uid, $term); } } diff --git a/lib/Service/ContactsIntegration.php b/lib/Service/ContactsIntegration.php index c6377e18a6..47b749aa7a 100644 --- a/lib/Service/ContactsIntegration.php +++ b/lib/Service/ContactsIntegration.php @@ -14,6 +14,7 @@ use OCP\IConfig; use OCP\IGroupManager; use OCP\IUserManager; +use function is_array; class ContactsIntegration { /** @var IManager */ @@ -46,55 +47,9 @@ public function __construct(IManager $contactsManager, * @return array */ public function getMatchingRecipient(string $userId, string $term): array { - if (!$this->contactsManager->isEnabled()) { - return []; - } - - // If 'Allow username autocompletion in share dialog' is disabled in the admin sharing settings, then we must not - // auto-complete system users - $shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes'; - $shareeEnumerationInGroupOnly = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes'; - $shareeEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes'; - $shareeEnumerationFullMatchUserId = $shareeEnumerationFullMatch && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_userid', 'yes') === 'yes'; - $shareeEnumerationFullMatchEmail = $shareeEnumerationFullMatch && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_email', 'yes') === 'yes'; - - $result = $this->contactsManager->search( - $term, - ['UID', 'FN', 'EMAIL'], - [ - 'enumeration' => $shareeEnumeration, - 'fullmatch' => $shareeEnumerationFullMatch, - 'limit' => 20, - ], - ); - if (empty($result)) { - return []; - } + $result = $this->search($userId, $term, ['UID', 'FN', 'EMAIL']); $receivers = []; - - if ($shareeEnumeration && $shareeEnumerationInGroupOnly) { - $user = $this->userManager->get($userId); - if ($user === null) { - return []; - } - $userGroups = $this->groupManager->getUserGroupIds($user); - } - foreach ($result as $r) { - $isSystemUser = isset($r['isLocalSystemBook']) && $r['isLocalSystemBook']; - $isInSameGroup = false; - if ($isSystemUser && $shareeEnumerationInGroupOnly) { - foreach ($userGroups as $userGroup) { - if ($this->groupManager->isInGroup($r['UID'], $userGroup)) { - $isInSameGroup = true; - break; - } - } - if (!$shareeEnumerationFullMatch && !$isInSameGroup) { - continue; - } - } - $id = $r['UID']; $fn = $r['FN'] ?? null; if (!isset($r['EMAIL'])) { @@ -111,23 +66,10 @@ public function getMatchingRecipient(string $userId, string $term): array { if ($e === '') { continue; } - $lowerTerm = strtolower($term); - - if ($isSystemUser && $shareeEnumerationInGroupOnly && !$isInSameGroup) { - // Check for full match. If full match is disabled, matching results already filtered out - if (!($lowerTerm !== '' && ( - ($shareeEnumerationFullMatch && !empty($fn) && $lowerTerm === strtolower($fn)) - || ($shareeEnumerationFullMatchUserId && $lowerTerm === strtolower($id)) - || ($shareeEnumerationFullMatchEmail && $lowerTerm === strtolower($e))))) { - // Not a full Match - continue; - } - } - $receivers[] = [ 'id' => $id, // Show full name if possible or fall back to email - 'label' => $fn, + 'label' => $fn ?? $e, 'email' => $e, 'photo' => $photo, 'source' => 'contacts', @@ -229,21 +171,98 @@ public function newContact(string $name, string $mailAddr, string $type = 'HOME' return $createdContact; } + private function search(string $userId, string $term, array $fields, ?bool $strictSearch = null): array { + if (!$this->contactsManager->isEnabled()) { + return []; + } + + // If 'Allow username autocompletion in share dialog' is disabled in the admin sharing settings, then we must not + // auto-complete system users + $shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes'; + $shareeEnumerationInGroupOnly = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes'; + $shareeEnumerationFullMatch = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes') === 'yes'; + $shareeEnumerationFullMatchDisplayName = $shareeEnumerationFullMatch && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_displayname', 'yes') === 'yes'; + $shareeEnumerationFullMatchUserId = $shareeEnumerationFullMatch && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_userid', 'yes') === 'yes'; + $shareeEnumerationFullMatchEmail = $shareeEnumerationFullMatch && $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match_email', 'yes') === 'yes'; + + $options = [ + 'enumeration' => $shareeEnumeration, + 'fullmatch' => $shareeEnumerationFullMatch, + 'limit' => 20, + ]; + if ($strictSearch !== null) { + $options['strict_search'] = $strictSearch; + } + + $result = $this->contactsManager->search( + $term, + $fields, + $options, + ); + + $userGroups = []; + if ($shareeEnumeration && $shareeEnumerationInGroupOnly) { + $user = $this->userManager->get($userId); + if ($user === null) { + return []; + } + $userGroups = $this->groupManager->getUserGroupIds($user); + } + + $filteredResults = []; + foreach ($result as $r) { + $isSystemUser = isset($r['isLocalSystemBook']) && $r['isLocalSystemBook']; + $isInSameGroup = false; + if ($isSystemUser && $shareeEnumerationInGroupOnly) { + foreach ($userGroups as $userGroup) { + if ($this->groupManager->isInGroup($r['UID'], $userGroup)) { + $isInSameGroup = true; + break; + } + } + if (!$shareeEnumerationFullMatch && !$isInSameGroup) { + continue; + } + } + + if ($isSystemUser && $shareeEnumerationInGroupOnly && !$isInSameGroup && $shareeEnumerationFullMatch) { + // Check for full match. If full match is disabled, non-matching results already filtered out above. + $id = $r['UID']; + $fn = $r['FN'] ?? null; + $lowerTerm = strtolower($term); + $isMatch = ($lowerTerm !== '' && ( + ($shareeEnumerationFullMatchDisplayName && !empty($fn) && $lowerTerm === strtolower($fn)) + || ($shareeEnumerationFullMatchUserId && $lowerTerm === strtolower($id)))) ; + if ($shareeEnumerationFullMatchEmail && !$isMatch) { + $email = $r['EMAIL'] ?? null; + if ($email === null) { + continue; + } + $emails = is_array($email) ? $email : [$email]; + foreach ($emails as $e) { + if ($lowerTerm === strtolower($e)) { + $isMatch = true; + break; + } + } + } + if (!$isMatch) { + continue; + } + } + + $filteredResults[] = $r; + } + return $filteredResults; + } + /** * @param string[] $fields */ - private function doSearch(string $term, array $fields, bool $strictSearch) : array { - $allowSystemUsers = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes'; - - $result = $this->contactsManager->search($term, $fields, [ - 'strict_search' => $strictSearch, - 'limit' => 20, - ]); + private function doSearch(string $userId, string $term, array $fields, bool $strictSearch) : array { + $result = $this->search($userId, $term, $fields, $strictSearch); $matches = []; foreach ($result as $r) { - if (!$allowSystemUsers && isset($r['isLocalSystemBook']) && $r['isLocalSystemBook']) { - continue; - } $id = $r['UID']; $fn = $r['FN']; $email = $r['EMAIL'] ?? null; @@ -258,18 +277,15 @@ private function doSearch(string $term, array $fields, bool $strictSearch) : arr /** * Extracts all Contacts with the specified mail address - * - * @param string $mailAddr - * @return array */ - public function getContactsWithMail(string $mailAddr) { - return $this->doSearch($mailAddr, ['EMAIL'], true); + public function getContactsWithMail(string $userId, string $mailAddr): array { + return $this->doSearch($userId, $mailAddr, ['EMAIL'], true); } /** * Extracts all Contacts with the specified name */ - public function getContactsWithName(string $name): array { - return $this->doSearch($name, ['FN'], false); + public function getContactsWithName(string $userId, string $name): array { + return $this->doSearch($userId, $name, ['FN'], false); } } diff --git a/lib/Service/PhishingDetection/ContactCheck.php b/lib/Service/PhishingDetection/ContactCheck.php index 5a8a55a34a..1129aadce0 100644 --- a/lib/Service/PhishingDetection/ContactCheck.php +++ b/lib/Service/PhishingDetection/ContactCheck.php @@ -22,9 +22,9 @@ public function __construct( $this->contactIntegration = $contactIntegration; } - public function run(string $fn, string $email): PhishingDetectionResult { + public function run(string $userId, string $fn, string $email): PhishingDetectionResult { $emails = []; - $contacts = $this->contactIntegration->getContactsWithName($fn); + $contacts = $this->contactIntegration->getContactsWithName($userId, $fn); foreach ($contacts as $contact) { if (!isset($contact['email'])) { continue; diff --git a/lib/Service/PhishingDetection/PhishingDetectionService.php b/lib/Service/PhishingDetection/PhishingDetectionService.php index 954229ed6a..c6595024c2 100644 --- a/lib/Service/PhishingDetection/PhishingDetectionService.php +++ b/lib/Service/PhishingDetection/PhishingDetectionService.php @@ -33,7 +33,7 @@ public function __construct( * @return array * @throws \Exception */ - public function checkHeadersForPhishing(Horde_Mime_Headers $headers, array $flags, bool $hasHtmlMessage, string $htmlMessage = ''): array { + public function checkHeadersForPhishing(string $uid, Horde_Mime_Headers $headers, array $flags, bool $hasHtmlMessage, string $htmlMessage = ''): array { /** @var string|null $fromFN */ $fromFN = null; /** @var string|null $fromEmail */ @@ -66,7 +66,7 @@ public function checkHeadersForPhishing(Horde_Mime_Headers $headers, array $flag $list->addCheck($this->replyToCheck->run($fromEmail, $replyToEmail)); } if ($fromFN !== null) { - $list->addCheck($this->contactCheck->run($fromFN, $fromEmail)); + $list->addCheck($this->contactCheck->run($uid, $fromFN, $fromEmail)); } if ($customEmail !== null) { $list->addCheck($this->customEmailCheck->run($fromEmail, $customEmail)); diff --git a/tests/Integration/Service/Phishing/PhishingDetectionServiceIntegrationTest.php b/tests/Integration/Service/Phishing/PhishingDetectionServiceIntegrationTest.php index 8b4fe1bc37..4590970d9d 100644 --- a/tests/Integration/Service/Phishing/PhishingDetectionServiceIntegrationTest.php +++ b/tests/Integration/Service/Phishing/PhishingDetectionServiceIntegrationTest.php @@ -52,10 +52,10 @@ protected function setUp(): void { public function testContactCheck(): void { $this->contactsIntegration->expects(self::once()) ->method('getContactsWithName') - ->with('John Doe') + ->with('batman', 'John Doe') ->willReturn([['id' => 1, 'fn' => 'John Doe', 'email' => ['jhon@example.org','Doe@example.org']]]); - $result = $this->contactCheck->run('John Doe', 'jhon.doe@example.org'); + $result = $this->contactCheck->run('batman', 'John Doe', 'jhon.doe@example.org'); $this->assertTrue($result->isPhishing()); } @@ -73,7 +73,7 @@ public function testCheckHeadersForPhishing(): void { $headerStream = fopen(__DIR__ . '/../../../data/phishing-mail-headers.txt', 'r'); $parsedHeaders = Horde_Mime_Headers::parseHeaders($headerStream); fclose($headerStream); - $result = $this->service->checkHeadersForPhishing($parsedHeaders, [], false); + $result = $this->service->checkHeadersForPhishing('batman', $parsedHeaders, [], false); $this->assertTrue($result['warning']); } } diff --git a/tests/Unit/Controller/ContactIntegrationControllerTest.php b/tests/Unit/Controller/ContactIntegrationControllerTest.php index 948298dbd9..42daccefe6 100644 --- a/tests/Unit/Controller/ContactIntegrationControllerTest.php +++ b/tests/Unit/Controller/ContactIntegrationControllerTest.php @@ -61,7 +61,7 @@ public function testMatch(): void { $this->service->expects($this->once()) ->method('findMatches') - ->with($mail) + ->with($this->userId, $mail) ->willReturn($expected); $response = $this->controller->match($mail); @@ -170,7 +170,7 @@ public function testAutoCompleteCacheMissCallsService(): void { $this->service->expects($this->once()) ->method('autoComplete') - ->with($term) + ->with($this->userId, $term) ->willReturn($serviceResult); $this->cache->expects($this->once()) @@ -201,7 +201,7 @@ public function testAutoCompleteCacheInvalidJsonFallsBackToService(): void { $this->service->expects($this->once()) ->method('autoComplete') - ->with($term) + ->with($this->userId, $term) ->willReturn($serviceResult); $this->cache->expects($this->once()) @@ -228,7 +228,7 @@ public function testAutoCompleteEmptyResult(): void { $this->service->expects($this->once()) ->method('autoComplete') - ->with($term) + ->with($this->userId, $term) ->willReturn([]); $this->cache->expects($this->once()) @@ -256,7 +256,7 @@ public function testAutoCompleteCacheKeyIsUserSpecific(): void { $this->service->expects($this->once()) ->method('autoComplete') - ->with($term) + ->with($this->userId, $term) ->willReturn([]); $this->cache->expects($this->once()) diff --git a/tests/Unit/Service/ContactsIntegrationTest.php b/tests/Unit/Service/ContactsIntegrationTest.php index c4c65b4d1e..9064495e5c 100644 --- a/tests/Unit/Service/ContactsIntegrationTest.php +++ b/tests/Unit/Service/ContactsIntegrationTest.php @@ -343,13 +343,14 @@ public function testGetMatchingRecipientRestrictedToGroupFullMatchFalse() { $this->assertEquals($expected, $actual); } - public function common($term, $searchResult, $allowSystemUsers, $allowSystemUsersInGroupOnly, $shareeEnumerationFullMatch, $shareeEnumerationFullMatchUserId = true, $shareeEnumerationFullMatchEmail = true) { + public function common($term, $searchResult, $allowSystemUsers, $allowSystemUsersInGroupOnly, $shareeEnumerationFullMatch, $shareeEnumerationFullMatchDisplayName = true, $shareeEnumerationFullMatchUserId = true, $shareeEnumerationFullMatchEmail = true) { $this->config->expects(self::atLeast(3)) ->method('getAppValue') ->withConsecutive( ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'], ['core', 'shareapi_restrict_user_enumeration_to_group', 'no'], ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes'], + ['core', 'shareapi_restrict_user_enumeration_full_match_displayname', 'yes'], ['core', 'shareapi_restrict_user_enumeration_full_match_userid', 'yes'], ['core', 'shareapi_restrict_user_enumeration_full_match_email', 'yes'], ) @@ -357,6 +358,7 @@ public function common($term, $searchResult, $allowSystemUsers, $allowSystemUser $allowSystemUsers ? 'yes' : ' no', $allowSystemUsersInGroupOnly ? 'yes' : ' no', $shareeEnumerationFullMatch ? 'yes' : ' no', + $shareeEnumerationFullMatchDisplayName ? 'yes' : 'no', $shareeEnumerationFullMatchUserId ? 'yes' : 'no', $shareeEnumerationFullMatchEmail ? 'yes' : ' no'); $this->contactsManager->expects($this->once()) @@ -420,13 +422,22 @@ public function testGetContactsWithName(): void { ], ]; - $this->config->expects($this->once()) + $this->contactsManager->expects($this->once()) + ->method('isEnabled') + ->willReturn(true); + $this->config->expects(self::exactly(3)) ->method('getAppValue') - ->with('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') - ->willReturn('yes'); + ->withConsecutive( + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'], + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no'], + ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes'], + ) + ->willReturnOnConsecutiveCalls('yes', 'no', 'no'); $this->contactsManager->expects($this->once()) ->method('search') ->with($name, ['FN'], [ + 'enumeration' => true, + 'fullmatch' => false, 'strict_search' => false, 'limit' => 20, ]) @@ -445,20 +456,16 @@ public function testGetContactsWithName(): void { ], ]; - $actual = $this->contactsIntegration->getContactsWithName($name); + $actual = $this->contactsIntegration->getContactsWithName('currentUser', $name); $this->assertEquals($expected, $actual); } public function testGetContactsWithNameFiltersSystemUsersWhenDisabled(): void { $name = 'John'; + // When enumeration is disabled the contacts manager filters system users; + // only non-system contacts are returned. $searchResult = [ - [ - 'UID' => 'jd', - 'FN' => 'John Doe', - 'EMAIL' => 'john@doe.com', - 'isLocalSystemBook' => true, - ], [ 'UID' => 'js', 'FN' => 'John Smith', @@ -466,13 +473,22 @@ public function testGetContactsWithNameFiltersSystemUsersWhenDisabled(): void { ], ]; - $this->config->expects($this->once()) + $this->contactsManager->expects($this->once()) + ->method('isEnabled') + ->willReturn(true); + $this->config->expects(self::exactly(3)) ->method('getAppValue') - ->with('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') - ->willReturn('no'); + ->withConsecutive( + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'], + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no'], + ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes'], + ) + ->willReturnOnConsecutiveCalls('no', 'no', 'no'); $this->contactsManager->expects($this->once()) ->method('search') ->with($name, ['FN'], [ + 'enumeration' => false, + 'fullmatch' => false, 'strict_search' => false, 'limit' => 20, ]) @@ -486,7 +502,7 @@ public function testGetContactsWithNameFiltersSystemUsersWhenDisabled(): void { ], ]; - $actual = $this->contactsIntegration->getContactsWithName($name); + $actual = $this->contactsIntegration->getContactsWithName('currentUser', $name); $this->assertEquals($expected, $actual); } @@ -494,19 +510,28 @@ public function testGetContactsWithNameFiltersSystemUsersWhenDisabled(): void { public function testGetContactsWithNameNoResults(): void { $name = 'Nonexistent'; - $this->config->expects($this->once()) + $this->contactsManager->expects($this->once()) + ->method('isEnabled') + ->willReturn(true); + $this->config->expects(self::exactly(3)) ->method('getAppValue') - ->with('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') - ->willReturn('yes'); + ->withConsecutive( + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'], + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no'], + ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes'], + ) + ->willReturnOnConsecutiveCalls('yes', 'no', 'no'); $this->contactsManager->expects($this->once()) ->method('search') ->with($name, ['FN'], [ + 'enumeration' => true, + 'fullmatch' => false, 'strict_search' => false, 'limit' => 20, ]) ->willReturn([]); - $actual = $this->contactsIntegration->getContactsWithName($name); + $actual = $this->contactsIntegration->getContactsWithName('currentUser', $name); $this->assertEquals([], $actual); } @@ -520,13 +545,22 @@ public function testGetContactsWithNameNoEmail(): void { ], ]; - $this->config->expects($this->once()) + $this->contactsManager->expects($this->once()) + ->method('isEnabled') + ->willReturn(true); + $this->config->expects(self::exactly(3)) ->method('getAppValue') - ->with('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') - ->willReturn('yes'); + ->withConsecutive( + ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'], + ['core', 'shareapi_restrict_user_enumeration_to_group', 'no'], + ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes'], + ) + ->willReturnOnConsecutiveCalls('yes', 'no', 'no'); $this->contactsManager->expects($this->once()) ->method('search') ->with($name, ['FN'], [ + 'enumeration' => true, + 'fullmatch' => false, 'strict_search' => false, 'limit' => 20, ]) @@ -540,7 +574,7 @@ public function testGetContactsWithNameNoEmail(): void { ], ]; - $actual = $this->contactsIntegration->getContactsWithName($name); + $actual = $this->contactsIntegration->getContactsWithName('currentUser', $name); $this->assertEquals($expected, $actual); } diff --git a/tests/Unit/Service/Phishing/ContactCheckTest.php b/tests/Unit/Service/Phishing/ContactCheckTest.php index a0296d4e50..f5bc3a3b04 100644 --- a/tests/Unit/Service/Phishing/ContactCheckTest.php +++ b/tests/Unit/Service/Phishing/ContactCheckTest.php @@ -38,9 +38,9 @@ public function testContactInABCorrectEmail(): void { ]; $this->contactsIntegration->expects(self::once()) ->method('getContactsWithName') - ->with($fn) + ->with('currentUser', $fn) ->willReturn($contacts); - $result = $this->service->run($fn, $email); + $result = $this->service->run('currentUser', $fn, $email); $this->assertFalse($result->isPhishing()); } @@ -56,9 +56,9 @@ public function testCaseInsensitiveEmail(): void { $this->contactsIntegration ->expects(self::once()) ->method('getContactsWithName') - ->with($fn) + ->with('currentUser', $fn) ->willReturn($contacts); - $result = $this->service->run($fn, $email); + $result = $this->service->run('currentUser', $fn, $email); $this->assertFalse($result->isPhishing()); } @@ -73,10 +73,10 @@ public function testContactInABWrongEmail(): void { ]; $this->contactsIntegration->expects(self::once()) ->method('getContactsWithName') - ->with($fn) + ->with('currentUser', $fn) ->willReturn($contacts); - $result = $this->service->run($fn, $email); + $result = $this->service->run('currentUser', $fn, $email); $this->assertTrue($result->isPhishing()); } @@ -88,10 +88,10 @@ public function testContactNotInAB(): void { $this->contactsIntegration ->expects(self::once()) ->method('getContactsWithName') - ->with($fn) + ->with('currentUser', $fn) ->willReturn($contacts); - $result = $this->service->run($fn, $email); + $result = $this->service->run('currentUser', $fn, $email); $this->assertFalse($result->isPhishing()); } diff --git a/tests/Unit/Service/Phishing/PhishingDetectionServiceTest.php b/tests/Unit/Service/Phishing/PhishingDetectionServiceTest.php index d89c5e4ea2..ea965c04a8 100644 --- a/tests/Unit/Service/Phishing/PhishingDetectionServiceTest.php +++ b/tests/Unit/Service/Phishing/PhishingDetectionServiceTest.php @@ -52,7 +52,7 @@ public function testCheckHeadersForPhishing(): void { ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::REPLYTO_CHECK, false)); $this->contactCheck->expects($this->once()) ->method('run') - ->with('Jhon Doe', 'jhondoe@example.com') + ->with('', 'Jhon Doe', 'jhondoe@example.com') ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::CONTACTS_CHECK, false)); $this->dateCheck->expects($this->once()) ->method('run') @@ -66,7 +66,7 @@ public function testCheckHeadersForPhishing(): void { $this->imapFlagCheck->expects($this->once()) ->method('run') ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::IMAP_FLAG_CHECK, false)); - $result = $this->service->checkHeadersForPhishing($parsedHeaders, [], true, ''); + $result = $this->service->checkHeadersForPhishing('', $parsedHeaders, [], true, ''); $this->assertFalse($result['warning']); } @@ -90,7 +90,7 @@ public function testCheckHeadersForPhishingWithoutFrom(): void { $this->imapFlagCheck->expects($this->once()) ->method('run') ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::IMAP_FLAG_CHECK, false)); - $result = $this->service->checkHeadersForPhishing($parsedHeaders, [], true, ''); + $result = $this->service->checkHeadersForPhishing('', $parsedHeaders, [], true, ''); $this->assertFalse($result['warning']); } @@ -102,7 +102,7 @@ public function testCheckHeadersForPhishingWithoutReplyTo(): void { ->method('run'); $this->contactCheck->expects($this->once()) ->method('run') - ->with('Jhon Doe', 'jhondoe@example.com') + ->with('', 'Jhon Doe', 'jhondoe@example.com') ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::CONTACTS_CHECK, false)); $this->dateCheck->expects($this->once()) ->method('run') @@ -116,7 +116,7 @@ public function testCheckHeadersForPhishingWithoutReplyTo(): void { $this->imapFlagCheck->expects($this->once()) ->method('run') ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::IMAP_FLAG_CHECK, false)); - $result = $this->service->checkHeadersForPhishing($parsedHeaders, [], true, ''); + $result = $this->service->checkHeadersForPhishing('', $parsedHeaders, [], true, ''); $this->assertFalse($result['warning']); } @@ -130,7 +130,7 @@ public function testCheckHeadersForPhishingWithMalformedDate(): void { ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::REPLYTO_CHECK, false)); $this->contactCheck->expects($this->once()) ->method('run') - ->with('Jhon Doe', 'jhondoe@example.com') + ->with('', 'Jhon Doe', 'jhondoe@example.com') ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::CONTACTS_CHECK, false)); $this->dateCheck->expects($this->once()) ->method('run') @@ -144,7 +144,7 @@ public function testCheckHeadersForPhishingWithMalformedDate(): void { $this->imapFlagCheck->expects($this->once()) ->method('run') ->willReturn(new PhishingDetectionResult(PhishingDetectionResult::IMAP_FLAG_CHECK, false)); - $result = $this->service->checkHeadersForPhishing($parsedHeaders, [], true, ''); + $result = $this->service->checkHeadersForPhishing('', $parsedHeaders, [], true, ''); $this->assertFalse($result['warning']); } } diff --git a/tests/Unit/Service/PhishingDetection/ContactCheckTest.php b/tests/Unit/Service/PhishingDetection/ContactCheckTest.php index e9938376ba..57b537cca1 100644 --- a/tests/Unit/Service/PhishingDetection/ContactCheckTest.php +++ b/tests/Unit/Service/PhishingDetection/ContactCheckTest.php @@ -34,7 +34,7 @@ public function testExactEmailMatchReturnsNonPhishing(): void { ['uid' => 'contact1', 'email' => ['sender@example.com']], ]); - $result = $this->check->run('Sender Name', 'sender@example.com'); + $result = $this->check->run('currentUser', 'Sender Name', 'sender@example.com'); $this->assertFalse($result->isPhishing()); } @@ -42,7 +42,7 @@ public function testExactEmailMatchReturnsNonPhishing(): void { public function testNoContactMatchReturnsNonPhishing(): void { $this->contactsIntegration->method('getContactsWithName')->willReturn([]); - $result = $this->check->run('Unknown Name', 'unknown@example.com'); + $result = $this->check->run('currentUser', 'Unknown Name', 'unknown@example.com'); $this->assertFalse($result->isPhishing()); } @@ -52,7 +52,7 @@ public function testDifferentEmailSingleContactReturnsPhishing(): void { ['uid' => 'contact1', 'email' => ['different@example.com']], ]); - $result = $this->check->run('Sender Name', 'sender@example.com'); + $result = $this->check->run('currentUser', 'Sender Name', 'sender@example.com'); $this->assertTrue($result->isPhishing()); } @@ -62,7 +62,7 @@ public function testDifferentEmailMultipleContactsReturnsPhishing(): void { ['uid' => 'contact1', 'email' => ['email1@example.com', 'email2@example.com']], ]); - $result = $this->check->run('Sender Name', 'sender@example.com'); + $result = $this->check->run('currentUser', 'Sender Name', 'sender@example.com'); $this->assertTrue($result->isPhishing()); } @@ -72,7 +72,7 @@ public function testCaseInsensitiveEmailComparison(): void { ['uid' => 'contact1', 'email' => ['Test@Example.com']], ]); - $result = $this->check->run('Sender Name', 'test@example.com'); + $result = $this->check->run('currentUser', 'Sender Name', 'test@example.com'); $this->assertFalse($result->isPhishing()); } @@ -82,7 +82,7 @@ public function testContactMissingEmailFieldSkipped(): void { ['uid' => 'contact1'], ]); - $result = $this->check->run('Sender Name', 'sender@example.com'); + $result = $this->check->run('currentUser', 'Sender Name', 'sender@example.com'); $this->assertFalse($result->isPhishing()); } @@ -93,7 +93,7 @@ public function testMultipleContacts(): void { ['uid' => 'contact2', 'email' => ['email2@example.com']], ]); - $result = $this->check->run('Sender Name', 'sender@example.com'); + $result = $this->check->run('currentUser', 'Sender Name', 'sender@example.com'); $this->assertTrue($result->isPhishing()); }