Skip to content

Commit

Permalink
Re-work the filters & Set the route name for routing in config (#444)
Browse files Browse the repository at this point in the history
* Update LoginFilter.php

* Update LoginFilter.php

* Update LoginFilter.php

use `uri_string()` to get the string from current url

* uri_string is a bad idea

I use `current_url()` and at line 51 I add an extra script in case if user use index.php :)

* Update LoginFilter.php

* use url_is() function for better solution

NOTE : Since url_is() is available start from CodeIgniter 4.0.5, user must update their application.

* a little re work for another filters

I remove the helper('auth) since it's no use in there (performance reason) and put the session check at the begin of code, because we need a session data right?

* fix

* Update PermissionFilter.php

* Candidate for BaseFilter & the reserved routes

I add defaultLandingRoute to store the default route name after user success to login (depend on the real case) or fail in Permission & Role Filters too

* Candidate for the new Filters

* Update BaseFilter.php

* extend the BaseFilter

sorry my mistake

* rename $defaultLandingRoute to $landingRoute

* just rename some strings

* Run CodeIgniter4 Coding Standards

* Update Routes.php

The Routes.php now will use reserved routing from Auth.php

* Fix typo

* Apply analysis fixes

Co-authored-by: MGatner <mgatner@icloud.com>
  • Loading branch information
mjamilasfihani and MGatner committed Jul 12, 2022
1 parent 1d1f074 commit 100822e
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 77 deletions.
37 changes: 37 additions & 0 deletions src/Config/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,43 @@ class Auth extends BaseConfig
*/
public $defaultUserGroup;

/**
* --------------------------------------------------------------------
* Landing Route
* --------------------------------------------------------------------
*
* This is your landing page (route name) after user success to login,
* i.e $landingRoute = 'dashboard'.
*
* If you set $silent = true the Permission and Role filters will
* use this config too for the routing.
*
* @var string
*/
public $landingRoute = '/';

/**
* --------------------------------------------------------------------
* Reserverd Routes
* --------------------------------------------------------------------
*
* The auth routes config is listed in here and you can customize it,
* i.e. $reservedRoutes = ['forgot' => 'forgot-password'].
*
* Do Not Change The Key!!! Because it's the identity for routing.
*
* @var array
*/
public $reservedRoutes = [
'login' => 'login',
'logout' => 'logout',
'register' => 'register',
'activate-account' => 'activate-account',
'resend-activate-account' => 'resend-activate-account',
'forgot' => 'forgot',
'reset-password' => 'reset-password',
];

/**
* --------------------------------------------------------------------
* Libraries
Expand Down
28 changes: 17 additions & 11 deletions src/Config/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,32 @@
namespace Myth\Auth\Config;

use CodeIgniter\Router\RouteCollection;
use Myth\Auth\Config\Auth as AuthConfig;

/** @var RouteCollection $routes */

// Myth:Auth routes file.
$routes->group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) {
// Load the reserved routes from Auth.php
$config = config(AuthConfig::class);
$reservedRoutes = $config->reservedRoutes;

// Login/out
$routes->get('login', 'AuthController::login', ['as' => 'login']);
$routes->post('login', 'AuthController::attemptLogin');
$routes->get('logout', 'AuthController::logout');
$routes->get($reservedRoutes['login'], 'Auth::login', ['as' => $reservedRoutes['login']]);
$routes->post($reservedRoutes['login'], 'Auth::attemptLogin');
$routes->get($reservedRoutes['logout'], 'Auth::logout');

// Registration
$routes->get('register', 'AuthController::register', ['as' => 'register']);
$routes->post('register', 'AuthController::attemptRegister');
$routes->get($reservedRoutes['register'], 'Auth::register', ['as' => $reservedRoutes['register']]);
$routes->post($reservedRoutes['register'], 'Auth::attemptRegister');

// Activation
$routes->get('activate-account', 'AuthController::activateAccount', ['as' => 'activate-account']);
$routes->get('resend-activate-account', 'AuthController::resendActivateAccount', ['as' => 'resend-activate-account']);
$routes->get($reservedRoutes['activate-account'], 'Auth::activateAccount', ['as' => $reservedRoutes['activate-account']]);
$routes->get($reservedRoutes['resend-activate-account'], 'Auth::resendActivateAccount', ['as' => $reservedRoutes['resend-activate-account']]);

// Forgot/Resets
$routes->get('forgot', 'AuthController::forgotPassword', ['as' => 'forgot']);
$routes->post('forgot', 'AuthController::attemptForgot');
$routes->get('reset-password', 'AuthController::resetPassword', ['as' => 'reset-password']);
$routes->post('reset-password', 'AuthController::attemptReset');
$routes->get($reservedRoutes['forgot'], 'Auth::forgotPassword', ['as' => $reservedRoutes['forgot']]);
$routes->post($reservedRoutes['forgot'], 'Auth::attemptForgot');
$routes->get($reservedRoutes['reset-password'], 'Auth::resetPassword', ['as' => $reservedRoutes['reset-password']]);
$routes->post($reservedRoutes['reset-password'], 'Auth::attemptReset');
});
52 changes: 52 additions & 0 deletions src/Filters/BaseFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Myth\Auth\Filters;

use Myth\Auth\Config\Auth as AuthConfig;

abstract class BaseFilter
{
/**
* Landing Route
*/
protected $landingRoute;

/**
* Reserved Routes
*/
protected $reservedRoutes;

/**
* Authenticate
*/
protected $authenticate;

/**
* Authorize
*/
protected $authorize;

/**
* Constructor
*/
public function __construct()
{
// Load the Auth config, for constructor only!!!
$config = config(AuthConfig::class);

// Load the routes
$this->landingRoute = $config->landingRoute;
$this->reservedRoutes = $config->reservedRoutes;

// Load the authenticate service
$this->authenticate = service('authentication');

// Load the authorize service
$this->authorize = service('authorization');

// Load the helper
if (! function_exists('logged_in')) {
helper('auth');
}
}
}
33 changes: 9 additions & 24 deletions src/Filters/LoginFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Config\App;

class LoginFilter implements FilterInterface
class LoginFilter extends BaseFilter implements FilterInterface
{
/**
* Verifies that a user is logged in, or redirects to login.
Expand All @@ -19,32 +18,18 @@ class LoginFilter implements FilterInterface
*/
public function before(RequestInterface $request, $arguments = null)
{
if (! function_exists('logged_in')) {
helper('auth');
// Make sure this isn't already a Myth\Auth routes.
foreach ($this->reservedRoutes as $reservedRoute) {
if (url_is(route_to($reservedRoute))) {
return;
}
}

$current = (string) current_url(true)
->setHost('')
->setScheme('')
->stripQuery('token');

$config = config(App::class);
if ($config->forceGlobalSecureRequests) {
// Remove "https:/"
$current = substr($current, 7);
}

// Make sure this isn't already a login route
if (in_array($current, [route_to('login'), route_to('forgot'), route_to('reset-password'), route_to('register'), route_to('activate-account')], true)) {
return;
}

// if no user is logged in then send to the login form
$authenticate = service('authentication');
if (! $authenticate->check()) {
// If no user is logged in then send them to the login form.
if (! $this->authenticate->check()) {
session()->set('redirect_url', current_url());

return redirect('login');
return redirect($this->reservedRoutes['login']);
}
}

Expand Down
31 changes: 10 additions & 21 deletions src/Filters/PermissionFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use CodeIgniter\HTTP\ResponseInterface;
use Myth\Auth\Exceptions\PermissionException;

class PermissionFilter implements FilterInterface
class PermissionFilter extends BaseFilter implements FilterInterface
{
/**
* @param array|null $arguments
Expand All @@ -17,34 +17,27 @@ class PermissionFilter implements FilterInterface
*/
public function before(RequestInterface $request, $arguments = null)
{
if (! function_exists('logged_in')) {
helper('auth');
// If no user is logged in then send them to the login form.
if (! $this->authenticate->check()) {
session()->set('redirect_url', current_url());

return redirect($this->reservedRoutes['login']);
}

if (empty($arguments)) {
return;
}

$authenticate = service('authentication');

// if no user is logged in then send to the login form
if (! $authenticate->check()) {
session()->set('redirect_url', current_url());

return redirect('login');
}

$authorize = service('authorization');
$result = true;
$result = true;

// Check each requested permission
foreach ($arguments as $permission) {
$result = $result && $authorize->hasPermission($permission, $authenticate->id());
$result = ($result && $this->authorize->hasPermission($permission, $this->authenticate->id()));
}

if (! $result) {
if ($authenticate->silent()) {
$redirectURL = session('redirect_url') ?? '/';
if ($this->authenticate->silent()) {
$redirectURL = session('redirect_url') ?? route_to($this->landingRoute);
unset($_SESSION['redirect_url']);

return redirect()->to($redirectURL)->with('error', lang('Auth.notEnoughPrivilege'));
Expand All @@ -54,8 +47,6 @@ public function before(RequestInterface $request, $arguments = null)
}
}

//--------------------------------------------------------------------

/**
* Allows After filters to inspect and modify the response
* object as needed. This method does not allow any way
Expand All @@ -69,6 +60,4 @@ public function before(RequestInterface $request, $arguments = null)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}

//--------------------------------------------------------------------
}
30 changes: 9 additions & 21 deletions src/Filters/RoleFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use CodeIgniter\HTTP\ResponseInterface;
use Myth\Auth\Exceptions\PermissionException;

class RoleFilter implements FilterInterface
class RoleFilter extends BaseFilter implements FilterInterface
{
/**
* @param array|null $arguments
Expand All @@ -17,34 +17,26 @@ class RoleFilter implements FilterInterface
*/
public function before(RequestInterface $request, $arguments = null)
{
if (! function_exists('logged_in')) {
helper('auth');
// If no user is logged in then send them to the login form.
if (! $this->authenticate->check()) {
session()->set('redirect_url', current_url());

return redirect($this->reservedRoutes['login']);
}

if (empty($arguments)) {
return;
}

$authenticate = service('authentication');

// if no user is logged in then send to the login form
if (! $authenticate->check()) {
session()->set('redirect_url', current_url());

return redirect('login');
}

$authorize = service('authorization');

// Check each requested permission
foreach ($arguments as $group) {
if ($authorize->inGroup($group, $authenticate->id())) {
if ($this->authorize->inGroup($group, $this->authenticate->id())) {
return;
}
}

if ($authenticate->silent()) {
$redirectURL = session('redirect_url') ?? '/';
if ($this->authenticate->silent()) {
$redirectURL = session('redirect_url') ?? route_to($this->landingRoute);
unset($_SESSION['redirect_url']);

return redirect()->to($redirectURL)->with('error', lang('Auth.notEnoughPrivilege'));
Expand All @@ -53,8 +45,6 @@ public function before(RequestInterface $request, $arguments = null)
throw new PermissionException(lang('Auth.notEnoughPrivilege'));
}

//--------------------------------------------------------------------

/**
* Allows After filters to inspect and modify the response
* object as needed. This method does not allow any way
Expand All @@ -68,6 +58,4 @@ public function before(RequestInterface $request, $arguments = null)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}

//--------------------------------------------------------------------
}

0 comments on commit 100822e

Please sign in to comment.