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
28 changes: 13 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ on:

jobs:
testsuite:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
cakephp-version: ['5.0.*']
php-version: ['8.1', '8.2', '8.3']
cakephp-version: ['5.0.*', '5.1.*', '5.2.*']
php-version: ['8.2', '8.3', '8.4']
db-type: ['mysql']
prefer-lowest: ['']
coverage: ['no']
Expand All @@ -27,14 +27,14 @@ jobs:
db-type: 'mysql:8.0'
prefer-lowest: 'prefer-lowest'
coverage: 'no'
- cakephp-version: '5.0.*'
php-version: '8.3'
- cakephp-version: '5.2.*'
php-version: '8.4'
db-type: 'mysql'
prefer-lowest: ''
coverage: 'no'

- php-version: '8.3'
cakephp-version: '5.0.*'
- php-version: '8.4'
cakephp-version: '5.2.*'
db-type: 'mysql'
prefer-lowest: ''
coverage: 'coverage'
Expand Down Expand Up @@ -80,9 +80,7 @@ jobs:

- name: Composer install
run: |
if [[ ${{ matrix.php-version }} == '8.1' ]]; then
composer update --ignore-platform-reqs
elif ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then
if ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then
composer update --prefer-lowest --prefer-stable
else
composer update
Expand Down Expand Up @@ -111,7 +109,7 @@ jobs:

cs-stan:
name: Coding Standard & Static Analysis
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
Expand All @@ -121,7 +119,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
php-version: '8.4'
extensions: mbstring, intl, apcu
coverage: none

Expand Down Expand Up @@ -152,6 +150,6 @@ jobs:
# if: success() || failure()
# run: vendor/bin/psalm.phar --output-format=github
#
# - name: Run phpstan
# if: success() || failure()
# run: vendor/bin/phpstan.phar analyse --error-format=github
- name: Run phpstan
if: success() || failure()
run: vendor/bin/phpstan.phar analyse --error-format=github
10 changes: 5 additions & 5 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

このプラグインは、Cookieによって永続的にログインする認証ハンドラを提供します。 暗号化されたユーザー名/パスワードをCookieに設定する代わりに、トークンを発行する方法を使用します。

This library inspired by Barry Jaspan's article "[Improved Persistent Login Cookie Best Practice](http://jaspan.com/improved_persistent_login_cookie_best_practice)", and Gabriel Birke's libray "https://github.com/gbirke/rememberme".
This library is inspired by Barry Jaspan's article "[Improved Persistent Login Cookie Best Practice](http://jaspan.com/improved_persistent_login_cookie_best_practice)", and Gabriel Birke's library "https://github.com/gbirke/rememberme".

## インストール

Expand Down Expand Up @@ -50,7 +50,7 @@ bin/cake migrations migrate -p RememberMe
## Authenticationプラグインでの使用方法

[cakephp/authentication](https://github.com/cakephp/authentication) を使用しているのであれば、
`RememberMeTokenIdentifier` と `CookeAuthenticator` を使用してください。
`RememberMeTokenIdentifier` と `CookieAuthenticator` を使用してください。

`Application` の `getAuthenticationService` フックで RememberMeプラグインの Identifier と Authenticator を呼び出す例です:

Expand Down Expand Up @@ -135,7 +135,7 @@ default: `'remember_me_token'`
]);
```

### RememberMe.CookeAuthenticator のオプション
### RememberMe.CookieAuthenticator のオプション

#### `loginUrl`

Expand Down Expand Up @@ -223,7 +223,7 @@ default: `'RememberMe.RememberMeTokens'`

#### `always`

このオプションをtrueに設定すると、ログインCookieは認証が識別された後、常に発行されます
このオプションをtrueに設定すると、認証が成功した後、常にログインCookieが発行されます

default: `false`

Expand All @@ -235,7 +235,7 @@ default: `false`

#### `dropExpiredToken`

このオプションをtrueに設定すると、認証が識別された後に有効期限が切れたトークンを削除します
このオプションをtrueに設定すると、認証が成功した後に有効期限が切れたトークンを削除します

default: `true`

Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
</a>
</p>

This plugin provides an authenticate handler that permanent login by cookie. This plugin use method of issuing a token, instead of set to cookie encrypted username/password.
This plugin provides an authentication handler that enables permanent login via cookie. This plugin uses a method of issuing a token instead of setting an encrypted username / password in a cookie.

This library inspired by Barry Jaspan's article "[Improved Persistent Login Cookie Best Practice](http://jaspan.com/improved_persistent_login_cookie_best_practice)", and Gabriel Birke's libray "https://github.com/gbirke/rememberme".
This library is inspired by Barry Jaspan's article "[Improved Persistent Login Cookie Best Practice](http://jaspan.com/improved_persistent_login_cookie_best_practice)", and Gabriel Birke's library "https://github.com/gbirke/rememberme".

## Installation

Expand Down Expand Up @@ -50,9 +50,9 @@ bin/cake migrations migrate -p RememberMe
## Usage with Authentication plugin

If you're using [cakephp/authentication](https://github.com/cakephp/authentication),
use `RememberMeTokenIdentifier` and `CookeAuthenticator`.
use `RememberMeTokenIdentifier` and `CookieAuthenticator`.

Example load RememberMe's Identifier and Authenticator into the `getAuthenticationService` hook within `Application`:
Example of loading RememberMe's Identifier and Authenticator into the `getAuthenticationService` hook within `Application`:

```php
// in your src/Application.php
Expand Down Expand Up @@ -97,8 +97,8 @@ default: `['username' => 'username']`

#### `resolver`

The identity resolver. If change your Resolver,
must extend `Authentication\Identifier\Resolver\OrmResolver`.
The identity resolver. If you change your Resolver,
it must extend `Authentication\Identifier\Resolver\OrmResolver`.

default: `'Authentication.Orm'`

Expand All @@ -113,7 +113,7 @@ default: `'Authentication.Orm'`

#### `tokenStorageModel`

A model used for find login cookie tokens.
A model used for finding login cookie tokens.

default: `'RememberMe.RememberMeTokens'`

Expand Down Expand Up @@ -223,7 +223,7 @@ default: `'RememberMe.RememberMeTokens'`

#### `always`

When this option is set to true, a login cookie is always issued after authentication identified.
When this option is set to true, a login cookie is always issued after successful authentication.

default: `false`

Expand All @@ -235,7 +235,7 @@ default: `false`

#### `dropExpiredToken`

When this option is set to true, drop expired tokens after authentication identified.
When this option is set to true, expired tokens are dropped after successful authentication.

default: `true`

Expand Down
10 changes: 9 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"cakephp/cakephp": "^5.0",
"cakephp/cakephp-codesniffer": "^5.1",
"cakephp/migrations": "^4.0",
"phpunit/phpunit": "^10.1"
"phpstan/phpstan": "^1.12",
"phpunit/phpunit": "^10.5.5 || ^11.1.3 || ^12.0.9"
},
"autoload": {
"psr-4": {
Expand All @@ -36,8 +37,15 @@
}
},
"scripts": {
"check": [
"@cs-check",
"@stan",
"@test"
],
"cs-check": "phpcs -p --extensions=php ./src ./tests",
"cs-fix": "phpcbf -p --extensions=php ./src ./tests",
"stan": "phpstan analyse",
"test": "phpunit --colors=always",
"update-lowest": "composer update --prefer-lowest --prefer-stable"
},
"config": {
Expand Down
11 changes: 11 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
parameters:
level: 8
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false
paths:
- src/
excludePaths:
- test_app/
ignoreErrors:
-
identifier: missingType.generics
15 changes: 10 additions & 5 deletions src/Authenticator/CookieAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
$encryptedToken = static::encryptToken(
$identity[$this->getConfig('fields.' . AbstractIdentifier::CREDENTIAL_USERNAME)],
$token['series'],
$token['token']
$token['token'],
);
$cookie = $this->_createCookie($encryptedToken, $token['expires']);

Expand All @@ -173,8 +173,13 @@
throw new InvalidArgumentException('Can\'t detect user model');
}

$userTable = $this->fetchTable($userModel);
/** @var \RememberMe\Model\Table\RememberMeTokensTableInterface $tokenTable */
$usersTable = $this->fetchTable($userModel);
$primaryKey = $usersTable->getPrimaryKey();
if (!is_string($primaryKey)) {
throw new InvalidArgumentException('User model must have a single primary key.');

Check warning on line 179 in src/Authenticator/CookieAuthenticator.php

View check run for this annotation

Codecov / codecov/patch

src/Authenticator/CookieAuthenticator.php#L179

Added line #L179 was not covered by tests
}

/** @var \RememberMe\Model\Table\RememberMeTokensTableInterface&\Cake\ORM\Table $tokenTable */
$tokenTable = $this->fetchTable($this->getConfig('tokenStorageModel'));

if ($this->getConfig('dropExpiredToken')) {
Expand All @@ -185,7 +190,7 @@
// create token entity
$entity = $tokenTable->newEntity([
'model' => $userModel,
'foreign_id' => $identity[$userTable->getPrimaryKey()],
'foreign_id' => $identity[$primaryKey],
'series' => static::_generateToken($identity),
'token' => $token,
'expires' => new DateTime($this->getConfig('cookie.expire')),
Expand Down Expand Up @@ -261,7 +266,7 @@
$data['path'],
$data['domain'],
$data['secure'],
$data['httpOnly']
$data['httpOnly'],
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Authenticator/EncryptCookieTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public static function encryptToken(string $username, string $series, string $to
return base64_encode(
Security::encrypt(
json_encode(compact('username', 'series', 'token'), JSON_THROW_ON_ERROR),
Security::getSalt()
)
Security::getSalt(),
),
);
}

Expand Down
14 changes: 9 additions & 5 deletions src/Identifier/RememberMeTokenIdentifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
/**
* @inheritDoc
*/
protected function buildResolver($config): OrmResolver
protected function buildResolver(array|string $config): OrmResolver
{
$instance = $this->traitBuildResolver($config);

Expand All @@ -71,7 +71,7 @@
!isset(
$credentials[self::CREDENTIAL_USERNAME],
$credentials[self::CREDENTIAL_SERIES],
$credentials[self::CREDENTIAL_TOKEN]
$credentials[self::CREDENTIAL_TOKEN],
)
) {
return null;
Expand Down Expand Up @@ -118,10 +118,10 @@
}

/**
* find user's remember me token.
* find some user's remember me token.
*
* @param \Cake\Datasource\EntityInterface $identity the identity
* @param string $series the credentials series
* @param string $series the credential series
* @return \Cake\Datasource\EntityInterface|null
*/
protected function _findToken(EntityInterface $identity, string $series): ?EntityInterface
Expand All @@ -133,11 +133,15 @@

$usersTable = $this->getResolver()->fetchTable($userModel);
$tokenStorageTable = $this->getResolver()->fetchTable($this->getConfig('tokenStorageModel'));
$primaryKey = $usersTable->getPrimaryKey();
if (!is_string($primaryKey)) {
throw new InvalidArgumentException('User model must have a single primary key.');

Check warning on line 138 in src/Identifier/RememberMeTokenIdentifier.php

View check run for this annotation

Codecov / codecov/patch

src/Identifier/RememberMeTokenIdentifier.php#L138

Added line #L138 was not covered by tests
}

return $tokenStorageTable->find()
->where([
'model' => $userModel,
'foreign_id' => $identity->get($usersTable->getPrimaryKey()),
'foreign_id' => $identity->get($primaryKey),
'series' => $series,
])
->first();
Expand Down
12 changes: 2 additions & 10 deletions src/Model/Entity/RememberMeToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,15 @@
class RememberMeToken extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* @var array
* @inheritDoc
*/
protected array $_accessible = [
'*' => true,
'id' => false,
];

/**
* Fields that are excluded from JSON versions of the entity.
*
* @var array
* @inheritDoc
*/
protected array $_hidden = [
'token',
Expand Down
Loading