Skip to content
Snippets Groups Projects
Commit 3a7cea84 authored by Dominik Hebeler's avatar Dominik Hebeler
Browse files

centrqalize login code storage

parent 8763ef68
No related branches found
No related tags found
2 merge requests!2260Translated using Weblate (German),!2258Resolve "Create API for Log access"
......@@ -7,6 +7,7 @@ use App\Models\Authorization\LogsUser;
use Auth;
use DB;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use Mail;
use Validator;
......@@ -71,12 +72,19 @@ class LogsApiController extends Controller
public function login(Request $request)
{
if (!is_null(Auth::guard("logs")->user()->getAuthIdentifier())) {
session()->flash("email", Auth::guard("logs")->user()->getAuthIdentifier());
}
return view("logs.login", ['title' => __('titles.logs.login')]);
}
public function login_post(Request $request)
{
$email_validation = "email:rfc,dns";
if (!$request->filled("code")) {
$email_validation = "required|" . $email_validation;
}
$validator = Validator::make($request->input(), [
"email" => "required|email:rfc,dns",
"email" => $email_validation,
'code' => 'regex:/^\d{6}$/i'
]);
......@@ -86,19 +94,18 @@ class LogsApiController extends Controller
}
$validated = $validator->validated();
$user = app(LogsUser::class)->fetchUserByMail($validated["email"]);
if (!is_null($user->getAuthIdentifier()) && !is_null($user->getAuthPassword())) {
if (!empty($validated["code"])) {
if (Auth::guard("logs")->attempt(["username" => $validated["email"], "password" => $validated["code"]])) {
session(["logs_authenticated" => true]);
$url = session("url.intended");
return redirect($url);
}
if (isset($validated["code"])) {
if (Auth::guard("logs")->validate(["username" => $validated["email"], "password" => $validated["code"]])) {
$url = session("url.intended");
return redirect($url);
} else {
// Send Email with login Code
Mail::to($validated["email"])->send(new LogsLoginCode($user->getAuthPassword()));
// Code wasn't correct
$errors = new MessageBag();
$errors->add("invalid_logincode", "Login Code was invalid");
return redirect(route("logs:login"))->withErrors($errors);
}
} else {
Auth::guard("logs")->init($validated["email"]);
}
return redirect(route("logs:login"))->with(["email" => $validated["email"]]);
}
......
<?php
namespace App\Models\Authorization;
use App\Mail\LogsLoginCode;
use Cache;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;
use Mail;
class LogsAuthGuard implements \Illuminate\Contracts\Auth\Guard
{
const SESSION_LOGS_USERNAME_KEY = "logs_username";
const CACHE_LOGS_PASSWORD_KEY = "logs_password";
const SESSION_LOGS_AUTHORIZED_KEY = "logs_authorized";
const SESSION_LOGS_AUTH_TRIES_KEY = "logs_authroization_tries";
private UserProvider $userProvider;
private Request $request;
private Authenticatable|null $user;
private bool $authorized = false;
public function __construct(UserProvider $userProvider, Request $request)
{
$this->userProvider = $userProvider;
$this->request = $request;
$this->user = null;
if (!is_null(session(self::SESSION_LOGS_AUTHORIZED_KEY))) {
$this->authorized = session(self::SESSION_LOGS_AUTHORIZED_KEY);
}
if (!is_null(session(self::SESSION_LOGS_USERNAME_KEY))) {
$credentials = ["username" => session(self::SESSION_LOGS_USERNAME_KEY)];
if (Cache::has(self::CACHE_LOGS_PASSWORD_KEY . ":" . $credentials["username"])) {
$credentials["password"] = Cache::get(self::CACHE_LOGS_PASSWORD_KEY . ":" . $credentials["username"]);
}
$this->user = $this->userProvider->retrieveByCredentials($credentials);
$this->sendPassword();
}
}
/**
* Initializes a new authorization providing an email address.
* That email address has to be authorized with a logincode furtheron.
*
*
* @param string $email
* @return void
*/
public function init(string $email)
{
$this->user = $this->userProvider->retrieveByCredentials(["username" => $email]);
session([
self::SESSION_LOGS_USERNAME_KEY => $this->user->getAuthIdentifier(),
]);
$this->sendPassword();
}
/**
* Checks if a logincode needs to be sent out to the user by mail
* @return void
*/
private function sendPassword()
{
// Store the password
if (!$this->authorized && !is_null($this->user->getAuthPassword()) && !Cache::has(self::CACHE_LOGS_PASSWORD_KEY . ":" . $this->user->getAuthIdentifier())) {
Cache::put(self::CACHE_LOGS_PASSWORD_KEY . ":" . $this->user->getAuthIdentifier(), $this->user->getAuthPassword(), now()->addMinutes(5));
// Send Email with login Code
Mail::to($this->user->getAuthIdentifier())->send(new LogsLoginCode($this->user->getAuthPassword()));
}
}
/**
* Determine if the current user is authenticated.
*
......@@ -23,7 +73,7 @@ class LogsAuthGuard implements \Illuminate\Contracts\Auth\Guard
*/
public function check(): bool
{
return !is_null($this->user);
return $this->authorized;
}
/**
......@@ -67,13 +117,24 @@ class LogsAuthGuard implements \Illuminate\Contracts\Auth\Guard
public function validate(array $credentials = [])
{
if (empty($credentials["username"]) || empty($credentials["password"])) {
session([self::SESSION_LOGS_AUTHORIZED_KEY => false]);
$this->authorized = false;
return false;
}
$user = $this->userProvider->retrieveByCredentials($credentials);
if (!is_null($user) && $this->userProvider->validateCredentials($user, $credentials)) {
$this->setUser($user);
if (!is_null($this->user) && $this->userProvider->validateCredentials($this->user, $credentials)) {
session([self::SESSION_LOGS_AUTHORIZED_KEY => true]);
$this->authorized = true;
return true;
} else {
session([self::SESSION_LOGS_AUTHORIZED_KEY => false]);
$tries = session(self::SESSION_LOGS_AUTH_TRIES_KEY, 0);
if ($tries < 5) {
session([self::SESSION_LOGS_AUTH_TRIES_KEY => ($tries + 1)]);
} else {
Cache::forget(self::CACHE_LOGS_PASSWORD_KEY . ":" . $this->user->getAuthIdentifier());
}
$this->authorized = false;
return false;
}
}
......
......@@ -11,23 +11,25 @@ class LogsUser implements Authenticatable
private int $discount;
public function fetchUserByMail(string $username)
public function fetchUserByCredentials(array $credentials)
{
$user = DB::table("logs_users")->where("email", "=", $username)->first();
$user = DB::table("logs_users")->where("email", "=", $credentials["username"])->first();
$this->email = $credentials["username"];
if (!is_null($user)) {
$this->email = $username;
if (!empty(session("login_token"))) {
$this->login_token = session("login_token");
if (isset($credentials["password"])) {
$this->login_token = $credentials["password"];
} else {
$this->login_token = (string) rand(0, 999999);
while (strlen($this->login_token) < 6) {
$this->login_token = '0' . $this->login_token;
}
session(["login_token" => $this->login_token]);
}
$this->discount = $user->discount;
} else {
$this->login_token = "";
}
return $this;
}
/**
* Get the name of the unique identifier for the user.
......
......@@ -60,7 +60,7 @@ class LogsUserProvider implements UserProvider
if (empty($credentials)) {
return;
}
return $this->user->fetchUserByMail($credentials["username"]);
return $this->user->fetchUserByCredentials($credentials);
}
/**
......
......@@ -16,6 +16,9 @@
@endif
<form action="{{ route("logs:login:post")}}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
@if(session("email"))
<input type="hidden" name="email" value="{{session('email')}}">
@endif
<div class="input-group">
<label for="email">Email Addresse</label>
@if(session("email"))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment