Laravel AT Protocol Client (alpha & unstable)
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add RequiresScopeMiddleware for route-level scope enforcement

+85
+85
src/Http/Middleware/RequiresScopeMiddleware.php
··· 1 + <?php 2 + 3 + namespace SocialDept\AtpClient\Http\Middleware; 4 + 5 + use Closure; 6 + use Illuminate\Http\Request; 7 + use SocialDept\AtpClient\Auth\ScopeChecker; 8 + use SocialDept\AtpClient\Contracts\HasAtpSession; 9 + use SocialDept\AtpClient\Enums\ScopeAuthorizationFailure; 10 + use SocialDept\AtpClient\Exceptions\ScopeAuthorizationException; 11 + use SocialDept\AtpClient\Session\SessionManager; 12 + use Symfony\Component\HttpFoundation\Response; 13 + 14 + class RequiresScopeMiddleware 15 + { 16 + public function __construct( 17 + protected SessionManager $sessions, 18 + protected ScopeChecker $checker, 19 + ) {} 20 + 21 + /** 22 + * Handle an incoming request. 23 + * 24 + * @param string ...$scopes 25 + */ 26 + public function handle(Request $request, Closure $next, string ...$scopes): Response 27 + { 28 + $user = $request->user(); 29 + 30 + // Ensure user is authenticated 31 + if (! $user) { 32 + return $this->handleFailure( 33 + new ScopeAuthorizationException($scopes, [], 'User not authenticated.') 34 + ); 35 + } 36 + 37 + // Ensure user implements HasAtpSession 38 + if (! $user instanceof HasAtpSession) { 39 + return $this->handleFailure( 40 + new ScopeAuthorizationException($scopes, [], 'User model must implement HasAtpSession interface.') 41 + ); 42 + } 43 + 44 + $did = $user->getAtpDid(); 45 + 46 + if (! $did) { 47 + return $this->handleFailure( 48 + new ScopeAuthorizationException($scopes, [], 'User has no ATP session.') 49 + ); 50 + } 51 + 52 + try { 53 + $session = $this->sessions->session($did); 54 + } catch (\Exception $e) { 55 + return $this->handleFailure( 56 + new ScopeAuthorizationException($scopes, [], 'Could not retrieve ATP session: '.$e->getMessage()) 57 + ); 58 + } 59 + 60 + // Check ALL scopes (AND logic) 61 + if (! $this->checker->check($session, $scopes)) { 62 + $granted = $session->scopes(); 63 + $missing = array_diff($scopes, $granted); 64 + 65 + return $this->handleFailure( 66 + new ScopeAuthorizationException($missing, $granted) 67 + ); 68 + } 69 + 70 + return $next($request); 71 + } 72 + 73 + protected function handleFailure(ScopeAuthorizationException $exception): Response 74 + { 75 + $action = config('atp-client.scope_authorization.failure_action', ScopeAuthorizationFailure::Abort); 76 + 77 + return match ($action) { 78 + ScopeAuthorizationFailure::Redirect => redirect( 79 + config('atp-client.scope_authorization.redirect_to', '/login') 80 + ), 81 + ScopeAuthorizationFailure::Exception => throw $exception, 82 + default => abort(403, $exception->getMessage()), 83 + }; 84 + } 85 + }