Skip to content

Commit 5e6d517

Browse files
authored
Merge pull request #490 from codeigniter4/develop
Prep for Beta 3
2 parents 342a368 + 50416c9 commit 5e6d517

File tree

145 files changed

+1955
-386
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

145 files changed

+1955
-386
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ end_of_line = lf
1111
insert_final_newline = true
1212
trim_trailing_whitespace = true
1313

14-
[*.yml]
14+
[*.{yml,yaml}]
1515
indent_size = 2

.github/release.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
changelog:
2+
exclude:
3+
authors:
4+
- dependabot
5+
categories:
6+
- title: Breaking Changes
7+
labels:
8+
- 'breaking change'
9+
- title: Fixed Bugs
10+
labels:
11+
- bug
12+
- title: New Features
13+
labels:
14+
- 'new feature'
15+
- title: Enhancements
16+
labels:
17+
- enhancement
18+
- title: Refactoring
19+
labels:
20+
- refactor
21+
- title: Others (Only for checking. Remove this category)
22+
labels:
23+
- "*"

.github/workflows/phpunit.yml

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,84 @@ on:
2020

2121
jobs:
2222
main:
23-
name: PHP ${{ matrix.php-versions }} Unit Tests
23+
name: PHP ${{ matrix.php-versions }} - ${{ matrix.db-platforms }}
2424
runs-on: ubuntu-latest
2525
if: "!contains(github.event.head_commit.message, '[ci skip]')"
2626
strategy:
2727
matrix:
2828
php-versions: ['7.4', '8.0', '8.1']
29+
db-platforms: ['MySQLi', 'Postgre', 'SQLite3', 'SQLSRV', 'OCI8']
30+
mysql-versions: [ '5.7' ]
31+
include:
32+
- php-versions: '7.4'
33+
db-platforms: MySQLi
34+
mysql-versions: '8.0'
35+
36+
services:
37+
mysql:
38+
image: mysql:${{ matrix.mysql-versions }}
39+
env:
40+
MYSQL_ALLOW_EMPTY_PASSWORD: yes
41+
MYSQL_DATABASE: test
42+
ports:
43+
- 3306:3306
44+
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
45+
46+
postgres:
47+
image: postgres
48+
env:
49+
POSTGRES_USER: postgres
50+
POSTGRES_PASSWORD: postgres
51+
POSTGRES_DB: test
52+
ports:
53+
- 5432:5432
54+
options: --health-cmd=pg_isready --health-interval=10s --health-timeout=5s --health-retries=3
55+
56+
mssql:
57+
image: mcr.microsoft.com/mssql/server:2019-CU10-ubuntu-20.04
58+
env:
59+
SA_PASSWORD: 1Secure*Password1
60+
ACCEPT_EULA: Y
61+
MSSQL_PID: Developer
62+
ports:
63+
- 1433:1433
64+
options: --health-cmd="/opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U sa -P 1Secure*Password1 -Q 'SELECT @@VERSION'" --health-interval=10s --health-timeout=5s --health-retries=3
65+
66+
oracle:
67+
image: quillbuilduser/oracle-18-xe
68+
env:
69+
ORACLE_ALLOW_REMOTE: true
70+
ports:
71+
- 1521:1521
72+
options: --health-cmd="/opt/oracle/product/18c/dbhomeXE/bin/sqlplus -s sys/Oracle18@oracledbxe/XE as sysdba <<< 'SELECT 1 FROM DUAL'" --health-interval=10s --health-timeout=5s --health-retries=3
2973

3074
steps:
75+
- name: Create database for MSSQL Server
76+
if: matrix.db-platforms == 'SQLSRV'
77+
run: sqlcmd -S 127.0.0.1 -U sa -P 1Secure*Password1 -Q "CREATE DATABASE test"
78+
79+
- name: Install Oracle InstantClient
80+
if: matrix.db-platforms == 'OCI8'
81+
run: |
82+
sudo apt-get install wget libaio1 alien
83+
sudo wget https://download.oracle.com/otn_software/linux/instantclient/185000/oracle-instantclient18.5-basic-18.5.0.0.0-3.x86_64.rpm
84+
sudo wget https://download.oracle.com/otn_software/linux/instantclient/185000/oracle-instantclient18.5-devel-18.5.0.0.0-3.x86_64.rpm
85+
sudo wget https://download.oracle.com/otn_software/linux/instantclient/185000/oracle-instantclient18.5-sqlplus-18.5.0.0.0-3.x86_64.rpm
86+
sudo alien oracle-instantclient18.5-basic-18.5.0.0.0-3.x86_64.rpm
87+
sudo alien oracle-instantclient18.5-devel-18.5.0.0.0-3.x86_64.rpm
88+
sudo alien oracle-instantclient18.5-sqlplus-18.5.0.0.0-3.x86_64.rpm
89+
sudo dpkg -i oracle-instantclient18.5-basic_18.5.0.0.0-4_amd64.deb oracle-instantclient18.5-devel_18.5.0.0.0-4_amd64.deb oracle-instantclient18.5-sqlplus_18.5.0.0.0-4_amd64.deb
90+
echo "LD_LIBRARY_PATH=/lib/oracle/18.5/client64/lib/" >> $GITHUB_ENV
91+
echo "NLS_LANG=AMERICAN_AMERICA.UTF8" >> $GITHUB_ENV
92+
echo "C_INCLUDE_PATH=/usr/include/oracle/18.5/client64" >> $GITHUB_ENV
93+
echo 'NLS_DATE_FORMAT=YYYY-MM-DD HH24:MI:SS' >> $GITHUB_ENV
94+
echo 'NLS_TIMESTAMP_FORMAT=YYYY-MM-DD HH24:MI:SS' >> $GITHUB_ENV
95+
echo 'NLS_TIMESTAMP_TZ_FORMAT=YYYY-MM-DD HH24:MI:SS' >> $GITHUB_ENV
96+
97+
- name: Create database for Oracle Database
98+
if: matrix.db-platforms == 'OCI8'
99+
run: echo -e "ALTER SESSION SET CONTAINER = XEPDB1;\nCREATE BIGFILE TABLESPACE \"TEST\" DATAFILE '/opt/oracle/product/18c/dbhomeXE/dbs/TEST' SIZE 10M AUTOEXTEND ON MAXSIZE UNLIMITED SEGMENT SPACE MANAGEMENT AUTO EXTENT MANAGEMENT LOCAL AUTOALLOCATE;\nCREATE USER \"ORACLE\" IDENTIFIED BY \"ORACLE\" DEFAULT TABLESPACE \"TEST\" TEMPORARY TABLESPACE TEMP QUOTA UNLIMITED ON \"TEST\";\nGRANT CONNECT,RESOURCE TO \"ORACLE\";\nexit;" | /lib/oracle/18.5/client64/bin/sqlplus -s sys/Oracle18@localhost:1521/XE as sysdba
100+
31101
- name: Checkout
32102
uses: actions/checkout@v3
33103

@@ -36,7 +106,7 @@ jobs:
36106
with:
37107
php-version: ${{ matrix.php-versions }}
38108
tools: composer, phive, phpunit
39-
extensions: intl, json, mbstring, gd, xdebug, xml, sqlite3
109+
extensions: intl, json, mbstring, gd, xdebug, xml, sqlite3, sqlsrv, oci8, pgsql
40110
coverage: xdebug
41111
env:
42112
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -63,6 +133,7 @@ jobs:
63133
- name: Test with PHPUnit
64134
run: vendor/bin/phpunit --verbose --coverage-text --testsuite main
65135
env:
136+
DB: ${{ matrix.db-platforms }}
66137
TERM: xterm-256color
67138
TACHYCARDIA_MONITOR_GA: enabled
68139

@@ -75,7 +146,7 @@ jobs:
75146
env:
76147
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77148
COVERALLS_PARALLEL: true
78-
COVERALLS_FLAG_NAME: PHP ${{ matrix.php-versions }}
149+
COVERALLS_FLAG_NAME: PHP ${{ matrix.php-versions }} - ${{ matrix.db-platforms }}
79150

80151
coveralls:
81152
needs: [main]

.php-cs-fixer.dist.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
use CodeIgniter\CodingStandard\CodeIgniter4;
46
use Nexus\CsConfig\Factory;
57
use PhpCsFixer\Finder;
@@ -13,7 +15,10 @@
1315
->exclude('build')
1416
->append([__FILE__]);
1517

16-
$overrides = [];
18+
$overrides = [
19+
'declare_strict_types' => true,
20+
'void_return' => true,
21+
];
1722

1823
$options = [
1924
'finder' => $finder,

CONTRIBUTING.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Contributing to CodeIgniter Shield
2+
3+
CodeIgniter is a community driven project and accepts contributions of
4+
code and documentation from the community.
5+
6+
If you'd like to contribute, please read [Contributing to CodeIgniter](https://github.com/codeigniter4/CodeIgniter4/blob/develop/contributing/README.md)
7+
in the [main repository](https://github.com/codeigniter4/CodeIgniter4).
8+
9+
If you are going to contribute to this repository, please [report bugs](https://github.com/codeigniter4/shield/issues/new?assignees=&labels=bug&template=bug_report.yml&title=Bug%3A+) or [send PRs](https://github.com/codeigniter4/shield/compare)
10+
to this repository instead of the main repository.

README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# CodeIgniter Shield
22

3-
[![Unit Tests](https://github.com/codeigniter4/shield/workflows/PHPUnit/badge.svg)](https://github.com/codeigniter4/shield/actions/workflows/test.yml)
4-
[![Static Analysis](https://github.com/codeigniter4/shield/workflows/PHPStan/badge.svg)](https://github.com/codeigniter4/shield/actions/workflows/analyze.yml)
5-
[![Architecture](https://github.com/codeigniter4/shield/workflows/Deptrac/badge.svg)](https://github.com/codeigniter4/shield/actions/workflows/inspect.yml)
3+
[![Unit Tests](https://github.com/codeigniter4/shield/workflows/PHPUnit/badge.svg)](https://github.com/codeigniter4/shield/actions/workflows/phpunit.yml)
4+
[![Static Analysis](https://github.com/codeigniter4/shield/workflows/PHPStan/badge.svg)](https://github.com/codeigniter4/shield/actions/workflows/phpstan.yml)
5+
[![Architecture](https://github.com/codeigniter4/shield/workflows/Deptrac/badge.svg)](https://github.com/codeigniter4/shield/actions/workflows/deptrac.yml)
66
[![Coverage Status](https://coveralls.io/repos/github/codeigniter4/shield/badge.svg?branch=develop)](https://coveralls.io/github/codeigniter4/shield?branch=develop)
77

88
Shield is an authentication and authorization framework for CodeIgniter 4. While it does provide a base set of tools
@@ -29,6 +29,18 @@ These are much like the access codes that GitHub uses, where they are unique to
2929
can have more than one. This can be used for API authentication of third-party users, and even for allowing
3030
access for a mobile application that you build.
3131

32+
## Some Important Features
33+
34+
* Session-based authentication (traditional email/password with remember me)
35+
* Stateless authentication using Personal Access Tokens
36+
* Optional Email verification on account registration
37+
* Optional Email-based Two Factor Authentication after login
38+
* Magic Login Links when a user forgets their password
39+
* Flexible groups-based access control (think roles, but more flexible)
40+
* Users can be granted additional permissions
41+
42+
See the [An Official Auth Library](https://codeigniter.com/news/shield) for more Info.
43+
3244
## Getting Started
3345

3446
### Prerequisites

composer.json

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
},
3838
"exclude-from-classmap": [
3939
"**/Database/Migrations/**"
40+
],
41+
"files": [
42+
"src/Helpers/auth_helper.php",
43+
"src/Helpers/email_helper.php"
4044
]
4145
},
4246
"autoload-dev": {
@@ -54,25 +58,33 @@
5458
"post-update-cmd": [
5559
"bash admin/setup.sh"
5660
],
57-
"analyze": "phpstan analyze",
61+
"analyze": [
62+
"phpstan analyze",
63+
"psalm",
64+
"rector process --dry-run"
65+
],
66+
"sa": "@analyze",
5867
"ci": [
5968
"Composer\\Config::disableProcessTimeout",
69+
"@cs",
6070
"@deduplicate",
61-
"@sa",
62-
"@test",
6371
"@inspect",
64-
"rector process",
65-
"@style"
72+
"@analyze",
73+
"@test"
6674
],
67-
"deduplicate": "phpcpd app/ src/",
75+
"cs": "php-cs-fixer fix --ansi --verbose --dry-run --diff",
76+
"cs-fix": "php-cs-fixer fix --ansi --verbose --diff",
77+
"deduplicate": "phpcpd app/ src/ --exclude src/Database/Migrations/2020-12-28-223112_create_auth_tables.php",
6878
"inspect": "deptrac analyze --cache-file=build/deptrac.cache",
6979
"mutate": "infection --threads=2 --skip-initial-tests --coverage=build/phpunit",
70-
"sa": [
71-
"phpstan analyze",
72-
"psalm"
73-
],
74-
"cs-fix": "php-cs-fixer fix --ansi --verbose --diff --using-cache=yes",
7580
"style": "@cs-fix",
7681
"test": "phpunit"
82+
},
83+
"support": {
84+
"forum": "https://github.com/codeigniter4/shield/discussions",
85+
"slack": "https://codeigniterchat.slack.com",
86+
"source": "https://github.com/codeigniter4/shield",
87+
"issues": "https://github.com/codeigniter4/shield/issues",
88+
"docs": "https://github.com/codeigniter4/shield/blob/develop/docs/index.md"
7789
}
7890
}

docs/auth_actions.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,35 @@
77
Authentication Actions are a way to group actions that can happen after login or registration.
88
Shield ships with two actions you can use, and makes it simple for you to define your own.
99

10-
1. **Email-based Two Factor Authentication** (Email2FA) will send a 6-digit code to the user's
10+
1. **Email-based Account Activation** (EmailActivate) confirms a new user's email address by
11+
sending them an email with a link they must follow in order to have their account activated.
12+
2. **Email-based Two Factor Authentication** (Email2FA) will send a 6-digit code to the user's
1113
email address that they must confirm before they can continue.
12-
2. **Email-based Account Activation** (EmailActivate) confirms a new user's email address by
13-
sending them an email with a link they must follow in order to have their account activated.
1414

1515
## Configuring Actions
1616

1717
Actions are setup in the `Auth` config file, with the `$actions` variable.
1818

1919
```php
2020
public $actions = [
21-
'login' => null,
2221
'register' => null,
22+
'login' => null,
2323
];
2424
```
2525

2626
To define an action to happen you will specify the class name as the value for the appropriate task:
2727

2828
```php
2929
public $actions = [
30-
'login' => 'CodeIgniter\Shield\Authentication\Actions\Email2FA',
3130
'register' => 'CodeIgniter\Shield\Authentication\Actions\EmailActivator',
31+
'login' => 'CodeIgniter\Shield\Authentication\Actions\Email2FA',
3232
];
3333
```
3434

35-
Once configured, everything should work out of the box. The routes are added with the basic `auth()->routes($routes)`
35+
You must register actions in the order of the actions to be performed.
36+
Once configured, everything should work out of the box.
37+
38+
The routes are added with the basic `auth()->routes($routes)`
3639
call, but can be manually added if you choose not to use this helper method.
3740

3841
```php
@@ -49,9 +52,9 @@ Views for all of these pages are defined in the `Auth` config file, with the `$v
4952
public $views = [
5053
'action_email_2fa' => '\CodeIgniter\Shield\Views\email_2fa_show',
5154
'action_email_2fa_verify' => '\CodeIgniter\Shield\Views\email_2fa_verify',
52-
'action_email_2fa_email' => '\CodeIgniter\Shield\Views\email_2fa_email',
53-
'action_email_activate_email' => '\CodeIgniter\Shield\Views\email_activate_email',
55+
'action_email_2fa_email' => '\CodeIgniter\Shield\Views\Email\email_2fa_email',
5456
'action_email_activate_show' => '\CodeIgniter\Shield\Views\email_activate_show',
57+
'action_email_activate_email' => '\CodeIgniter\Shield\Views\Email\email_activate_email',
5558
];
5659
```
5760

@@ -61,7 +64,7 @@ While the provided email-based activation and 2FA will work for many sites, othe
6164
needs, like using SMS to verify or something completely different. Actions have only one requirement:
6265
they must implement `CodeIgniter\Shield\Authentication\Actions\ActionInterface`.
6366

64-
The interface defines three methods:
67+
The interface defines three methods for `ActionController`:
6568

6669
**show()** should display the initial page the user lands on immediately after the authentication task,
6770
like login. It will typically display instructions to the user and provide an action to take, like
@@ -77,4 +80,4 @@ and provides feedback. In the `Email2FA` class, it verifies the code against wha
7780
database and either sends them back to the previous form to try again or redirects the user to the
7881
page that a `login` task would have redirected them to anyway.
7982

80-
All methods should return either a `RedirectResponse` or a view string (e.g. using the `view()` function).
83+
All methods should return either a `Response` or a view string (e.g. using the `view()` function).

docs/authentication.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ helper method provides the `auth()` command which returns a convenient interface
5454
used functionality within the auth libraries. This must be loaded before it can be used.
5555

5656
```php
57-
helper('auth');
58-
5957
// get the current user
6058
auth()->user();
6159

@@ -65,6 +63,10 @@ auth()->id();
6563
user_id();
6664
```
6765

66+
> **Note**
67+
> The `auth_helper` is autoloaded by Composer. If you want to *override* the functions,
68+
> you need to define them in `app/Common.php`.
69+
6870
## Authenticator Responses
6971

7072
Many of the authenticator methods will return a `CodeIgniter\Shield\Result` class. This provides a consistent
@@ -144,11 +146,11 @@ $credentials = [
144146
$validCreds = auth()->check($credentials);
145147

146148
if (! $validCreds->isOK()) {
147-
return redirect()->back()->with('error', $loginAttempt->reason());
149+
return redirect()->back()->with('error', $validCreds->reason());
148150
}
149151
```
150152

151-
The Result instance returned contains the logged in user as `extraInfo()`.
153+
The Result instance returned contains the valid user as `extraInfo()`.
152154

153155
### loggedIn()
154156

@@ -238,7 +240,7 @@ token, you would need to get the user's access tokens and delete them manually.
238240
You can revoke all access tokens with the `revokeAllAccessTokens()` method.
239241

240242
```php
241-
$user->revokeAllAccessTokens($token);
243+
$user->revokeAllAccessTokens();
242244
```
243245

244246
### Retrieving Access Tokens

docs/concepts.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,17 @@ public $passwordValidators = [
8888
//'CodeIgniter\Shield\Authentication\Passwords\PwnedValidator',
8989
];
9090
```
91+
92+
You use `strong_password` rule for password validation explained above.
93+
94+
> **Note**
95+
> The `strong_password` rule only supports use cases to check the user's own password.
96+
> It fetches the authenticated user's data for **NothingPersonalValidator**
97+
> if the visitor is authenticated.
98+
>
99+
> If you want to have use cases that set and check another user's password,
100+
> you can't use `strong_password`. You need to use `service('passwords')` directly
101+
> to check the password.
102+
>
103+
> But remember, it is not good practice to set passwords for other users.
104+
> This is because the password should be known only by that user.

0 commit comments

Comments
 (0)