diff options
Diffstat (limited to 'apps/settings/lib')
16 files changed, 377 insertions, 204 deletions
diff --git a/apps/settings/lib/AppInfo/Application.php b/apps/settings/lib/AppInfo/Application.php index 8240b310558..f089260a7c7 100644 --- a/apps/settings/lib/AppInfo/Application.php +++ b/apps/settings/lib/AppInfo/Application.php @@ -35,34 +35,29 @@ declare(strict_types=1); namespace OCA\Settings\AppInfo; -use BadMethodCallException; use OC\AppFramework\Utility\TimeFactory; +use OC\Authentication\Events\AppPasswordCreatedEvent; use OC\Authentication\Token\IProvider; -use OC\Authentication\Token\IToken; -use OC\Group\Manager; use OC\Server; -use OCA\Settings\Activity\Provider; use OCA\Settings\Hooks; +use OCA\Settings\Listener\AppPasswordCreatedActivityListener; +use OCA\Settings\Listener\UserAddedToGroupActivityListener; +use OCA\Settings\Listener\UserRemovedFromGroupActivityListener; use OCA\Settings\Mailer\NewUserMailHelper; use OCA\Settings\Middleware\SubadminMiddleware; use OCA\Settings\Search\AppSearch; use OCA\Settings\Search\SectionSearch; -use OCP\Activity\IManager as IActivityManager; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\IAppContainer; use OCP\Defaults; -use OCP\IGroup; -use OCP\IGroupManager; -use OCP\ILogger; +use OCP\Group\Events\UserAddedEvent; +use OCP\Group\Events\UserRemovedEvent; use OCP\IServerContainer; -use OCP\IUser; use OCP\Settings\IManager; use OCP\Util; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; class Application extends App implements IBootstrap { public const APP_ID = 'settings'; @@ -81,6 +76,11 @@ class Application extends App implements IBootstrap { $context->registerSearchProvider(SectionSearch::class); $context->registerSearchProvider(AppSearch::class); + // Register listeners + $context->registerEventListener(AppPasswordCreatedEvent::class, AppPasswordCreatedActivityListener::class); + $context->registerEventListener(UserAddedEvent::class, UserAddedToGroupActivityListener::class); + $context->registerEventListener(UserRemovedEvent::class, UserRemovedFromGroupActivityListener::class); + /** * Core class wrappers */ @@ -129,54 +129,10 @@ class Application extends App implements IBootstrap { } public function boot(IBootContext $context): void { - $context->injectFn(function (EventDispatcherInterface $dispatcher, IAppContainer $appContainer) { - $dispatcher->addListener('app_password_created', function (GenericEvent $event) use ($appContainer) { - if (($token = $event->getSubject()) instanceof IToken) { - /** @var IActivityManager $activityManager */ - $activityManager = $appContainer->get(IActivityManager::class); - /** @var ILogger $logger */ - $logger = $appContainer->get(ILogger::class); - - $activity = $activityManager->generateEvent(); - $activity->setApp('settings') - ->setType('security') - ->setAffectedUser($token->getUID()) - ->setAuthor($token->getUID()) - ->setSubject(Provider::APP_TOKEN_CREATED, ['name' => $token->getName()]) - ->setObject('app_token', $token->getId()); - - try { - $activityManager->publish($activity); - } catch (BadMethodCallException $e) { - $logger->logException($e, ['message' => 'could not publish activity', 'level' => ILogger::WARN]); - } - } - }); - }); - Util::connectHook('OC_User', 'post_setPassword', $this, 'onChangePassword'); Util::connectHook('OC_User', 'changeUser', $this, 'onChangeInfo'); - - $context->injectFn(function (IGroupManager $groupManager) { - /** @var IGroupManager|Manager $groupManager */ - $groupManager->listen('\OC\Group', 'postRemoveUser', [$this, 'removeUserFromGroup']); - $groupManager->listen('\OC\Group', 'postAddUser', [$this, 'addUserToGroup']); - }); - } - - public function addUserToGroup(IGroup $group, IUser $user): void { - /** @var Hooks $hooks */ - $hooks = $this->getContainer()->query(Hooks::class); - $hooks->addUserToGroup($group, $user); - } - - public function removeUserFromGroup(IGroup $group, IUser $user): void { - /** @var Hooks $hooks */ - $hooks = $this->getContainer()->query(Hooks::class); - $hooks->removeUserFromGroup($group, $user); } - /** * @param array $parameters * @throws \InvalidArgumentException diff --git a/apps/settings/lib/Controller/AppSettingsController.php b/apps/settings/lib/Controller/AppSettingsController.php index 4d22e90f645..b9bbfddb249 100644 --- a/apps/settings/lib/Controller/AppSettingsController.php +++ b/apps/settings/lib/Controller/AppSettingsController.php @@ -48,11 +48,11 @@ use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; use OCP\IL10N; -use OCP\ILogger; use OCP\INavigationManager; use OCP\IRequest; use OCP\IURLGenerator; use OCP\L10N\IFactory; +use Psr\Log\LoggerInterface; class AppSettingsController extends Controller { @@ -76,7 +76,7 @@ class AppSettingsController extends Controller { private $installer; /** @var IURLGenerator */ private $urlGenerator; - /** @var ILogger */ + /** @var LoggerInterface */ private $logger; /** @var array */ @@ -95,7 +95,7 @@ class AppSettingsController extends Controller { * @param BundleFetcher $bundleFetcher * @param Installer $installer * @param IURLGenerator $urlGenerator - * @param ILogger $logger + * @param LoggerInterface $logger */ public function __construct(string $appName, IRequest $request, @@ -109,7 +109,7 @@ class AppSettingsController extends Controller { BundleFetcher $bundleFetcher, Installer $installer, IURLGenerator $urlGenerator, - ILogger $logger) { + LoggerInterface $logger) { parent::__construct($appName, $request); $this->l10n = $l10n; $this->config = $config; @@ -458,7 +458,7 @@ class AppSettingsController extends Controller { } return new JSONResponse(['data' => ['update_required' => $updateRequired]]); } catch (\Exception $e) { - $this->logger->logException($e); + $this->logger->error('could not enable apps', ['exception' => $e]); return new JSONResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_INTERNAL_SERVER_ERROR); } } @@ -499,7 +499,7 @@ class AppSettingsController extends Controller { } return new JSONResponse([]); } catch (\Exception $e) { - $this->logger->logException($e); + $this->logger->error('could not disable app', ['exception' => $e]); return new JSONResponse(['data' => ['message' => $e->getMessage()]], Http::STATUS_INTERNAL_SERVER_ERROR); } } diff --git a/apps/settings/lib/Controller/AuthSettingsController.php b/apps/settings/lib/Controller/AuthSettingsController.php index 13815f95c50..9535b3bec67 100644 --- a/apps/settings/lib/Controller/AuthSettingsController.php +++ b/apps/settings/lib/Controller/AuthSettingsController.php @@ -46,12 +46,12 @@ use OCP\Activity\IManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; -use OCP\ILogger; use OCP\IRequest; use OCP\ISession; use OCP\IUserSession; use OCP\Security\ISecureRandom; use OCP\Session\Exceptions\SessionNotAvailableException; +use Psr\Log\LoggerInterface; class AuthSettingsController extends Controller { @@ -76,7 +76,7 @@ class AuthSettingsController extends Controller { /** @var RemoteWipe */ private $remoteWipe; - /** @var ILogger */ + /** @var LoggerInterface */ private $logger; /** @@ -89,7 +89,7 @@ class AuthSettingsController extends Controller { * @param IUserSession $userSession * @param IManager $activityManager * @param RemoteWipe $remoteWipe - * @param ILogger $logger + * @param LoggerInterface $logger */ public function __construct(string $appName, IRequest $request, @@ -100,7 +100,7 @@ class AuthSettingsController extends Controller { IUserSession $userSession, IManager $activityManager, RemoteWipe $remoteWipe, - ILogger $logger) { + LoggerInterface $logger) { parent::__construct($appName, $request); $this->tokenProvider = $tokenProvider; $this->uid = $userId; @@ -252,8 +252,7 @@ class AuthSettingsController extends Controller { try { $this->activityManager->publish($event); } catch (BadMethodCallException $e) { - $this->logger->warning('could not publish activity'); - $this->logger->logException($e); + $this->logger->warning('could not publish activity', ['exception' => $e]); } } diff --git a/apps/settings/lib/Controller/CheckSetupController.php b/apps/settings/lib/Controller/CheckSetupController.php index b660ab5a262..367b631706d 100644 --- a/apps/settings/lib/Controller/CheckSetupController.php +++ b/apps/settings/lib/Controller/CheckSetupController.php @@ -73,11 +73,11 @@ use OCP\IConfig; use OCP\IDateTimeFormatter; use OCP\IDBConnection; use OCP\IL10N; -use OCP\ILogger; use OCP\IRequest; use OCP\IURLGenerator; use OCP\Lock\ILockingProvider; use OCP\Security\ISecureRandom; +use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; @@ -92,7 +92,7 @@ class CheckSetupController extends Controller { private $l10n; /** @var Checker */ private $checker; - /** @var ILogger */ + /** @var LoggerInterface */ private $logger; /** @var EventDispatcherInterface */ private $dispatcher; @@ -118,7 +118,7 @@ class CheckSetupController extends Controller { IURLGenerator $urlGenerator, IL10N $l10n, Checker $checker, - ILogger $logger, + LoggerInterface $logger, EventDispatcherInterface $dispatcher, Connection $db, ILockingProvider $lockingProvider, @@ -178,7 +178,10 @@ class CheckSetupController extends Controller { $client->get($httpSiteName); $client->get($httpsSiteName); } catch (\Exception $e) { - $this->logger->logException($e, ['app' => 'internet_connection_check']); + $this->logger->error('Cannot connect to: ' . $sitename, [ + 'app' => 'internet_connection_check', + 'exception' => $e, + ]); return false; } return true; @@ -273,7 +276,10 @@ class CheckSetupController extends Controller { return $this->l10n->t('cURL is using an outdated %1$s version (%2$s). Please update your operating system or features such as %3$s will not work reliably.', ['NSS', $versionString, $features]); } } catch (\Exception $e) { - $this->logger->logException($e, ['app' => 'settings', 'level' => \OCP\ILogger::WARN]); + $this->logger->warning('error checking curl', [ + 'app' => 'settings', + 'exception' => $e, + ]); return $this->l10n->t('Could not determine if TLS version of cURL is outdated or not because an error happened during the HTTPS request against https://nextcloud.com. Please check the nextcloud log file for more details.'); } } @@ -364,9 +370,8 @@ class CheckSetupController extends Controller { /** * @NoCSRFRequired - * @return DataResponse */ - public function getFailedIntegrityCheckFiles() { + public function getFailedIntegrityCheckFiles(): DataDisplayResponse { if (!$this->checker->isCodeCheckEnforced()) { return new DataDisplayResponse('Integrity checker has been disabled. Integrity cannot be verified.'); } @@ -410,15 +415,13 @@ Raw output } - $response = new DataDisplayResponse( + return new DataDisplayResponse( $formattedTextResponse, Http::STATUS_OK, [ 'Content-Type' => 'text/plain', ] ); - - return $response; } /** diff --git a/apps/settings/lib/Controller/HelpController.php b/apps/settings/lib/Controller/HelpController.php index 93c3bee1931..b612303f9f3 100644 --- a/apps/settings/lib/Controller/HelpController.php +++ b/apps/settings/lib/Controller/HelpController.php @@ -73,7 +73,7 @@ class HelpController extends Controller { public function help(string $mode = 'user'): TemplateResponse { $this->navigationManager->setActiveEntry('help'); - if (!isset($mode) || $mode !== 'admin') { + if ($mode !== 'admin') { $mode = 'user'; } diff --git a/apps/settings/lib/Controller/UsersController.php b/apps/settings/lib/Controller/UsersController.php index cd34dd7266f..a9b72571de6 100644 --- a/apps/settings/lib/Controller/UsersController.php +++ b/apps/settings/lib/Controller/UsersController.php @@ -42,10 +42,10 @@ use OC\AppFramework\Http; use OC\Encryption\Exceptions\ModuleDoesNotExistsException; use OC\ForbiddenException; use OC\Group\Manager as GroupManager; +use OC\KnownUser\KnownUserService; use OC\L10N\Factory; use OC\Security\IdentityProof\Manager; use OC\User\Manager as UserManager; -use OCA\FederatedFileSharing\FederatedShareProvider; use OCA\Settings\BackgroundJobs\VerifyUserData; use OCA\Settings\Events\BeforeTemplateRenderedEvent; use OCA\User_LDAP\User_Proxy; @@ -96,6 +96,8 @@ class UsersController extends Controller { private $jobList; /** @var IManager */ private $encryptionManager; + /** @var KnownUserService */ + private $knownUserService; /** @var IEventDispatcher */ private $dispatcher; @@ -116,6 +118,7 @@ class UsersController extends Controller { Manager $keyManager, IJobList $jobList, IManager $encryptionManager, + KnownUserService $knownUserService, IEventDispatcher $dispatcher ) { parent::__construct($appName, $request); @@ -132,6 +135,7 @@ class UsersController extends Controller { $this->keyManager = $keyManager; $this->jobList = $jobList; $this->encryptionManager = $encryptionManager; + $this->knownUserService = $knownUserService; $this->dispatcher = $dispatcher; } @@ -189,7 +193,7 @@ class UsersController extends Controller { ); $groupsInfo->setSorting($sortGroupsBy); - list($adminGroup, $groups) = $groupsInfo->get(); + [$adminGroup, $groups] = $groupsInfo->get(); if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) { $isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) { @@ -363,6 +367,19 @@ class UsersController extends Controller { ?string $twitter = null, ?string $twitterScope = null ) { + $user = $this->userSession->getUser(); + if (!$user instanceof IUser) { + return new DataResponse( + [ + 'status' => 'error', + 'data' => [ + 'message' => $this->l10n->t('Invalid user') + ] + ], + Http::STATUS_UNAUTHORIZED + ); + } + $email = strtolower($email); if (!empty($email) && !$this->mailer->validateMailAddress($email)) { return new DataResponse( @@ -375,24 +392,24 @@ class UsersController extends Controller { Http::STATUS_UNPROCESSABLE_ENTITY ); } - $user = $this->userSession->getUser(); + $data = $this->accountManager->getUser($user); + $beforeData = $data; $data[IAccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope]; if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) { $data[IAccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope]; $data[IAccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope]; } - if ($this->appManager->isEnabledForUser('federatedfilesharing')) { - $shareProvider = \OC::$server->query(FederatedShareProvider::class); - if ($shareProvider->isLookupServerUploadEnabled()) { - $data[IAccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope]; - $data[IAccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope]; - $data[IAccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope]; - $data[IAccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope]; - } - } + $data[IAccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope]; + $data[IAccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope]; + $data[IAccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope]; + $data[IAccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope]; + try { $data = $this->saveUserSettings($user, $data); + if ($beforeData[IAccountManager::PROPERTY_PHONE]['value'] !== $data[IAccountManager::PROPERTY_PHONE]['value']) { + $this->knownUserService->deleteByContactUserId($user->getUID()); + } return new DataResponse( [ 'status' => 'success', diff --git a/apps/settings/lib/Hooks.php b/apps/settings/lib/Hooks.php index 62eddcd1c0b..c8fa5609914 100644 --- a/apps/settings/lib/Hooks.php +++ b/apps/settings/lib/Hooks.php @@ -27,11 +27,9 @@ namespace OCA\Settings; -use OCA\Settings\Activity\GroupProvider; use OCA\Settings\Activity\Provider; use OCP\Activity\IManager as IActivityManager; use OCP\IConfig; -use OCP\IGroup; use OCP\IGroupManager; use OCP\IURLGenerator; use OCP\IUser; @@ -214,78 +212,4 @@ class Hooks { $this->mailer->send($message); } } - - /** - * @param IGroup $group - * @param IUser $user - * @throws \InvalidArgumentException - * @throws \BadMethodCallException - */ - public function addUserToGroup(IGroup $group, IUser $user): void { - $subAdminManager = $this->groupManager->getSubAdmin(); - $usersToNotify = $subAdminManager->getGroupsSubAdmins($group); - $usersToNotify[] = $user; - - - $event = $this->activityManager->generateEvent(); - $event->setApp('settings') - ->setType('group_settings'); - - $actor = $this->userSession->getUser(); - if ($actor instanceof IUser) { - $event->setAuthor($actor->getUID()) - ->setSubject(GroupProvider::ADDED_TO_GROUP, [ - 'user' => $user->getUID(), - 'group' => $group->getGID(), - 'actor' => $actor->getUID(), - ]); - } else { - $event->setSubject(GroupProvider::ADDED_TO_GROUP, [ - 'user' => $user->getUID(), - 'group' => $group->getGID(), - ]); - } - - foreach ($usersToNotify as $userToNotify) { - $event->setAffectedUser($userToNotify->getUID()); - $this->activityManager->publish($event); - } - } - - /** - * @param IGroup $group - * @param IUser $user - * @throws \InvalidArgumentException - * @throws \BadMethodCallException - */ - public function removeUserFromGroup(IGroup $group, IUser $user): void { - $subAdminManager = $this->groupManager->getSubAdmin(); - $usersToNotify = $subAdminManager->getGroupsSubAdmins($group); - $usersToNotify[] = $user; - - - $event = $this->activityManager->generateEvent(); - $event->setApp('settings') - ->setType('group_settings'); - - $actor = $this->userSession->getUser(); - if ($actor instanceof IUser) { - $event->setAuthor($actor->getUID()) - ->setSubject(GroupProvider::REMOVED_FROM_GROUP, [ - 'user' => $user->getUID(), - 'group' => $group->getGID(), - 'actor' => $actor->getUID(), - ]); - } else { - $event->setSubject(GroupProvider::REMOVED_FROM_GROUP, [ - 'user' => $user->getUID(), - 'group' => $group->getGID(), - ]); - } - - foreach ($usersToNotify as $userToNotify) { - $event->setAffectedUser($userToNotify->getUID()); - $this->activityManager->publish($event); - } - } } diff --git a/apps/settings/lib/Listener/AppPasswordCreatedActivityListener.php b/apps/settings/lib/Listener/AppPasswordCreatedActivityListener.php new file mode 100644 index 00000000000..83aa67642a7 --- /dev/null +++ b/apps/settings/lib/Listener/AppPasswordCreatedActivityListener.php @@ -0,0 +1,73 @@ +<?php + +declare(strict_types=1); + +/* + * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace OCA\Settings\Listener; + +use BadMethodCallException; +use OC\Authentication\Events\AppPasswordCreatedEvent; +use OCA\Settings\Activity\Provider; +use OCP\Activity\IManager as IActivityManager; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use Psr\Log\LoggerInterface; + +/** + * @template-implements IEventListener<\OC\Authentication\Events\AppPasswordCreatedEvent> + */ +class AppPasswordCreatedActivityListener implements IEventListener { + /** @var IActivityManager */ + private $activityManager; + + /** @var LoggerInterface */ + private $logger; + + public function __construct(IActivityManager $activityManager, + LoggerInterface $logger) { + $this->activityManager = $activityManager; + $this->logger = $logger; + } + + public function handle(Event $event): void { + if (!($event instanceof AppPasswordCreatedEvent)) { + return; + } + + $activity = $this->activityManager->generateEvent(); + $activity->setApp('settings') + ->setType('security') + ->setAffectedUser($event->getToken()->getUID()) + ->setAuthor($event->getToken()->getUID()) + ->setSubject(Provider::APP_TOKEN_CREATED, ['name' => $event->getToken()->getName()]) + ->setObject('app_token', $event->getToken()->getId()); + + try { + $this->activityManager->publish($activity); + } catch (BadMethodCallException $e) { + $this->logger->warning('Could not publish activity: ' . $e->getMessage(), [ + 'exception' => $e + ]); + } + } +} diff --git a/apps/settings/lib/Listener/UserAddedToGroupActivityListener.php b/apps/settings/lib/Listener/UserAddedToGroupActivityListener.php new file mode 100644 index 00000000000..181b65986a6 --- /dev/null +++ b/apps/settings/lib/Listener/UserAddedToGroupActivityListener.php @@ -0,0 +1,96 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2021 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Settings\Listener; + +use OC\Group\Manager; +use OCA\Settings\Activity\GroupProvider; +use OCP\Activity\IManager; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Group\Events\UserAddedEvent; +use OCP\IUser; +use OCP\IUserSession; + +class UserAddedToGroupActivityListener implements IEventListener { + + /** @var Manager */ + private $groupManager; + + /** @var IManager */ + private $activityManager; + + /** @var IUserSession */ + private $userSession; + + public function __construct( + Manager $groupManager, + IManager $activityManager, + IUserSession $userSession + ) { + $this->groupManager = $groupManager; + $this->activityManager = $activityManager; + $this->userSession = $userSession; + } + + public function handle(Event $event): void { + if (!($event instanceof UserAddedEvent)) { + return; + } + + $user = $event->getUser(); + $group = $event->getGroup(); + + $subAdminManager = $this->groupManager->getSubAdmin(); + $usersToNotify = $subAdminManager->getGroupsSubAdmins($group); + $usersToNotify[] = $user; + + + $event = $this->activityManager->generateEvent(); + $event->setApp('settings') + ->setType('group_settings'); + + $actor = $this->userSession->getUser(); + if ($actor instanceof IUser) { + $event->setAuthor($actor->getUID()) + ->setSubject(GroupProvider::ADDED_TO_GROUP, [ + 'user' => $user->getUID(), + 'group' => $group->getGID(), + 'actor' => $actor->getUID(), + ]); + } else { + $event->setSubject(GroupProvider::ADDED_TO_GROUP, [ + 'user' => $user->getUID(), + 'group' => $group->getGID(), + ]); + } + + foreach ($usersToNotify as $userToNotify) { + $event->setAffectedUser($userToNotify->getUID()); + $this->activityManager->publish($event); + } + } +} diff --git a/apps/settings/lib/Listener/UserRemovedFromGroupActivityListener.php b/apps/settings/lib/Listener/UserRemovedFromGroupActivityListener.php new file mode 100644 index 00000000000..b6e1fbc5188 --- /dev/null +++ b/apps/settings/lib/Listener/UserRemovedFromGroupActivityListener.php @@ -0,0 +1,96 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2021 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Settings\Listener; + +use OC\Group\Manager; +use OCA\Settings\Activity\GroupProvider; +use OCP\Activity\IManager; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Group\Events\UserRemovedEvent; +use OCP\IUser; +use OCP\IUserSession; + +class UserRemovedFromGroupActivityListener implements IEventListener { + + /** @var Manager */ + private $groupManager; + + /** @var IManager */ + private $activityManager; + + /** @var IUserSession */ + private $userSession; + + public function __construct( + Manager $groupManager, + IManager $activityManager, + IUserSession $userSession + ) { + $this->groupManager = $groupManager; + $this->activityManager = $activityManager; + $this->userSession = $userSession; + } + + public function handle(Event $event): void { + if (!($event instanceof UserRemovedEvent)) { + return; + } + + $user = $event->getUser(); + $group = $event->getGroup(); + + $subAdminManager = $this->groupManager->getSubAdmin(); + $usersToNotify = $subAdminManager->getGroupsSubAdmins($group); + $usersToNotify[] = $user; + + + $event = $this->activityManager->generateEvent(); + $event->setApp('settings') + ->setType('group_settings'); + + $actor = $this->userSession->getUser(); + if ($actor instanceof IUser) { + $event->setAuthor($actor->getUID()) + ->setSubject(GroupProvider::REMOVED_FROM_GROUP, [ + 'user' => $user->getUID(), + 'group' => $group->getGID(), + 'actor' => $actor->getUID(), + ]); + } else { + $event->setSubject(GroupProvider::REMOVED_FROM_GROUP, [ + 'user' => $user->getUID(), + 'group' => $group->getGID(), + ]); + } + + foreach ($usersToNotify as $userToNotify) { + $event->setAffectedUser($userToNotify->getUID()); + $this->activityManager->publish($event); + } + } +} diff --git a/apps/settings/lib/Mailer/NewUserMailHelper.php b/apps/settings/lib/Mailer/NewUserMailHelper.php index f8dfeec30ff..abee7b2e045 100644 --- a/apps/settings/lib/Mailer/NewUserMailHelper.php +++ b/apps/settings/lib/Mailer/NewUserMailHelper.php @@ -172,9 +172,16 @@ class NewUserMailHelper { * @throws \Exception If mail could not be sent */ public function sendMail(IUser $user, - IEMailTemplate $emailTemplate) { + IEMailTemplate $emailTemplate): void { + + // Be sure to never try to send to an empty e-mail + $email = $user->getEMailAddress(); + if ($email === null) { + return; + } + $message = $this->mailer->createMessage(); - $message->setTo([$user->getEMailAddress() => $user->getDisplayName()]); + $message->setTo([$email => $user->getDisplayName()]); $message->setFrom([$this->fromAddress => $this->themingDefaults->getName()]); $message->useTemplate($emailTemplate); $this->mailer->send($message); diff --git a/apps/settings/lib/Settings/Admin/Security.php b/apps/settings/lib/Settings/Admin/Security.php index a7ff58be68f..b7f460f1bca 100644 --- a/apps/settings/lib/Settings/Admin/Security.php +++ b/apps/settings/lib/Settings/Admin/Security.php @@ -29,8 +29,8 @@ namespace OCA\Settings\Settings\Admin; use OC\Authentication\TwoFactorAuth\MandatoryTwoFactor; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; use OCP\Encryption\IManager; -use OCP\IInitialStateService; use OCP\IUserManager; use OCP\Settings\ISettings; @@ -45,13 +45,13 @@ class Security implements ISettings { /** @var MandatoryTwoFactor */ private $mandatoryTwoFactor; - /** @var IInitialStateService */ + /** @var IInitialState */ private $initialState; public function __construct(IManager $manager, IUserManager $userManager, MandatoryTwoFactor $mandatoryTwoFactor, - IInitialStateService $initialState) { + IInitialState $initialState) { $this->manager = $manager; $this->userManager = $userManager; $this->mandatoryTwoFactor = $mandatoryTwoFactor; @@ -61,7 +61,7 @@ class Security implements ISettings { /** * @return TemplateResponse */ - public function getForm() { + public function getForm(): TemplateResponse { $encryptionModules = $this->manager->getEncryptionModules(); $defaultEncryptionModuleId = $this->manager->getDefaultEncryptionModuleId(); $encryptionModuleList = []; @@ -74,7 +74,6 @@ class Security implements ISettings { } $this->initialState->provideInitialState( - 'settings', 'mandatory2FAState', $this->mandatoryTwoFactor->getState() ); @@ -94,7 +93,7 @@ class Security implements ISettings { /** * @return string the section ID, e.g. 'sharing' */ - public function getSection() { + public function getSection(): string { return 'security'; } @@ -105,7 +104,7 @@ class Security implements ISettings { * * E.g.: 70 */ - public function getPriority() { + public function getPriority(): int { return 10; } } diff --git a/apps/settings/lib/Settings/Admin/Sharing.php b/apps/settings/lib/Settings/Admin/Sharing.php index 313a182501d..6285ef399a8 100644 --- a/apps/settings/lib/Settings/Admin/Sharing.php +++ b/apps/settings/lib/Settings/Admin/Sharing.php @@ -73,6 +73,8 @@ class Sharing implements ISettings { 'allowResharing' => $this->config->getAppValue('core', 'shareapi_allow_resharing', 'yes'), 'allowShareDialogUserEnumeration' => $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'), 'restrictUserEnumerationToGroup' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no'), + 'restrictUserEnumerationToPhone' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no'), + 'restrictUserEnumerationFullMatch' => $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_full_match', 'yes'), 'enforceLinkPassword' => Util::isPublicLinkPasswordRequired(), 'onlyShareWithGroupMembers' => $this->shareManager->shareWithGroupMembersOnly(), 'shareAPIEnabled' => $this->config->getAppValue('core', 'shareapi_enabled', 'yes'), diff --git a/apps/settings/lib/Settings/Personal/Additional.php b/apps/settings/lib/Settings/Personal/Additional.php index 5fff714b245..a3203431cd8 100644 --- a/apps/settings/lib/Settings/Personal/Additional.php +++ b/apps/settings/lib/Settings/Personal/Additional.php @@ -33,7 +33,7 @@ class Additional implements ISettings { * @return TemplateResponse returns the instance with all parameters set, ready to be rendered * @since 9.1 */ - public function getForm() { + public function getForm(): TemplateResponse { return new TemplateResponse('settings', 'settings/empty'); } @@ -41,7 +41,7 @@ class Additional implements ISettings { * @return string the section ID, e.g. 'sharing' * @since 9.1 */ - public function getSection() { + public function getSection(): string { return 'additional'; } @@ -53,7 +53,7 @@ class Additional implements ISettings { * E.g.: 70 * @since 9.1 */ - public function getPriority() { - return '5'; + public function getPriority(): int { + return 5; } } diff --git a/apps/settings/lib/Settings/Personal/PersonalInfo.php b/apps/settings/lib/Settings/Personal/PersonalInfo.php index a853846fadd..7a0253d2be4 100644 --- a/apps/settings/lib/Settings/Personal/PersonalInfo.php +++ b/apps/settings/lib/Settings/Personal/PersonalInfo.php @@ -37,6 +37,7 @@ namespace OCA\Settings\Settings\Personal; use OC\Accounts\AccountManager; use OCA\FederatedFileSharing\FederatedShareProvider; +use OCP\Accounts\IAccount; use OCP\Accounts\IAccountManager; use OCP\App\IAppManager; use OCP\AppFramework\Http\TemplateResponse; @@ -96,7 +97,7 @@ class PersonalInfo implements ISettings { $uid = \OC_User::getUser(); $user = $this->userManager->get($uid); - $userData = $this->accountManager->getUser($user); + $account = $this->accountManager->getAccount($user); // make sure FS is setup before querying storage related stuff... \OC_Util::setupFS($user->getUID()); @@ -110,7 +111,7 @@ class PersonalInfo implements ISettings { $languageParameters = $this->getLanguages($user); $localeParameters = $this->getLocales($user); - $messageParameters = $this->getMessageParameters($userData); + $messageParameters = $this->getMessageParameters($account); $parameters = [ 'total_space' => $totalSpace, @@ -119,23 +120,23 @@ class PersonalInfo implements ISettings { 'quota' => $storageInfo['quota'], 'avatarChangeSupported' => $user->canChangeAvatar(), 'lookupServerUploadEnabled' => $lookupServerUploadEnabled, - 'avatarScope' => $userData[IAccountManager::PROPERTY_AVATAR]['scope'], + 'avatarScope' => $account->getProperty(IAccountManager::PROPERTY_AVATAR)->getScope(), 'displayNameChangeSupported' => $user->canChangeDisplayName(), - 'displayName' => $userData[IAccountManager::PROPERTY_DISPLAYNAME]['value'], - 'displayNameScope' => $userData[IAccountManager::PROPERTY_DISPLAYNAME]['scope'], - 'email' => $userData[IAccountManager::PROPERTY_EMAIL]['value'], - 'emailScope' => $userData[IAccountManager::PROPERTY_EMAIL]['scope'], - 'emailVerification' => $userData[IAccountManager::PROPERTY_EMAIL]['verified'], - 'phone' => $userData[IAccountManager::PROPERTY_PHONE]['value'], - 'phoneScope' => $userData[IAccountManager::PROPERTY_PHONE]['scope'], - 'address' => $userData[IAccountManager::PROPERTY_ADDRESS]['value'], - 'addressScope' => $userData[IAccountManager::PROPERTY_ADDRESS]['scope'], - 'website' => $userData[IAccountManager::PROPERTY_WEBSITE]['value'], - 'websiteScope' => $userData[IAccountManager::PROPERTY_WEBSITE]['scope'], - 'websiteVerification' => $userData[IAccountManager::PROPERTY_WEBSITE]['verified'], - 'twitter' => $userData[IAccountManager::PROPERTY_TWITTER]['value'], - 'twitterScope' => $userData[IAccountManager::PROPERTY_TWITTER]['scope'], - 'twitterVerification' => $userData[IAccountManager::PROPERTY_TWITTER]['verified'], + 'displayName' => $account->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getValue(), + 'displayNameScope' => $account->getProperty(IAccountManager::PROPERTY_DISPLAYNAME)->getScope(), + 'email' => $account->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue(), + 'emailScope' => $account->getProperty(IAccountManager::PROPERTY_EMAIL)->getScope(), + 'emailVerification' => $account->getProperty(IAccountManager::PROPERTY_EMAIL)->getVerified(), + 'phone' => $account->getProperty(IAccountManager::PROPERTY_PHONE)->getValue(), + 'phoneScope' => $account->getProperty(IAccountManager::PROPERTY_PHONE)->getScope(), + 'address' => $account->getProperty(IAccountManager::PROPERTY_ADDRESS)->getValue(), + 'addressScope' => $account->getProperty(IAccountManager::PROPERTY_ADDRESS)->getScope(), + 'website' => $account->getProperty(IAccountManager::PROPERTY_WEBSITE)->getValue(), + 'websiteScope' => $account->getProperty(IAccountManager::PROPERTY_WEBSITE)->getScope(), + 'websiteVerification' => $account->getProperty(IAccountManager::PROPERTY_WEBSITE)->getVerified(), + 'twitter' => $account->getProperty(IAccountManager::PROPERTY_TWITTER)->getValue(), + 'twitterScope' => $account->getProperty(IAccountManager::PROPERTY_TWITTER)->getScope(), + 'twitterVerification' => $account->getProperty(IAccountManager::PROPERTY_TWITTER)->getVerified(), 'groups' => $this->getGroups($user), ] + $messageParameters + $languageParameters + $localeParameters; @@ -263,14 +264,14 @@ class PersonalInfo implements ISettings { } /** - * @param array $userData + * @param IAccount $account * @return array */ - private function getMessageParameters(array $userData): array { + private function getMessageParameters(IAccount $account): array { $needVerifyMessage = [IAccountManager::PROPERTY_EMAIL, IAccountManager::PROPERTY_WEBSITE, IAccountManager::PROPERTY_TWITTER]; $messageParameters = []; foreach ($needVerifyMessage as $property) { - switch ($userData[$property]['verified']) { + switch ($account->getProperty($property)->getVerified()) { case AccountManager::VERIFIED: $message = $this->l->t('Verifying'); break; diff --git a/apps/settings/lib/Settings/Personal/ServerDevNotice.php b/apps/settings/lib/Settings/Personal/ServerDevNotice.php index 1c1c870d8e9..03cea34713c 100644 --- a/apps/settings/lib/Settings/Personal/ServerDevNotice.php +++ b/apps/settings/lib/Settings/Personal/ServerDevNotice.php @@ -74,7 +74,7 @@ class ServerDevNotice implements ISettings { /** * @return TemplateResponse */ - public function getForm() { + public function getForm(): TemplateResponse { $userFolder = $this->rootFolder->getUserFolder($this->userSession->getUser()->getUID()); $hasInitialState = false; @@ -98,9 +98,9 @@ class ServerDevNotice implements ISettings { } /** - * @return string the section ID, e.g. 'sharing' + * @return string|null the section ID, e.g. 'sharing' */ - public function getSection() { + public function getSection(): ?string { if ($this->registry->delegateHasValidSubscription()) { return null; } @@ -115,7 +115,7 @@ class ServerDevNotice implements ISettings { * * E.g.: 70 */ - public function getPriority() { + public function getPriority(): int { return 1000; } } |