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;
|
namespace App\Http\Services;
|
||||||
|
|
||||||
|
use App\Models\AuthenticationToken;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class AuthService
|
class AuthService
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Check whether the user is authenticated
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function isAuthenticated()
|
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::get('/blog/popular', [\App\Http\Controllers\BlogArticleController::class, 'popular']);
|
||||||
Route::resource('/blog', \App\Http\Controllers\BlogArticleController::class)->except(['create', 'edit']);
|
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