Commit 00ac82cc authored by Jacob Priddy's avatar Jacob Priddy 👌
Browse files

Expire token use case

parent d4512fc2
......@@ -27,6 +27,8 @@ use Source\UseCases\Users\GetAllUsers\GetAllUsersUseCaseServiceProvider;
use Source\UseCases\Groups\CreateGroup\CreateGroupUseCaseServiceProvider;
use Source\UseCases\Groups\DeleteGroup\DeleteGroupUseCaseServiceProvider;
use Source\UseCases\Groups\UpdateGroup\UpdateGroupUseCaseServiceProvider;
use Source\UseCases\Tokens\CreateToken\CreateTokenUseCaseServiceProvider;
use Source\UseCases\Tokens\ExpireToken\ExpireTokenUseCaseServiceProvider;
use Source\UseCases\Token\Authenticate\AuthenticateUseCaseServiceProvider;
use Source\UseCases\Groups\GetAllGroups\GetAllGroupsUseCaseServiceProvider;
use Source\UseCases\DoorGroup\GetDoorGroups\GetDoorGroupsUseCaseServiceProvider;
......@@ -101,6 +103,10 @@ class AppServiceProvider extends ServiceProvider
DoorAuthenticateUseCaseServiceProvider::class,
UserAuthenticateUseCaseServiceProvider::class,
GenerateDoorTokenUseCaseServiceProvider::class,
// Tokens
CreateTokenUseCaseServiceProvider::class,
ExpireTokenUseCaseServiceProvider::class,
];
/**
......
......@@ -83,6 +83,19 @@ class Token
return $this->tokenString === $token;
}
/**
* @param string|null $id
* @return bool
*/
public function hasIdOf(?string $id): bool
{
if (!$id) {
return false;
}
return (int)$id === $this->id;
}
/**
* @return int
*/
......
......@@ -7,11 +7,14 @@ use App\User;
use Carbon\Carbon;
use Source\Entities\Token;
use Illuminate\Support\Str;
use Source\Sanitize\CastsTo;
use Illuminate\Database\Eloquent\Builder;
use Source\Exceptions\EntityNotFoundException;
class DatabaseTokensRepository implements TokensRepository
{
use CastsTo;
/**
* @inheritDoc
*/
......@@ -33,6 +36,10 @@ class DatabaseTokensRepository implements TokensRepository
return $this->dbTokenToToken($dbToken);
}
/**
* @param \App\Token $token
* @return \Source\Entities\Token
*/
protected function dbTokenToToken(\App\Token $token): Token
{
return new Token(
......@@ -89,4 +96,23 @@ class DatabaseTokensRepository implements TokensRepository
{
return Str::random(60);
}
/**
* @inheritDoc
*/
public function invalidateTokenById(string $tokenId): void
{
$dbToken = \App\Token::find($this->castToInt($tokenId));
if (!$dbToken) {
throw new EntityNotFoundException();
}
$token = $this->dbTokenToToken($dbToken);
if ($token->isValid()) {
$token->expires_at = Carbon::now();
$token->save();
}
}
}
......@@ -66,4 +66,16 @@ class InMemoryTokensRepository implements TokensRepository
// We don't need to do anything special
return DatabaseTokensRepository::generateTokenString();
}
/**
* @inheritDoc
*/
public function invalidateTokenById(string $tokenId): void
{
foreach ($this->tokens as $token) {
if ($token->hasIdOf($tokenId) && $token->isValid()) {
$token->setExpiresAt(Carbon::now());
}
}
}
}
......@@ -26,6 +26,12 @@ interface TokensRepository
*/
public function invalidateToken(string $token): void;
/**
* @param string $tokenId
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function invalidateTokenById(string $tokenId): void;
/**
* @return string
*/
......
<?php
namespace Source\UseCases\Tokens\ExpireToken;
use Source\UseCases\BasePresenter;
class APIPresenter extends BasePresenter implements Presenter
{
protected array $viewModel = [];
/** @inheritDoc */
public function present(ResponseModel $responseModel): void
{
$this->viewModel['message'] = $responseModel->getMessage();
}
/** @inheritDoc */
public function getViewModel(): array
{
return $this->viewModel;
}
}
<?php
namespace Source\UseCases\Tokens\ExpireToken;
use Source\Gateways\Tokens\TokensRepository;
class ExpireToken implements ExpireTokenUseCase
{
/**
* @var \Source\Gateways\Tokens\TokensRepository
*/
protected TokensRepository $tokens;
public function __construct(TokensRepository $tokens)
{
$this->tokens = $tokens;
}
/**
* @inheritDoc
*/
public function expire(string $tokenId, Presenter $presenter): void
{
$this->tokens->invalidateTokenById($tokenId);
$presenter->present(new ResponseModel('Success'));
}
}
<?php
namespace Source\UseCases\Tokens\ExpireToken;
interface ExpireTokenUseCase
{
/**
* @param string $tokenId
* @param \Source\UseCases\Tokens\ExpireToken\Presenter $presenter
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function expire(string $tokenId, Presenter $presenter): void;
}
<?php
namespace Source\UseCases\Tokens\ExpireToken;
use Source\Gateways\Tokens\TokensRepository;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
/**
* Service provider must be registered in AppServiceProvider
*/
class ExpireTokenUseCaseServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind(ExpireTokenUseCase::class, static function (Application $app) {
return new ExpireToken($app->make(TokensRepository::class));
});
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
}
/**
* @return array
*/
public function provides()
{
return [ExpireTokenUseCase::class];
}
}
<?php
namespace Source\UseCases\Tokens\ExpireToken;
interface Presenter
{
/**
* @param ResponseModel $responseModel
* @return void
*/
public function present(ResponseModel $responseModel): void;
/**
* @return array
*/
public function getViewModel(): array;
}
<?php
namespace Source\UseCases\Tokens\ExpireToken;
class ResponseModel
{
/**
* @var string
*/
protected string $message;
public function __construct(string $message)
{
$this->message = $message;
}
/**
* @return string
*/
public function getMessage(): string
{
return $this->message;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment