Skip to content
Closed
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
8 changes: 4 additions & 4 deletions docs/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ Shield has the following rules for registration:
[
'username' => [
'label' => 'Auth.username',
'rules' => 'required|max_length[30]|min_length[3]|regex_match[/\A[a-zA-Z0-9\.]+\z/]|is_unique[users.username]',
'rules' => 'required|max_length[30]|min_length[3]|regex_match[/\A[a-zA-Z0-9\.]+\z/]|is_unique[' . SHIELD_TABLES['users'] . '.username]',
],
'email' => [
'label' => 'Auth.email',
'rules' => 'required|max_length[254]|valid_email|is_unique[auth_identities.secret]',
'rules' => 'required|max_length[254]|valid_email|is_unique[' . SHIELD_TABLES['identities'] . '.secret]',
],
'password' => [
'label' => 'Auth.password',
Expand All @@ -175,11 +175,11 @@ If you need a different set of rules for registration, you can specify them in y
public $registration = [
'username' => [
'label' => 'Auth.username',
'rules' => 'required|max_length[30]|min_length[3]|regex_match[/\A[a-zA-Z0-9\.]+\z/]|is_unique[users.username]',
'rules' => 'required|max_length[30]|min_length[3]|regex_match[/\A[a-zA-Z0-9\.]+\z/]|is_unique[' . SHIELD_TABLES['users'] . '.username]',
],
'email' => [
'label' => 'Auth.email',
'rules' => 'required|max_length[254]|valid_email|is_unique[auth_identities.secret]',
'rules' => 'required|max_length[254]|valid_email|is_unique[' . SHIELD_TABLES['identities'] . '.secret]',
],
'password' => [
'label' => 'Auth.password',
Expand Down
1 change: 1 addition & 0 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
__DIR__ . '/src/Helpers',
__DIR__ . '/src/Language',
__DIR__ . '/tests/_support',
__DIR__ . '/src/Config/Constants.php',
],

// May load view files directly when detecting classes
Expand Down
30 changes: 30 additions & 0 deletions src/Config/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,36 @@ class Auth extends BaseConfig
'magic-link-email' => '\CodeIgniter\Shield\Views\Email\magic_link_email',
];

/**
* --------------------------------------------------------------------
* Customize Name of Shield Tables
* --------------------------------------------------------------------
* Only change if you want to rename the default Shield table names
*
* It may be necessary to change the names of the tables for
* security reasons, to prevent the conflict of table names,
* the internal policy of the companies or any other reason.
*
* - users Auth Users Table, the users info is stored.
* - auth_identities Auth Identities Table, Used for storage of passwords, access tokens, social login identities, etc.
* - auth_logins Auth Login Attempts, Table records login attempts.
* - auth_token_logins Auth Token Login Attempts Table, Records Bearer Token type login attempts.
* - auth_remember_tokens Auth Remember Tokens (remember-me) Table.
* - auth_groups_users Groups Users Table.
* - auth_permissions_users Users Permissions Table.
*
* @var array<string, string>
*/
public array $tables = [
'users' => 'users',
'identities' => 'auth_identities',
'logins' => 'auth_logins',
'token_logins' => 'auth_token_logins',
'remember_tokens' => 'auth_remember_tokens',
'groups_users' => 'auth_groups_users',
'permissions_users' => 'auth_permissions_users',
];

/**
* --------------------------------------------------------------------
* Redirect URLs
Expand Down
7 changes: 7 additions & 0 deletions src/Config/Constants.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

declare(strict_types=1);

use CodeIgniter\Shield\Config\Auth as ShieldAuth;

define('SHIELD_TABLES', (new ShieldAuth())->tables);
2 changes: 2 additions & 0 deletions src/Config/Registrar.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use CodeIgniter\Shield\Filters\SessionAuth;
use CodeIgniter\Shield\Filters\TokenAuth;

include_once __DIR__ . '/Constants.php';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know we should use the constant or not.
But even if we use it, I would like to remove the include_once line and the constant file.


class Registrar
{
/**
Expand Down
4 changes: 2 additions & 2 deletions src/Controllers/RegisterController.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,11 @@ protected function getValidationRules(): array
{
$registrationUsernameRules = array_merge(
config('AuthSession')->usernameValidationRules,
['is_unique[users.username]']
[sprintf('is_unique[%s.username]', SHIELD_TABLES['users'])]
);
$registrationEmailRules = array_merge(
config('AuthSession')->emailValidationRules,
['is_unique[auth_identities.secret]']
[sprintf('is_unique[%s.secret]', SHIELD_TABLES['identities'])]
);

return setting('Validation.registration') ?? [
Expand Down
36 changes: 18 additions & 18 deletions src/Database/Migrations/2020-12-28-223112_create_auth_tables.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function up(): void
]);
$this->forge->addPrimaryKey('id');
$this->forge->addUniqueKey('username');
$this->forge->createTable('users');
$this->forge->createTable(SHIELD_TABLES['users']);

/*
* Auth Identities Table
Expand All @@ -47,8 +47,8 @@ public function up(): void
$this->forge->addPrimaryKey('id');
$this->forge->addUniqueKey(['type', 'secret']);
$this->forge->addKey('user_id');
$this->forge->addForeignKey('user_id', 'users', 'id', '', 'CASCADE');
$this->forge->createTable('auth_identities');
$this->forge->addForeignKey('user_id', SHIELD_TABLES['users'], 'id', '', 'CASCADE');
$this->forge->createTable(SHIELD_TABLES['identities']);

/**
* Auth Login Attempts Table
Expand All @@ -69,7 +69,7 @@ public function up(): void
$this->forge->addKey(['id_type', 'identifier']);
$this->forge->addKey('user_id');
// NOTE: Do NOT delete the user_id or identifier when the user is deleted for security audits
$this->forge->createTable('auth_logins');
$this->forge->createTable(SHIELD_TABLES['logins']);

/*
* Auth Token Login Attempts Table
Expand All @@ -89,7 +89,7 @@ public function up(): void
$this->forge->addKey(['id_type', 'identifier']);
$this->forge->addKey('user_id');
// NOTE: Do NOT delete the user_id or identifier when the user is deleted for security audits
$this->forge->createTable('auth_token_logins');
$this->forge->createTable(SHIELD_TABLES['token_logins']);

/*
* Auth Remember Tokens (remember-me) Table
Expand All @@ -106,8 +106,8 @@ public function up(): void
]);
$this->forge->addPrimaryKey('id');
$this->forge->addUniqueKey('selector');
$this->forge->addForeignKey('user_id', 'users', 'id', '', 'CASCADE');
$this->forge->createTable('auth_remember_tokens');
$this->forge->addForeignKey('user_id', SHIELD_TABLES['users'], 'id', '', 'CASCADE');
$this->forge->createTable(SHIELD_TABLES['remember_tokens']);

// Groups Users Table
$this->forge->addField([
Expand All @@ -117,8 +117,8 @@ public function up(): void
'created_at' => ['type' => 'datetime', 'null' => false],
]);
$this->forge->addPrimaryKey('id');
$this->forge->addForeignKey('user_id', 'users', 'id', '', 'CASCADE');
$this->forge->createTable('auth_groups_users');
$this->forge->addForeignKey('user_id', SHIELD_TABLES['users'], 'id', '', 'CASCADE');
$this->forge->createTable(SHIELD_TABLES['groups_users']);

// Users Permissions Table
$this->forge->addField([
Expand All @@ -128,8 +128,8 @@ public function up(): void
'created_at' => ['type' => 'datetime', 'null' => false],
]);
$this->forge->addPrimaryKey('id');
$this->forge->addForeignKey('user_id', 'users', 'id', '', 'CASCADE');
$this->forge->createTable('auth_permissions_users');
$this->forge->addForeignKey('user_id', SHIELD_TABLES['users'], 'id', '', 'CASCADE');
$this->forge->createTable(SHIELD_TABLES['permissions_users']);
}

// --------------------------------------------------------------------
Expand All @@ -138,13 +138,13 @@ public function down(): void
{
$this->db->disableForeignKeyChecks();

$this->forge->dropTable('auth_logins', true);
$this->forge->dropTable('auth_token_logins', true);
$this->forge->dropTable('auth_remember_tokens', true);
$this->forge->dropTable('auth_identities', true);
$this->forge->dropTable('auth_groups_users', true);
$this->forge->dropTable('auth_permissions_users', true);
$this->forge->dropTable('users', true);
$this->forge->dropTable(SHIELD_TABLES['logins'], true);
$this->forge->dropTable(SHIELD_TABLES['token_logins'], true);
$this->forge->dropTable(SHIELD_TABLES['remember_tokens'], true);
$this->forge->dropTable(SHIELD_TABLES['identities'], true);
$this->forge->dropTable(SHIELD_TABLES['groups_users'], true);
$this->forge->dropTable(SHIELD_TABLES['permissions_users'], true);
$this->forge->dropTable(SHIELD_TABLES['users'], true);

$this->db->enableForeignKeyChecks();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Models/GroupModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class GroupModel extends Model
{
use CheckQueryReturnTrait;

protected $table = 'auth_groups_users';
protected $table = SHIELD_TABLES['groups_users'];
protected $primaryKey = 'id';
protected $returnType = 'array';
protected $useSoftDeletes = false;
Expand Down
2 changes: 1 addition & 1 deletion src/Models/LoginModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class LoginModel extends Model
{
use CheckQueryReturnTrait;

protected $table = 'auth_logins';
protected $table = SHIELD_TABLES['logins'];
protected $primaryKey = 'id';
protected $returnType = Login::class;
protected $useSoftDeletes = false;
Expand Down
2 changes: 1 addition & 1 deletion src/Models/PermissionModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class PermissionModel extends Model
{
use CheckQueryReturnTrait;

protected $table = 'auth_permissions_users';
protected $table = SHIELD_TABLES['permissions_users'];
protected $primaryKey = 'id';
protected $returnType = 'array';
protected $useSoftDeletes = false;
Expand Down
2 changes: 1 addition & 1 deletion src/Models/RememberModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class RememberModel extends Model
{
use CheckQueryReturnTrait;

protected $table = 'auth_remember_tokens';
protected $table = SHIELD_TABLES['remember_tokens'];
protected $primaryKey = 'id';
protected $returnType = 'object';
protected $useSoftDeletes = false;
Expand Down
2 changes: 1 addition & 1 deletion src/Models/TokenLoginModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

class TokenLoginModel extends LoginModel
{
protected $table = 'auth_token_logins';
protected $table = SHIELD_TABLES['token_logins'];

/**
* Generate a fake login for testing
Expand Down
2 changes: 1 addition & 1 deletion src/Models/UserIdentityModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class UserIdentityModel extends Model
{
use CheckQueryReturnTrait;

protected $table = 'auth_identities';
protected $table = SHIELD_TABLES['identities'];
protected $primaryKey = 'id';
protected $returnType = UserIdentity::class;
protected $useSoftDeletes = false;
Expand Down
12 changes: 6 additions & 6 deletions src/Models/UserModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class UserModel extends Model
{
use CheckQueryReturnTrait;

protected $table = 'users';
protected $table = SHIELD_TABLES['users'];
protected $primaryKey = 'id';
protected $returnType = User::class;
protected $useSoftDeletes = true;
Expand Down Expand Up @@ -184,19 +184,19 @@ public function findByCredentials(array $credentials): ?User
// any of the credentials used should be case-insensitive
foreach ($credentials as $key => $value) {
$this->where(
'LOWER(' . $this->db->protectIdentifiers("users.{$key}") . ')',
'LOWER(' . $this->db->protectIdentifiers(SHIELD_TABLES['users'] . ".{$key}") . ')',
strtolower($value)
);
}

if ($email !== null) {
$data = $this->select(
'users.*, auth_identities.secret as email, auth_identities.secret2 as password_hash'
sprintf('%1$s.*, %2$s.secret as email, %2$s.secret2 as password_hash', SHIELD_TABLES['users'], SHIELD_TABLES['identities'])
)
->join('auth_identities', 'auth_identities.user_id = users.id')
->where('auth_identities.type', Session::ID_TYPE_EMAIL_PASSWORD)
->join(SHIELD_TABLES['identities'], sprintf('%1$s.user_id = %2$s.id', SHIELD_TABLES['identities'], SHIELD_TABLES['users']))
->where(SHIELD_TABLES['identities'] . '.type', Session::ID_TYPE_EMAIL_PASSWORD)
->where(
'LOWER(' . $this->db->protectIdentifiers('auth_identities.secret') . ')',
'LOWER(' . $this->db->protectIdentifiers(SHIELD_TABLES['identities'] . '.secret') . ')',
strtolower($email)
)
->asArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public function testCheckSuccess(): void
$user = fake(UserModel::class);
$token = $user->generateAccessToken('foo');

$this->seeInDatabase('auth_identities', [
$this->seeInDatabase(SHIELD_TABLES['identities'], [
'user_id' => $user->id,
'type' => 'access_token',
'last_used_at' => null,
Expand Down Expand Up @@ -201,7 +201,7 @@ public function testAttemptSuccess(): void
$this->assertSame($token->token, $foundUser->currentAccessToken()->token);

// A login attempt should have been recorded
$this->seeInDatabase('auth_token_logins', [
$this->seeInDatabase(SHIELD_TABLES['token_logins'], [
'id_type' => AccessTokens::ID_TYPE_ACCESS_TOKEN,
'identifier' => $token->raw_token,
'success' => 1,
Expand Down
Loading