change namespace and cleanup code

This commit is contained in:
2022-05-14 18:21:55 +02:00
parent 76edd961b7
commit 377dc53037
46 changed files with 400 additions and 360 deletions

View File

@@ -0,0 +1,32 @@
<?php
namespace Bitinflow\Accounts\Http\Middleware;
use Bitinflow\Accounts\Exceptions\MissingScopeException;
use stdClass;
class CheckClientCredentials extends CheckCredentials
{
/**
* Validate token credentials.
*
* @param stdClass $token
* @param array $scopes
*
* @return void
* @throws MissingScopeException
*
*/
protected function validateScopes(stdClass $token, array $scopes)
{
if (in_array('*', $token->scopes)) {
return;
}
foreach ($scopes as $scope) {
if (!in_array($scope, $token->scopes)) {
throw new MissingScopeException($scopes);
}
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Bitinflow\Accounts\Http\Middleware;
use Bitinflow\Accounts\Exceptions\MissingScopeException;
use stdClass;
class CheckClientCredentialsForAnyScope extends CheckCredentials
{
/**
* Validate token credentials.
*
* @param stdClass $token
* @param array $scopes
*
* @return void
* @throws MissingScopeException
*
*/
protected function validateScopes(stdClass $token, array $scopes)
{
if (in_array('*', $token->scopes)) {
return;
}
foreach ($scopes as $scope) {
if (in_array($scope, $token->scopes)) {
return;
}
}
throw new MissingScopeException($scopes);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Bitinflow\Accounts\Http\Middleware;
use Bitinflow\Accounts\Exceptions\MissingScopeException;
use Bitinflow\Accounts\Helpers\JwtParser;
use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use stdClass;
abstract class CheckCredentials
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @param mixed ...$scopes
*
* @return mixed
* @throws AuthenticationException|MissingScopeException
*
*/
public function handle($request, Closure $next, ...$scopes)
{
$decoded = $this->getJwtParser()->decode($request);
$request->attributes->set('oauth_access_token_id', $decoded->jti);
$request->attributes->set('oauth_client_id', $decoded->aud);
//$request->attributes->set('oauth_client_trusted', $decoded->client->trusted);
$request->attributes->set('oauth_user_id', $decoded->sub);
$request->attributes->set('oauth_scopes', $decoded->scopes);
$this->validateScopes($decoded, $scopes);
return $next($request);
}
private function getJwtParser(): JwtParser
{
return app(JwtParser::class);
}
abstract protected function validateScopes(stdClass $token, array $scopes);
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Bitinflow\Accounts\Http\Middleware;
use Bitinflow\Accounts\Exceptions\MissingScopeException;
use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class CheckForAnyScope
{
/**
* Handle the incoming request.
*
* @param Request $request
* @param Closure $next
* @param mixed ...$scopes
* @return Response
*
* @throws AuthenticationException|MissingScopeException
*/
public function handle($request, $next, ...$scopes)
{
if (!$request->user() || !$request->user()->bitinflowToken()) {
throw new AuthenticationException;
}
foreach ($scopes as $scope) {
if ($request->user()->bitinflowTokenCan($scope)) {
return $next($request);
}
}
throw new MissingScopeException($scopes);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Bitinflow\Accounts\Http\Middleware;
use Bitinflow\Accounts\Exceptions\MissingScopeException;
use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class CheckScopes
{
/**
* Handle the incoming request.
*
* @param Request $request
* @param Closure $next
* @param mixed ...$scopes
* @return Response
*
* @throws AuthenticationException|MissingScopeException
*/
public function handle($request, $next, ...$scopes)
{
if (!$request->user() || !$request->user()->bitinflowToken()) {
throw new AuthenticationException;
}
foreach ($scopes as $scope) {
if (!$request->user()->bitinflowTokenCan($scope)) {
throw new MissingScopeException($scope);
}
}
return $next($request);
}
}

View File

@@ -0,0 +1,117 @@
<?php
namespace Bitinflow\Accounts\Http\Middleware;
use Bitinflow\Accounts\ApiTokenCookieFactory;
use Bitinflow\Accounts\BitinflowAccounts;
use Closure;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class CreateFreshApiToken
{
/**
* The API token cookie factory instance.
*
* @var ApiTokenCookieFactory
*/
protected $cookieFactory;
/**
* The authentication guard.
*
* @var string
*/
protected $guard;
/**
* Create a new middleware instance.
*
* @param ApiTokenCookieFactory $cookieFactory
* @return void
*/
public function __construct(ApiTokenCookieFactory $cookieFactory)
{
$this->cookieFactory = $cookieFactory;
}
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
$this->guard = $guard;
$response = $next($request);
if ($this->shouldReceiveFreshToken($request, $response)) {
$response->withCookie($this->cookieFactory->make(
$request->user($this->guard)->getAuthIdentifier(), $request->session()->token()
));
}
return $response;
}
/**
* Determine if the given request should receive a fresh token.
*
* @param Request $request
* @param Response $response
* @return bool
*/
protected function shouldReceiveFreshToken($request, $response): bool
{
return $this->requestShouldReceiveFreshToken($request) &&
$this->responseShouldReceiveFreshToken($response);
}
/**
* Determine if the request should receive a fresh token.
*
* @param Request $request
* @return bool
*/
protected function requestShouldReceiveFreshToken($request)
{
return $request->isMethod('GET') && $request->user($this->guard);
}
/**
* Determine if the response should receive a fresh token.
*
* @param Response $response
* @return bool
*/
protected function responseShouldReceiveFreshToken($response)
{
return ($response instanceof Response ||
$response instanceof JsonResponse) &&
!$this->alreadyContainsToken($response);
}
/**
* Determine if the given response already contains an API token.
*
* This avoids us overwriting a just "refreshed" token.
*
* @param Response $response
* @return bool
*/
protected function alreadyContainsToken($response): bool
{
foreach ($response->headers->getCookies() as $cookie) {
if ($cookie->getName() === BitinflowAccounts::cookie()) {
return true;
}
}
return false;
}
}