diff --git a/UPGRADING.md b/UPGRADING.md index bfcef207c..6a558a894 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -25,6 +25,29 @@ following steps will be done. $this->helpers = array_merge($this->helpers, ['setting']); ``` +#### Config\Auth + +The following items have been added. Copy the properties in **src/Config/Auth.php**. + +- `permission_denied` and `group_denied` are added to `Config\Auth::$redirects`. +- `permissionDeniedRedirect()` and `groupDeniedRedirect()` are added. + +### Fix Custom Filter If extends `AbstractAuthFilter` + +If you have written a custom filter that extends `AbstractAuthFilter`, now you need to add and implement the `redirectToDeniedUrl()` method to your custom filter. +The following example is related to the above explanation for **group** filter. + +```php +/** + * If the user does not belong to the group, redirect to the configured URL with an error message. + */ +protected function redirectToDeniedUrl(): RedirectResponse +{ + return redirect()->to(config('Auth')->groupDeniedRedirect()) + ->with('error', lang('Auth.notEnoughPrivilege')); +} +``` + ## Version 1.0.0-beta.6 to 1.0.0-beta.7 ### The minimum CodeIgniter version diff --git a/src/Config/Auth.php b/src/Config/Auth.php index e7ad04189..1b9bad087 100644 --- a/src/Config/Auth.php +++ b/src/Config/Auth.php @@ -65,10 +65,12 @@ class Auth extends BaseConfig * to apply any logic you may need. */ public array $redirects = [ - 'register' => '/', - 'login' => '/', - 'logout' => 'login', - 'force_reset' => '/', + 'register' => '/', + 'login' => '/', + 'logout' => 'login', + 'force_reset' => '/', + 'permission_denied' => '/', + 'group_denied' => '/', ]; /** @@ -475,6 +477,28 @@ public function forcePasswordResetRedirect(): string return $this->getUrl($url); } + /** + * Returns the URL the user should be redirected to + * if permission denied. + */ + public function permissionDeniedRedirect(): string + { + $url = setting('Auth.redirects')['permission_denied']; + + return $this->getUrl($url); + } + + /** + * Returns the URL the user should be redirected to + * if group denied. + */ + public function groupDeniedRedirect(): string + { + $url = setting('Auth.redirects')['group_denied']; + + return $this->getUrl($url); + } + /** * Accepts a string which can be an absolute URL or * a named route or just a URI path, and returns the diff --git a/src/Filters/AbstractAuthFilter.php b/src/Filters/AbstractAuthFilter.php index 750f5993a..d4a38a379 100644 --- a/src/Filters/AbstractAuthFilter.php +++ b/src/Filters/AbstractAuthFilter.php @@ -7,7 +7,6 @@ use CodeIgniter\Filters\FilterInterface; use CodeIgniter\HTTP\RedirectResponse; use CodeIgniter\HTTP\RequestInterface; -use CodeIgniter\HTTP\Response; use CodeIgniter\HTTP\ResponseInterface; /** @@ -43,20 +42,27 @@ public function before(RequestInterface $request, $arguments = null) return; } - // Otherwise, we'll just send them to the home page. - return redirect()->to('/')->with('error', lang('Auth.notEnoughPrivilege')); + return $this->redirectToDeniedUrl(); } /** * We don't have anything to do here. * - * @param Response|ResponseInterface $response - * @param array|null $arguments + * @param array|null $arguments */ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null): void { // Nothing required } + /** + * Ensures the user is logged in and has one or more + * of the permissions as specified in the filter. + */ abstract protected function isAuthorized(array $arguments): bool; + + /** + * Returns redirect response when the user does not have access authorizations. + */ + abstract protected function redirectToDeniedUrl(): RedirectResponse; } diff --git a/src/Filters/GroupFilter.php b/src/Filters/GroupFilter.php index 22e73ab4c..7c0a33b16 100644 --- a/src/Filters/GroupFilter.php +++ b/src/Filters/GroupFilter.php @@ -4,6 +4,8 @@ namespace CodeIgniter\Shield\Filters; +use CodeIgniter\HTTP\RedirectResponse; + /** * Group Authorization Filter. */ @@ -17,4 +19,13 @@ protected function isAuthorized(array $arguments): bool { return auth()->user()->inGroup(...$arguments); } + + /** + * If the user does not belong to the group, redirect to the configured URL with an error message. + */ + protected function redirectToDeniedUrl(): RedirectResponse + { + return redirect()->to(config('Auth')->groupDeniedRedirect()) + ->with('error', lang('Auth.notEnoughPrivilege')); + } } diff --git a/src/Filters/PermissionFilter.php b/src/Filters/PermissionFilter.php index 486910818..e20f7a23d 100644 --- a/src/Filters/PermissionFilter.php +++ b/src/Filters/PermissionFilter.php @@ -4,6 +4,8 @@ namespace CodeIgniter\Shield\Filters; +use CodeIgniter\HTTP\RedirectResponse; + /** * Permission Authorization Filter. */ @@ -23,4 +25,13 @@ protected function isAuthorized(array $arguments): bool return false; } + + /** + * If the user does not have the permission, redirect to the configured URL with an error message. + */ + protected function redirectToDeniedUrl(): RedirectResponse + { + return redirect()->to(config('Auth')->permissionDeniedRedirect()) + ->with('error', lang('Auth.notEnoughPrivilege')); + } } diff --git a/tests/Authentication/Filters/GroupFilterTest.php b/tests/Authentication/Filters/GroupFilterTest.php index 2690eeaff..ddfb423b1 100644 --- a/tests/Authentication/Filters/GroupFilterTest.php +++ b/tests/Authentication/Filters/GroupFilterTest.php @@ -69,8 +69,8 @@ public function testFilterIncorrectGroupNoPrevious(): void ->get('protected-route'); // Should redirect to home page since previous_url is not set - $result->assertRedirectTo(site_url('/')); + $result->assertRedirectTo(config('Auth')->groupDeniedRedirect()); // Should have error message - $result->assertSessionHas('error'); + $result->assertSessionHas('error', lang('Auth.notEnoughPrivilege')); } } diff --git a/tests/Authentication/Filters/PermissionFilterTest.php b/tests/Authentication/Filters/PermissionFilterTest.php index 140bde35b..d4580017b 100644 --- a/tests/Authentication/Filters/PermissionFilterTest.php +++ b/tests/Authentication/Filters/PermissionFilterTest.php @@ -69,8 +69,8 @@ public function testFilterIncorrectGroupNoPrevious(): void ->get('protected-route'); // Should redirect to home page since previous_url is not set - $result->assertRedirectTo(site_url('/')); + $result->assertRedirectTo(config('Auth')->permissionDeniedRedirect()); // Should have error message - $result->assertSessionHas('error'); + $result->assertSessionHas('error', lang('Auth.notEnoughPrivilege')); } }