Implement authentication endpoints
This commit is contained in:
parent
5cfa98653e
commit
af00f64cf7
81
app/Console/Commands/AuthenticationCommand.php
Normal file
81
app/Console/Commands/AuthenticationCommand.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Http\Services\AuthService;
|
||||
use App\Models\AuthenticationToken;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class AuthenticationCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'auth:escalate';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Escalate user to a management session';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$authTokens = AuthenticationToken::select('id', 'token', 'authenticated', 'valid_until')->whereDate('valid_until', '>', Carbon::now())->get();
|
||||
|
||||
$this->table(['id', 'token', 'authenticated', 'valid_until'], $authTokens);
|
||||
|
||||
$response = $this->ask('Token ID to escalate:');
|
||||
|
||||
if (strlen($response) === 0) {
|
||||
$this->info('Nothing entered, exiting.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!is_numeric($response)) {
|
||||
$this->info('Invalid input entered, exiting.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$id = (int)$response;
|
||||
$token = AuthenticationToken::find($id);
|
||||
|
||||
if ($token === null) {
|
||||
$this->info('Invalid token ID given, exiting.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$targetRole = $this->choice('Should this token be a manager or normal user?', ['user', 'manager']);
|
||||
$authState = ['manager' => true, 'user' => false][$targetRole];
|
||||
|
||||
$token->authenticated = $authState;
|
||||
$token->save();
|
||||
|
||||
if ($authState) {
|
||||
$this->info('Token ' . $id . ' escalated to manager.');
|
||||
} else {
|
||||
$this->info('Token ' . $id . ' deescalated to user.');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
29
app/Http/Controllers/AuthenticationController.php
Normal file
29
app/Http/Controllers/AuthenticationController.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Services\AuthService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AuthenticationController extends Controller
|
||||
{
|
||||
private $authService;
|
||||
|
||||
public function __construct(AuthService $authService)
|
||||
{
|
||||
$this->authService = $authService;
|
||||
}
|
||||
|
||||
public function isAuthenticated()
|
||||
{
|
||||
return [
|
||||
'status' => $this->authService->isAuthenticated()
|
||||
];
|
||||
}
|
||||
|
||||
public function requestAuthentication()
|
||||
{
|
||||
$token = $this->authService->generateToken();
|
||||
return response()->json($token);
|
||||
}
|
||||
}
|
||||
@ -2,25 +2,47 @@
|
||||
|
||||
namespace App\Http\Services;
|
||||
|
||||
use App\Models\AuthenticationToken;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class AuthService
|
||||
{
|
||||
/**
|
||||
* Check whether the user is authenticated
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isAuthenticated()
|
||||
{
|
||||
return false;
|
||||
$auth = request()->header('Authorization');
|
||||
|
||||
if ($auth === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$authToken = AuthenticationToken::where('token', $auth)->where('valid_until', '>', Carbon::now())->first();
|
||||
|
||||
if ($authToken === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $authToken->authenticated;
|
||||
}
|
||||
|
||||
public function authenticate()
|
||||
public function generateToken()
|
||||
{
|
||||
session()->put('auth', true);
|
||||
return AuthenticationToken::create([
|
||||
'token' => Hash::make(Str::random(32)),
|
||||
'valid_until' => Carbon::now()->addDay(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function logout()
|
||||
public function authenticate(AuthenticationToken $token)
|
||||
{
|
||||
session()->remove('auth');
|
||||
$token->authenticated = true;
|
||||
$token->save();
|
||||
}
|
||||
|
||||
public function logout(AuthenticationToken $token)
|
||||
{
|
||||
$token->authenticated = false;
|
||||
$token->save();
|
||||
}
|
||||
}
|
||||
|
||||
21
app/Models/AuthenticationToken.php
Normal file
21
app/Models/AuthenticationToken.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class AuthenticationToken extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'token',
|
||||
'valid_until',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'valid_until' => 'datetime',
|
||||
'authenticated' => 'boolean',
|
||||
];
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateAuthenticationTokensTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('authentication_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
|
||||
$table->string('token', 60); // The right size to store a hash
|
||||
$table->boolean('authenticated')->default(false);
|
||||
$table->dateTime('valid_until');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('authentication_tokens');
|
||||
}
|
||||
}
|
||||
@ -23,3 +23,5 @@ Route::get('/blog/recent', [\App\Http\Controllers\BlogArticleController::class,
|
||||
Route::get('/blog/popular', [\App\Http\Controllers\BlogArticleController::class, 'popular']);
|
||||
Route::resource('/blog', \App\Http\Controllers\BlogArticleController::class)->except(['create', 'edit']);
|
||||
|
||||
Route::get('/auth', [\App\Http\Controllers\AuthenticationController::class, 'isAuthenticated']);
|
||||
Route::post('/auth', [\App\Http\Controllers\AuthenticationController::class, 'requestAuthentication']);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user