Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# Upgrade Guide

## Version 1.0.0-beta.7 to 1.0.0-beta.8

### Mandatory Config Changes

#### Helper Autoloading

Helper autoloading has been changed to be done by CodeIgniter's autoloader
instead of Composer.

So you need to update the settings. Run `php spark shield:setup` again, and the
following steps will be done.

1. Add `auth` and `setting` to the `$helpers` array in **app/Config/Autoload.php**:

```php
public $helpers = ['auth', 'setting'];
```

2. Remove the following code in the `initController()` method in
`**app/Controllers/BaseController.php**:

```php
$this->helpers = array_merge($this->helpers, ['setting']);
```

## Version 1.0.0-beta.6 to 1.0.0-beta.7

### The minimum CodeIgniter version
Expand Down
3 changes: 0 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@
"psr-4": {
"CodeIgniter\\Shield\\": "src"
},
"files": [
"src/Helpers/auth_helper.php"
],
"exclude-from-classmap": [
"**/Database/Migrations/**"
]
Expand Down
29 changes: 14 additions & 15 deletions docs/getting_started/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ your project.

### Manual Setup

1. Copy the **Auth.php**, **AuthGroups.php**, and **AuthToken.php** from **vendor/codeigniter4/shield/src/Config/** into your project's config folder and update the namespace to `Config`. You will also need to have these classes extend the original classes. See the example below. These files contain all the settings, group, and permission information for your application and will need to be modified to meet the needs of your site.
1. **Config Setup:**
Copy the **Auth.php**, **AuthGroups.php**, and **AuthToken.php** from **vendor/codeigniter4/shield/src/Config/** into your project's config folder and update the namespace to `Config`. You will also need to have these classes extend the original classes. See the example below. These files contain all the settings, group, and permission information for your application and will need to be modified to meet the needs of your site.

```php
// new file - app/Config/Auth.php
Expand All @@ -91,29 +92,26 @@ your project.
}
```

2. **Helper Setup** The `setting` helper needs to be included in almost every page. The simplest way to do this is to add it to the `BaseController::initController()` method:
2. **Helper Setup:**
The `auth` and `setting` helpers need to be included in almost every page.
The simplest way to do this is to add it to the **app/Config/Autoload.php** file:

```php
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
$this->helpers = array_merge($this->helpers, ['setting']);

// Do Not Edit This Line
parent::initController($request, $response, $logger);
}
public $helpers = ['auth', 'setting'];
```

This requires that all of your controllers extend the `BaseController`, but that's a good practice anyway.

3. **Routes Setup** The default auth routes can be setup with a single call in **app/Config/Routes.php**:
3. **Routes Setup:**
The default auth routes can be setup with a single call in **app/Config/Routes.php**:

```php
service('auth')->routes($routes);
```

4. **Security Setup** Set `Config\Security::$csrfProtection` to `'session'` for security reasons, if you use Session Authenticator.
4. **Security Setup:**
Set `Config\Security::$csrfProtection` to `'session'` for security reasons, if you use Session Authenticator.

5. Configure **app/Config/Email.php** to allow Shield to send emails with the [Email Class](https://codeigniter.com/user_guide/libraries/email.html).
5. **Email Setup:**
Configure **app/Config/Email.php** to allow Shield to send emails.

```php
<?php
Expand All @@ -130,7 +128,8 @@ your project.
}
```

6. **Migration** Run the migrations.
6. **Migration:**
Run the migrations.

!!! note

Expand Down
5 changes: 3 additions & 2 deletions docs/references/authentication/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ auth()->getProvider();

!!! note

The `auth_helper` is autoloaded by Composer. If you want to *override* the functions,
you need to define them in **app/Common.php**.
The `auth_helper` is autoloaded by CodeIgniter's autoloader if you follow the
installation instruction. If you want to *override* the functions, create
**app/Helpers/auth_helper.php**.

## Authenticator Responses

Expand Down
2 changes: 0 additions & 2 deletions src/Authentication/Authenticators/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ class Session implements AuthenticatorInterface

public function __construct(UserModel $provider)
{
helper('setting');

$this->provider = $provider;

$this->loginModel = model(LoginModel::class);
Expand Down
7 changes: 0 additions & 7 deletions src/Authorization/Groups.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@
*/
class Groups
{
public function __construct()
{
if (! function_exists('setting')) {
helper('setting');
}
}

/**
* Grabs a group info from settings.
*/
Expand Down
12 changes: 3 additions & 9 deletions src/Authorization/Traits/Authorizable.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,7 @@ public function can(string ...$permissions): bool
return false;
}

$matrix = function_exists('setting')
? setting('AuthGroups.matrix')
: config('AuthGroups')->matrix;
$matrix = setting('AuthGroups.matrix');

foreach ($this->groupCache as $group) {
// Check exact match
Expand Down Expand Up @@ -396,18 +394,14 @@ private function saveGroupsOrPermissions(string $type, $model, array $cache): vo
*/
private function getConfigGroups(): array
{
return function_exists('setting')
? array_keys(setting('AuthGroups.groups'))
: array_keys(config('AuthGroups')->groups);
return array_keys(setting('AuthGroups.groups'));
}

/**
* @return string[]
*/
private function getConfigPermissions(): array
{
return function_exists('setting')
? array_keys(setting('AuthGroups.permissions'))
: array_keys(config('AuthGroups')->permissions);
return array_keys(setting('AuthGroups.permissions'));
}
}
56 changes: 44 additions & 12 deletions src/Commands/Setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use CodeIgniter\Commands\Database\Migrate;
use CodeIgniter\Shield\Commands\Setup\ContentReplacer;
use CodeIgniter\Test\Filters\CITestStreamFilter;
use Config\Autoload as AutoloadConfig;
use Config\Email as EmailConfig;
use Config\Services;

Expand Down Expand Up @@ -78,7 +79,7 @@ private function publishConfig(): void
$this->publishConfigAuthGroups();
$this->publishConfigAuthToken();

$this->setupHelper();
$this->setAutoloadHelpers();
$this->setupRoutes();

$this->setSecurityCSRF();
Expand Down Expand Up @@ -236,24 +237,55 @@ private function replace(string $file, array $replaces): bool
return false;
}

private function setupHelper(): void
private function setAutoloadHelpers(): void
{
$file = 'Controllers/BaseController.php';
$check = '$this->helpers = array_merge($this->helpers, [\'setting\']);';
$file = 'Config/Autoload.php';

$path = $this->distPath . $file;
$cleanPath = clean_path($path);

$config = new AutoloadConfig();
$helpers = $config->helpers;
$newHelpers = array_unique(array_merge($helpers, ['auth', 'setting']));

$pattern = '/^ public \$helpers = \[.*\];/mu';
$replace = ' public $helpers = [\'' . implode("', '", $newHelpers) . '\'];';
$content = file_get_contents($path);
$output = preg_replace($pattern, $replace, $content);

// check if the content is updated
if ($output === $content) {
$this->write(CLI::color(' Autoload Setup: ', 'green') . 'Everything is fine.');

return;
}

if (write_file($path, $output)) {
$this->write(CLI::color(' Updated: ', 'green') . $cleanPath);

$this->removeHelperLoadingInBaseController();
} else {
$this->error(" Error updating file '{$cleanPath}'.");
}
}

private function removeHelperLoadingInBaseController(): void
{
$file = 'Controllers/BaseController.php';

$check = ' $this->helpers = array_merge($this->helpers, [\'setting\']);';

// Replace old helper setup
$replaces = [
'$this->helpers = array_merge($this->helpers, [\'auth\', \'setting\']);' => $check,
];
if ($this->replace($file, $replaces)) {
return;
}

// Add helper setup
$pattern = '/(' . preg_quote('// Do Not Edit This Line', '/') . ')/u';
$replace = $check . "\n\n " . '$1';
$this->replace($file, $replaces);

$this->add($file, $check, $pattern, $replace);
// Remove helper setup
$replaces = [
"\n" . $check . "\n" => '',
];
$this->replace($file, $replaces);
}

private function setupRoutes(): void
Expand Down
1 change: 0 additions & 1 deletion src/Controllers/ActionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
class ActionController extends BaseController
{
protected ?ActionInterface $action = null;
protected $helpers = ['setting'];

/**
* Perform an initial check if we have a valid action or not.
Expand Down
2 changes: 0 additions & 2 deletions src/Controllers/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ class LoginController extends BaseController
{
use Viewable;

protected $helpers = ['setting'];

/**
* Displays the form the login to the site.
*
Expand Down
2 changes: 0 additions & 2 deletions src/Controllers/MagicLinkController.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ class MagicLinkController extends BaseController

public function __construct()
{
helper('setting');

/** @var class-string<UserModel> $providerClass */
$providerClass = setting('Auth.userProvider');

Expand Down
2 changes: 0 additions & 2 deletions src/Controllers/RegisterController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ class RegisterController extends BaseController
{
use Viewable;

protected $helpers = ['setting'];

public function initController(
RequestInterface $request,
ResponseInterface $response,
Expand Down
2 changes: 0 additions & 2 deletions src/Filters/ForcePasswordResetFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ public function before(RequestInterface $request, $arguments = null)
return;
}

helper('setting');

/** @var Session $authenticator */
$authenticator = auth('session')->getAuthenticator();

Expand Down
2 changes: 0 additions & 2 deletions src/Filters/HmacAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ public function before(RequestInterface $request, $arguments = null)
{
$authenticator = auth('hmac')->getAuthenticator();

helper('setting');

$requestParams = [
'token' => $request->getHeaderLine(setting('Auth.authenticatorHeader')['hmac'] ?? 'Authorization'),
'body' => $request->getBody() ?? '',
Expand Down
2 changes: 0 additions & 2 deletions src/Filters/JWTAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ public function before(RequestInterface $request, $arguments = null)
return;
}

helper('setting');

/** @var JWT $authenticator */
$authenticator = auth('jwt')->getAuthenticator();

Expand Down
2 changes: 0 additions & 2 deletions src/Filters/SessionAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ public function before(RequestInterface $request, $arguments = null)
return;
}

helper('setting');

/** @var Session $authenticator */
$authenticator = auth('session')->getAuthenticator();

Expand Down
2 changes: 0 additions & 2 deletions src/Filters/TokenAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ public function before(RequestInterface $request, $arguments = null)
return;
}

helper('setting');

/** @var AccessTokens $authenticator */
$authenticator = auth('tokens')->getAuthenticator();

Expand Down
2 changes: 0 additions & 2 deletions src/Helpers/email_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
*/
function emailer(array $overrides = []): Email
{
helper('setting');

$config = [
'userAgent' => setting('Email.userAgent'),
'protocol' => setting('Email.protocol'),
Expand Down
4 changes: 0 additions & 4 deletions src/Validation/ValidationRules.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ public function __construct()

public function getRegistrationRules(): array
{
helper('setting');

$setting = setting('Validation.registration');
if ($setting !== null) {
return $setting;
Expand Down Expand Up @@ -59,8 +57,6 @@ public function getRegistrationRules(): array

public function getLoginRules(): array
{
helper('setting');

return setting('Validation.login') ?? [
// 'username' => $this->config->usernameValidationRules,
'email' => $this->config->emailValidationRules,
Expand Down
7 changes: 5 additions & 2 deletions tests/Commands/SetupTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public function testRun(): void
$this->assertStringContainsString('namespace Config;', $authToken);
$this->assertStringContainsString('use CodeIgniter\Shield\Config\AuthToken as ShieldAuthToken;', $authToken);

$autoload = file_get_contents($appFolder . 'Config/Autoload.php');
$this->assertStringContainsString('$helpers = [\'auth\', \'setting\'];', $autoload);

$routes = file_get_contents($appFolder . 'Config/Routes.php');
$this->assertStringContainsString('service(\'auth\')->routes($routes);', $routes);

Expand All @@ -77,7 +80,7 @@ public function testRun(): void
' Created: vfs://root/Config/Auth.php
Created: vfs://root/Config/AuthGroups.php
Created: vfs://root/Config/AuthToken.php
Updated: vfs://root/Controllers/BaseController.php
Updated: vfs://root/Config/Autoload.php
Updated: vfs://root/Config/Routes.php
Updated: We have updated file \'vfs://root/Config/Security.php\' for security reasons.
Updated: vfs://root/Config/Email.php',
Expand Down Expand Up @@ -112,7 +115,7 @@ public function testRunEmailConfigIsFine(): void
' Created: vfs://root/Config/Auth.php
Created: vfs://root/Config/AuthGroups.php
Created: vfs://root/Config/AuthToken.php
Updated: vfs://root/Controllers/BaseController.php
Updated: vfs://root/Config/Autoload.php
Updated: vfs://root/Config/Routes.php
Updated: We have updated file \'vfs://root/Config/Security.php\' for security reasons.',
$result
Expand Down
4 changes: 3 additions & 1 deletion tests/_support/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ protected function setUp(): void
$settings = new Settings($configSettings);
Services::injectMock('settings', $settings);

// Load helpers that should be autoloaded
helper(['auth', 'setting']);

// Ensure from email is available anywhere during Tests
helper('setting');
setting('Email.fromEmail', '[email protected]');
setting('Email.fromName', 'John Smith');

Expand Down