diff options
author | Jonas Dreßler <verdre@v0yd.nl> | 2023-09-20 17:13:28 +0200 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2023-10-25 16:34:04 +0200 |
commit | 0076d6bbf0ac0c3cfff596625f48d008c83d359e (patch) | |
tree | f679b56b7e9f3a872b9e34db1509b8139b7eba51 | |
parent | 55e5fa00ffcdafe3eb3a94bc03b25e6f2ee9982d (diff) |
feat: Allow guests to contacts user via public profile "Talk to" link
Signed-off-by: Jonas Dreßler <verdre@v0yd.nl>
-rw-r--r-- | lib/Controller/PageController.php | 62 | ||||
-rw-r--r-- | lib/Profile/TalkAction.php | 8 |
2 files changed, 63 insertions, 7 deletions
diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 537bd4339..fd232e16f 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -52,6 +52,7 @@ use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\Template\PublicTemplateResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Http\TooManyRequestsResponse; use OCP\AppFramework\Services\IInitialState; use OCP\Collaboration\Reference\RenderReferenceEvent; use OCP\Collaboration\Resources\LoadAdditionalScriptsEvent; @@ -64,9 +65,13 @@ use OCP\IGroupManager; use OCP\IRequest; use OCP\IURLGenerator; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; +use OCP\L10N\IFactory; use OCP\Notification\IManager as INotificationManager; use OCP\Security\Bruteforce\IThrottler; +use OCP\Security\RateLimiting\ILimiter; +use OCP\Security\RateLimiting\IRateLimitExceededException; use Psr\Log\LoggerInterface; #[IgnoreOpenAPI] @@ -95,6 +100,9 @@ class PageController extends Controller { Config $talkConfig, IConfig $serverConfig, IGroupManager $groupManager, + protected IUserManager $userManager, + protected ILimiter $limiter, + protected IFactory $l10nFactory, ) { parent::__construct($appName, $request); $this->initialState = $initialState; @@ -148,7 +156,7 @@ class PageController extends Controller { /** * @param string $token * @param string $callUser - * @return TemplateResponse|RedirectResponse + * @return TemplateResponse|RedirectResponse|TooManyRequestsResponse * @throws HintException */ #[NoCSRFRequired] @@ -163,17 +171,65 @@ class PageController extends Controller { } /** + * @param string $forUser + * @return ?Room + */ + protected function createPrivateRoom(string $forUser): ?Room { + $user = $this->userManager->get($forUser); + if (!$user instanceof IUser) { + return null; + } + + try { + $objectType = ''; + $objectId = ''; + $l = $this->l10nFactory->get('spreed', $this->l10nFactory->getUserLanguage($user)); + $room = $this->roomService->createConversation(Room::TYPE_PUBLIC, + $l->t('Contact request'), $user, $objectType, $objectId, + ); + } catch (\InvalidArgumentException $e) { + return null; + } + + return $room; + } + + /** * @param string $token * @param string $callUser * @param string $password - * @return TemplateResponse|RedirectResponse + * @return TemplateResponse|RedirectResponse|TooManyRequestsResponse * @throws HintException */ protected function pageHandler(string $token = '', string $callUser = '', string $password = ''): Response { $bruteForceToken = $token; $user = $this->userSession->getUser(); if (!$user instanceof IUser) { - return $this->guestEnterRoom($token, $password); + if ($token === '') { + $room = $this->createPrivateRoom($callUser); + if ($room === null) { + $response = new TemplateResponse('core', '404-profile', [], 'guest'); + $response->throttle(['action' => 'callUser', 'callUser' => $callUser]); + + return $response; + } + + try { + $this->limiter->registerAnonRequest( + 'create-anonymous-conversation', + 5, // Five conversations + 60 * 60, // Per hour + $this->request->getRemoteAddress(), + ); + } catch (IRateLimitExceededException) { + return new TooManyRequestsResponse(); + } + + // FIXME: add rate limiting + return $this->redirectToConversation($room->getToken()); + } else { + return $this->guestEnterRoom($token, $password); + } } $throttle = false; diff --git a/lib/Profile/TalkAction.php b/lib/Profile/TalkAction.php index 943aed15b..b922a873c 100644 --- a/lib/Profile/TalkAction.php +++ b/lib/Profile/TalkAction.php @@ -63,9 +63,10 @@ class TalkAction implements ILinkAction { public function getTitle(): string { $visitingUser = $this->userSession->getUser(); - if (!$visitingUser || $visitingUser === $this->targetUser) { + if ($visitingUser === $this->targetUser) { return $this->l->t('Open Talk'); } + return $this->l->t('Talk to %s', [$this->targetUser->getDisplayName()]); } @@ -80,9 +81,8 @@ class TalkAction implements ILinkAction { public function getTarget(): ?string { $visitingUser = $this->userSession->getUser(); if ( - !$visitingUser - || $this->config->isDisabledForUser($this->targetUser) - || $this->config->isDisabledForUser($visitingUser) + $this->config->isDisabledForUser($this->targetUser) + || ($visitingUser && $this->config->isDisabledForUser($visitingUser)) ) { return null; } |