public function tryLogin($data) { // Reject requests if ($this->isExceedingRateLimit(2)) { $this->response->setStatusCode(429, 'Too many requests'); $this->flash->notice('Too many requests.'); return false; } /** @var User $user */ $user = User::findFirst(['email = :email:', 'bind' => ['email' => $data['user']]]); // Sleep for 1-500ms usleep(mt_rand(1000, 500000)); if ($user && $user->validatePassword($data['password'])) { // Validate TOTP token // This needs to be done at this stage as the two factor auth key is // encrypted with the user's password. if ($otpKey = $user->getOtpKey($data['password'])) { $otp = new \Rych\OTP\TOTP($otpKey); if (!$otp->validate($data['token'])) { $this->flash->error('Incorrect login details'); return false; } } $keyService = new \Stecman\Passnote\AccountKeyService(); $keyService->unlockAccountKeyForSession($user, $data['password']); $this->session->set(Security::SESSION_USER_ID, $user->id); $this->session->set(Security::SESSION_KEY, $user->getSessionKey()); session_regenerate_id(); $this->response->redirect(''); } else { // Keep timing $this->security->hash(openssl_random_pseudo_bytes(12)); $this->flash->error('Incorrect login details'); } }
protected function decryptContent(ReadableEncryptedContent $object) { $user = Security::getCurrentUser(); if ($object->getKeyId() === $user->accountKey_id) { $keyService = new \Stecman\Passnote\AccountKeyService(); return $keyService->decryptObject($object); } else { // Prompt for decryption passphrase } }