Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UserStorage: support int in setExpiration() #71

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
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
19 changes: 0 additions & 19 deletions .github/ISSUE_TEMPLATE/Bug_report.md

This file was deleted.

9 changes: 0 additions & 9 deletions .github/ISSUE_TEMPLATE/Feature_request.md

This file was deleted.

12 changes: 0 additions & 12 deletions .github/ISSUE_TEMPLATE/Support_question.md

This file was deleted.

21 changes: 0 additions & 21 deletions .github/ISSUE_TEMPLATE/Support_us.md

This file was deleted.

2 changes: 0 additions & 2 deletions .github/funding.yml

This file was deleted.

11 changes: 0 additions & 11 deletions .github/pull_request_template.md

This file was deleted.

8 changes: 4 additions & 4 deletions .github/workflows/coding-style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ jobs:
name: Nette Code Checker
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: 7.2
php-version: 8.0
coverage: none

- run: composer create-project nette/code-checker temp/code-checker ^3 --no-progress
Expand All @@ -21,10 +21,10 @@ jobs:
name: Nette Coding Standard
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: 7.4
php-version: 8.0
coverage: none

- run: composer create-project nette/coding-standard temp/coding-standard ^3 --no-progress
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ jobs:
name: PHPStan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: 7.4
php-version: 8.0
coverage: none

- run: composer install --no-progress --prefer-dist
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
php: ['8.0', '8.1', '8.2']

fail-fast: false

name: PHP ${{ matrix.php }} tests
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
Expand All @@ -22,7 +22,7 @@ jobs:
- run: composer install --no-progress --prefer-dist
- run: vendor/bin/tester tests -s -C
- if: failure()
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: output
path: tests/**/output
Expand All @@ -32,10 +32,10 @@ jobs:
name: Lowest Dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: 7.2
php-version: 8.0
coverage: none

- run: composer update --no-progress --prefer-dist --prefer-lowest --prefer-stable
Expand All @@ -46,10 +46,10 @@ jobs:
name: Code Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: 7.4
php-version: 8.0
coverage: none

- run: composer install --no-progress --prefer-dist
Expand Down
14 changes: 7 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
}
],
"require": {
"php": ">=7.2 <8.3",
"nette/utils": "^3.2.1"
"php": ">=8.0 <8.3",
"nette/utils": "^4.0"
},
"require-dev": {
"nette/di": "^3.0.1",
"nette/http": "^3.0.0",
"nette/tester": "^2.0",
"tracy/tracy": "^2.4",
"nette/di": "^4.0",
"nette/http": "^4.0",
"nette/tester": "^2.4",
"tracy/tracy": "^2.8",
"phpstan/phpstan-nette": "^1.0",
"mockery/mockery": "^1.5"
},
Expand All @@ -40,7 +40,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
"dev-master": "4.0-dev"
}
}
}
33 changes: 0 additions & 33 deletions contributing.md

This file was deleted.

26 changes: 13 additions & 13 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Authentication & Authorization library for Nette.

Documentation can be found on the [website](https://doc.nette.org/access-control).

It requires PHP version 7.2 and supports PHP up to 8.2.
It requires PHP version 8.0 and supports PHP up to 8.2.


[Support Me](https://github.com/sponsors/dg)
Expand Down Expand Up @@ -72,7 +72,7 @@ $user->setExpiration(null);

Expiration must be set to value equal or lower than the expiration of sessions.

The reason of the last logout can be obtained by method `$user->getLogoutReason()`, which returns either the constant `Nette\Security\IUserStorage::INACTIVITY` if the time expired or `IUserStorage::MANUAL` when the `logout()` method was called.
The reason of the last logout can be obtained by method `$user->getLogoutReason()`, which returns either the constant `Nette\Security\UserStorage::LOGOUT_INACTIVITY` if the time expired or `UserStorage::LOGOUT_MANUAL` when the `logout()` method was called.

In presenters, you can verify login in the `startup()` method:

Expand Down Expand Up @@ -102,12 +102,12 @@ $authenticator = new Nette\Security\SimpleAuthenticator([

This solution is more suitable for testing purposes. We will show you how to create an authenticator that will verify credentials against a database table.

An authenticator is an object that implements the [Nette\Security\IAuthenticator](https://api.nette.org/3.0/Nette/Security/IAuthenticator.html) interface with method `authenticate()`. Its task is either to return the so-called [identity](#Identity) or to throw an exception `Nette\Security\AuthenticationException`. It would also be possible to provide an fine-grain error code `IAuthenticator::IDENTITY_NOT_FOUND` or `IAuthenticator::INVALID_CREDENTIAL`.
An authenticator is an object that implements the [Nette\Security\Authenticator](https://api.nette.org/3.0/Nette/Security/Authenticator.html) interface with method `authenticate()`. Its task is either to return the so-called [identity](#Identity) or to throw an exception `Nette\Security\AuthenticationException`. It would also be possible to provide an fine-grain error code `Authenticator::IDENTITY_NOT_FOUND` or `Authenticator::INVALID_CREDENTIAL`.

```php
use Nette;

class MyAuthenticator implements Nette\Security\IAuthenticator
class MyAuthenticator implements Nette\Security\Authenticator
{
private $database;
private $passwords;
Expand All @@ -118,10 +118,8 @@ class MyAuthenticator implements Nette\Security\IAuthenticator
$this->passwords = $passwords;
}

public function authenticate(array $credentials): Nette\Security\IIdentity
public function authenticate($username, $password): Nette\Security\IIdentity
{
[$username, $password] = $credentials;

$row = $this->database->table('users')
->where('username', $username)
->fetch();
Expand All @@ -134,7 +132,7 @@ class MyAuthenticator implements Nette\Security\IAuthenticator
throw new Nette\Security\AuthenticationException('Invalid password.');
}

return new Nette\Security\Identity(
return new Nette\Security\SimpleIdentity(
$row->id,
$row->role, // or array of roles
['name' => $row->username]
Expand Down Expand Up @@ -180,7 +178,7 @@ Importantly, **when user logs out, identity is not deleted** and is still availa

Thanks to this, you can still assume which user is at the computer and, for example, display personalized offers in the e-shop, however, you can only display his personal data after logging in.

Identity is an object that implements the [Nette\Security\IIdentity](https://api.nette.org/3.0/Nette/Security/IIdentity.html) interface, the default implementation is [Nette\Security\Identity](https://api.nette.org/3.0/Nette/Security/Identity.html). And as mentioned, identity is stored in the session, so if, for example, we change the role of some of the logged-in users, old data will be kept in the identity until he logs in again.
Identity is an object that implements the [Nette\Security\IIdentity](https://api.nette.org/3.0/Nette/Security/IIdentity.html) interface, the default implementation is [Nette\Security\SimpleIdentity](https://api.nette.org/3.0/Nette/Security/SimpleIdentity.html). And as mentioned, identity is stored in the session, so if, for example, we change the role of some of the logged-in users, old data will be kept in the identity until he logs in again.



Expand All @@ -201,7 +199,7 @@ if ($user->isLoggedIn()) { // is user logged in?
Roles
-----

The purpose of roles is to offer a more precise permission management and remain independent on the user name. As soon as user logs in, he is assigned one or more roles. Roles themselves may be simple strings, for example, `admin`, `member`, `guest`, etc. They are specified in the second argument of `Identity` constructor, either as a string or an array.
The purpose of roles is to offer a more precise permission management and remain independent on the user name. As soon as user logs in, he is assigned one or more roles. Roles themselves may be simple strings, for example, `admin`, `member`, `guest`, etc. They are specified in the second argument of `SimpleIdentity` constructor, either as a string or an array.

As an authorization criterion, we will now use the method `isInRole()`, which checks whether the user is in the given role:

Expand All @@ -211,7 +209,7 @@ if ($user->isInRole('admin')) { // is the admin role assigned to the user?
}
```

As you already know, logging the user out does not erase his identity. Thus, method `getIdentity()` still returns object `Identity`, including all granted roles. The Nette Framework adheres to the principle of "less code, more security", so when you are checking roles, you do not have to check whether the user is logged in too. Method `isInRole()` works with **effective roles**, ie if the user is logged in, roles assigned to identity are used, if he is not logged in, an automatic special role `guest` is used instead.
As you already know, logging the user out does not erase his identity. Thus, method `getIdentity()` still returns object `SimpleIdentity`, including all granted roles. The Nette Framework adheres to the principle of "less code, more security", so when you are checking roles, you do not have to check whether the user is logged in too. Method `isInRole()` works with **effective roles**, ie if the user is logged in, roles assigned to identity are used, if he is not logged in, an automatic special role `guest` is used instead.


Authorizator
Expand All @@ -223,10 +221,10 @@ In addition to roles, we will introduce the terms resource and operation:
- **resource** is a logical unit of the application - article, page, user, menu item, poll, presenter, ...
- **operation** is a specific activity, which user may or may not do with *resource* - view, edit, delete, vote, ...

An authorizer is an object that decides whether a given *role* has permission to perform a certain *operation* with specific *resource*. It is an object implementing the [Nette\Security\IAuthorizator](https://api.nette.org/3.0/Nette/Security/IAuthorizator.html) interface with only one method `isAllowed()`:
An authorizer is an object that decides whether a given *role* has permission to perform a certain *operation* with specific *resource*. It is an object implementing the [Nette\Security\Authorizator](https://api.nette.org/3.0/Nette/Security/Authorizator.html) interface with only one method `isAllowed()`:

```php
class MyAuthorizator implements Nette\Security\IAuthorizator
class MyAuthorizator implements Nette\Security\Authorizator
{
public function isAllowed($role, $resource, $operation): bool
{
Expand Down Expand Up @@ -434,3 +432,5 @@ It is possible to have several independent logged users within one site and one
```php
$user->getStorage()->setNamespace('forum');
```

[Continue...](https://doc.nette.org/en/3.0/access-control)
13 changes: 4 additions & 9 deletions src/Bridges/SecurityDI/SecurityExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
*/
class SecurityExtension extends Nette\DI\CompilerExtension
{
/** @var bool */
private $debugMode;
private bool $debugMode;


public function __construct(bool $debugMode = false)
Expand All @@ -40,8 +39,8 @@ public function getConfigSchema(): Nette\Schema\Schema
'password' => Expect::string(),
'roles' => Expect::anyOf(Expect::string(), Expect::listOf('string')),
'data' => Expect::array(),
])->castTo('array')
)
])->castTo('array'),
),
),
'roles' => Expect::arrayOf('string|array|null'), // role => parent(s)
'resources' => Expect::arrayOf('string|null'), // resource => parent
Expand Down Expand Up @@ -81,10 +80,6 @@ public function loadConfiguration()
$storage->addSetup('setCookieParameters', [$auth->cookieName, $auth->cookieDomain, $auth->cookieSamesite]);
}

$builder->addDefinition($this->prefix('legacyUserStorage')) // deprecated
->setType(Nette\Security\IUserStorage::class)
->setFactory(Nette\Http\UserStorage::class);

$user = $builder->addDefinition($this->prefix('user'))
->setFactory(Nette\Security\User::class);

Expand All @@ -102,7 +97,7 @@ public function loadConfiguration()
}

$builder->addDefinition($this->prefix('authenticator'))
->setType(Nette\Security\IAuthenticator::class)
->setType(Nette\Security\Authenticator::class)
->setFactory(Nette\Security\SimpleAuthenticator::class, [$usersList, $usersRoles, $usersData]);

if ($this->name === 'security') {
Expand Down
Loading