request = $request; return $this; } public function init(IlluminateRequest $request) { $this->request = $request; return $this; } public function isAuthenticated() { if(!$this->hasSecretKey() || !$this->isEnabled() || $this->noUserIsAuthenticated()){ return false; } if($this->twoFactorAuthStillValid()){ return true; } return ($this->checkOTP() === $this::OTP_VALID); } public function logout() { $this->sessionForget(); } public function makeActiveOneTimePasswordResponse() { if($this->request->isMethod('post') && Request::get('action') === 'activate_user_one_time_password'){ $user = $this->getUser(); $user->google2fa = true; $user->save(); return back(); } $MyGoogle2FA = new MyGoogle2FA(); $MyGoogle2FA->init($this->getUser())->generate(); $fill = [ 'MyGoogle2FA' => $MyGoogle2FA, ]; $view = view("auth.google2fa_activate", $fill); return new IlluminateHtmlResponse($view); } public function makeRequestOneTimePasswordResponse() { $view = view($this->config('view')); $statusCode = $this->makeStatusCode(); if ($statusCode !== SymfonyResponse::HTTP_OK) { $view->withErrors($this->getErrorBagForStatusCode($statusCode)); } return new IlluminateHtmlResponse($view, $statusCode); } protected function checkOTP() { if (!$this->request->has($this->config('otp_input') )|| empty($this->request->input($this->config('otp_input')))) { return $this::OTP_EMPTY; } $isValid = $this->verifyOneTimePassword(); if ($isValid) { $this->login(); return $this::OTP_VALID; } return $this::OTP_INVALID; } protected function login() { $this->sessionPut($this::SESSION_AUTH_PASSED, true); } protected function verifyOneTimePassword() { return Google2FA::verifyKey($this->getGoogle2FASecretKey(), $this->getOneTimePassword()); } private function getOneTimePassword() { $password =$this->request->input($this->config('otp_input')); if (is_null($password) || empty($password)) { if ($this->config('throw_exceptions', true)) { throw new \Exception($this->config('error_messages.cannot_be_empty')); } } return $password; } private function getGoogle2FASecretKey() { return $this->getUser()->{$this->config('otp_secret_column')}; } private function hasSecretKey() { $secret = $this->getGoogle2FASecretKey(); return !is_null($secret) && !empty($secret); } private function twoFactorAuthStillValid() { return (bool) $this->sessionGet($this::SESSION_AUTH_PASSED, false); } private function isEnabled() { return $this->config('enabled'); } private function noUserIsAuthenticated() { return is_null($this->getUser()); } private function config($string, $default = null) { if (is_null(config($config = $this::CONFIG_PACKAGE_NAME))) { throw new \Exception("Config ({$config}.php) not found. Have you published it?"); } return config( implode('.', [$this::CONFIG_PACKAGE_NAME, $string]), $default ); } private function getAuth() { if (is_null($this->auth)) { $this->auth = app($this->config('auth')); if (!empty($this->config('guard'))) { $this->auth = app($this->config('auth'))->guard($this->config('guard')); } } return $this->auth; } private function getUser() { return $this->getAuth()->user(); } private function makeSessionVarName($name = null) { return $this->config('session_var') . (is_null($name) || empty($name) ? '' : '.' . $name); } private function sessionGet($var = null, $default = null) { return $this->request->session()->get( $this->makeSessionVarName($var), $default ); } private function sessionPut($var, $value) { $this->request->session()->put( $this->makeSessionVarName($var), $value ); return $value; } private function sessionForget($var = null) { $this->request->session()->forget( $this->makeSessionVarName($var) ); } private function makeStatusCode() { if ($this->request->isMethod('get') || ($this->checkOTP() === $this::OTP_VALID)) { return SymfonyResponse::HTTP_OK; } if ($this->checkOTP() === $this::OTP_EMPTY) { return SymfonyResponse::HTTP_BAD_REQUEST; } return SymfonyResponse::HTTP_UNPROCESSABLE_ENTITY; } private function getErrorBagForStatusCode($statusCode) { $errorMap = [ SymfonyResponse::HTTP_UNPROCESSABLE_ENTITY => 'google2fa.error_messages.wrong_otp', SymfonyResponse::HTTP_BAD_REQUEST => 'google2fa.error_messages.cannot_be_empty', ]; return $this->createErrorBagForMessage( trans( config( array_key_exists($statusCode, $errorMap) ? $errorMap[$statusCode] : 'google2fa.error_messages.unknown' ) ) ); } private function createErrorBagForMessage($message) { return new MessageBag([ 'message' => $message, ]); } }