diff --git a/src/app/AuthAttempt.php b/src/app/AuthAttempt.php index 23de2bbe..b00d2557 100644 --- a/src/app/AuthAttempt.php +++ b/src/app/AuthAttempt.php @@ -1,195 +1,196 @@ The attributes that can be not set */ protected $nullable = ['reason']; /** @var array The attributes that are mass assignable */ protected $fillable = [ 'ip', 'user_id', 'status', 'reason', 'expires_at', 'last_seen', ]; /** @var array The attributes that should be cast */ protected $casts = [ 'expires_at' => 'datetime', 'last_seen' => 'datetime' ]; /** - * Prepare a date for array / JSON serialization. - * - * Required to not omit timezone and match the format of update_at/created_at timestamps. - * - * @param \DateTimeInterface $date - * @return string - */ + * Prepare a date for array / JSON serialization. + * + * Required to not omit timezone and match the format of update_at/created_at timestamps. + * + * @param \DateTimeInterface $date + * + * @return string + */ protected function serializeDate(\DateTimeInterface $date): string { return Carbon::instance($date)->toIso8601ZuluString('microseconds'); } /** - * Returns true if the authentication attempt is accepted. - * - * @return bool - */ + * Returns true if the authentication attempt is accepted. + * + * @return bool + */ public function isAccepted(): bool { return $this->status == self::STATUS_ACCEPTED && Carbon::now() < $this->expires_at; } /** - * Returns true if the authentication attempt is denied. - * - * @return bool - */ + * Returns true if the authentication attempt is denied. + * + * @return bool + */ public function isDenied(): bool { return $this->status == self::STATUS_DENIED; } /** - * Accept the authentication attempt. - */ + * Accept the authentication attempt. + */ public function accept($reason = AuthAttempt::REASON_NONE) { $this->expires_at = Carbon::now()->addHours(8); $this->status = self::STATUS_ACCEPTED; $this->reason = $reason; $this->save(); } /** - * Deny the authentication attempt. - */ + * Deny the authentication attempt. + */ public function deny($reason = AuthAttempt::REASON_NONE) { $this->status = self::STATUS_DENIED; $this->reason = $reason; $this->save(); } /** - * Notify the user of this authentication attempt. - * - * @return bool false if there was no means to notify - */ + * Notify the user of this authentication attempt. + * + * @return bool false if there was no means to notify + */ public function notify(): bool { return CompanionApp::notifyUser($this->user_id, ['token' => $this->id]); } /** - * Notify the user and wait for a confirmation. - */ + * Notify the user and wait for a confirmation. + */ private function notifyAndWait() { if (!$this->notify()) { - //FIXME if the webclient can confirm too we don't need to abort here. + // FIXME if the webclient can confirm too we don't need to abort here. \Log::warning("There is no 2fa device to notify."); return false; } \Log::debug("Authentication attempt: {$this->id}"); $confirmationTimeout = 120; $timeout = Carbon::now()->addSeconds($confirmationTimeout); do { if ($this->isDenied()) { \Log::debug("The authentication attempt was denied {$this->id}"); return false; } if ($this->isAccepted()) { \Log::debug("The authentication attempt was accepted {$this->id}"); return true; } if ($timeout < Carbon::now()) { \Log::debug("The authentication attempt timed-out: {$this->id}"); return false; } sleep(2); $this->refresh(); } while (true); } /** - * Record a new authentication attempt or update an existing one. - * - * @param \App\User $user The user attempting to authenticate. - * @param string $clientIP The ip the authentication attempt is coming from. - * - * @return \App\AuthAttempt - */ + * Record a new authentication attempt or update an existing one. + * + * @param \App\User $user The user attempting to authenticate. + * @param string $clientIP The ip the authentication attempt is coming from. + * + * @return \App\AuthAttempt + */ public static function recordAuthAttempt(User $user, $clientIP) { $authAttempt = AuthAttempt::where('ip', $clientIP)->where('user_id', $user->id)->first(); if (!$authAttempt) { $authAttempt = new AuthAttempt(); $authAttempt->ip = $clientIP; $authAttempt->user_id = $user->id; } $authAttempt->last_seen = Carbon::now(); $authAttempt->save(); return $authAttempt; } /** - * Trigger a notification if necessary and wait for confirmation. - * - * @return bool Returns true if the attempt is accepted on confirmation - */ + * Trigger a notification if necessary and wait for confirmation. + * + * @return bool Returns true if the attempt is accepted on confirmation + */ public function waitFor2FA(): bool { if ($this->isAccepted()) { return true; } if ($this->isDenied()) { return false; } if (!$this->notifyAndWait()) { return false; } return $this->isAccepted(); } }