From 5e7723f15c7e4ba31b0a5d35d22fd3a22e45ec81 Mon Sep 17 00:00:00 2001 From: Roger Szabo Date: Fri, 31 Mar 2017 15:16:22 +0800 Subject: [PATCH] restore ldap_password_renew_pr Signed-off-by: Roger Szabo --- apps/user_ldap/ajax/wizard.php | 3 +- apps/user_ldap/appinfo/app.php | 19 +- apps/user_ldap/appinfo/register_command.php | 3 +- apps/user_ldap/appinfo/routes.php | 11 +- apps/user_ldap/css/renewPassword.css | 20 ++ apps/user_ldap/js/renewPassword.js | 50 ++++ apps/user_ldap/js/wizard/wizardTabAdvanced.js | 15 +- apps/user_ldap/lib/AppInfo/Application.php | 53 ++++ apps/user_ldap/lib/Command/Search.php | 2 +- apps/user_ldap/lib/Configuration.php | 3 + .../Controller/RenewPasswordController.php | 185 +++++++++++++ .../ConstraintViolationException.php | 2 +- apps/user_ldap/lib/Helper.php | 3 +- apps/user_ldap/lib/Jobs/CleanUp.php | 3 +- apps/user_ldap/lib/Jobs/UpdateGroups.php | 3 +- apps/user_ldap/lib/Migration/UUIDFixGroup.php | 3 +- apps/user_ldap/lib/Notification/Notifier.php | 71 +++++ apps/user_ldap/lib/Proxy.php | 5 +- apps/user_ldap/lib/User/Manager.php | 32 ++- apps/user_ldap/lib/User/User.php | 115 ++++++++- apps/user_ldap/lib/User_LDAP.php | 23 +- apps/user_ldap/lib/User_Proxy.php | 6 +- apps/user_ldap/templates/renewpassword.php | 73 ++++++ apps/user_ldap/templates/settings.php | 1 + apps/user_ldap/tests/AccessTest.php | 4 +- .../IntegrationTestFetchUsersByLoginName.php | 2 +- .../Integration/Lib/IntegrationTestPaging.php | 2 +- .../Lib/IntegrationTestUserHome.php | 2 +- .../Lib/User/IntegrationTestUserAvatar.php | 5 +- .../User/IntegrationTestUserDisplayName.php | 2 +- apps/user_ldap/tests/User/ManagerTest.php | 36 +-- apps/user_ldap/tests/User/UserTest.php | 244 ++++++++++++++---- apps/user_ldap/tests/User_LDAPTest.php | 96 +++---- apps/user_ldap/tests/User_ProxyTest.php | 5 + 34 files changed, 940 insertions(+), 162 deletions(-) create mode 100644 apps/user_ldap/css/renewPassword.css create mode 100644 apps/user_ldap/js/renewPassword.js create mode 100644 apps/user_ldap/lib/AppInfo/Application.php create mode 100644 apps/user_ldap/lib/Controller/RenewPasswordController.php create mode 100644 apps/user_ldap/lib/Notification/Notifier.php create mode 100644 apps/user_ldap/templates/renewpassword.php diff --git a/apps/user_ldap/ajax/wizard.php b/apps/user_ldap/ajax/wizard.php index 5d994f40dc..60102c72b4 100644 --- a/apps/user_ldap/ajax/wizard.php +++ b/apps/user_ldap/ajax/wizard.php @@ -58,7 +58,8 @@ $userManager = new \OCA\User_LDAP\User\Manager( \OC::$server->getAvatarManager(), new \OCP\Image(), \OC::$server->getDatabaseConnection(), - \OC::$server->getUserManager()); + \OC::$server->getUserManager(), + \OC::$server->getNotificationManager()); $access = new \OCA\User_LDAP\Access($con, $ldapWrapper, $userManager, new \OCA\User_LDAP\Helper( \OC::$server->getConfig() diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index 6f930ea39f..cbdcafc58d 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -31,6 +31,18 @@ $helper = new \OCA\User_LDAP\Helper(\OC::$server->getConfig()); $configPrefixes = $helper->getServerConfigurationPrefixes(true); $ldapWrapper = new OCA\User_LDAP\LDAP(); $ocConfig = \OC::$server->getConfig(); +$notificationManager = \OC::$server->getNotificationManager(); +$notificationManager->registerNotifier(function() { + return new \OCA\User_LDAP\Notification\Notifier( + \OC::$server->getL10NFactory() + ); +}, function() { + $l = \OC::$server->getL10N('user_ldap'); + return [ + 'id' => 'user_ldap', + 'name' => $l->t('LDAP user and group backend'), + ]; +}); if(count($configPrefixes) === 1) { $dbc = \OC::$server->getDatabaseConnection(); $userManager = new OCA\User_LDAP\User\Manager($ocConfig, @@ -39,18 +51,19 @@ if(count($configPrefixes) === 1) { \OC::$server->getAvatarManager(), new \OCP\Image(), $dbc, - \OC::$server->getUserManager() + \OC::$server->getUserManager(), + $notificationManager ); $connector = new OCA\User_LDAP\Connection($ldapWrapper, $configPrefixes[0]); $ldapAccess = new OCA\User_LDAP\Access($connector, $ldapWrapper, $userManager, $helper); $ldapAccess->setUserMapper(new OCA\User_LDAP\Mapping\UserMapping($dbc)); $ldapAccess->setGroupMapper(new OCA\User_LDAP\Mapping\GroupMapping($dbc)); - $userBackend = new OCA\User_LDAP\User_LDAP($ldapAccess, $ocConfig); + $userBackend = new OCA\User_LDAP\User_LDAP($ldapAccess, $ocConfig, $notificationManager); $groupBackend = new \OCA\User_LDAP\Group_LDAP($ldapAccess); } else if(count($configPrefixes) > 1) { $userBackend = new OCA\User_LDAP\User_Proxy( - $configPrefixes, $ldapWrapper, $ocConfig + $configPrefixes, $ldapWrapper, $ocConfig, $notificationManager ); $groupBackend = new OCA\User_LDAP\Group_Proxy($configPrefixes, $ldapWrapper); } diff --git a/apps/user_ldap/appinfo/register_command.php b/apps/user_ldap/appinfo/register_command.php index 41083f8d12..3ae8bdbfc1 100644 --- a/apps/user_ldap/appinfo/register_command.php +++ b/apps/user_ldap/appinfo/register_command.php @@ -35,7 +35,8 @@ $ocConfig = \OC::$server->getConfig(); $uBackend = new User_Proxy( $helper->getServerConfigurationPrefixes(true), new LDAP(), - $ocConfig + $ocConfig, + \OC::$server->getNotificationManager() ); $deletedUsersIndex = new DeletedUsersIndex( $ocConfig, $dbConnection, $userMapping diff --git a/apps/user_ldap/appinfo/routes.php b/apps/user_ldap/appinfo/routes.php index 45b43c2140..af355173b1 100644 --- a/apps/user_ldap/appinfo/routes.php +++ b/apps/user_ldap/appinfo/routes.php @@ -21,7 +21,6 @@ * */ -/** @var $this \OCP\Route\IRouter */ $this->create('user_ldap_ajax_clearMappings', 'ajax/clearMappings.php') ->actionInclude('user_ldap/ajax/clearMappings.php'); $this->create('user_ldap_ajax_deleteConfiguration', 'ajax/deleteConfiguration.php') @@ -46,3 +45,13 @@ $application->registerRoutes($this, [ ['name' => 'ConfigAPI#delete', 'url' => '/api/v1/config/{configID}', 'verb' => 'DELETE'], ] ]); + +$application = new OCA\User_LDAP\AppInfo\Application(); +$application->registerRoutes($this, [ + 'routes' => [ + ['name' => 'renewPassword#tryRenewPassword', 'url' => '/renewpassword', 'verb' => 'POST'], + ['name' => 'renewPassword#showRenewPasswordForm', 'url' => '/renewpassword/{user}', 'verb' => 'GET'], + ['name' => 'renewPassword#cancel', 'url' => '/renewpassword/cancel', 'verb' => 'GET'], + ['name' => 'renewPassword#showLoginFormInvalidPassword', 'url' => '/renewpassword/invalidlogin/{user}', 'verb' => 'GET'], + ] +]); diff --git a/apps/user_ldap/css/renewPassword.css b/apps/user_ldap/css/renewPassword.css new file mode 100644 index 0000000000..a06a101efe --- /dev/null +++ b/apps/user_ldap/css/renewPassword.css @@ -0,0 +1,20 @@ +#personal-show + label { + left: 222px !important; + margin-top: 3px !important; +} + +#renewpassword .strengthify-wrapper { + left: 10px; + margin-top: 65px; + position: absolute; + width: 219px; +} + +#cancel-container p.info { + margin-top: 10px; + text-align: center; +} + +#renewpassword .title { + background-color: transparent; +} diff --git a/apps/user_ldap/js/renewPassword.js b/apps/user_ldap/js/renewPassword.js new file mode 100644 index 0000000000..bea2c0409f --- /dev/null +++ b/apps/user_ldap/js/renewPassword.js @@ -0,0 +1,50 @@ +/** + * + * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de) + * + * @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 . + * + */ + +OCA = OCA || {}; +OCA.LDAP = _.extend(OC.LDAP || {}, { + onRenewPassword: function () { + $('#submit') + .removeClass('icon-confirm-white') + .addClass('icon-loading-small') + .attr('value', t('core', 'Renewing …')); + return true; + }, +}); + +$(document).ready(function() { + $('form[name=renewpassword]').submit(OCA.LDAP.onRenewPassword); + + if($('#newPassword').length) { + $('#newPassword').showPassword().keyup(); + } + $('#newPassword').strengthify({ + zxcvbn: OC.linkTo('core','vendor/zxcvbn/dist/zxcvbn.js'), + titles: [ + t('core', 'Very weak password'), + t('core', 'Weak password'), + t('core', 'So-so password'), + t('core', 'Good password'), + t('core', 'Strong password') + ], + drawTitles: true, + }); +}); diff --git a/apps/user_ldap/js/wizard/wizardTabAdvanced.js b/apps/user_ldap/js/wizard/wizardTabAdvanced.js index d0922bbff3..c4dfb3e85a 100644 --- a/apps/user_ldap/js/wizard/wizardTabAdvanced.js +++ b/apps/user_ldap/js/wizard/wizardTabAdvanced.js @@ -99,6 +99,10 @@ OCA = OCA || {}; $element: $('#ldap_turn_on_pwd_change'), setMethod: 'setPasswordChangeEnabled' }, + ldap_default_ppolicy_dn: { + $element: $('#ldap_default_ppolicy_dn'), + setMethod: 'setDefaultPPolicyDN' + }, //Special Attributes ldap_quota_attr: { @@ -292,7 +296,7 @@ OCA = OCA || {}; setPagingSize: function(size) { this.setElementValue(this.managedItems.ldap_paging_size.$element, size); }, - + /** * sets whether the password changes per user should be enabled * @@ -304,6 +308,15 @@ OCA = OCA || {}; ); }, + /** + * sets the default ppolicy attribute + * + * @param {string} attribute + */ + setDefaultPPolicyDN: function(attribute) { + this.setElementValue(this.managedItems.ldap_default_ppolicy_dn.$element, attribute); + }, + /** * sets the email attribute * diff --git a/apps/user_ldap/lib/AppInfo/Application.php b/apps/user_ldap/lib/AppInfo/Application.php new file mode 100644 index 0000000000..7932984a7d --- /dev/null +++ b/apps/user_ldap/lib/AppInfo/Application.php @@ -0,0 +1,53 @@ + + * + * @author Roger Szabo + * + * @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 . + * + */ + +namespace OCA\User_LDAP\AppInfo; + +use OCA\User_LDAP\Controller\RenewPasswordController; +use OCP\AppFramework\App; +use OCP\AppFramework\IAppContainer; + +class Application extends App { + public function __construct () { + parent::__construct('user_ldap'); + $container = $this->getContainer(); + + /** + * Controller + */ + $container->registerService('RenewPasswordController', function(IAppContainer $c) { + /** @var \OC\Server $server */ + $server = $c->query('ServerContainer'); + + return new RenewPasswordController( + $c->getAppName(), + $server->getRequest(), + $c->query('UserManager'), + $server->getConfig(), + $c->query('OCP\IL10N'), + //$c->query('Session'), + $server->getURLGenerator() + ); + }); + } +} diff --git a/apps/user_ldap/lib/Command/Search.php b/apps/user_ldap/lib/Command/Search.php index 57970b1ac5..463ad2eaeb 100644 --- a/apps/user_ldap/lib/Command/Search.php +++ b/apps/user_ldap/lib/Command/Search.php @@ -120,7 +120,7 @@ class Search extends Command { $limit = null; } } else { - $proxy = new User_Proxy($configPrefixes, $ldapWrapper, $this->ocConfig); + $proxy = new User_Proxy($configPrefixes, $ldapWrapper, $this->ocConfig, \OC::$server->getNotificationManager()); $getMethod = 'getDisplayNames'; $printID = true; } diff --git a/apps/user_ldap/lib/Configuration.php b/apps/user_ldap/lib/Configuration.php index 65ee9c7080..654a63cdc7 100644 --- a/apps/user_ldap/lib/Configuration.php +++ b/apps/user_ldap/lib/Configuration.php @@ -93,6 +93,7 @@ class Configuration { 'ldapPagingSize' => null, 'turnOnPasswordChange' => false, 'ldapDynamicGroupMemberURL' => null, + 'ldapDefaultPPolicyDN' => null, ); /** @@ -457,6 +458,7 @@ class Configuration { 'ldap_turn_on_pwd_change' => 0, 'ldap_experienced_admin' => 0, 'ldap_dynamic_group_member_url' => '', + 'ldap_default_ppolicy_dn' => '', ); } @@ -514,6 +516,7 @@ class Configuration { 'ldap_turn_on_pwd_change' => 'turnOnPasswordChange', 'ldap_experienced_admin' => 'ldapExperiencedAdmin', 'ldap_dynamic_group_member_url' => 'ldapDynamicGroupMemberURL', + 'ldap_default_ppolicy_dn' => 'ldapDefaultPPolicyDN', ); return $array; } diff --git a/apps/user_ldap/lib/Controller/RenewPasswordController.php b/apps/user_ldap/lib/Controller/RenewPasswordController.php new file mode 100644 index 0000000000..79708e99fa --- /dev/null +++ b/apps/user_ldap/lib/Controller/RenewPasswordController.php @@ -0,0 +1,185 @@ + + * + * @author Roger Szabo + * + * @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 . + * + */ + +namespace OCA\User_LDAP\Controller; + +use OC\HintException; +use OC_Util; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\RedirectResponse; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IL10N; +use OCP\IRequest; +use OCP\ISession; +use OCP\IURLGenerator; +use OCP\IUser; +use OCP\IUserManager; + +class RenewPasswordController extends Controller { + /** @var IUserManager */ + private $userManager; + /** @var IConfig */ + private $config; + /** @var IL10N */ + protected $l10n; + /** @var ISession */ + private $session; + /** @var IURLGenerator */ + private $urlGenerator; + + /** + * @param string $appName + * @param IRequest $request + * @param IUserManager $userManager + * @param IConfig $config + * @param IURLGenerator $urlGenerator + */ + function __construct($appName, + IRequest $request, + IUserManager $userManager, + IConfig $config, + IL10N $l10n, + ISession $session, + IURLGenerator $urlGenerator) { + parent::__construct($appName, $request); + $this->userManager = $userManager; + $this->config = $config; + $this->l10n = $l10n; + $this->session = $session; + $this->urlGenerator = $urlGenerator; + } + + /** + * @PublicPage + * @NoCSRFRequired + * + * @return RedirectResponse + */ + public function cancel() { + return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); + } + + /** + * @PublicPage + * @NoCSRFRequired + * @UseSession + * + * @param string $user + * + * @return TemplateResponse|RedirectResponse + */ + public function showRenewPasswordForm($user) { + if($this->config->getUserValue($user, 'user_ldap', 'needsPasswordReset') !== 'true') { + return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); + } + $parameters = array(); + $renewPasswordMessages = $this->session->get('renewPasswordMessages'); + $errors = []; + $messages = []; + if (is_array($renewPasswordMessages)) { + list($errors, $messages) = $renewPasswordMessages; + } + $this->session->remove('renewPasswordMessages'); + foreach ($errors as $value) { + $parameters[$value] = true; + } + + $parameters['messages'] = $messages; + $parameters['user'] = $user; + + $parameters['canResetPassword'] = true; + $parameters['resetPasswordLink'] = $this->config->getSystemValue('lost_password_link', ''); + if (!$parameters['resetPasswordLink']) { + $userObj = $this->userManager->get($user); + if ($userObj instanceof IUser) { + $parameters['canResetPassword'] = $userObj->canChangePassword(); + } + } + $parameters['cancelLink'] = $this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'); + + return new TemplateResponse( + $this->appName, 'renewpassword', $parameters, 'guest' + ); + } + + /** + * @PublicPage + * @UseSession + * + * @param string $user + * @param string $oldPassword + * @param string $newPassword + * + * @return RedirectResponse + */ + public function tryRenewPassword($user, $oldPassword, $newPassword) { + if($this->config->getUserValue($user, 'user_ldap', 'needsPasswordReset') !== 'true') { + return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); + } + $args = !is_null($user) ? ['user' => $user] : []; + $loginResult = $this->userManager->checkPassword($user, $oldPassword); + if ($loginResult === false) { + $this->session->set('renewPasswordMessages', [ + ['invalidpassword'], [] + ]); + return new RedirectResponse($this->urlGenerator->linkToRoute('user_ldap.renewPassword.showRenewPasswordForm', $args)); + } + + try { + if (!is_null($newPassword) && \OC_User::setPassword($user, $newPassword)) { + $this->session->set('loginMessages', [ + [], [$this->l10n->t("Please login with the new password")] + ]); + $this->session->remove('needPasswordRenewal'); + return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args)); + } else { + $this->session->set('renewPasswordMessages', [ + ['internalexception'], [] + ]); + } + } catch (HintException $e) { + $this->session->set('renewPasswordMessages', [ + [], [$e->getHint()] + ]); + } + + return new RedirectResponse($this->urlGenerator->linkToRoute('user_ldap.renewPassword.showRenewPasswordForm', $args)); + } + + /** + * @PublicPage + * @NoCSRFRequired + * @UseSession + * + * @return RedirectResponse + */ + public function showLoginFormInvalidPassword($user) { + $args = !is_null($user) ? ['user' => $user] : []; + $this->session->set('loginMessages', [ + ['invalidpassword'], [] + ]); + return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args)); + } + +} diff --git a/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php b/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php index 997b01b2d4..586a80b9eb 100644 --- a/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php +++ b/apps/user_ldap/lib/Exceptions/ConstraintViolationException.php @@ -1,6 +1,6 @@ + * @copyright Copyright (c) 2017 Roger Szabo * * @author Roger Szabo * diff --git a/apps/user_ldap/lib/Helper.php b/apps/user_ldap/lib/Helper.php index f1186ffa31..83b2f05f1d 100644 --- a/apps/user_ldap/lib/Helper.php +++ b/apps/user_ldap/lib/Helper.php @@ -293,9 +293,10 @@ class Helper { $configPrefixes = $helper->getServerConfigurationPrefixes(true); $ldapWrapper = new LDAP(); $ocConfig = \OC::$server->getConfig(); + $notificationManager = \OC::$server->getNotificationManager(); $userBackend = new User_Proxy( - $configPrefixes, $ldapWrapper, $ocConfig + $configPrefixes, $ldapWrapper, $ocConfig, $notificationManager ); $uid = $userBackend->loginName2UserName($param['uid'] ); if($uid !== false) { diff --git a/apps/user_ldap/lib/Jobs/CleanUp.php b/apps/user_ldap/lib/Jobs/CleanUp.php index e69d24dfd0..a4dd4ba32a 100644 --- a/apps/user_ldap/lib/Jobs/CleanUp.php +++ b/apps/user_ldap/lib/Jobs/CleanUp.php @@ -98,7 +98,8 @@ class CleanUp extends TimedJob { $this->userBackend = new User_Proxy( $this->ldapHelper->getServerConfigurationPrefixes(true), new LDAP(), - $this->ocConfig + $this->ocConfig, + \OC::$server->getNotificationManager() ); } diff --git a/apps/user_ldap/lib/Jobs/UpdateGroups.php b/apps/user_ldap/lib/Jobs/UpdateGroups.php index b4259425fc..4c9a06a5f6 100644 --- a/apps/user_ldap/lib/Jobs/UpdateGroups.php +++ b/apps/user_ldap/lib/Jobs/UpdateGroups.php @@ -185,7 +185,8 @@ class UpdateGroups extends \OC\BackgroundJob\TimedJob { \OC::$server->getAvatarManager(), new \OCP\Image(), $dbc, - \OC::$server->getUserManager()); + \OC::$server->getUserManager(), + \OC::$server->getNotificationManager()); $connector = new Connection($ldapWrapper, $configPrefixes[0]); $ldapAccess = new Access($connector, $ldapWrapper, $userManager, $helper); $groupMapper = new GroupMapping($dbc); diff --git a/apps/user_ldap/lib/Migration/UUIDFixGroup.php b/apps/user_ldap/lib/Migration/UUIDFixGroup.php index cbc3836698..6aacb37257 100644 --- a/apps/user_ldap/lib/Migration/UUIDFixGroup.php +++ b/apps/user_ldap/lib/Migration/UUIDFixGroup.php @@ -32,6 +32,7 @@ use OCP\IConfig; class UUIDFixGroup extends UUIDFix { public function __construct(GroupMapping $mapper, LDAP $ldap, IConfig $config, Helper $helper) { $this->mapper = $mapper; - $this->proxy = new User_Proxy($helper->getServerConfigurationPrefixes(true), $ldap, $config); + $this->proxy = new User_Proxy($helper->getServerConfigurationPrefixes(true), $ldap, $config, + \OC::$server->getNotificationManager()); } } diff --git a/apps/user_ldap/lib/Notification/Notifier.php b/apps/user_ldap/lib/Notification/Notifier.php new file mode 100644 index 0000000000..a6053cfcb1 --- /dev/null +++ b/apps/user_ldap/lib/Notification/Notifier.php @@ -0,0 +1,71 @@ + + * + * @author Roger Szabo + * + * @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 . + * + */ + +namespace OCA\User_LDAP\Notification; + + +use OCP\IUser; +use OCP\IUserManager; +use OCP\L10N\IFactory; +use OCP\Notification\INotification; +use OCP\Notification\INotifier; + +class Notifier implements INotifier { + + /** @var IFactory */ + protected $l10nFactory; + + /** + * @param IFactory $l10nFactory + */ + public function __construct(\OCP\L10N\IFactory $l10nFactory) { + $this->l10nFactory = $l10nFactory; + } + + /** + * @param INotification $notification + * @param string $languageCode The code of the language that should be used to prepare the notification + * @return INotification + * @throws \InvalidArgumentException When the notification was not prepared by a notifier + */ + public function prepare(INotification $notification, $languageCode) { + if ($notification->getApp() !== 'user_ldap') { + // Not my app => throw + throw new \InvalidArgumentException(); + } + + // Read the language from the notification + $l = $this->l10nFactory->get('user_ldap', $languageCode); + + switch ($notification->getSubject()) { + // Deal with known subjects + case 'pwd_exp_warn_days': + $notification->setParsedSubject($l->t('Your password will expire within %s day(s).', $notification->getSubjectParameters())); + return $notification; + + default: + // Unknown subject => Unknown notification => throw + throw new \InvalidArgumentException(); + } + } +} diff --git a/apps/user_ldap/lib/Proxy.php b/apps/user_ldap/lib/Proxy.php index 7f998314e2..96bb670b78 100644 --- a/apps/user_ldap/lib/Proxy.php +++ b/apps/user_ldap/lib/Proxy.php @@ -64,6 +64,7 @@ abstract class Proxy { static $groupMap; static $db; static $coreUserManager; + static $coreNotificationManager; if(is_null($fs)) { $ocConfig = \OC::$server->getConfig(); $fs = new FilesystemHelper(); @@ -73,9 +74,11 @@ abstract class Proxy { $userMap = new UserMapping($db); $groupMap = new GroupMapping($db); $coreUserManager = \OC::$server->getUserManager(); + $coreNotificationManager = \OC::$server->getNotificationManager(); } $userManager = - new Manager($ocConfig, $fs, $log, $avatarM, new \OCP\Image(), $db, $coreUserManager); + new Manager($ocConfig, $fs, $log, $avatarM, new \OCP\Image(), $db, + $coreUserManager, $coreNotificationManager); $connector = new Connection($this->ldap, $configPrefix); $access = new Access($connector, $this->ldap, $userManager, new Helper(\OC::$server->getConfig())); $access->setUserMapper($userMap); diff --git a/apps/user_ldap/lib/User/Manager.php b/apps/user_ldap/lib/User/Manager.php index 1a9138176b..3887d7cae1 100644 --- a/apps/user_ldap/lib/User/Manager.php +++ b/apps/user_ldap/lib/User/Manager.php @@ -34,6 +34,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\Image; use OCP\IUserManager; +use OCP\Notification\IManager as INotificationManager; /** * Manager @@ -51,6 +52,12 @@ class Manager { /** @var IDBConnection */ protected $db; + /** @var IUserManager */ + protected $userManager; + + /** @var INotificationManager */ + protected $notificationManager; + /** @var FilesystemHelper */ protected $ocFilesystem; @@ -85,17 +92,19 @@ class Manager { public function __construct(IConfig $ocConfig, FilesystemHelper $ocFilesystem, LogWrapper $ocLog, IAvatarManager $avatarManager, Image $image, - IDBConnection $db, IUserManager $userManager) { + IDBConnection $db, IUserManager $userManager, + INotificationManager $notificationManager) { - $this->ocConfig = $ocConfig; - $this->ocFilesystem = $ocFilesystem; - $this->ocLog = $ocLog; - $this->avatarManager = $avatarManager; - $this->image = $image; - $this->db = $db; - $this->userManager = $userManager; - $this->usersByDN = new CappedMemoryCache(); - $this->usersByUid = new CappedMemoryCache(); + $this->ocConfig = $ocConfig; + $this->ocFilesystem = $ocFilesystem; + $this->ocLog = $ocLog; + $this->avatarManager = $avatarManager; + $this->image = $image; + $this->db = $db; + $this->userManager = $userManager; + $this->notificationManager = $notificationManager; + $this->usersByDN = new CappedMemoryCache(); + $this->usersByUid = new CappedMemoryCache(); } /** @@ -118,7 +127,8 @@ class Manager { $this->checkAccess(); $user = new User($uid, $dn, $this->access, $this->ocConfig, $this->ocFilesystem, clone $this->image, $this->ocLog, - $this->avatarManager, $this->userManager); + $this->avatarManager, $this->userManager, + $this->notificationManager); $this->usersByDN[$dn] = $user; $this->usersByUid[$uid] = $user; return $user; diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php index 5d4af1fd09..24abab7b46 100644 --- a/apps/user_ldap/lib/User/User.php +++ b/apps/user_ldap/lib/User/User.php @@ -7,6 +7,7 @@ * @author Morris Jobke * @author Thomas Müller * @author Jörn Friedrich Dreyer + * @author Roger Szabo * * @license AGPL-3.0 * @@ -34,6 +35,7 @@ use OCP\IConfig; use OCP\Image; use OCP\IUserManager; use OCP\Util; +use OCP\Notification\IManager as INotificationManager; /** * User @@ -73,6 +75,10 @@ class User { * @var IUserManager */ protected $userManager; + /** + * @var INotificationManager + */ + protected $notificationManager; /** * @var string */ @@ -108,11 +114,13 @@ class User { * @param LogWrapper $log * @param IAvatarManager $avatarManager * @param IUserManager $userManager + * @param INotificationManager $notificationManager */ public function __construct($username, $dn, IUserTools $access, IConfig $config, FilesystemHelper $fs, Image $image, - LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager) { - + LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager, + INotificationManager $notificationManager) { + if ($username === null) { $log->log("uid for '$dn' must not be null!", Util::ERROR); throw new \InvalidArgumentException('uid must not be null!'); @@ -121,16 +129,19 @@ class User { throw new \InvalidArgumentException('uid must not be an empty string!'); } - $this->access = $access; - $this->connection = $access->getConnection(); - $this->config = $config; - $this->fs = $fs; - $this->dn = $dn; - $this->uid = $username; - $this->image = $image; - $this->log = $log; - $this->avatarManager = $avatarManager; - $this->userManager = $userManager; + $this->access = $access; + $this->connection = $access->getConnection(); + $this->config = $config; + $this->fs = $fs; + $this->dn = $dn; + $this->uid = $username; + $this->image = $image; + $this->log = $log; + $this->avatarManager = $avatarManager; + $this->userManager = $userManager; + $this->notificationManager = $notificationManager; + + \OCP\Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry'); } /** @@ -587,4 +598,84 @@ class User { } } + /** + * called by a post_login hook to handle password expiry + * + * @param array $params + */ + public function handlePasswordExpiry($params) { + $ppolicyDN = $this->connection->ldapDefaultPPolicyDN; + if (empty($ppolicyDN) || (intval($this->connection->turnOnPasswordChange) !== 1)) { + return;//password expiry handling disabled + } + $uid = $params['uid']; + if(isset($uid) && $uid === $this->getUsername()) { + //handle grace login + $pwdGraceUseTime = $this->access->readAttribute($this->dn, 'pwdGraceUseTime'); + $pwdGraceUseTimeCount = count($pwdGraceUseTime); + if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login? + $pwdGraceAuthNLimit = $this->access->readAttribute($ppolicyDN, 'pwdGraceAuthNLimit'); + if($pwdGraceAuthNLimit + && (count($pwdGraceAuthNLimit) > 0) + &&($pwdGraceUseTimeCount < intval($pwdGraceAuthNLimit[0]))) { //at least one more grace login available? + $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true'); + header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute( + 'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid))); + } else { //no more grace login available + header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute( + 'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid))); + } + exit(); + } + //handle pwdReset attribute + $pwdReset = $this->access->readAttribute($this->dn, 'pwdReset'); + if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password + $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true'); + header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute( + 'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid))); + exit(); + } + //handle password expiry warning + $pwdChangedTime = $this->access->readAttribute($this->dn, 'pwdChangedTime');//for efficiency read only 1 attribute first + if($pwdChangedTime && (count($pwdChangedTime) > 0)) { + $pwdPolicySubentry = $this->access->readAttribute($this->dn, 'pwdPolicySubentry'); + if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){ + $ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN + } + $pwdMaxAge = $this->access->readAttribute($ppolicyDN, 'pwdMaxAge'); + $pwdExpireWarning = $this->access->readAttribute($ppolicyDN, 'pwdExpireWarning'); + if($pwdMaxAge && (count($pwdMaxAge) > 0) + && $pwdExpireWarning && (count($pwdExpireWarning) > 0)) { + $pwdMaxAgeInt = intval($pwdMaxAge[0]); + $pwdExpireWarningInt = intval($pwdExpireWarning[0]); + //pwdMaxAge=0 -> password never expires + //pwdExpireWarning=0 -> don't warn about expiry + if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){ + $pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]); + $pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S')); + $currentDateTime = new \DateTime(); + $secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp(); + if($secondsToExpiry <= $pwdExpireWarningInt) { + //remove last password expiry warning if any + $notification = $this->notificationManager->createNotification(); + $notification->setApp('user_ldap') + ->setUser($uid) + ->setObject('pwd_exp_warn', $uid) + ; + $this->notificationManager->markProcessed($notification); + //create new password expiry warning + $notification = $this->notificationManager->createNotification(); + $notification->setApp('user_ldap') + ->setUser($uid) + ->setDateTime($currentDateTime) + ->setObject('pwd_exp_warn', $uid) + ->setSubject('pwd_exp_warn_days', [strval(ceil($secondsToExpiry / 60 / 60 / 24))]) + ; + $this->notificationManager->notify($notification); + } + } + } + } + } + } } diff --git a/apps/user_ldap/lib/User_LDAP.php b/apps/user_ldap/lib/User_LDAP.php index cfd2450a12..8fbbd4e394 100644 --- a/apps/user_ldap/lib/User_LDAP.php +++ b/apps/user_ldap/lib/User_LDAP.php @@ -41,6 +41,7 @@ use OCA\User_LDAP\Exceptions\NotOnLDAP; use OCA\User_LDAP\User\OfflineUser; use OCA\User_LDAP\User\User; use OCP\IConfig; +use OCP\Notification\IManager as INotificationManager; use OCP\Util; class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP { @@ -50,13 +51,18 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn /** @var \OCP\IConfig */ protected $ocConfig; + /** @var INotificationManager */ + protected $notificationManager; + /** * @param Access $access * @param \OCP\IConfig $ocConfig + * @param \OCP\Notification\IManager $notificationManager */ - public function __construct(Access $access, IConfig $ocConfig) { + public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager) { parent::__construct($access); $this->ocConfig = $ocConfig; + $this->notificationManager = $notificationManager; } /** @@ -190,8 +196,19 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid . '. Maybe the LDAP entry has no set display name attribute?'); } - if($user->getUsername() !== false) { - return $this->access->setPassword($user->getDN(), $password); + if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) { + $ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN; + $turnOnPasswordChange = $this->access->connection->turnOnPasswordChange; + if (!empty($ldapDefaultPPolicyDN) && (intval($turnOnPasswordChange) === 1)) { + //remove last password expiry warning if any + $notification = $this->notificationManager->createNotification(); + $notification->setApp('user_ldap') + ->setUser($uid) + ->setObject('pwd_exp_warn', $uid) + ; + $this->notificationManager->markProcessed($notification); + } + return true; } return false; diff --git a/apps/user_ldap/lib/User_Proxy.php b/apps/user_ldap/lib/User_Proxy.php index 2cdf401880..8b058ba6f6 100644 --- a/apps/user_ldap/lib/User_Proxy.php +++ b/apps/user_ldap/lib/User_Proxy.php @@ -31,6 +31,7 @@ namespace OCA\User_LDAP; use OCA\User_LDAP\User\User; use OCP\IConfig; +use OCP\Notification\IManager as INotificationManager; class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP { private $backends = array(); @@ -40,11 +41,12 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, * Constructor * @param array $serverConfigPrefixes array containing the config Prefixes */ - public function __construct(array $serverConfigPrefixes, ILDAPWrapper $ldap, IConfig $ocConfig) { + public function __construct(array $serverConfigPrefixes, ILDAPWrapper $ldap, IConfig $ocConfig, + INotificationManager $notificationManager) { parent::__construct($ldap); foreach($serverConfigPrefixes as $configPrefix) { $this->backends[$configPrefix] = - new User_LDAP($this->getAccess($configPrefix), $ocConfig); + new User_LDAP($this->getAccess($configPrefix), $ocConfig, $notificationManager); if(is_null($this->refBackend)) { $this->refBackend = &$this->backends[$configPrefix]; } diff --git a/apps/user_ldap/templates/renewpassword.php b/apps/user_ldap/templates/renewpassword.php new file mode 100644 index 0000000000..7b1df75e06 --- /dev/null +++ b/apps/user_ldap/templates/renewpassword.php @@ -0,0 +1,73 @@ + + + + +
+
+
+ t('Please renew your password.')); ?>
+
+ +
+
+
+ + +
+ t('An internal error occurred.')); ?>
+ t('Please try again or contact your administrator.')); ?> +
+ + +

+ + +

+ +

+ + + +

+ + + + + + t('Wrong password. Reset it?')); ?> + + +

+ t('Wrong password.')); ?> +

+ +

+ + t('Cancel')); ?> + +

+ + +
+
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 6942b2eb2b..0d4ca804dd 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -103,6 +103,7 @@ style('user_ldap', 'settings');

t('(New password is sent as plain text to LDAP)'));?>

+

t('Special Attributes'));?>

diff --git a/apps/user_ldap/tests/AccessTest.php b/apps/user_ldap/tests/AccessTest.php index 271e8eb605..85f0516dec 100644 --- a/apps/user_ldap/tests/AccessTest.php +++ b/apps/user_ldap/tests/AccessTest.php @@ -42,6 +42,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\Image; use OCP\IUserManager; +use OCP\Notification\IManager as INotificationManager; /** * Class AccessTest @@ -89,7 +90,8 @@ class AccessTest extends \Test\TestCase { $this->createMock(IAvatarManager::class), $this->createMock(Image::class), $this->createMock(IDBConnection::class), - $this->createMock(IUserManager::class)]) + $this->createMock(IUserManager::class), + $this->createMock(INotificationManager::class)]) ->getMock(); $helper = new Helper(\OC::$server->getConfig()); diff --git a/apps/user_ldap/tests/Integration/Lib/IntegrationTestFetchUsersByLoginName.php b/apps/user_ldap/tests/Integration/Lib/IntegrationTestFetchUsersByLoginName.php index 32fc2151a7..25b7cf83f9 100644 --- a/apps/user_ldap/tests/Integration/Lib/IntegrationTestFetchUsersByLoginName.php +++ b/apps/user_ldap/tests/Integration/Lib/IntegrationTestFetchUsersByLoginName.php @@ -47,7 +47,7 @@ class IntegrationTestFetchUsersByLoginName extends AbstractIntegrationTest { $this->mapping = new UserMapping(\OC::$server->getDatabaseConnection()); $this->mapping->clear(); $this->access->setUserMapper($this->mapping); - $this->backend = new \OCA\User_LDAP\User_LDAP($this->access, \OC::$server->getConfig()); + $this->backend = new \OCA\User_LDAP\User_LDAP($this->access, \OC::$server->getConfig(), \OC::$server->getNotificationManager()); } /** diff --git a/apps/user_ldap/tests/Integration/Lib/IntegrationTestPaging.php b/apps/user_ldap/tests/Integration/Lib/IntegrationTestPaging.php index 3826cbdae5..2f14b0d1c1 100644 --- a/apps/user_ldap/tests/Integration/Lib/IntegrationTestPaging.php +++ b/apps/user_ldap/tests/Integration/Lib/IntegrationTestPaging.php @@ -44,7 +44,7 @@ class IntegrationTestPaging extends AbstractIntegrationTest { require(__DIR__ . '/../setup-scripts/createExplicitUsers.php'); parent::init(); - $this->backend = new \OCA\User_LDAP\User_LDAP($this->access, \OC::$server->getConfig()); + $this->backend = new \OCA\User_LDAP\User_LDAP($this->access, \OC::$server->getConfig(), \OC::$server->getNotificationManager()); } /** diff --git a/apps/user_ldap/tests/Integration/Lib/IntegrationTestUserHome.php b/apps/user_ldap/tests/Integration/Lib/IntegrationTestUserHome.php index 2200ac327a..c054ae495b 100644 --- a/apps/user_ldap/tests/Integration/Lib/IntegrationTestUserHome.php +++ b/apps/user_ldap/tests/Integration/Lib/IntegrationTestUserHome.php @@ -48,7 +48,7 @@ class IntegrationTestUserHome extends AbstractIntegrationTest { $this->mapping = new UserMapping(\OC::$server->getDatabaseConnection()); $this->mapping->clear(); $this->access->setUserMapper($this->mapping); - $this->backend = new \OCA\User_LDAP\User_LDAP($this->access, \OC::$server->getConfig()); + $this->backend = new \OCA\User_LDAP\User_LDAP($this->access, \OC::$server->getConfig(), \OC::$server->getNotificationManager()); } /** diff --git a/apps/user_ldap/tests/Integration/Lib/User/IntegrationTestUserAvatar.php b/apps/user_ldap/tests/Integration/Lib/User/IntegrationTestUserAvatar.php index 7c8f9475b4..3fb5a67591 100644 --- a/apps/user_ldap/tests/Integration/Lib/User/IntegrationTestUserAvatar.php +++ b/apps/user_ldap/tests/Integration/Lib/User/IntegrationTestUserAvatar.php @@ -45,7 +45,7 @@ class IntegrationTestUserAvatar extends AbstractIntegrationTest { $this->mapping = new UserMapping(\OC::$server->getDatabaseConnection()); $this->mapping->clear(); $this->access->setUserMapper($this->mapping); - $userBackend = new \OCA\User_LDAP\User_LDAP($this->access, \OC::$server->getConfig()); + $userBackend = new \OCA\User_LDAP\User_LDAP($this->access, \OC::$server->getConfig(), \OC::$server->getNotificationManager()); \OC_User::useBackend($userBackend); } @@ -130,7 +130,8 @@ class IntegrationTestUserAvatar extends AbstractIntegrationTest { \OC::$server->getAvatarManager(), new \OCP\Image(), \OC::$server->getDatabaseConnection(), - \OC::$server->getUserManager() + \OC::$server->getUserManager(), + \OC::$server->getNotificationManager() ); } diff --git a/apps/user_ldap/tests/Integration/Lib/User/IntegrationTestUserDisplayName.php b/apps/user_ldap/tests/Integration/Lib/User/IntegrationTestUserDisplayName.php index d0444daca5..616bf410e0 100644 --- a/apps/user_ldap/tests/Integration/Lib/User/IntegrationTestUserDisplayName.php +++ b/apps/user_ldap/tests/Integration/Lib/User/IntegrationTestUserDisplayName.php @@ -43,7 +43,7 @@ class IntegrationTestUserDisplayName extends AbstractIntegrationTest { $this->mapping = new UserMapping(\OC::$server->getDatabaseConnection()); $this->mapping->clear(); $this->access->setUserMapper($this->mapping); - $userBackend = new User_LDAP($this->access, \OC::$server->getConfig()); + $userBackend = new User_LDAP($this->access, \OC::$server->getConfig(), \OC::$server->getNotificationManager()); \OC_User::useBackend($userBackend); } diff --git a/apps/user_ldap/tests/User/ManagerTest.php b/apps/user_ldap/tests/User/ManagerTest.php index 16d6a3d9d6..823081f1da 100644 --- a/apps/user_ldap/tests/User/ManagerTest.php +++ b/apps/user_ldap/tests/User/ManagerTest.php @@ -36,6 +36,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\Image; use OCP\IUserManager; +use OCP\Notification\IManager as INotificationManager; /** * Class Test_User_Manager @@ -55,6 +56,7 @@ class ManagerTest extends \Test\TestCase { $image = $this->createMock(Image::class); $dbc = $this->createMock(IDBConnection::class); $userMgr = $this->createMock(IUserManager::class); + $notiMgr = $this->createMock(INotificationManager::class); $connection = new \OCA\User_LDAP\Connection( $lw = $this->createMock(ILDAPWrapper::class), @@ -66,11 +68,11 @@ class ManagerTest extends \Test\TestCase { ->method('getConnection') ->will($this->returnValue($connection)); - return array($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr); + return array($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr); } public function testGetByDNExisting() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); $inputDN = 'cn=foo,dc=foobar,dc=bar'; @@ -89,7 +91,7 @@ class ManagerTest extends \Test\TestCase { $access->expects($this->never()) ->method('username2dn'); - $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr); + $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr); $manager->setLdapAccess($access); $user = $manager->get($inputDN); @@ -101,7 +103,7 @@ class ManagerTest extends \Test\TestCase { } public function testGetByEDirectoryDN() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); $inputDN = 'uid=foo,o=foobar,c=bar'; @@ -120,7 +122,7 @@ class ManagerTest extends \Test\TestCase { $access->expects($this->never()) ->method('username2dn'); - $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr); + $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr); $manager->setLdapAccess($access); $user = $manager->get($inputDN); @@ -128,7 +130,7 @@ class ManagerTest extends \Test\TestCase { } public function testGetByExoticDN() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); $inputDN = 'ab=cde,f=ghei,mno=pq'; @@ -147,7 +149,7 @@ class ManagerTest extends \Test\TestCase { $access->expects($this->never()) ->method('username2dn'); - $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr); + $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr); $manager->setLdapAccess($access); $user = $manager->get($inputDN); @@ -155,7 +157,7 @@ class ManagerTest extends \Test\TestCase { } public function testGetByDNNotExisting() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); $inputDN = 'cn=gone,dc=foobar,dc=bar'; @@ -175,7 +177,7 @@ class ManagerTest extends \Test\TestCase { ->with($this->equalTo($inputDN)) ->will($this->returnValue(false)); - $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr); + $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr); $manager->setLdapAccess($access); $user = $manager->get($inputDN); @@ -183,7 +185,7 @@ class ManagerTest extends \Test\TestCase { } public function testGetByUidExisting() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); $dn = 'cn=foo,dc=foobar,dc=bar'; @@ -202,7 +204,7 @@ class ManagerTest extends \Test\TestCase { ->with($this->equalTo($uid)) ->will($this->returnValue(false)); - $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr); + $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr); $manager->setLdapAccess($access); $user = $manager->get($uid); @@ -214,7 +216,7 @@ class ManagerTest extends \Test\TestCase { } public function testGetByUidNotExisting() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); $uid = 'gone'; @@ -227,7 +229,7 @@ class ManagerTest extends \Test\TestCase { ->with($this->equalTo($uid)) ->will($this->returnValue(false)); - $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr); + $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr); $manager->setLdapAccess($access); $user = $manager->get($uid); @@ -235,10 +237,10 @@ class ManagerTest extends \Test\TestCase { } public function testGetAttributesAll() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); - $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr); + $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr); $manager->setLdapAccess($access); $connection = $access->getConnection(); @@ -253,10 +255,10 @@ class ManagerTest extends \Test\TestCase { } public function testGetAttributesMinimal() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); - $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr); + $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr); $manager->setLdapAccess($access); $attributes = $manager->getAttributes(true); diff --git a/apps/user_ldap/tests/User/UserTest.php b/apps/user_ldap/tests/User/UserTest.php index 6961e39d9f..6a12fc2c87 100644 --- a/apps/user_ldap/tests/User/UserTest.php +++ b/apps/user_ldap/tests/User/UserTest.php @@ -37,6 +37,7 @@ use OCP\IDBConnection; use OCP\Image; use OCP\IUser; use OCP\IUserManager; +use OCP\Notification\IManager as INotificationManager; /** * Class UserTest @@ -56,11 +57,12 @@ class UserTest extends \Test\TestCase { $image = $this->createMock(Image::class); $dbc = $this->createMock(IDBConnection::class); $userMgr = $this->createMock(IUserManager::class); + $notiMgr = $this->createMock(INotificationManager::class); - return array($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr); + return array($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr); } - private function getAdvancedMocks($cfMock, $fsMock, $logMock, $avaMgr, $dbc, $userMgr = null) { + private function getAdvancedMocks($cfMock, $fsMock, $logMock, $avaMgr, $dbc, $userMgr = null, $notiMgr = null) { static $conMethods; static $accMethods; static $umMethods; @@ -77,9 +79,12 @@ class UserTest extends \Test\TestCase { if (is_null($userMgr)) { $userMgr = $this->createMock(IUserManager::class); } + if (is_null($notiMgr)) { + $notiMgr = $this->createMock(INotificationManager::class); + } $um = $this->getMockBuilder('\OCA\User_LDAP\User\Manager') ->setMethods($umMethods) - ->setConstructorArgs([$cfMock, $fsMock, $logMock, $avaMgr, $im, $dbc, $userMgr]) + ->setConstructorArgs([$cfMock, $fsMock, $logMock, $avaMgr, $im, $dbc, $userMgr, $notiMgr]) ->getMock(); $helper = new \OCA\User_LDAP\Helper(\OC::$server->getConfig()); $connector = $this->getMockBuilder('\OCA\User_LDAP\Connection') @@ -95,25 +100,25 @@ class UserTest extends \Test\TestCase { } public function testGetDNandUsername() { - list($access, $config, $filesys, $image, $log, $avaMgr, $db, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $db, $userMgr, $notiMgr) = $this->getTestInstances(); $uid = 'alice'; $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $this->assertSame($dn, $user->getDN()); $this->assertSame($uid, $user->getUsername()); } public function testUpdateEmailProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = - $this->getAdvancedMocks($config, $filesys, $log, $avaMgr, $dbc, $userMgr); + $this->getAdvancedMocks($config, $filesys, $log, $avaMgr, $dbc, $userMgr, $notiMgr); $connection->expects($this->once()) ->method('__get') @@ -140,13 +145,13 @@ class UserTest extends \Test\TestCase { ->method('get') ->willReturn($uuser); $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateEmail(); } public function testUpdateEmailNotProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -170,13 +175,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateEmail(); } public function testUpdateEmailNotConfigured() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -197,13 +202,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateEmail(); } public function testUpdateQuotaAllProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -244,13 +249,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateQuota(); } public function testUpdateQuotaToDefaultAllProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -369,13 +374,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateQuota(); } public function testUpdateQuotaIndividualProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -416,13 +421,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateQuota(); } public function testUpdateQuotaNoneProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -464,13 +469,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateQuota(); } public function testUpdateQuotaNoneConfigured() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -510,13 +515,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateQuota(); } public function testUpdateQuotaFromValue() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -734,14 +739,14 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateQuota(); } //the testUpdateAvatar series also implicitely tests getAvatarImage public function testUpdateAvatarJpegPhotoProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -784,13 +789,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateAvatar(); } public function testUpdateAvatarThumbnailPhotoProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -842,13 +847,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateAvatar(); } public function testUpdateAvatarNotProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -888,13 +893,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->updateAvatar(); } public function testUpdateBeforeFirstLogin() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -924,13 +929,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->update(); } public function testUpdateAfterFirstLogin() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -964,13 +969,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->update(); } public function testUpdateNoRefresh() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -1000,13 +1005,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->update(); } public function testMarkLogin() { - list($access, $config, $filesys, $image, $log, $avaMgr, $db, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $db, $userMgr, $notiMgr) = $this->getTestInstances(); $config->expects($this->once()) @@ -1021,13 +1026,13 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->markLogin(); } public function testGetAvatarImageProvided() { - list($access, $config, $filesys, $image, $log, $avaMgr, $db, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $db, $userMgr, $notiMgr) = $this->getTestInstances(); $access->expects($this->once()) @@ -1040,7 +1045,7 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $photo = $user->getAvatarImage(); $this->assertSame('this is a photo', $photo); @@ -1050,7 +1055,7 @@ class UserTest extends \Test\TestCase { } public function testProcessAttributes() { - list(, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list(, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -1070,7 +1075,7 @@ class UserTest extends \Test\TestCase { ); $userMock = $this->getMockBuilder('OCA\User_LDAP\User\User') - ->setConstructorArgs(array($uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr)) + ->setConstructorArgs(array($uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr)) ->setMethods($requiredMethods) ->getMock(); @@ -1102,7 +1107,7 @@ class UserTest extends \Test\TestCase { $userMock->expects($this->once()) ->method($method); } - + \OC_Hook::clear();//disconnect irrelevant hooks $userMock->processAttributes($record); \OC_Hook::emit('OC_User', 'post_login', array('uid' => $uid)); } @@ -1118,7 +1123,7 @@ class UserTest extends \Test\TestCase { * @dataProvider emptyHomeFolderAttributeValueProvider */ public function testGetHomePathNotConfigured($attributeValue) { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -1139,14 +1144,14 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $path = $user->getHomePath(); $this->assertSame($path, false); } public function testGetHomePathConfiguredNotAvailableAllowed() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = @@ -1170,7 +1175,7 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $path = $user->getHomePath(); @@ -1181,11 +1186,11 @@ class UserTest extends \Test\TestCase { * @expectedException \Exception */ public function testGetHomePathConfiguredNotAvailableNotAllowed() { - list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = $this->getTestInstances(); list($access, $connection) = - $this->getAdvancedMocks($config, $filesys, $log, $avaMgr, $dbc, $userMgr); + $this->getAdvancedMocks($config, $filesys, $log, $avaMgr, $dbc, $userMgr, $notiMgr); $connection->expects($this->any()) ->method('__get') @@ -1205,7 +1210,7 @@ class UserTest extends \Test\TestCase { $dn = 'uid=alice,dc=foo,dc=bar'; $user = new User( - $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $user->getHomePath(); } @@ -1222,16 +1227,151 @@ class UserTest extends \Test\TestCase { * @dataProvider displayNameProvider */ public function testComposeAndStoreDisplayName($part1, $part2, $expected) { - list($access, $config, $filesys, $image, $log, $avaMgr, , $userMgr) = + list($access, $config, $filesys, $image, $log, $avaMgr, , $userMgr, $notiMgr) = $this->getTestInstances(); $config->expects($this->once()) ->method('setUserValue'); $user = new User( - 'user', 'cn=user', $access, $config, $filesys, $image, $log, $avaMgr, $userMgr); + 'user', 'cn=user', $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); $displayName = $user->composeAndStoreDisplayName($part1, $part2); $this->assertSame($expected, $displayName); } + + public function testHandlePasswordExpiryWarningDefaultPolicy() { + list(, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = + $this->getTestInstances(); + + list($access, $connection) = + $this->getAdvancedMocks($config, $filesys, $log, $avaMgr, $dbc); + + $uid = 'alice'; + $dn = 'uid=alice'; + + $connection->expects($this->any()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapDefaultPPolicyDN') { + return 'cn=default,ou=policies,dc=foo,dc=bar'; + } + if($name === 'turnOnPasswordChange') { + return '1'; + } + return $name; + })); + + $access->expects($this->any()) + ->method('readAttribute') + ->will($this->returnCallback(function($dn, $attr) { + if($attr === 'pwdChangedTime') { + return array((new \DateTime())->sub(new \DateInterval('P28D'))->format('Ymdhis').'Z'); + } + if($dn === 'cn=default,ou=policies,dc=foo,dc=bar' && $attr === 'pwdMaxAge') { + return array('2592000'); + } + if($dn === 'cn=default,ou=policies,dc=foo,dc=bar' && $attr === 'pwdExpireWarning') { + return array('2591999'); + } + return array(); + })); + + $notification = $this->getMockBuilder('OCP\Notification\INotification') + ->disableOriginalConstructor() + ->getMock(); + $notification->expects($this->any()) + ->method('setApp') + ->will($this->returnValue($notification)); + $notification->expects($this->any()) + ->method('setUser') + ->will($this->returnValue($notification)); + $notification->expects($this->any()) + ->method('setObject') + ->will($this->returnValue($notification)); + $notification->expects($this->any()) + ->method('setDateTime') + ->will($this->returnValue($notification)); + $notiMgr->expects($this->exactly(2)) + ->method('createNotification') + ->will($this->returnValue($notification)); + $notiMgr->expects($this->exactly(1)) + ->method('notify'); + + $user = new User( + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); + + \OC_Hook::clear();//disconnect irrelevant hooks + \OCP\Util::connectHook('OC_User', 'post_login', $user, 'handlePasswordExpiry'); + \OC_Hook::emit('OC_User', 'post_login', array('uid' => $uid)); + } + + public function testHandlePasswordExpiryWarningCustomPolicy() { + list(, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) = + $this->getTestInstances(); + + list($access, $connection) = + $this->getAdvancedMocks($config, $filesys, $log, $avaMgr, $dbc); + + $uid = 'alice'; + $dn = 'uid=alice'; + + $connection->expects($this->any()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapDefaultPPolicyDN') { + return 'cn=default,ou=policies,dc=foo,dc=bar'; + } + if($name === 'turnOnPasswordChange') { + return '1'; + } + return $name; + })); + + $access->expects($this->any()) + ->method('readAttribute') + ->will($this->returnCallback(function($dn, $attr) { + if($attr === 'pwdPolicySubentry') { + return array('cn=custom,ou=policies,dc=foo,dc=bar'); + } + if($attr === 'pwdChangedTime') { + return array((new \DateTime())->sub(new \DateInterval('P28D'))->format('Ymdhis').'Z'); + } + if($dn === 'cn=custom,ou=policies,dc=foo,dc=bar' && $attr === 'pwdMaxAge') { + return array('2592000'); + } + if($dn === 'cn=custom,ou=policies,dc=foo,dc=bar' && $attr === 'pwdExpireWarning') { + return array('2591999'); + } + return array(); + })); + + $notification = $this->getMockBuilder('OCP\Notification\INotification') + ->disableOriginalConstructor() + ->getMock(); + $notification->expects($this->any()) + ->method('setApp') + ->will($this->returnValue($notification)); + $notification->expects($this->any()) + ->method('setUser') + ->will($this->returnValue($notification)); + $notification->expects($this->any()) + ->method('setObject') + ->will($this->returnValue($notification)); + $notification->expects($this->any()) + ->method('setDateTime') + ->will($this->returnValue($notification)); + $notiMgr->expects($this->exactly(2)) + ->method('createNotification') + ->will($this->returnValue($notification)); + $notiMgr->expects($this->exactly(1)) + ->method('notify'); + + $user = new User( + $uid, $dn, $access, $config, $filesys, $image, $log, $avaMgr, $userMgr, $notiMgr); + + \OC_Hook::clear();//disconnect irrelevant hooks + \OCP\Util::connectHook('OC_User', 'post_login', $user, 'handlePasswordExpiry'); + \OC_Hook::emit('OC_User', 'post_login', array('uid' => $uid)); + } } diff --git a/apps/user_ldap/tests/User_LDAPTest.php b/apps/user_ldap/tests/User_LDAPTest.php index f1a23f9a6c..2d13779c5a 100644 --- a/apps/user_ldap/tests/User_LDAPTest.php +++ b/apps/user_ldap/tests/User_LDAPTest.php @@ -47,6 +47,7 @@ use OCP\IDBConnection; use OCP\Image; use OCP\IUserManager; use Test\TestCase; +use OCP\Notification\IManager as INotificationManager; /** * Class Test_User_Ldap_Direct @@ -92,7 +93,8 @@ class User_LDAPTest extends TestCase { $this->createMock(IAvatarManager::class), $this->createMock(Image::class), $this->createMock(IDBConnection::class), - $this->createMock(IUserManager::class) + $this->createMock(IUserManager::class), + $this->createMock(INotificationManager::class) ]) ->getMock(); @@ -197,7 +199,7 @@ class User_LDAPTest extends TestCase { $access = $this->getAccessMock(); $this->prepareAccessForCheckPassword($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = $backend->checkPassword('roland', 'dt19'); @@ -208,7 +210,7 @@ class User_LDAPTest extends TestCase { $access = $this->getAccessMock(); $this->prepareAccessForCheckPassword($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = $backend->checkPassword('roland', 'wrong'); @@ -219,7 +221,7 @@ class User_LDAPTest extends TestCase { $access = $this->getAccessMock(); $this->prepareAccessForCheckPassword($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = $backend->checkPassword('mallory', 'evil'); @@ -234,7 +236,7 @@ class User_LDAPTest extends TestCase { ->method('username2dn') ->will($this->returnValue(false)); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = $backend->checkPassword('roland', 'dt19'); @@ -244,7 +246,7 @@ class User_LDAPTest extends TestCase { public function testCheckPasswordPublicAPI() { $access = $this->getAccessMock(); $this->prepareAccessForCheckPassword($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = \OCP\User::checkPassword('roland', 'dt19'); @@ -254,7 +256,7 @@ class User_LDAPTest extends TestCase { public function testCheckPasswordPublicAPIWrongPassword() { $access = $this->getAccessMock(); $this->prepareAccessForCheckPassword($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = \OCP\User::checkPassword('roland', 'wrong'); @@ -264,7 +266,7 @@ class User_LDAPTest extends TestCase { public function testCheckPasswordPublicAPIWrongUser() { $access = $this->getAccessMock(); $this->prepareAccessForCheckPassword($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = \OCP\User::checkPassword('mallory', 'evil'); @@ -273,7 +275,7 @@ class User_LDAPTest extends TestCase { public function testDeleteUserCancel() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $result = $backend->deleteUser('notme'); $this->assertFalse($result); } @@ -295,7 +297,7 @@ class User_LDAPTest extends TestCase { ->method('getUserValue') ->will($this->onConsecutiveCalls('1', '/var/vhome/jdings/')); - $backend = new UserLDAP($access, $config); + $backend = new UserLDAP($access, $config, $this->createMock(INotificationManager::class)); $result = $backend->deleteUser('jeremy'); $this->assertTrue($result); @@ -356,7 +358,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersNoParam() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $result = $backend->getUsers(); $this->assertEquals(3, count($result)); @@ -365,7 +367,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersLimitOffset() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $result = $backend->getUsers('', 1, 2); $this->assertEquals(1, count($result)); @@ -374,7 +376,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersLimitOffset2() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $result = $backend->getUsers('', 2, 1); $this->assertEquals(2, count($result)); @@ -383,7 +385,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersSearchWithResult() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $result = $backend->getUsers('yo'); $this->assertEquals(2, count($result)); @@ -392,7 +394,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersSearchEmptyResult() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $result = $backend->getUsers('nix'); $this->assertEquals(0, count($result)); @@ -401,7 +403,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersViaAPINoParam() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = \OCP\User::getUsers(); @@ -411,7 +413,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersViaAPILimitOffset() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = \OCP\User::getUsers('', 1, 2); @@ -421,7 +423,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersViaAPILimitOffset2() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = \OCP\User::getUsers('', 2, 1); @@ -431,7 +433,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersViaAPISearchWithResult() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = \OCP\User::getUsers('yo'); @@ -441,7 +443,7 @@ class User_LDAPTest extends TestCase { public function testGetUsersViaAPISearchEmptyResult() { $access = $this->getAccessMock(); $this->prepareAccessForGetUsers($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $result = \OCP\User::getUsers('nix'); @@ -450,7 +452,7 @@ class User_LDAPTest extends TestCase { public function testUserExists() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); $access->expects($this->any()) @@ -472,7 +474,7 @@ class User_LDAPTest extends TestCase { */ public function testUserExistsForDeleted() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); $access->expects($this->any()) @@ -490,7 +492,7 @@ class User_LDAPTest extends TestCase { public function testUserExistsForNeverExisting() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); $access->expects($this->any()) @@ -509,7 +511,7 @@ class User_LDAPTest extends TestCase { public function testUserExistsPublicAPI() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); \OC_User::useBackend($backend); @@ -532,7 +534,7 @@ class User_LDAPTest extends TestCase { */ public function testUserExistsPublicAPIForDeleted() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); \OC_User::useBackend($backend); @@ -551,7 +553,7 @@ class User_LDAPTest extends TestCase { public function testUserExistsPublicAPIForNeverExisting() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); \OC_User::useBackend($backend); @@ -571,7 +573,7 @@ class User_LDAPTest extends TestCase { public function testDeleteUser() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); //we do not support deleting users at all $result = $backend->deleteUser('gunslinger'); @@ -581,7 +583,8 @@ class User_LDAPTest extends TestCase { public function testGetHomeAbsolutePath() { $access = $this->getAccessMock(); $config = $this->createMock(IConfig::class); - $backend = new UserLDAP($access, $config); + $noti = $this->createMock(INotificationManager::class); + $backend = new UserLDAP($access, $config, $noti); $this->prepareMockForUserExists($access); $access->connection->expects($this->any()) @@ -616,7 +619,8 @@ class User_LDAPTest extends TestCase { public function testGetHomeRelative() { $access = $this->getAccessMock(); $config = $this->createMock(IConfig::class); - $backend = new UserLDAP($access, $config); + $noti = $this->createMock(INotificationManager::class); + $backend = new UserLDAP($access, $config, $noti); $this->prepareMockForUserExists($access); $dataDir = \OC::$server->getConfig()->getSystemValue( @@ -659,7 +663,7 @@ class User_LDAPTest extends TestCase { */ public function testGetHomeNoPath() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); $access->connection->expects($this->any()) @@ -690,7 +694,7 @@ class User_LDAPTest extends TestCase { */ public function testGetHomeDeletedUser() { $access = $this->getAccessMock(); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); $access->connection->expects($this->any()) @@ -761,7 +765,7 @@ class User_LDAPTest extends TestCase { public function testGetDisplayName() { $access = $this->getAccessMock(); $this->prepareAccessForGetDisplayName($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); $access->connection->expects($this->any()) @@ -802,7 +806,7 @@ class User_LDAPTest extends TestCase { } })); $this->prepareAccessForGetDisplayName($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $this->prepareMockForUserExists($access); $access->connection->expects($this->any()) @@ -832,7 +836,7 @@ class User_LDAPTest extends TestCase { ->method('countUsers') ->will($this->returnValue(5)); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $result = $backend->countUsers(); $this->assertEquals(5, $result); @@ -845,7 +849,7 @@ class User_LDAPTest extends TestCase { ->method('countUsers') ->will($this->returnValue(false)); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $result = $backend->countUsers(); $this->assertFalse($result); @@ -878,7 +882,7 @@ class User_LDAPTest extends TestCase { ->method('writeToCache') ->with($this->equalTo('loginName2UserName-'.$loginName), $this->equalTo($username)); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $name = $backend->loginName2UserName($loginName); $this->assertSame($username, $name); @@ -907,7 +911,7 @@ class User_LDAPTest extends TestCase { ->method('writeToCache') ->with($this->equalTo('loginName2UserName-'.$loginName), false); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $name = $backend->loginName2UserName($loginName); $this->assertSame(false, $name); @@ -954,7 +958,7 @@ class User_LDAPTest extends TestCase { ->method('getUserValue') ->willReturn(1); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); $name = $backend->loginName2UserName($loginName); $this->assertSame(false, $name); @@ -1035,7 +1039,7 @@ class User_LDAPTest extends TestCase { $access = $this->getAccessMock(); $this->prepareAccessForSetPassword($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $this->assertTrue(\OC_User::setPassword('roland', 'dt')); @@ -1045,17 +1049,17 @@ class User_LDAPTest extends TestCase { $access = $this->getAccessMock(); $this->prepareAccessForSetPassword($access); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $this->assertTrue(\OC_User::setPassword('roland', 'dt12234$')); } - + public function testSetPasswordValidDisabled() { $access = $this->getAccessMock(); $this->prepareAccessForSetPassword($access, false); - $backend = new UserLDAP($access, $this->createMock(IConfig::class)); + $backend = new UserLDAP($access, $this->createMock(IConfig::class), $this->createMock(INotificationManager::class)); \OC_User::useBackend($backend); $this->assertFalse(\OC_User::setPassword('roland', 'dt12234$')); @@ -1074,9 +1078,11 @@ class User_LDAPTest extends TestCase { ->with('NotExistingUser') ->willReturn(null); $config = $this->createMock(IConfig::class); + $noti = $this->createMock(INotificationManager::class); $ldap = new User_LDAP( $access, - $config + $config, + $noti ); $ldap->setPassword('NotExistingUser', 'Password'); } @@ -1095,9 +1101,11 @@ class User_LDAPTest extends TestCase { ->with('NotExistingUser') ->willReturn($user); $config = $this->createMock(IConfig::class); + $noti = $this->createMock(INotificationManager::class); $ldap = new User_LDAP( $access, - $config + $config, + $noti ); $this->assertFalse($ldap->setPassword('NotExistingUser', 'Password')); } diff --git a/apps/user_ldap/tests/User_ProxyTest.php b/apps/user_ldap/tests/User_ProxyTest.php index 6d779d758e..df021a6de3 100644 --- a/apps/user_ldap/tests/User_ProxyTest.php +++ b/apps/user_ldap/tests/User_ProxyTest.php @@ -24,6 +24,7 @@ namespace OCA\User_LDAP\Tests; use OCA\User_LDAP\ILDAPWrapper; use OCA\User_LDAP\User_Proxy; use OCP\IConfig; +use OCP\Notification\IManager as INotificationManager; use Test\TestCase; class User_ProxyTest extends TestCase { @@ -31,6 +32,8 @@ class User_ProxyTest extends TestCase { private $ldapWrapper; /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ private $config; + /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ + private $notificationManager; /** @var User_Proxy|\PHPUnit_Framework_MockObject_MockObject */ private $proxy; @@ -39,11 +42,13 @@ class User_ProxyTest extends TestCase { $this->ldapWrapper = $this->createMock(ILDAPWrapper::class); $this->config = $this->createMock(IConfig::class); + $this->notificationManager = $this->createMock(INotificationManager::class); $this->proxy = $this->getMockBuilder(User_Proxy::class) ->setConstructorArgs([ [], $this->ldapWrapper, $this->config, + $this->notificationManager, ]) ->setMethods(['handleRequest']) ->getMock();