From 51e05643fd2e85ac75a19bec6d718d2c68c14dd2 Mon Sep 17 00:00:00 2001 From: Adam Pippin Date: Thu, 15 Jul 2021 12:31:22 -0700 Subject: [PATCH] Resolve all issues identified by phan --- .phan/config.php | 5 +- .phan/stubs/Auth.php | 6 +- .phan/stubs/Cache.php | 3 + .phan/stubs/Route.php | 3 + .phan/stubs/Session.php | 3 + .phan/stubs/Storage.php | 3 + composer.json | 4 + examples/custom/composer.lock | 10 ++- src/Authkit2.php | 73 +++++++++++++++++-- .../Controllers/AuthenticationController.php | 35 ++++++++- src/Models/Token.php | 20 ++++- src/Observers/UserObserver.php | 62 +++++++++++++--- src/Oidc/Authentication/Authentication.php | 19 ++++- .../Authentication/ClientAuthentication.php | 6 +- .../Authentication/TokenAuthentication.php | 15 +++- src/Oidc/Client.php | 66 +++++++++++++---- src/Oidc/Flows/ServiceAccountFlow.php | 1 - src/Oidc/Flows/UserFlow.php | 3 +- src/Oidc/Token.php | 46 ++++++------ src/Providers/Authkit2ServiceProvider.php | 3 + src/Providers/AuthnServiceProvider.php | 9 ++- src/Providers/AuthzServiceProvider.php | 10 +++ 22 files changed, 319 insertions(+), 86 deletions(-) create mode 100644 .phan/stubs/Cache.php create mode 100644 .phan/stubs/Route.php create mode 100644 .phan/stubs/Session.php create mode 100644 .phan/stubs/Storage.php diff --git a/.phan/config.php b/.phan/config.php index 5d05d9c..287ba40 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -10,7 +10,10 @@ return [ 'src/', 'vendor/laravel/', 'vendor/composer/', - 'vendor/symfony/' + 'vendor/symfony/', + 'vendor/guzzlehttp/', + 'vendor/psr/', + 'vendor/firebase/' ], 'exclude_analysis_directory_list' => [ diff --git a/.phan/stubs/Auth.php b/.phan/stubs/Auth.php index cbb9678..27d07b1 100644 --- a/.phan/stubs/Auth.php +++ b/.phan/stubs/Auth.php @@ -1,7 +1,3 @@ function(string $key) { return \Session::get($key); }, - 'session_set' => function(string $key, $value) { \Session::put($key, $value); }, - 'cache_get' => function(string $key) { return \Cache::get($key); }, - 'cache_set' => function(string $key, $value) { \Cache::set($key, $value); } + 'session_get' => + /** + * Fetch a variable from the session + * @param string $key + * @return mixed + */ + function(string $key) { return \Session::get($key); }, + 'session_set' => + /** + * Set a variable in the session + * @param string $key + * @param mixed $value + * @return void + */ + function(string $key, $value): void { \Session::put($key, $value); }, + 'cache_get' => + /** + * Fetch a value from cache + * @param string $key + * @return mixed + */ + function(string $key) { return \Cache::get($key); }, + 'cache_set' => + /** + * Set a value in cache + * @param string $key + * @param mixed $value + * @return void + */ + function(string $key, $value): void { \Cache::set($key, $value); } ]; } @@ -250,22 +276,55 @@ class Authkit2 { } + /** + * Configure the authkit2 library + * + * @param string $client_id + * @param string $client_secret + * @param string $endpoint + * @return void + */ protected function ak2_configure(string $client_id, string $client_secret, string $endpoint): void { $this->client = new \authkit2\Oidc\Client($endpoint, $client_id, $client_secret); } + /** + * Fetch a OIDC client authenticated as this application + * + * @return Oidc\Client + */ protected function ak2_get_client(): Oidc\Client { return $this->client; } + /** + * Given the essential values from a token (access token, refresh token), + * convert that into a Token object that can be used to make and authenticate + * requests. + * + * The refresh token is not strictly required, however if the token is + * expired then requests will simply fail. This use case is intended for + * authenticating requests using tokens other applications have sent to us. + * + * @param string $access_token + * @param ?string $refresh_token + * @return Oidc\Token + */ protected function ak2_get_token(string $access_token, ?string $refresh_token = null): Oidc\Token { return Oidc\Token::fromString($this->client, $access_token, $refresh_token); } - protected function ak2_refresh_token(Oidc\Token $token): Token + /** + * Refresh a token object -- generate a new access token from its + * refresh_token. + * + * @param Oidc\Token $token + * @return Oidc\Token a newly generated token + */ + protected function ak2_refresh_token(Oidc\Token $token): Oidc\Token { return $this->client->refreshToken($token); } diff --git a/src/Http/Controllers/AuthenticationController.php b/src/Http/Controllers/AuthenticationController.php index db072d2..e2b235b 100644 --- a/src/Http/Controllers/AuthenticationController.php +++ b/src/Http/Controllers/AuthenticationController.php @@ -11,6 +11,10 @@ use authkit2\Models\Token; */ class AuthenticationController extends Controller { + /** + * OIDC flow to mediate the actual login process and exchanges + * @var \authkit2\Oidc\Flows\UserFlow + */ protected $user_flow; public function __construct(\authkit2\Oidc\Flows\UserFlow $user_flow) @@ -44,7 +48,7 @@ class AuthenticationController extends Controller */ public function callback(Request $request) { - $user_class = config('auth.providers.users.model'); + $user_class = (string)config('auth.providers.users.model'); // Verify the passed in state value $this->user_flow->validateState($request->state); @@ -86,17 +90,36 @@ class AuthenticationController extends Controller } } + // TODO: Log a useful error message in these cases if (!isset($user)) { - // TODO: Log a useful error message abort(500); + die(); + } + else if (!method_exists($user, 'save')) + { + abort(500); + die(); + } + else if (!method_exists($user, 'getAuthIdentifierName')) + { + abort(500); + die(); } $token = new Token(); $token->id = $oidc_token->getUserId(); $token->access_token = $oidc_token->getAccessToken(); - $token->refresh_token = $oidc_token->getRefreshToken(); + $refresh_token = $oidc_token->getRefreshToken(); + if (!isset($refresh_token)) + { + abort(500); + die(); + } + $token->refresh_token = $refresh_token; + // @phan-suppress-next-line PhanNonClassMethodCall $token->user_id = $user->{$user->getAuthIdentifierName()}; + // @phan-suppress-next-line PhanNonClassMethodCall $token->save(); } else @@ -109,10 +132,16 @@ class AuthenticationController extends Controller $login_event_result = event(new \authkit2\Events\UserLogin($user, $user_info)); if (!sizeof($login_event_result)) { + if (!isset($user) || !method_exists($user, 'save')) + { + // TODO: Log a useful error message + abort(500); + } // If nothing handled the login event, assume we're using laravel default // everything and just go ahead and update the name/email $user->name = $user_info['name']; $user->email = $user_info['email']; + // @phan-suppress-next-line PhanNonClassMethodCall $user->save(); } diff --git a/src/Models/Token.php b/src/Models/Token.php index 4f6e62d..fde8bbd 100644 --- a/src/Models/Token.php +++ b/src/Models/Token.php @@ -7,14 +7,26 @@ use \Illuminate\Database\Eloquent\Model; /** * User's OIDC token * - * @property string id - * @property int user_id - * @property string access_token - * @property string refresh_token + * @property string $id + * @property int $user_id + * @property string $access_token + * @property string $refresh_token */ class Token extends Model { + /** + * Override the default generated table name so we can namespace this and + * avoid conflicting with anything the app might already be using. + * + * @var string + */ protected $table = 'authkit2_token'; + + /** + * Disable Eloquent's default created/updated fields + * + * @var bool + */ public $timestamps = false; } diff --git a/src/Observers/UserObserver.php b/src/Observers/UserObserver.php index 20d2b93..7ef2e1c 100644 --- a/src/Observers/UserObserver.php +++ b/src/Observers/UserObserver.php @@ -4,15 +4,30 @@ namespace authkit2\Observers; use authkit2\Authkit2; use authkit2\Models\Token; +/** + * Watch for user models being loaded or saved and handle installing an + * `authkit` object on them to allow the main application to easily interact + * with other services as the user or fetch data from the OIDC provider. + */ class UserObserver { - /*'retrieved', 'creating', 'created', 'updating', 'updated', - 'saving', 'saved', 'restoring', 'restored', 'replicating', - 'deleting', 'deleted', 'forceDeleted',*/ - + /** + * When a user model is saved we have to remove the authkit property from it + * to avoid Eloquent or another ORM from trying to save it. When we do so, + * we cache it here so we can restore it when the save is complete. + * + * @var array + */ protected static $token_cache = []; - public function retrieved($user) + /** + * Run in response to a user model being loaded, locating their token and + * creating a client to place on the model + * + * @param mixed $user + * @return void + */ + public function retrieved($user): void { // Find the token + refresh token for the user $token = Token::where('user_id', $user->{$user->getAuthIdentifierName()})->first(); @@ -22,25 +37,48 @@ class UserObserver // Set a refresh callback on the token -- when it's been refreshed, // save the new tokens. - $user->authkit->setRefreshCallback(function($oidc_token) use ($token) { - $token->access_token = $oidc_token->getAccessToken(); - $token->refresh_token = $oidc_token->getRefreshToken(); - $token->save(); - }); + $user->authkit->setRefreshCallback( + /** + * When a token has been refreshed, save the updated values + * to the token model + * @param \authkit2\Oidc\Token $oidc_token + * @return void + */ + function(\authkit2\Oidc\Token $oidc_token) use ($token) : void { + $token->access_token = $oidc_token->getAccessToken(); + $token->refresh_token = $oidc_token->getRefreshToken(); + $token->save(); + }); } - public function saving($user) + /** + * Before we save a user model, remove the token/client so the ORM doesn't + * try and write those out. + * + * @param mixed $user + * @return void + */ + public function saving($user): void { if (isset($user->authkit)) static::$token_cache[$user->{$user->getAuthIdentifierName()}] = $user->authkit; unset($user->authkit); } - public function saved($user) + /** + * After a user model is saved, restore the client and token + * + * @param mixed $user + * @return void + */ + public function saved($user): void { $user_id = $user->{$user->getAuthIdentifierName()}; if (isset(static::$token_cache[$user_id])) + { $user->authkit = static::$token_cache[$user_id]; + unset(static::$token_cache[$user_id]); + } } } diff --git a/src/Oidc/Authentication/Authentication.php b/src/Oidc/Authentication/Authentication.php index 379dcdb..22bc7f3 100644 --- a/src/Oidc/Authentication/Authentication.php +++ b/src/Oidc/Authentication/Authentication.php @@ -10,10 +10,10 @@ abstract class Authentication /** * Authenticate the passed in HTTP request * - * @param \GuzzleHttp\Psr7\Request $request request to authenticate - * @return \GuzzleHttp\Psr7\Request authenticated request + * @param \Psr\Http\Message\RequestInterface $request request to authenticate + * @return \Psr\Http\Message\RequestInterface authenticated request */ - public abstract function authenticate(\GuzzleHttp\Psr7\Request $request): \GuzzleHttp\Psr7\Request; + public abstract function authenticate(\Psr\Http\Message\RequestInterface $request): \Psr\Http\Message\RequestInterface; /** * Wrap this provider up as a middleware appropriate for use directly with @@ -24,7 +24,12 @@ abstract class Authentication public function getMiddleware(): callable { $auth = $this; - return function(callable $handler) use ($auth) { + return function(callable $handler) use ($auth) : callable { + /** + * @param \Psr\Http\Message\RequestInterface $request + * @param mixed[] $options + * @return mixed + */ return function(\Psr\Http\Message\RequestInterface $request, array $options) use ($handler, $auth) { return $handler( $auth->authenticate($request), @@ -34,6 +39,12 @@ abstract class Authentication }; } + /** + * Fetch a guzzle client with the authentication middleware included + * + * @param mixed[] $options options to pass through to the guzzle client + * @return \GuzzleHttp\Client + */ public function getClient(array $options = []): \GuzzleHttp\Client { $stack = new \GuzzleHttp\HandlerStack(); diff --git a/src/Oidc/Authentication/ClientAuthentication.php b/src/Oidc/Authentication/ClientAuthentication.php index 86a0e2b..aeb23f2 100644 --- a/src/Oidc/Authentication/ClientAuthentication.php +++ b/src/Oidc/Authentication/ClientAuthentication.php @@ -37,10 +37,10 @@ class ClientAuthentication extends Authentication * Client authentication uses HTTP basic authentication with the client id * as the username and the client secret as the password. * - * @param \GuzzleHttp\Psr7\Request $request request to authenticate - * @return \GuzzleHttp\Psr7\Request authenticated request + * @param \Psr\Http\Message\RequestInterface $request request to authenticate + * @return \Psr\Http\Message\RequestInterface authenticated request */ - public function authenticate(\GuzzleHttp\Psr7\Request $request): \GuzzleHttp\Psr7\Request + public function authenticate(\Psr\Http\Message\RequestInterface $request): \Psr\Http\Message\RequestInterface { return $request->withHeader('Authorization', 'Basic '.base64_encode($this->client_id.':'.$this->client_secret)); } diff --git a/src/Oidc/Authentication/TokenAuthentication.php b/src/Oidc/Authentication/TokenAuthentication.php index 19be8d9..e0bb12e 100644 --- a/src/Oidc/Authentication/TokenAuthentication.php +++ b/src/Oidc/Authentication/TokenAuthentication.php @@ -17,7 +17,7 @@ class TokenAuthentication extends Authentication /** * Who to call if the token is expired - * @var callable + * @var ?callable */ protected $refresh_callback; @@ -25,6 +25,7 @@ class TokenAuthentication extends Authentication * Create a new token authentication provider * * @param Token $token token to authenticate requests with + * @param ?callable $refreshCallback callback to generate us a new token when our existing one expires */ public function __construct(Token $token, callable $refreshCallback = null) { @@ -32,6 +33,12 @@ class TokenAuthentication extends Authentication $this->refresh_callback = $refreshCallback; } + /** + * Set the callback to be called when the underlying token expires + * + * @param callable $refreshCallback + * @return void + */ public function setRefreshCallback(callable $refreshCallback): void { $this->refresh_callback = $refreshCallback; @@ -42,10 +49,10 @@ class TokenAuthentication extends Authentication * * Token authentication uses the token as a bearer token. * - * @param \GuzzleHttp\Psr7\Request $request request to authenticate - * @return \GuzzleHttp\Psr7\Request authenticated request + * @param \Psr\Http\Message\RequestInterface $request request to authenticate + * @return \Psr\Http\Message\RequestInterface authenticated request */ - public function authenticate(\GuzzleHttp\Psr7\Request $request): \GuzzleHttp\Psr7\Request + public function authenticate(\Psr\Http\Message\RequestInterface $request): \Psr\Http\Message\RequestInterface { if ($this->token->isExpired() && isset($this->refresh_callback)) { diff --git a/src/Oidc/Client.php b/src/Oidc/Client.php index 4e77dd4..241d3b2 100644 --- a/src/Oidc/Client.php +++ b/src/Oidc/Client.php @@ -35,7 +35,7 @@ class Client /** * OIDC config fetched from the server or restored from cache - * @var array + * @var ?array */ protected $oidc_config; @@ -76,7 +76,7 @@ class Client * * @return ?string */ - public function getUrl(): string + public function getUrl(): ?string { return $this->oidc_url; } @@ -84,17 +84,22 @@ class Client /** * Get the OpenId Connect configuration * - * @return array + * @return array */ public function getConfiguration(): array { if (!isset($this->oidc_config)) { $url = $this->oidc_url; - $this->oidc_config = Authkit2::cache('oidc.config.'.md5($this->oidc_url), function() use ($url) { - $response = (new \GuzzleHttp\Client())->get($url.'/.well-known/openid-configuration'); - return json_decode($response->getBody(), true); - }); + $this->oidc_config = Authkit2::cache('oidc.config.'.md5($this->oidc_url), + /** + * @return array + */ + function() use ($url) { + $response = (new \GuzzleHttp\Client())->get($url.'/.well-known/openid-configuration'); + return json_decode($response->getBody(), true); + } + ); } return $this->oidc_config; @@ -110,10 +115,15 @@ class Client if (!isset($this->oidc_jwks)) { $client = $this; - $this->oidc_jwks = Authkit2::cache('oidc.config.'.md5($this->oidc_url).'.jwks', function() use ($client) { - $response = $client->get($client->getConfiguration()['jwks_uri']); - return json_decode(json_encode($response), true); - }); + $this->oidc_jwks = Authkit2::cache('oidc.config.'.md5($this->oidc_url).'.jwks', + /** + * @return array + */ + function() use ($client) { + $response = $client->get($client->getConfiguration()['jwks_uri']); + return json_decode(json_encode($response), true); + } + ); } return $this->oidc_jwks; } @@ -219,6 +229,15 @@ class Client return Token::fromResponse($this, $response); } + /** + * Generate the URL to redirect to in order to initiate the three-legged + * oauth flow + * + * @param string $redirect_uri url to redirect the user to after authentication + * @param string[] $scopes scopes to request from the openid provider + * @param string $state nonce + * @return string fully formed url + */ public function createAuthorizationRedirectUrl(string $redirect_uri, array $scopes, string $state): string { return $this->getEndpointUrl('authorization').'?'.http_build_query([ @@ -230,6 +249,13 @@ class Client ]); } + /** + * Generate the URL to redirect to in order to initiate a signout from the + * OIDC provider + * + * @param string $redirect_uri url to redirect the user to after logout + * @return string fully formed url + */ public function createLogoutUrl(string $redirect_uri): string { return $this->getEndpointUrl('end_session').'?'.http_build_query([ @@ -237,11 +263,26 @@ class Client ]); } + /** + * Refresh a token using a refresh token + * + * @param Token $token expired token that includes a refresh token + * @return Token newly generated token + */ public function refreshToken(Token $token): Token { - return $this->createTokenFromRefreshToken($token->getRefreshToken()); + $refresh_token = $token->getRefreshToken(); + if (!isset($refresh_token)) + throw new \Exception("Cannot refresh token initialized without refresh token"); + return $this->createTokenFromRefreshToken($refresh_token); } + /** + * Fetch the available information on the user from the OIDC provider + * + * @param Token $token token representing the user + * @return array + */ public function getTokenUserInfo(Token $token): array { return json_decode($token->getClient()->get($this->getEndpointUrl('userinfo'))->getBody(), true); @@ -249,5 +290,4 @@ class Client // todo: introspect, etc - } diff --git a/src/Oidc/Flows/ServiceAccountFlow.php b/src/Oidc/Flows/ServiceAccountFlow.php index bc74e10..49f2554 100644 --- a/src/Oidc/Flows/ServiceAccountFlow.php +++ b/src/Oidc/Flows/ServiceAccountFlow.php @@ -2,7 +2,6 @@ namespace authkit2\Oidc\Flows; use authkit2\Oidc\Client; -use authkit2\Oidc\Authentication\ClientAuthentication; use authkit2\Oidc\Token; /** diff --git a/src/Oidc/Flows/UserFlow.php b/src/Oidc/Flows/UserFlow.php index 012a8c1..145a80f 100644 --- a/src/Oidc/Flows/UserFlow.php +++ b/src/Oidc/Flows/UserFlow.php @@ -3,7 +3,6 @@ namespace authkit2\Oidc\Flows; use authkit2\Authkit2; use authkit2\Oidc\Client; -use authkit2\Oidc\Authentication\ClientAuthentication; use authkit2\Oidc\Token; /** @@ -74,8 +73,8 @@ class UserFlow * * THIS DOES NOT VALIDATE THE STATE. Call validateState first. * - * @param string $redirect_uri url the oidc endpoint redirects back to; must match one given in call to getRedirectUrl * @param string $code code returned by the authorization flow + * @param string $redirect_uri url the oidc endpoint redirects back to; must match one given in call to getRedirectUrl * @return Token */ public function exchangeCodeForToken(string $code, string $redirect_uri): Token diff --git a/src/Oidc/Token.php b/src/Oidc/Token.php index bfccdf2..d33886c 100644 --- a/src/Oidc/Token.php +++ b/src/Oidc/Token.php @@ -1,7 +1,6 @@ $options * @return \GuzzleHttp\Client */ public function getClient(array $options = []): \GuzzleHttp\Client @@ -90,26 +89,29 @@ class Token // to ask it to refresh itself $state = new \stdClass(); - $state->refresher = function($token) use ($state) { - $client = $this->client; - $refresh_callback = $this->refresh_callback; + $state->refresher = + function(Token $token) use ($state) : Token { + $client = $this->client; + $refresh_callback = $this->refresh_callback; - // Refresh the token - $new_token = $client->createTokenFromRefreshToken($this->refresh_token); + // Refresh the token + if (!isset($this->refresh_token)) + throw new \Exception("Token expired"); + $new_token = $client->createTokenFromRefreshToken($this->refresh_token); - // Rebind this callback to the new token - $state->refresher->bindTo($new_token); + // Rebind this callback to the new token + $state->refresher->bindTo($new_token); - // Call the refresh callback - if (isset($refresh_callback)) - { - // Copy over the token-level refresh callback - $new_token->setRefreshCallback($refresh_callback); - $refresh_callback($new_token); - } + // Call the refresh callback + if (isset($refresh_callback)) + { + // Copy over the token-level refresh callback + $new_token->setRefreshCallback($refresh_callback); + $refresh_callback($new_token); + } - return $new_token; - }; + return $new_token; + }; $auth = new Authentication\TokenAuthentication($this, $state->refresher); return $auth->getClient($options); @@ -171,7 +173,7 @@ class Token } $this->refresh_token_data = json_decode(json_encode($this->decode($this->refresh_token)), true); } - return $this->token_data; + return $this->refresh_token_data; } /** @@ -266,9 +268,9 @@ class Token /** * Fetch the user's refresh token * - * @return string + * @return ?string */ - public function getRefreshToken(): string + public function getRefreshToken(): ?string { return $this->refresh_token; } diff --git a/src/Providers/Authkit2ServiceProvider.php b/src/Providers/Authkit2ServiceProvider.php index b2b8289..4ae7edc 100644 --- a/src/Providers/Authkit2ServiceProvider.php +++ b/src/Providers/Authkit2ServiceProvider.php @@ -4,6 +4,9 @@ namespace authkit2\Providers; use Illuminate\Support\ServiceProvider; +/** + * Core Authkit2 provider + */ class Authkit2ServiceProvider extends ServiceProvider { diff --git a/src/Providers/AuthnServiceProvider.php b/src/Providers/AuthnServiceProvider.php index 45ee712..30d20de 100644 --- a/src/Providers/AuthnServiceProvider.php +++ b/src/Providers/AuthnServiceProvider.php @@ -19,10 +19,10 @@ class AuthnServiceProvider extends ServiceProvider */ public function register(): void { - $this->app->singleton(\authkit2\Oidc\Flows\ServiceAccountFlow::class, function($app) { + $this->app->singleton(\authkit2\Oidc\Flows\ServiceAccountFlow::class, function() : \authkit2\Oidc\Flows\ServiceAccountFlow { return new \authkit2\Oidc\Flows\ServiceAccountFlow(Authkit2::get_client()); }); - $this->app->singleton(\authkit2\Oidc\Flows\UserFlow::class, function($app) { + $this->app->singleton(\authkit2\Oidc\Flows\UserFlow::class, function() : \authkit2\Oidc\Flows\UserFlow { return new \authkit2\Oidc\Flows\UserFlow(Authkit2::get_client()); }); } @@ -36,7 +36,7 @@ class AuthnServiceProvider extends ServiceProvider { // register our observer on the user model so we can dynamically add/remove // the token object + client - $user_model = config('auth.providers.users.model'); + $user_model = (string)config('auth.providers.users.model'); $user_model::observe(\authkit2\Observers\UserObserver::class); // Register all authentication routes @@ -66,6 +66,7 @@ class AuthnServiceProvider extends ServiceProvider // TODO: For some reason route($name) isn't working here. We're // just looking through the routes manually for now... + // @phan-suppress-next-line PhanTypeNoPropertiesForeach foreach (\Route::getRoutes() as $route) { if ($route->getName() === 'login.callback') @@ -124,7 +125,7 @@ class AuthnServiceProvider extends ServiceProvider // running a composer require/composer install without credentials present. if (config('authkit.authn.openid.client_id') != null && config('authkit.authn.openid.client_secret') != null && config('authkit.authn.openid.endpoint') != null) { - $this->app->booted(function($app) { + $this->app->booted(function() { Authkit2::configure(config('authkit.authn.openid.client_id'), config('authkit.authn.openid.client_secret'), config('authkit.authn.openid.endpoint')); }); } diff --git a/src/Providers/AuthzServiceProvider.php b/src/Providers/AuthzServiceProvider.php index 3503455..ab4b403 100644 --- a/src/Providers/AuthzServiceProvider.php +++ b/src/Providers/AuthzServiceProvider.php @@ -12,10 +12,20 @@ use Illuminate\Support\ServiceProvider; */ class AuthzServiceProvider extends ServiceProvider { + /** + * Register the additional service providers the authorization process depends on + * + * @return void + */ public function register() { } + /** + * Initialize and register all authorization resources + * + * @return void + */ public function boot() { }