diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md deleted file mode 100644 index a4cd1263..00000000 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: "🐛 Bug Report" -about: "If something isn't working as expected 🤔" - ---- - -Version: ?.?.? - -### Bug Description -... A clear and concise description of what the bug is. A good bug report shouldn't leave others needing to chase you up for more information. - -### Steps To Reproduce -... If possible a minimal demo of the problem ... - -### Expected Behavior -... A clear and concise description of what you expected to happen. - -### Possible Solution -... Only if you have suggestions on a fix for the bug diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md deleted file mode 100644 index d2e21948..00000000 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: "🚀 Feature Request" -about: "I have a suggestion (and may want to implement it) 🙂" - ---- - -- Is your feature request related to a problem? Please describe. -- Explain your intentions. -- It's up to you to make a strong case to convince the project's developers of the merits of this feature. diff --git a/.github/ISSUE_TEMPLATE/Support_question.md b/.github/ISSUE_TEMPLATE/Support_question.md deleted file mode 100644 index 75c48b6e..00000000 --- a/.github/ISSUE_TEMPLATE/Support_question.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: "🤗 Support Question" -about: "If you have a question 💬, please check out our forum!" - ---- - ---------------^ Click "Preview" for a nicer view! -We primarily use GitHub as an issue tracker; for usage and support questions, please check out these resources below. Thanks! 😁. - -* Nette Forum: https://forum.nette.org -* Nette Gitter: https://gitter.im/nette/nette -* Slack (czech): https://pehapkari.slack.com/messages/C2R30BLKA diff --git a/.github/ISSUE_TEMPLATE/Support_us.md b/.github/ISSUE_TEMPLATE/Support_us.md deleted file mode 100644 index 92d8a4c3..00000000 --- a/.github/ISSUE_TEMPLATE/Support_us.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: "❤️ Support us" -about: "If you would like to support our efforts in maintaining this project 🙌" - ---- - ---------------^ Click "Preview" for a nicer view! - -> https://nette.org/donate - -Help support Nette! - -We develop Nette Framework for more than 14 years. In order to make your life more comfortable. Nette cares about the safety of your sites. Nette saves you time. And gives job opportunities. - -Nette earns you money. And is absolutely free. - -To ensure future development and improving the documentation, we need your donation. - -Whether you are chief of IT company which benefits from Nette, or developer who goes for advice on our forum, if you like Nette, [please make a donation now](https://nette.org/donate). - -Thank you! diff --git a/.github/funding.yml b/.github/funding.yml deleted file mode 100644 index 25adc952..00000000 --- a/.github/funding.yml +++ /dev/null @@ -1,2 +0,0 @@ -github: dg -custom: "https://nette.org/donate" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index f8aa3f40..00000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,11 +0,0 @@ -- bug fix / new feature? -- BC break? yes/no -- doc PR: nette/docs#??? - - diff --git a/.github/workflows/coding-style.yml b/.github/workflows/coding-style.yml index d8020f6f..23019765 100644 --- a/.github/workflows/coding-style.yml +++ b/.github/workflows/coding-style.yml @@ -10,7 +10,7 @@ jobs: - 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 @@ -24,7 +24,7 @@ jobs: - 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 diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 08f1414a..b23bf1a1 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -13,7 +13,7 @@ jobs: - 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 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cf1784de..58b8cf7c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] + php: ['8.0', '8.1', '8.2', '8.3'] fail-fast: false @@ -35,7 +35,7 @@ jobs: - 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 @@ -49,7 +49,7 @@ jobs: - 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 diff --git a/composer.json b/composer.json index 16f8e372..38684854 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "nette/security", + "name": "involve-digital/security", "description": "🔑 Nette Security: provides authentication, authorization and a role-based access control management via ACL (Access Control List)", "keywords": ["nette", "authentication", "authorization", "ACL"], "homepage": "https://nette.org", @@ -15,16 +15,16 @@ } ], "require": { - "php": "7.2 - 8.3", + "php": "8.0 - 8.3", "nette/utils": "^3.2.1 || ~4.0.0" }, "require-dev": { - "nette/di": "^3.0.1", - "nette/http": "^3.0.0", - "nette/tester": "^2.0", - "tracy/tracy": "^2.4", + "nette/di": "^3.1 || ^4.0", + "nette/http": "^4.0", + "nette/tester": "^2.4", + "tracy/tracy": "^2.9", "phpstan/phpstan-nette": "^1.0", - "mockery/mockery": "^1.3.6" + "mockery/mockery": "^1.5" }, "conflict": { "nette/di": "<3.0-stable", @@ -40,7 +40,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } } } diff --git a/contributing.md b/contributing.md deleted file mode 100644 index 184152c0..00000000 --- a/contributing.md +++ /dev/null @@ -1,33 +0,0 @@ -How to contribute & use the issue tracker -========================================= - -Nette welcomes your contributions. There are several ways to help out: - -* Create an issue on GitHub, if you have found a bug -* Write test cases for open bug issues -* Write fixes for open bug/feature issues, preferably with test cases included -* Contribute to the [documentation](https://nette.org/en/writing) - -Issues ------- - -Please **do not use the issue tracker to ask questions**. We will be happy to help you -on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette). - -A good bug report shouldn't leave others needing to chase you up for more -information. Please try to be as detailed as possible in your report. - -**Feature requests** are welcome. But take a moment to find out whether your idea -fits with the scope and aims of the project. It's up to *you* to make a strong -case to convince the project's developers of the merits of this feature. - -Contributing ------------- - -If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing). - -The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them. - -Please do not fix whitespace, format code, or make a purely cosmetic patch. - -Thanks! :heart: diff --git a/readme.md b/readme.md index 74854f9c..354f7ce6 100644 --- a/readme.md +++ b/readme.md @@ -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.3. +It requires PHP version 8.0 and supports PHP up to 8.3. [Support Me](https://github.com/sponsors/dg) diff --git a/src/Bridges/SecurityDI/SecurityExtension.php b/src/Bridges/SecurityDI/SecurityExtension.php index b2e3b145..14796df5 100644 --- a/src/Bridges/SecurityDI/SecurityExtension.php +++ b/src/Bridges/SecurityDI/SecurityExtension.php @@ -19,8 +19,7 @@ */ class SecurityExtension extends Nette\DI\CompilerExtension { - /** @var bool */ - private $debugMode; + private bool $debugMode; public function __construct(bool $debugMode = false) @@ -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 @@ -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); @@ -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') { diff --git a/src/Bridges/SecurityHttp/CookieStorage.php b/src/Bridges/SecurityHttp/CookieStorage.php index 12764efd..6c5e77cb 100644 --- a/src/Bridges/SecurityHttp/CookieStorage.php +++ b/src/Bridges/SecurityHttp/CookieStorage.php @@ -23,26 +23,13 @@ final class CookieStorage implements Nette\Security\UserStorage private const MinLength = 13; - /** @var Http\IRequest */ - private $request; - - /** @var Http\IResponse */ - private $response; - - /** @var ?string */ - private $uid; - - /** @var string */ - private $cookieName = 'userid'; - - /** @var ?string */ - private $cookieDomain; - - /** @var string */ - private $cookieSameSite = 'Lax'; - - /** @var ?string */ - private $cookieExpiration; + private Http\IRequest $request; + private Http\IResponse $response; + private ?string $uid = null; + private string $cookieName = 'userid'; + private ?string $cookieDomain = null; + private string $cookieSameSite = 'Lax'; + private ?string $cookieExpiration = null; public function __construct(Http\IRequest $request, Http\IResponse $response) @@ -64,11 +51,8 @@ public function saveAuthentication(IIdentity $identity): void $this->cookieName, $uid, $this->cookieExpiration, - null, - $this->cookieDomain, - null, - true, - $this->cookieSameSite + domain: $this->cookieDomain, + sameSite: $this->cookieSameSite, ); } @@ -78,8 +62,7 @@ public function clearAuthentication(bool $clearIdentity): void $this->uid = ''; $this->response->deleteCookie( $this->cookieName, - null, - $this->cookieDomain + domain: $this->cookieDomain, ); } @@ -106,7 +89,7 @@ public function setExpiration(?string $expire, bool $clearIdentity): void public function setCookieParameters( ?string $name = null, ?string $domain = null, - ?string $sameSite = null + ?string $sameSite = null, ) { $this->cookieName = $name ?? $this->cookieName; $this->cookieDomain = $domain ?? $this->cookieDomain; diff --git a/src/Bridges/SecurityHttp/SessionStorage.php b/src/Bridges/SecurityHttp/SessionStorage.php index c1d2d491..a2f18abf 100644 --- a/src/Bridges/SecurityHttp/SessionStorage.php +++ b/src/Bridges/SecurityHttp/SessionStorage.php @@ -22,20 +22,11 @@ final class SessionStorage implements Nette\Security\UserStorage { use Nette\SmartObject; - /** @var string */ - private $namespace = ''; - - /** @var Session */ - private $sessionHandler; - - /** @var SessionSection */ - private $sessionSection; - - /** @var ?int */ - private $expireTime; - - /** @var bool */ - private $expireIdentity = false; + private string $namespace = ''; + private Session $sessionHandler; + private ?SessionSection $sessionSection = null; + private ?int $expireTime = null; + private bool $expireIdentity = false; public function __construct(Session $sessionHandler) @@ -110,9 +101,8 @@ private function setupExpiration(): void /** * Changes namespace; allows more users to share a session. - * @return static */ - public function setNamespace(string $namespace) + public function setNamespace(string $namespace): static { if ($this->namespace !== $namespace) { $this->namespace = $namespace; diff --git a/src/Bridges/SecurityTracy/UserPanel.php b/src/Bridges/SecurityTracy/UserPanel.php index 488757c1..123d86c1 100644 --- a/src/Bridges/SecurityTracy/UserPanel.php +++ b/src/Bridges/SecurityTracy/UserPanel.php @@ -20,8 +20,7 @@ class UserPanel implements Tracy\IBarPanel { use Nette\SmartObject; - /** @var Nette\Security\User */ - private $user; + private Nette\Security\User $user; public function __construct(Nette\Security\User $user) diff --git a/src/Security/Authenticator.php b/src/Security/Authenticator.php index d79e6364..4bc1df39 100644 --- a/src/Security/Authenticator.php +++ b/src/Security/Authenticator.php @@ -13,7 +13,7 @@ /** * Performs authentication. */ -interface Authenticator extends IAuthenticator +interface Authenticator { /** Exception error code */ public const @@ -22,6 +22,18 @@ interface Authenticator extends IAuthenticator Failure = 3, NotApproved = 4; + /** @deprecated use Authenticator::IdentityNotFound */ + public const IDENTITY_NOT_FOUND = self::IdentityNotFound; + + /** @deprecated use Authenticator::InvalidCredential */ + public const INVALID_CREDENTIAL = self::InvalidCredential; + + /** @deprecated use Authenticator::Failure */ + public const FAILURE = self::Failure; + + /** @deprecated use Authenticator::NotApproved */ + public const NOT_APPROVED = self::NotApproved; + /** * Performs an authentication. * @throws AuthenticationException diff --git a/src/Security/Authorizator.php b/src/Security/Authorizator.php index 267fcccd..a8fa356e 100644 --- a/src/Security/Authorizator.php +++ b/src/Security/Authorizator.php @@ -25,17 +25,19 @@ interface Authorizator /** Permission type: deny */ public const Deny = false; + /** @deprecated use Authorizator::All */ public const ALL = self::All; + + /** @deprecated use Authorizator::Allow */ public const ALLOW = self::Allow; + + /** @deprecated use Authorizator::Deny */ public const DENY = self::Deny; /** * Performs a role-based authorization. - * @param string|null $role - * @param string|null $resource - * @param string|null $privilege */ - function isAllowed($role, $resource, $privilege): bool; + function isAllowed(?string $role, ?string $resource, ?string $privilege): bool; } diff --git a/src/Security/IAuthenticator.php b/src/Security/IAuthenticator.php deleted file mode 100644 index 4d845ad6..00000000 --- a/src/Security/IAuthenticator.php +++ /dev/null @@ -1,37 +0,0 @@ -setId($id); - $this->setRoles((array) $roles); - $this->data = $data instanceof \Traversable - ? iterator_to_array($data) - : (array) $data; - } - - - /** - * Sets the ID of user. - * @param string|int $id - * @return static - */ - public function setId($id) - { - if (!is_string($id) && !is_int($id)) { - throw new Nette\InvalidArgumentException('Identity identifier must be string|int, but type "' . gettype($id) . '" given.'); - } - - $this->id = is_numeric($id) && !is_float($tmp = $id * 1) ? $tmp : $id; - return $this; - } - - - /** - * Returns the ID of user. - * @return mixed - */ - public function getId() - { - return $this->id; - } - - - /** - * Sets a list of roles that the user is a member of. - * @return static - */ - public function setRoles(array $roles) - { - $this->roles = $roles; - return $this; - } - - - /** - * Returns a list of roles that the user is a member of. - */ - public function getRoles(): array - { - return $this->roles; - } - - - /** - * Returns a user data. - */ - public function getData(): array - { - return $this->data; - } - - - /** - * Sets user data value. - */ - public function __set(string $key, $value): void - { - if ($this->parentIsSet($key)) { - $this->parentSet($key, $value); - - } else { - $this->data[$key] = $value; - } - } - - - /** - * Returns user data value. - * @return mixed - */ - public function &__get(string $key) - { - if ($this->parentIsSet($key)) { - return $this->parentGet($key); - - } else { - return $this->data[$key]; - } - } - - - public function __isset(string $key): bool - { - return isset($this->data[$key]) || $this->parentIsSet($key); - } -} diff --git a/src/Security/Passwords.php b/src/Security/Passwords.php index 476514b3..f7b55b9a 100644 --- a/src/Security/Passwords.php +++ b/src/Security/Passwords.php @@ -19,21 +19,14 @@ class Passwords { use Nette\SmartObject; - /** @var int|string string since PHP 7.4 */ - private $algo; - - /** @var array */ - private $options; - - /** * Chooses which secure algorithm is used for hashing and how to configure it. * @see https://php.net/manual/en/password.constants.php */ - public function __construct($algo = PASSWORD_DEFAULT, array $options = []) - { - $this->algo = $algo; - $this->options = $options; + public function __construct( + private string $algo = PASSWORD_DEFAULT, + private array $options = [], + ) { } diff --git a/src/Security/Permission.php b/src/Security/Permission.php index d1a801bc..e69ca4f4 100644 --- a/src/Security/Permission.php +++ b/src/Security/Permission.php @@ -21,14 +21,14 @@ class Permission implements Authorizator { use Nette\SmartObject; - /** @var array Role storage */ - private $roles = []; + /** Role storage */ + private array $roles = []; - /** @var array Resource storage */ - private $resources = []; + /** Resource storage */ + private array $resources = []; - /** @var array Access Control List rules; whitelist (deny everything to all) by default */ - private $rules = [ + /** Access Control List rules; whitelist (deny everything to all) by default */ + private array $rules = [ 'allResources' => [ 'allRoles' => [ 'allPrivileges' => [ @@ -42,9 +42,7 @@ class Permission implements Authorizator 'byResource' => [], ]; - /** @var mixed */ - private $queriedRole; - + private mixed $queriedRole; private $queriedResource; @@ -391,7 +389,7 @@ public function allow( $roles = self::All, $resources = self::All, $privileges = self::All, - ?callable $assertion = null + ?callable $assertion = null, ) { $this->setRule(true, self::Allow, $roles, $resources, $privileges, $assertion); return $this; @@ -411,7 +409,7 @@ public function deny( $roles = self::All, $resources = self::All, $privileges = self::All, - ?callable $assertion = null + ?callable $assertion = null, ) { $this->setRule(true, self::Deny, $roles, $resources, $privileges, $assertion); return $this; @@ -426,7 +424,7 @@ public function deny( * @param string|string[]|null $privileges * @return static */ - public function removeAllow($roles = self::All, $resources = self::All, $privileges = self::All) + public function removeAllow($roles = self::All, $resources = self::All, $privileges = self::All): static { $this->setRule(false, self::Allow, $roles, $resources, $privileges); return $this; @@ -441,7 +439,7 @@ public function removeAllow($roles = self::All, $resources = self::All, $privile * @param string|string[]|null $privileges * @return static */ - public function removeDeny($roles = self::All, $resources = self::All, $privileges = self::All) + public function removeDeny($roles = self::All, $resources = self::All, $privileges = self::All): static { $this->setRule(false, self::Deny, $roles, $resources, $privileges); return $this; diff --git a/src/Security/SimpleAuthenticator.php b/src/Security/SimpleAuthenticator.php index cbf2aae8..9f9b0efb 100644 --- a/src/Security/SimpleAuthenticator.php +++ b/src/Security/SimpleAuthenticator.php @@ -19,16 +19,6 @@ class SimpleAuthenticator implements Authenticator { use Nette\SmartObject; - /** @var array */ - private $passwords; - - /** @var array */ - private $roles; - - /** @var array */ - private $data; - - /** * @param array $passwords list of pairs username => password * @param array $roles list of pairs username => role[] @@ -36,13 +26,10 @@ class SimpleAuthenticator implements Authenticator */ public function __construct( #[\SensitiveParameter] - array $passwords, - array $roles = [], - array $data = [] + private array $passwords, + private array $roles = [], + private array $data = [], ) { - $this->passwords = $passwords; - $this->roles = $roles; - $this->data = $data; } diff --git a/src/Security/SimpleIdentity.php b/src/Security/SimpleIdentity.php index 279aadd0..3c5ab1b1 100644 --- a/src/Security/SimpleIdentity.php +++ b/src/Security/SimpleIdentity.php @@ -9,10 +9,133 @@ namespace Nette\Security; +use Nette; + /** * Default implementation of IIdentity. + * @property string|int $id + * @property array $roles + * @property array $data */ -class SimpleIdentity extends Identity +class SimpleIdentity implements IIdentity { + use Nette\SmartObject { + __get as private parentGet; + __set as private parentSet; + __isset as private parentIsSet; + } + + private string|int $id; + private array $roles; + private array $data; + + + public function __construct($id, $roles = null, ?iterable $data = null) + { + $this->setId($id); + $this->setRoles((array) $roles); + $this->data = $data instanceof \Traversable + ? iterator_to_array($data) + : (array) $data; + } + + + /** + * Sets the ID of user. + */ + public function setId(string|int $id): static + { + $this->id = is_numeric($id) && !is_float($tmp = $id * 1) ? $tmp : $id; + return $this; + } + + + /** + * Returns the ID of user. + */ + public function getId(): string|int + { + return $this->id; + } + + + /** + * Sets a list of roles that the user is a member of. + */ + public function setRoles(array $roles): static + { + $this->roles = $roles; + return $this; + } + + + /** + * Returns a list of roles that the user is a member of. + */ + public function getRoles(): array + { + return $this->roles; + } + + + /** + * Returns a user data. + */ + public function getData(): array + { + return $this->data; + } + + + /** + * Sets user data value. + */ + public function __set(string $key, $value): void + { + if ($this->parentIsSet($key)) { + $this->parentSet($key, $value); + + } else { + $this->data[$key] = $value; + } + } + + + /** + * Returns user data value. + */ + public function &__get(string $key): mixed + { + if ($this->parentIsSet($key)) { + return $this->parentGet($key); + + } else { + return $this->data[$key]; + } + } + + + public function __isset(string $key): bool + { + return isset($this->data[$key]) || $this->parentIsSet($key); + } + + + public function __serialize(): array + { + return [ + 'id' => $this->id, + 'roles' => $this->roles, + 'data' => $this->data, + ]; + } + + + public function __unserialize(array $data): void + { + $this->id = $data['id'] ?? $data["\00Nette\\Security\\Identity\00id"] ?? 0; + $this->roles = $data['roles'] ?? $data["\00Nette\\Security\\Identity\00roles"] ?? []; + $this->data = $data['data'] ?? $data["\00Nette\\Security\\Identity\00data"] ?? []; + } } diff --git a/src/Security/User.php b/src/Security/User.php index 10dafe72..96e0a5c2 100644 --- a/src/Security/User.php +++ b/src/Security/User.php @@ -16,82 +16,61 @@ /** * User authentication and authorization. * - * @property-read bool $loggedIn - * @property-read IIdentity $identity - * @property-read mixed $id - * @property-read array $roles - * @property-read int $logoutReason - * @property IAuthenticator $authenticator - * @property Authorizator $authorizator + * @property-deprecated bool $loggedIn + * @property-deprecated IIdentity $identity + * @property-deprecated string|int $id + * @property-deprecated array $roles + * @property-deprecated int $logoutReason + * @property-deprecated Authenticator $authenticator + * @property-deprecated Authorizator $authorizator */ class User { use Nette\SmartObject; - /** @deprecated */ - public const - MANUAL = IUserStorage::MANUAL, - INACTIVITY = IUserStorage::INACTIVITY; - /** Log-out reason */ public const LogoutManual = UserStorage::LogoutManual, LogoutInactivity = UserStorage::LogoutInactivity; + /** @deprecated use User::LogoutManual */ public const LOGOUT_MANUAL = self::LogoutManual; - public const LOGOUT_INACTIVITY = self::LogoutInactivity; - /** @var string default role for unauthenticated user */ - public $guestRole = 'guest'; + /** @deprecated use User::LogoutManual */ + public const MANUAL = self::LogoutManual; - /** @var string default role for authenticated user without own identity */ - public $authenticatedRole = 'authenticated'; - - /** @var callable[] function (User $sender): void; Occurs when the user is successfully logged in */ - public $onLoggedIn = []; - - /** @var callable[] function (User $sender): void; Occurs when the user is logged out */ - public $onLoggedOut = []; + /** @deprecated use User::LogoutInactivity */ + public const LOGOUT_INACTIVITY = self::LogoutInactivity; - /** @var UserStorage|IUserStorage Session storage for current user */ - private $storage; + /** @deprecated use User::LogoutInactivity */ + public const INACTIVITY = self::LogoutInactivity; - /** @var IAuthenticator|null */ - private $authenticator; + /** default role for unauthenticated user */ + public string $guestRole = 'guest'; - /** @var Authorizator|null */ - private $authorizator; + /** default role for authenticated user without own identity */ + public string $authenticatedRole = 'authenticated'; - /** @var IIdentity|null */ - private $identity; + /** @var callable[] function (User $sender): void; Occurs when the user is successfully logged in */ + public array $onLoggedIn = []; - /** @var bool|null */ - private $authenticated; + /** @var callable[] function (User $sender): void; Occurs when the user is logged out */ + public array $onLoggedOut = []; - /** @var int|null */ - private $logoutReason; + private ?IIdentity $identity = null; + private ?bool $authenticated = null; + private ?int $logoutReason = null; public function __construct( - ?IUserStorage $legacyStorage = null, - ?IAuthenticator $authenticator = null, - ?Authorizator $authorizator = null, - ?UserStorage $storage = null + private UserStorage $storage, + private ?Authenticator $authenticator = null, + private ?Authorizator $authorizator = null, ) { - $this->storage = $storage ?? $legacyStorage; // back compatibility - if (!$this->storage) { - throw new Nette\InvalidStateException('UserStorage has not been set.'); - } - - $this->authenticator = $authenticator; - $this->authorizator = $authorizator; } - /** - * @return UserStorage|IUserStorage - */ - final public function getStorage() + final public function getStorage(): UserStorage { return $this->storage; } @@ -106,7 +85,7 @@ final public function getStorage() * @throws AuthenticationException if authentication was not successful */ public function login( - $user, + string|IIdentity $user, #[\SensitiveParameter] ?string $password = null ): void @@ -116,21 +95,14 @@ public function login( $this->identity = $user; } else { $authenticator = $this->getAuthenticator(); - $this->identity = $authenticator instanceof Authenticator - ? $authenticator->authenticate(...func_get_args()) - : $authenticator->authenticate(func_get_args()); + $this->identity = $authenticator->authenticate(...func_get_args()); } $id = $this->authenticator instanceof IdentityHandler ? $this->authenticator->sleepIdentity($this->identity) : $this->identity; - if ($this->storage instanceof UserStorage) { - $this->storage->saveAuthentication($id); - } else { - $this->storage->setIdentity($id); - $this->storage->setAuthenticated(true); - } + $this->storage->saveAuthentication($id); $this->authenticated = true; $this->logoutReason = null; Arrays::invoke($this->onLoggedIn, $this); @@ -143,16 +115,7 @@ public function login( final public function logout(bool $clearIdentity = false): void { $logged = $this->isLoggedIn(); - - if ($this->storage instanceof UserStorage) { - $this->storage->clearAuthentication($clearIdentity); - } else { - $this->storage->setAuthenticated(false); - if ($clearIdentity) { - $this->storage->setIdentity(null); - } - } - + $this->storage->clearAuthentication($clearIdentity); $this->authenticated = false; $this->logoutReason = self::MANUAL; if ($logged) { @@ -191,17 +154,11 @@ final public function getIdentity(): ?IIdentity private function getStoredData(): void { - if ($this->storage instanceof UserStorage) { - (function (bool $state, ?IIdentity $id, ?int $reason) use (&$identity) { - $identity = $id; - $this->authenticated = $state; - $this->logoutReason = $reason; - })(...$this->storage->getState()); - } else { - $identity = $this->storage->getIdentity(); - $this->authenticated = $this->storage->isAuthenticated(); - $this->logoutReason = $this->storage->getLogoutReason(); - } + (function (bool $state, ?IIdentity $id, ?int $reason) use (&$identity) { + $identity = $id; + $this->authenticated = $state; + $this->logoutReason = $reason; + })(...$this->storage->getState()); $this->identity = $identity && $this->authenticator instanceof IdentityHandler ? $this->authenticator->wakeupIdentity($identity) @@ -212,9 +169,8 @@ private function getStoredData(): void /** * Returns current user ID, if any. - * @return mixed */ - public function getId() + public function getId(): string|int|null { $identity = $this->getIdentity(); return $identity ? $identity->getId() : null; @@ -229,9 +185,8 @@ final public function refreshStorage(): void /** * Sets authentication handler. - * @return static */ - public function setAuthenticator(IAuthenticator $handler) + public function setAuthenticator(Authenticator $handler): static { $this->authenticator = $handler; return $this; @@ -241,14 +196,9 @@ public function setAuthenticator(IAuthenticator $handler) /** * Returns authentication handler. */ - final public function getAuthenticator(): ?IAuthenticator + final public function getAuthenticator(): Authenticator { - if (func_num_args()) { - trigger_error(__METHOD__ . '() parameter $throw is deprecated, use getAuthenticatorIfExists()', E_USER_DEPRECATED); - $throw = func_get_arg(0); - } - - if (($throw ?? true) && !$this->authenticator) { + if (!$this->authenticator) { throw new Nette\InvalidStateException('Authenticator has not been set.'); } @@ -259,7 +209,7 @@ final public function getAuthenticator(): ?IAuthenticator /** * Returns authentication handler. */ - final public function getAuthenticatorIfExists(): ?IAuthenticator + final public function getAuthenticatorIfExists(): ?Authenticator { return $this->authenticator; } @@ -274,25 +224,10 @@ final public function hasAuthenticator(): bool /** * Enables log out after inactivity (like '20 minutes'). - * @param string|null $expire - * @param int|bool $clearIdentity - * @return static */ - public function setExpiration($expire, $clearIdentity = null) + public function setExpiration(?string $expire, bool $clearIdentity = false) { - if ($expire !== null && !is_string($expire)) { - trigger_error("Expiration should be a string like '20 minutes' etc.", E_USER_DEPRECATED); - } - - if (func_num_args() > 2) { - $clearIdentity = $clearIdentity || func_get_arg(2); - trigger_error(__METHOD__ . '() third parameter is deprecated, use second one: setExpiration($time, true|false)', E_USER_DEPRECATED); - } - - $arg = $this->storage instanceof UserStorage - ? (bool) $clearIdentity - : ($clearIdentity ? IUserStorage::CLEAR_IDENTITY : 0); - $this->storage->setExpiration($expire, $arg); + $this->storage->setExpiration($expire, $clearIdentity); return $this; } @@ -356,9 +291,8 @@ public function isAllowed($resource = Authorizator::All, $privilege = Authorizat /** * Sets authorization handler. - * @return static */ - public function setAuthorizator(Authorizator $handler) + public function setAuthorizator(Authorizator $handler): static { $this->authorizator = $handler; return $this; @@ -368,14 +302,9 @@ public function setAuthorizator(Authorizator $handler) /** * Returns current authorization handler. */ - final public function getAuthorizator(): ?Authorizator + final public function getAuthorizator(): Authorizator { - if (func_num_args()) { - trigger_error(__METHOD__ . '() parameter $throw is deprecated, use getAuthorizatorIfExists()', E_USER_DEPRECATED); - $throw = func_get_arg(0); - } - - if (($throw ?? true) && !$this->authorizator) { + if (!$this->authorizator) { throw new Nette\InvalidStateException('Authorizator has not been set.'); } diff --git a/src/Security/UserStorage.php b/src/Security/UserStorage.php index 1b5e97e3..e4ca9427 100644 --- a/src/Security/UserStorage.php +++ b/src/Security/UserStorage.php @@ -20,7 +20,10 @@ interface UserStorage LogoutManual = 1, LogoutInactivity = 2; + /** @deprecated use User::LogoutManual */ public const LOGOUT_MANUAL = self::LogoutManual; + + /** @deprecated use User::LogoutInactivity */ public const LOGOUT_INACTIVITY = self::LogoutInactivity; /** diff --git a/src/compatibility-intf.php b/src/compatibility-intf.php new file mode 100644 index 00000000..ebfd19d1 --- /dev/null +++ b/src/compatibility-intf.php @@ -0,0 +1,37 @@ +compile()); $container = new Container; Assert::type(Nette\Bridges\SecurityHttp\SessionStorage::class, $container->getService('security.userStorage')); -Assert::type(Nette\Http\UserStorage::class, $container->getService('security.legacyUserStorage')); Assert::type(Nette\Security\User::class, $container->getService('security.user')); // aliases diff --git a/tests/Security.Http/CookieStorage.authentication.phpt b/tests/Security.Http/CookieStorage.authentication.phpt index 8debb1ae..f88f01a6 100644 --- a/tests/Security.Http/CookieStorage.authentication.phpt +++ b/tests/Security.Http/CookieStorage.authentication.phpt @@ -12,9 +12,10 @@ require __DIR__ . '/../bootstrap.php'; $request = new Nette\Http\Request(new Nette\Http\UrlScript); $response = Mockery::mock(Nette\Http\IResponse::class); $storage = new CookieStorage($request, $response); -Assert::exception(function () use ($storage) { - $storage->saveAuthentication(new SimpleIdentity('short')); -}, LogicException::class); +Assert::exception( + fn() => $storage->saveAuthentication(new SimpleIdentity('short')), + LogicException::class, +); // correct id $id = '123456789123456'; diff --git a/tests/Security.Http/CookieStorage.getState.phpt b/tests/Security.Http/CookieStorage.getState.phpt index 148a0102..ba4d0961 100644 --- a/tests/Security.Http/CookieStorage.getState.phpt +++ b/tests/Security.Http/CookieStorage.getState.phpt @@ -15,18 +15,18 @@ $storage = new CookieStorage($request, $response); Assert::same([false, null, null], $storage->getState()); // short id -$request = new Nette\Http\Request(new Nette\Http\UrlScript, [], [], ['userid' => 'short']); +$request = new Nette\Http\Request(new Nette\Http\UrlScript, cookies: ['userid' => 'short']); $storage = new CookieStorage($request, $response); Assert::same([false, null, null], $storage->getState()); // correct id $id = '123456789123456'; -$request = new Nette\Http\Request(new Nette\Http\UrlScript, [], [], ['userid' => $id]); +$request = new Nette\Http\Request(new Nette\Http\UrlScript, cookies: ['userid' => $id]); $storage = new CookieStorage($request, $response); Assert::equal([true, new SimpleIdentity($id), null], $storage->getState()); // custom cookie -$request = new Nette\Http\Request(new Nette\Http\UrlScript, [], [], ['foo' => $id]); +$request = new Nette\Http\Request(new Nette\Http\UrlScript, cookies: ['foo' => $id]); $storage = new CookieStorage($request, $response); $storage->setCookieParameters('foo'); Assert::equal([true, new SimpleIdentity($id), null], $storage->getState()); diff --git a/tests/Security/Identity.phpt b/tests/Security/Identity.phpt index 30ea0d6b..8cc91415 100644 --- a/tests/Security/Identity.phpt +++ b/tests/Security/Identity.phpt @@ -1,12 +1,12 @@ 'John']); + $id = new SimpleIdentity(12, 'admin', ['name' => 'John']); Assert::same(12, $id->getId()); Assert::same(12, $id->id); @@ -27,10 +27,10 @@ test('', function () { test('', function () { - $id = new Identity('12'); + $id = new SimpleIdentity('12'); Assert::same(12, $id->getId()); - $id = new Identity('12345678901234567890'); + $id = new SimpleIdentity('12345678901234567890'); Assert::same('12345678901234567890', $id->getId()); }); diff --git a/tests/Security/MockUserStorage.legacy.php b/tests/Security/MockUserStorage.legacy.php deleted file mode 100644 index d4b134be..00000000 --- a/tests/Security/MockUserStorage.legacy.php +++ /dev/null @@ -1,45 +0,0 @@ -auth = $state; - } - - - public function isAuthenticated(): bool - { - return $this->auth; - } - - - public function setIdentity(?Nette\Security\IIdentity $identity = null) - { - $this->identity = $identity; - } - - - public function getIdentity(): ?Nette\Security\IIdentity - { - return $this->identity; - } - - - public function setExpiration(?string $time, int $flags = 0) - { - } - - - public function getLogoutReason(): ?int - { - return null; - } -} diff --git a/tests/Security/Passwords.hash().phpt b/tests/Security/Passwords.hash().phpt index c8b7d376..a6acbcd1 100644 --- a/tests/Security/Passwords.hash().phpt +++ b/tests/Security/Passwords.hash().phpt @@ -14,20 +14,23 @@ require __DIR__ . '/../bootstrap.php'; Assert::truthy( - preg_match('#^\$.{50,}\z#', (new Passwords)->hash('my-password')) + preg_match('#^\$.{50,}\z#', (new Passwords)->hash('my-password')), ); Assert::truthy( - preg_match('#^\$2y\$05\$.{53}\z#', (new Passwords(PASSWORD_BCRYPT, ['cost' => 5]))->hash('dg')) + preg_match('#^\$2y\$05\$.{53}\z#', (new Passwords(PASSWORD_BCRYPT, ['cost' => 5]))->hash('dg')), ); $hash = (new Passwords(PASSWORD_BCRYPT))->hash('dg'); Assert::same($hash, crypt('dg', $hash)); -Assert::exception(function () { - (new Passwords(PASSWORD_BCRYPT, ['cost' => 3]))->hash('dg'); -}, PHP_VERSION_ID < 80000 ? Nette\InvalidStateException::class : ValueError::class); +Assert::exception( + fn() => (new Passwords(PASSWORD_BCRYPT, ['cost' => 3]))->hash('dg'), + PHP_VERSION_ID < 80000 ? Nette\InvalidStateException::class : ValueError::class, +); -Assert::exception(function () { - (new Passwords)->hash(''); -}, Nette\InvalidArgumentException::class, 'Password can not be empty.'); +Assert::exception( + fn() => (new Passwords)->hash(''), + Nette\InvalidArgumentException::class, + 'Password can not be empty.', +); diff --git a/tests/Security/Permission.IsAllowedNonExistent.phpt b/tests/Security/Permission.IsAllowedNonExistent.phpt index 260303c6..437e5085 100644 --- a/tests/Security/Permission.IsAllowedNonExistent.phpt +++ b/tests/Security/Permission.IsAllowedNonExistent.phpt @@ -13,12 +13,16 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -Assert::exception(function () { - $acl = new Permission; - $acl->isAllowed('nonexistent'); -}, Nette\InvalidStateException::class, "Role 'nonexistent' does not exist."); - -Assert::exception(function () { - $acl = new Permission; - $acl->isAllowed(null, 'nonexistent'); -}, Nette\InvalidStateException::class, "Resource 'nonexistent' does not exist."); +$acl = new Permission; +Assert::exception( + fn() => $acl->isAllowed('nonexistent'), + Nette\InvalidStateException::class, + "Role 'nonexistent' does not exist.", +); + +$acl = new Permission; +Assert::exception( + fn() => $acl->isAllowed(null, 'nonexistent'), + Nette\InvalidStateException::class, + "Resource 'nonexistent' does not exist.", +); diff --git a/tests/Security/Permission.ResourceAddInheritsNonExistent.phpt b/tests/Security/Permission.ResourceAddInheritsNonExistent.phpt index 9bdf4678..0351edcf 100644 --- a/tests/Security/Permission.ResourceAddInheritsNonExistent.phpt +++ b/tests/Security/Permission.ResourceAddInheritsNonExistent.phpt @@ -14,6 +14,8 @@ require __DIR__ . '/../bootstrap.php'; $acl = new Permission; -Assert::exception(function () use ($acl) { - $acl->addResource('area', 'nonexistent'); -}, Nette\InvalidStateException::class, "Resource 'nonexistent' does not exist."); +Assert::exception( + fn() => $acl->addResource('area', 'nonexistent'), + Nette\InvalidStateException::class, + "Resource 'nonexistent' does not exist.", +); diff --git a/tests/Security/Permission.ResourceDuplicate.phpt b/tests/Security/Permission.ResourceDuplicate.phpt index 25788827..983e8308 100644 --- a/tests/Security/Permission.ResourceDuplicate.phpt +++ b/tests/Security/Permission.ResourceDuplicate.phpt @@ -13,8 +13,10 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -Assert::exception(function () { - $acl = new Permission; - $acl->addResource('area'); - $acl->addResource('area'); -}, Nette\InvalidStateException::class, "Resource 'area' already exists in the list."); +$acl = new Permission; +$acl->addResource('area'); +Assert::exception( + fn() => $acl->addResource('area'), + Nette\InvalidStateException::class, + "Resource 'area' already exists in the list.", +); diff --git a/tests/Security/Permission.ResourceInheritsNonExistent.phpt b/tests/Security/Permission.ResourceInheritsNonExistent.phpt index 5503d6e6..5f1c88cf 100644 --- a/tests/Security/Permission.ResourceInheritsNonExistent.phpt +++ b/tests/Security/Permission.ResourceInheritsNonExistent.phpt @@ -15,10 +15,14 @@ require __DIR__ . '/../bootstrap.php'; $acl = new Permission; $acl->addResource('area'); -Assert::exception(function () use ($acl) { - $acl->resourceInheritsFrom('nonexistent', 'area'); -}, Nette\InvalidStateException::class, "Resource 'nonexistent' does not exist."); - -Assert::exception(function () use ($acl) { - $acl->resourceInheritsFrom('area', 'nonexistent'); -}, Nette\InvalidStateException::class, "Resource 'nonexistent' does not exist."); +Assert::exception( + fn() => $acl->resourceInheritsFrom('nonexistent', 'area'), + Nette\InvalidStateException::class, + "Resource 'nonexistent' does not exist.", +); + +Assert::exception( + fn() => $acl->resourceInheritsFrom('area', 'nonexistent'), + Nette\InvalidStateException::class, + "Resource 'nonexistent' does not exist.", +); diff --git a/tests/Security/Permission.ResourceRemoveOneNonExistent.phpt b/tests/Security/Permission.ResourceRemoveOneNonExistent.phpt index 2b981b95..b3c79077 100644 --- a/tests/Security/Permission.ResourceRemoveOneNonExistent.phpt +++ b/tests/Security/Permission.ResourceRemoveOneNonExistent.phpt @@ -14,6 +14,8 @@ require __DIR__ . '/../bootstrap.php'; $acl = new Permission; -Assert::exception(function () use ($acl) { - $acl->removeResource('nonexistent'); -}, Nette\InvalidStateException::class, "Resource 'nonexistent' does not exist."); +Assert::exception( + fn() => $acl->removeResource('nonexistent'), + Nette\InvalidStateException::class, + "Resource 'nonexistent' does not exist.", +); diff --git a/tests/Security/Permission.RoleRegistryAddInheritsNonExistent.phpt b/tests/Security/Permission.RoleRegistryAddInheritsNonExistent.phpt index d2305cd5..4b91c0ca 100644 --- a/tests/Security/Permission.RoleRegistryAddInheritsNonExistent.phpt +++ b/tests/Security/Permission.RoleRegistryAddInheritsNonExistent.phpt @@ -14,6 +14,8 @@ require __DIR__ . '/../bootstrap.php'; $acl = new Permission; -Assert::exception(function () use ($acl) { - $acl->addRole('guest', 'nonexistent'); -}, Nette\InvalidStateException::class, "Role 'nonexistent' does not exist."); +Assert::exception( + fn() => $acl->addRole('guest', 'nonexistent'), + Nette\InvalidStateException::class, + "Role 'nonexistent' does not exist.", +); diff --git a/tests/Security/Permission.RoleRegistryDuplicate.phpt b/tests/Security/Permission.RoleRegistryDuplicate.phpt index 9389568d..7eafc570 100644 --- a/tests/Security/Permission.RoleRegistryDuplicate.phpt +++ b/tests/Security/Permission.RoleRegistryDuplicate.phpt @@ -14,7 +14,9 @@ require __DIR__ . '/../bootstrap.php'; $acl = new Permission; -Assert::exception(function () use ($acl) { - $acl->addRole('guest'); - $acl->addRole('guest'); -}, Nette\InvalidStateException::class, "Role 'guest' already exists in the list."); +$acl->addRole('guest'); +Assert::exception( + fn() => $acl->addRole('guest'), + Nette\InvalidStateException::class, + "Role 'guest' already exists in the list.", +); diff --git a/tests/Security/Permission.RoleRegistryInheritsNonExistent.phpt b/tests/Security/Permission.RoleRegistryInheritsNonExistent.phpt index 8001493d..3840c06e 100644 --- a/tests/Security/Permission.RoleRegistryInheritsNonExistent.phpt +++ b/tests/Security/Permission.RoleRegistryInheritsNonExistent.phpt @@ -15,10 +15,14 @@ require __DIR__ . '/../bootstrap.php'; $acl = new Permission; $acl->addRole('guest'); -Assert::exception(function () use ($acl) { - $acl->roleInheritsFrom('nonexistent', 'guest'); -}, Nette\InvalidStateException::class, "Role 'nonexistent' does not exist."); - -Assert::exception(function () use ($acl) { - $acl->roleInheritsFrom('guest', 'nonexistent'); -}, Nette\InvalidStateException::class, "Role 'nonexistent' does not exist."); +Assert::exception( + fn() => $acl->roleInheritsFrom('nonexistent', 'guest'), + Nette\InvalidStateException::class, + "Role 'nonexistent' does not exist.", +); + +Assert::exception( + fn() => $acl->roleInheritsFrom('guest', 'nonexistent'), + Nette\InvalidStateException::class, + "Role 'nonexistent' does not exist.", +); diff --git a/tests/Security/Permission.RoleRegistryRemoveOneNonExistent.phpt b/tests/Security/Permission.RoleRegistryRemoveOneNonExistent.phpt index cbc0e6a5..e49801a1 100644 --- a/tests/Security/Permission.RoleRegistryRemoveOneNonExistent.phpt +++ b/tests/Security/Permission.RoleRegistryRemoveOneNonExistent.phpt @@ -14,6 +14,8 @@ require __DIR__ . '/../bootstrap.php'; $acl = new Permission; -Assert::exception(function () use ($acl) { - $acl->removeRole('nonexistent'); -}, Nette\InvalidStateException::class, "Role 'nonexistent' does not exist."); +Assert::exception( + fn() => $acl->removeRole('nonexistent'), + Nette\InvalidStateException::class, + "Role 'nonexistent' does not exist.", +); diff --git a/tests/Security/Permission.RuleRoleRemove.phpt b/tests/Security/Permission.RuleRoleRemove.phpt index 39f76f0f..a4a2b13a 100644 --- a/tests/Security/Permission.RuleRoleRemove.phpt +++ b/tests/Security/Permission.RuleRoleRemove.phpt @@ -18,9 +18,11 @@ $acl->addRole('guest'); $acl->allow('guest'); Assert::true($acl->isAllowed('guest')); $acl->removeRole('guest'); -Assert::exception(function () use ($acl) { - $acl->isAllowed('guest'); -}, Nette\InvalidStateException::class, "Role 'guest' does not exist."); +Assert::exception( + fn() => $acl->isAllowed('guest'), + Nette\InvalidStateException::class, + "Role 'guest' does not exist.", +); $acl->addRole('guest'); Assert::false($acl->isAllowed('guest')); diff --git a/tests/Security/Permission.RuleRoleRemoveAll.phpt b/tests/Security/Permission.RuleRoleRemoveAll.phpt index 245caeca..d6b6a436 100644 --- a/tests/Security/Permission.RuleRoleRemoveAll.phpt +++ b/tests/Security/Permission.RuleRoleRemoveAll.phpt @@ -18,9 +18,11 @@ $acl->addRole('guest'); $acl->allow('guest'); Assert::true($acl->isAllowed('guest')); $acl->removeAllRoles(); -Assert::exception(function () use ($acl) { - $acl->isAllowed('guest'); -}, Nette\InvalidStateException::class, "Role 'guest' does not exist."); +Assert::exception( + fn() => $acl->isAllowed('guest'), + Nette\InvalidStateException::class, + "Role 'guest' does not exist.", +); $acl->addRole('guest'); Assert::false($acl->isAllowed('guest')); diff --git a/tests/Security/Permission.RulesResourceRemove.phpt b/tests/Security/Permission.RulesResourceRemove.phpt index ee1b902e..c51cc11b 100644 --- a/tests/Security/Permission.RulesResourceRemove.phpt +++ b/tests/Security/Permission.RulesResourceRemove.phpt @@ -18,9 +18,11 @@ $acl->addResource('area'); $acl->allow(null, 'area'); Assert::true($acl->isAllowed(null, 'area')); $acl->removeResource('area'); -Assert::exception(function () use ($acl) { - $acl->isAllowed(null, 'area'); -}, Nette\InvalidStateException::class, "Resource 'area' does not exist."); +Assert::exception( + fn() => $acl->isAllowed(null, 'area'), + Nette\InvalidStateException::class, + "Resource 'area' does not exist.", +); $acl->addResource('area'); Assert::false($acl->isAllowed(null, 'area')); diff --git a/tests/Security/Permission.RulesResourceRemoveAll.phpt b/tests/Security/Permission.RulesResourceRemoveAll.phpt index c346c096..4f14e870 100644 --- a/tests/Security/Permission.RulesResourceRemoveAll.phpt +++ b/tests/Security/Permission.RulesResourceRemoveAll.phpt @@ -18,9 +18,11 @@ $acl->addResource('area'); $acl->allow(null, 'area'); Assert::true($acl->isAllowed(null, 'area')); $acl->removeAllResources(); -Assert::exception(function () use ($acl) { - $acl->isAllowed(null, 'area'); -}, Nette\InvalidStateException::class, "Resource 'area' does not exist."); +Assert::exception( + fn() => $acl->isAllowed(null, 'area'), + Nette\InvalidStateException::class, + "Resource 'area' does not exist.", +); $acl->addResource('area'); Assert::false($acl->isAllowed(null, 'area')); diff --git a/tests/Security/SimpleAuthenticator.phpt b/tests/Security/SimpleAuthenticator.phpt index a2c2370f..ed0ecfc4 100644 --- a/tests/Security/SimpleAuthenticator.phpt +++ b/tests/Security/SimpleAuthenticator.phpt @@ -28,10 +28,14 @@ $identity = $authenticator->authenticate('admin', 'admin'); Assert::type(Nette\Security\IIdentity::class, $identity); Assert::equal('admin', $identity->getId()); -Assert::exception(function () use ($authenticator) { - $authenticator->authenticate('admin', 'wrong password'); -}, Nette\Security\AuthenticationException::class, 'Invalid password.'); - -Assert::exception(function () use ($authenticator) { - $authenticator->authenticate('nobody', 'password'); -}, Nette\Security\AuthenticationException::class, "User 'nobody' not found."); +Assert::exception( + fn() => $authenticator->authenticate('admin', 'wrong password'), + Nette\Security\AuthenticationException::class, + 'Invalid password.', +); + +Assert::exception( + fn() => $authenticator->authenticate('nobody', 'password'), + Nette\Security\AuthenticationException::class, + "User 'nobody' not found.", +); diff --git a/tests/Security/User.authentication.legacy.phpt b/tests/Security/User.authentication.legacy.phpt deleted file mode 100644 index 8c0e559d..00000000 --- a/tests/Security/User.authentication.legacy.phpt +++ /dev/null @@ -1,117 +0,0 @@ - 0, - 'logout' => 0, -]; - -$user->onLoggedIn[] = function () use ($counter) { - $counter->login++; -}; - -$user->onLoggedOut[] = function () use ($counter) { - $counter->logout++; -}; - - -Assert::false($user->isLoggedIn()); -Assert::null($user->getIdentity()); -Assert::null($user->getId()); - - -// authenticate -Assert::exception(function () use ($user) { - // login without handler - $user->login('jane', ''); -}, Nette\InvalidStateException::class, 'Authenticator has not been set.'); - -$handler = new Authenticator; -$user->setAuthenticator($handler); - -Assert::exception(function () use ($user) { - // login as jane - $user->login('jane', ''); -}, Nette\Security\AuthenticationException::class, 'Unknown user'); - -Assert::exception(function () use ($user) { - // login as john - $user->login('john', ''); -}, Nette\Security\AuthenticationException::class, 'Password not match'); - -// login as john#2 -$user->login('john', 'xxx'); -Assert::same(1, $counter->login); -Assert::true($user->isLoggedIn()); -Assert::equal(new Identity('John Doe', 'admin'), $user->getIdentity()); -Assert::same('John Doe', $user->getId()); - -// login as john#3 -$user->logout(true); -Assert::same(1, $counter->logout); -$user->login(new Identity('John Doe', 'admin')); -Assert::same(2, $counter->login); -Assert::true($user->isLoggedIn()); -Assert::equal(new Identity('John Doe', 'admin'), $user->getIdentity()); - - -// log out -// logging out... -$user->logout(false); -Assert::same(2, $counter->logout); - -Assert::false($user->isLoggedIn()); -Assert::equal(new Identity('John Doe', 'admin'), $user->getIdentity()); - - -// logging out and clearing identity... -$user->logout(true); -Assert::same(2, $counter->logout); // not logged in -> logout event not triggered - -Assert::false($user->isLoggedIn()); -Assert::null($user->getIdentity()); - - -// namespace -// login as john#2? -$user->login('john', 'xxx'); -Assert::same(3, $counter->login); -Assert::true($user->isLoggedIn()); diff --git a/tests/Security/User.authentication.phpt b/tests/Security/User.authentication.phpt index 9a94a8db..5d6413e6 100644 --- a/tests/Security/User.authentication.phpt +++ b/tests/Security/User.authentication.phpt @@ -36,7 +36,7 @@ class Authenticator implements Nette\Security\Authenticator } -$user = new Nette\Security\User(null, null, null, new MockUserStorage); +$user = new Nette\Security\User(new MockUserStorage); $counter = (object) [ 'login' => 0, @@ -58,23 +58,26 @@ Assert::null($user->getId()); // authenticate -Assert::exception(function () use ($user) { - // login without handler - $user->login('jane', ''); -}, Nette\InvalidStateException::class, 'Authenticator has not been set.'); +Assert::exception( + fn() => $user->login('jane', ''), + Nette\InvalidStateException::class, + 'Authenticator has not been set.', +); $handler = new Authenticator; $user->setAuthenticator($handler); -Assert::exception(function () use ($user) { - // login as jane - $user->login('jane', ''); -}, Nette\Security\AuthenticationException::class, 'Unknown user'); - -Assert::exception(function () use ($user) { - // login as john - $user->login('john', ''); -}, Nette\Security\AuthenticationException::class, 'Password not match'); +Assert::exception( + fn() => $user->login('jane', ''), + Nette\Security\AuthenticationException::class, + 'Unknown user', +); + +Assert::exception( + fn() => $user->login('john', ''), + Nette\Security\AuthenticationException::class, + 'Password not match', +); // login as john#2 $user->login('john', 'xxx'); diff --git a/tests/Security/User.authorization.phpt b/tests/Security/User.authorization.phpt index a0c48ab2..ee26305e 100644 --- a/tests/Security/User.authorization.phpt +++ b/tests/Security/User.authorization.phpt @@ -42,7 +42,7 @@ class Authorizator implements Nette\Security\Authorizator { public function isAllowed($role = self::All, $resource = self::All, $privilege = self::All): bool { - return $role === 'admin' && strpos($resource, 'jany') === false; + return $role === 'admin' && !str_contains($resource, 'jany'); } } @@ -54,7 +54,7 @@ class TesterRole implements Role } } -$user = new Nette\Security\User(null, null, null, new MockUserStorage); +$user = new Nette\Security\User(new MockUserStorage); // guest Assert::false($user->isLoggedIn()); @@ -81,9 +81,11 @@ Assert::false($user->isInRole('guest')); // authorization -Assert::exception(function () use ($user) { - $user->isAllowed('delete_file'); -}, Nette\InvalidStateException::class, 'Authorizator has not been set.'); +Assert::exception( + fn() => $user->isAllowed('delete_file'), + Nette\InvalidStateException::class, + 'Authorizator has not been set.', +); $handler = new Authorizator; $user->setAuthorizator($handler);