_validateConfig(); $this->_initAuth(); if (Configure::read('Users.Social.login')) { $this->_loadSocialLogin(); } if (Configure::read('Users.RememberMe.active')) { $this->_loadRememberMe(); } if ($this->getTwoFactorAuthenticationChecker()->isEnabled()) { $this->_loadGoogleAuthenticator(); } $this->_attachPermissionChecker(); } /** * Load GoogleAuthenticator object * * @return void */ protected function _loadGoogleAuthenticator() { $this->getController()->loadComponent('CakeDC/Users.GoogleAuthenticator'); } /** * Load Social Auth object * * @return void */ protected function _loadSocialLogin() { $this->getController()->Auth->setConfig('authenticate', [ Configure::read('Users.Social.authenticator') ], true); } /** * Load RememberMe component and Auth objects * * @return void */ protected function _loadRememberMe() { $this->getController()->loadComponent('CakeDC/Users.RememberMe'); } /** * Attach the isUrlAuthorized event to allow using the Auth authorize from the UserHelper * * @return void */ protected function _attachPermissionChecker() { EventManager::instance()->on(self::EVENT_IS_AUTHORIZED, [], [$this, 'isUrlAuthorized']); } /** * Initialize the AuthComponent and configure allowed actions * * @return void */ protected function _initAuth() { if (Configure::read('Users.auth')) { //initialize Auth $this->getController()->loadComponent('Auth', Configure::read('Auth')); } list($plugin, $controller) = pluginSplit(Configure::read('Users.controller')); if ($this->getController()->getRequest()->getParam('plugin', null) === $plugin && $this->getController()->getRequest()->getParam('controller') === $controller ) { $this->getController()->Auth->allow([ // LoginTrait 'twitterLogin', 'login', 'socialEmail', 'verify', // RegisterTrait 'register', 'validateEmail', // PasswordManagementTrait used in RegisterTrait 'changePassword', 'resetPassword', 'requestResetPassword', // UserValidationTrait used in PasswordManagementTrait 'resendTokenValidation', // Social 'endpoint', 'authenticated', 'u2f', 'u2fRegister', 'u2fRegisterFinish', 'u2fAuthenticate', 'u2fAuthenticateFinish', ]); } } /** * Check if a given url is authorized * * @param Event $event event * * @return bool */ public function isUrlAuthorized(Event $event) { $url = Hash::get((array)$event->getData(), 'url'); if (empty($url)) { return false; } if (is_array($url)) { $requestUrl = Router::normalize(Router::reverse($url)); $requestParams = Router::parseRequest(new ServerRequest($requestUrl)); } else { try { //remove base from $url if exists $normalizedUrl = Router::normalize($url); $requestParams = Router::parseRequest(new ServerRequest($normalizedUrl)); } catch (MissingRouteException $ex) { //if it's a url pointing to our own app if (substr($normalizedUrl, 0, 1) === '/') { throw $ex; } return true; } $requestUrl = $url; } // check if controller action is allowed if ($this->_isActionAllowed($requestParams)) { return true; } // check we are logged in $user = $this->getController()->Auth->user(); if (empty($user)) { return false; } $request = new ServerRequest($requestUrl); $request = $request->withAttribute('params', $requestParams); $isAuthorized = $this->getController()->Auth->isAuthorized(null, $request); return $isAuthorized; } /** * Validate if the passed configuration makes sense * * @throws BadConfigurationException * @return void */ protected function _validateConfig() { if (!Configure::read('Users.Email.required') && Configure::read('Users.Email.validate')) { $message = __d('CakeDC/Users', 'You can\'t enable email validation workflow if use_email is false'); throw new BadConfigurationException($message); } } /** * Check if the action is in allowedActions array for the controller * Important, this function will check only for allowed actions in the current * controller, creating a new instance and providing initialization for the Auth * instance in another controller could lead to undesired side effects. * * @param array $requestParams request parameters * @return bool */ protected function _isActionAllowed($requestParams = []) { if (empty($requestParams['action'])) { return false; } if (!empty($requestParams['controller']) && $requestParams['controller'] !== $this->getController()->getName()) { return false; } $action = strtolower($requestParams['action']); if (in_array($action, array_map('strtolower', $this->getController()->Auth->allowedActions))) { return true; } return false; } /** * Get the configured two factory authentication * * @return \CakeDC\Users\Auth\TwoFactorAuthenticationCheckerInterface */ protected function getTwoFactorAuthenticationChecker() { return (new TwoFactorAuthenticationCheckerFactory())->build(); } }