diff --git a/lib/FederatedItems/SingleMemberAdd.php b/lib/FederatedItems/SingleMemberAdd.php index 2c7aa6a01..a690aab74 100644 --- a/lib/FederatedItems/SingleMemberAdd.php +++ b/lib/FederatedItems/SingleMemberAdd.php @@ -31,14 +31,9 @@ namespace OCA\Circles\FederatedItems; -use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException; -use ArtificialOwl\MySmallPhpTools\Exceptions\RequestNetworkException; -use ArtificialOwl\MySmallPhpTools\Exceptions\SignatoryException; use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Deserialize; use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Logger; use ArtificialOwl\MySmallPhpTools\Traits\TStringTools; -use Exception; -use OC\User\NoUserException; use OCA\Circles\Db\MemberRequest; use OCA\Circles\Exceptions\CircleNotFoundException; use OCA\Circles\Exceptions\FederatedItemBadRequestException; @@ -57,7 +52,6 @@ use OCA\Circles\Exceptions\RemoteResourceNotFoundException; use OCA\Circles\Exceptions\RequestBuilderException; use OCA\Circles\Exceptions\SingleCircleNotFoundException; -use OCA\Circles\Exceptions\TokenDoesNotExistException; use OCA\Circles\Exceptions\UnknownRemoteException; use OCA\Circles\Exceptions\UserTypeNotFoundException; use OCA\Circles\IFederatedItem; @@ -65,16 +59,12 @@ use OCA\Circles\IFederatedItemHighSeverity; use OCA\Circles\IFederatedItemMemberCheckNotRequired; use OCA\Circles\IFederatedItemMemberRequired; -use OCA\Circles\IFederatedUser; use OCA\Circles\Model\Circle; -use OCA\Circles\Model\DeprecatedCircle; -use OCA\Circles\Model\DeprecatedMember; use OCA\Circles\Model\Federated\FederatedEvent; use OCA\Circles\Model\Federated\RemoteInstance; use OCA\Circles\Model\Helpers\MemberHelper; use OCA\Circles\Model\ManagedModel; use OCA\Circles\Model\Member; -use OCA\Circles\Model\SharesToken; use OCA\Circles\Service\CircleService; use OCA\Circles\Service\ConfigService; use OCA\Circles\Service\EventService; @@ -83,10 +73,7 @@ use OCA\Circles\Service\MembershipService; use OCA\Circles\Service\RemoteStreamService; use OCA\Circles\StatusCode; -use OCP\IUser; use OCP\IUserManager; -use OCP\Mail\IEMailTemplate; -use OCP\Util; /** * Class MemberAdd @@ -476,369 +463,4 @@ private function confirmPatron(FederatedEvent $event, Member $member): void { $this->federatedUserService->confirmSingleIdUniqueness($patron); } - - - /** - * confirm the validity of a UserId, based on UserType. - * - * @param IFederatedUser $member - * - * @throws FederatedUserException - * @throws InvalidIdException - * @throws UserTypeNotFoundException - * @throws CircleNotFoundException - * @throws FederatedUserNotFoundException - * @throws OwnerNotFoundException - * @throws RemoteInstanceException - * @throws RemoteNotFoundException - * @throws RemoteResourceNotFoundException - * @throws UnknownRemoteException - * @throws InvalidItemException - * @throws RequestNetworkException - * @throws SignatoryException - */ - private function confirmMember(IFederatedUser $member): void { - - // TODO: confirm SingleId ??? -// switch ($member->getUserType()) { -// case Member::TYPE_USER: - $this->federatedUserService->getFederatedUser($member->getUserId(), $member->getUserType()); -// break; -// -// // TODO: confirm other UserType -// default: -// break; -//// throw new UserTypeNotFoundException(); -// } - } - - - /** - * @param IFederatedUser $member - * - * @throws NoUserException - */ - private function confirmMemberTypeUser(IFederatedUser $member): void { - if ($this->configService->isLocalInstance($member->getInstance())) { - $user = $this->userManager->get($member->getUserId()); - if ($user === null) { - throw new NoUserException('user not found'); - } - - $member->setUserId($user->getUID()); - - return; - } - - // TODO #M002: request the remote instance and check that user exists - } - -// /** -// * Verify if a local account is valid. -// * -// * @param $ident -// * @param $type -// * -// * @param string $instance -// * -// * @throws NoUserException -// */ -// private function verifyIdentLocalMember(&$ident, $type, string $instance = '') { -// if ($type !== DeprecatedMember::TYPE_USER) { -// return; -// } -// -// if ($instance === '') { -// try { -// $ident = $this->miscService->getRealUserId($ident); -// } catch (NoUserException $e) { -// throw new NoUserException($this->l10n->t("This user does not exist")); -// } -// } -// } -// -// -// /** -// * Verify if a mail have a valid format. -// * -// * @param string $ident -// * @param int $type -// * -// * @throws EmailAccountInvalidFormatException -// */ -// private function verifyIdentEmailAddress(string $ident, int $type) { -// if ($type !== DeprecatedMember::TYPE_MAIL) { -// return; -// } -// -// if ($this->configService->isAccountOnly()) { -// throw new EmailAccountInvalidFormatException( -// $this->l10n->t('You cannot add a email address as member of your Circle') -// ); -// } -// -// if (!filter_var($ident, FILTER_VALIDATE_EMAIL)) { -// throw new EmailAccountInvalidFormatException( -// $this->l10n->t('Email format is not valid') -// ); -// } -// } -// -// -// /** -// * Verify if a contact exist in current user address books. -// * -// * @param $ident -// * @param $type -// * -// * @throws NoUserException -// * @throws EmailAccountInvalidFormatException -// */ -// private function verifyIdentContact(&$ident, $type) { -// if ($type !== DeprecatedMember::TYPE_CONTACT) { -// return; -// } -// -// if ($this->configService->isAccountOnly()) { -// throw new EmailAccountInvalidFormatException( -// $this->l10n->t('You cannot add a contact as member of your Circle') -// ); -// } -// -// $tmpContact = $this->userId . ':' . $ident; -// $result = MiscService::getContactData($tmpContact); -// if (empty($result)) { -// throw new NoUserException($this->l10n->t("This contact is not available")); -// } -// -// $ident = $tmpContact; -// } - - - /** - * @param DeprecatedCircle $circle - * @param string $recipient - * @param array $links - * @param string $password - */ - private function memberIsMailbox( - DeprecatedCircle $circle, string $recipient, array $links, string $password - ) { - if ($circle->getViewer() === null) { - $author = $circle->getOwner() - ->getUserId(); - } else { - $author = $circle->getViewer() - ->getUserId(); - } - - try { - $template = $this->generateMailExitingShares($author, $circle->getName()); - $this->fillMailExistingShares($template, $links); - $this->sendMailExistingShares($template, $author, $recipient); - $this->sendPasswordExistingShares($author, $recipient, $password); - } catch (Exception $e) { - $this->miscService->log('Failed to send mail about existing share ' . $e->getMessage()); - } - } - - - /** - * @param DeprecatedCircle $circle - * @param DeprecatedMember $member - * @param string $password - * - * @return array - */ - private function generateUnknownSharesLinks( - DeprecatedCircle $circle, DeprecatedMember $member, string $password - ): array { - $unknownShares = $this->getUnknownShares($member); - - $data = []; - foreach ($unknownShares as $share) { - try { - $data[] = $this->getMailLinkFromShare($share, $member, $password); - } catch (TokenDoesNotExistException $e) { - } - } - - return $data; - } - - - /** - * @param DeprecatedMember $member - * - * @return array - */ - private function getUnknownShares(DeprecatedMember $member): array { - $allShares = $this->fileSharesRequest->getSharesForCircle($member->getCircleId()); - $knownShares = array_map( - function (SharesToken $shareToken) { - return $shareToken->getShareId(); - }, - $this->tokensRequest->getTokensFromMember($member) - ); - - $unknownShares = []; - foreach ($allShares as $share) { - if (!in_array($share['id'], $knownShares)) { - $unknownShares[] = $share; - } - } - - return $unknownShares; - } - - - /** - * @param array $share - * @param DeprecatedMember $member - * @param string $password - * - * @return array - * @throws TokenDoesNotExistException - */ - private function getMailLinkFromShare(array $share, DeprecatedMember $member, string $password = '') { - $sharesToken = $this->tokensRequest->generateTokenForMember($member, (int)$share['id'], $password); - $link = $this->urlGenerator->linkToRouteAbsolute( - 'files_sharing.sharecontroller.showShare', - ['token' => $sharesToken->getToken()] - ); - $author = $share['uid_initiator']; - $filename = basename($share['file_target']); - - return [ - 'author' => $author, - 'link' => $link, - 'filename' => $filename - ]; - } - - - /** - * @param string $author - * @param string $circleName - * - * @return IEMailTemplate - */ - private function generateMailExitingShares(string $author, string $circleName): IEMailTemplate { - $emailTemplate = $this->mailer->createEMailTemplate('circles.ExistingShareNotification', []); - $emailTemplate->addHeader(); - - $text = $this->l10n->t('%s shared multiple files with "%s".', [$author, $circleName]); - $emailTemplate->addBodyText(htmlspecialchars($text), $text); - - return $emailTemplate; - } - - /** - * @param IEMailTemplate $emailTemplate - * @param array $links - */ - private function fillMailExistingShares(IEMailTemplate $emailTemplate, array $links) { - foreach ($links as $item) { - $emailTemplate->addBodyButton( - $this->l10n->t('Open »%s«', [htmlspecialchars($item['filename'])]), $item['link'] - ); - } - } - - - /** - * @param IEMailTemplate $emailTemplate - * @param string $author - * @param string $recipient - * - * @throws Exception - */ - private function sendMailExistingShares(IEMailTemplate $emailTemplate, string $author, string $recipient - ) { - $subject = $this->l10n->t('%s shared multiple files with you.', [$author]); - - $instanceName = $this->defaults->getName(); - $senderName = $this->l10n->t('%s on %s', [$author, $instanceName]); - - $message = $this->mailer->createMessage(); - - $message->setFrom([Util::getDefaultEmailAddress($instanceName) => $senderName]); - $message->setSubject($subject); - $message->setPlainBody($emailTemplate->renderText()); - $message->setHtmlBody($emailTemplate->renderHtml()); - $message->setTo([$recipient]); - - $this->mailer->send($message); - } - - - /** - * @param string $author - * @param string $email - * @param string $password - * - * @throws Exception - */ - protected function sendPasswordExistingShares(string $author, string $email, string $password) { - if ($password === '') { - return; - } - - $message = $this->mailer->createMessage(); - - $authorUser = $this->userManager->get($author); - $authorName = ($authorUser instanceof IUser) ? $authorUser->getDisplayName() : $author; - $authorEmail = ($authorUser instanceof IUser) ? $authorUser->getEMailAddress() : null; - - $this->miscService->log("Sending password mail about existing files to '" . $email . "'", 0); - - $plainBodyPart = $this->l10n->t( - "%1\$s shared multiple files with you.\nYou should have already received a separate email with a link to access them.\n", - [$authorName] - ); - $htmlBodyPart = $this->l10n->t( - '%1$s shared multiple files with you. You should have already received a separate email with a link to access them.', - [$authorName] - ); - - $emailTemplate = $this->mailer->createEMailTemplate( - 'sharebymail.RecipientPasswordNotification', [ - 'password' => $password, - 'author' => $author - ] - ); - - $emailTemplate->setSubject( - $this->l10n->t( - 'Password to access files shared to you by %1$s', [$authorName] - ) - ); - $emailTemplate->addHeader(); - $emailTemplate->addHeading($this->l10n->t('Password to access files'), false); - $emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart); - $emailTemplate->addBodyText($this->l10n->t('It is protected with the following password:')); - $emailTemplate->addBodyText($password); - - // The "From" contains the sharers name - $instanceName = $this->defaults->getName(); - $senderName = $this->l10n->t( - '%1$s via %2$s', - [ - $authorName, - $instanceName - ] - ); - - $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]); - if ($authorEmail !== null) { - $message->setReplyTo([$authorEmail => $authorName]); - $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan()); - } else { - $emailTemplate->addFooter(); - } - - $message->setTo([$email]); - $message->useTemplate($emailTemplate); - $this->mailer->send($message); - } }