From fe478d89c955fa1a9e6d8fb62fa93fe7987012fa Mon Sep 17 00:00:00 2001 From: MartkCz Date: Mon, 27 Jan 2020 10:39:47 +0100 Subject: [PATCH] SecurityExtensions: add option for users data --- src/Bridges/SecurityDI/SecurityExtension.php | 10 +++--- src/Security/SimpleAuthenticator.php | 9 +++-- tests/Security/SimpleAuthenticator.Data.phpt | 37 ++++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 tests/Security/SimpleAuthenticator.Data.phpt diff --git a/src/Bridges/SecurityDI/SecurityExtension.php b/src/Bridges/SecurityDI/SecurityExtension.php index 8d4d4973..d87f21a7 100644 --- a/src/Bridges/SecurityDI/SecurityExtension.php +++ b/src/Bridges/SecurityDI/SecurityExtension.php @@ -35,9 +35,10 @@ public function getConfigSchema(): Nette\Schema\Schema 'users' => Expect::arrayOf( Expect::anyOf( Expect::string(), // user => password - Expect::structure([ // user => password + roles + Expect::structure([ // user => password + roles + data 'password' => Expect::string(), 'roles' => Expect::anyOf(Expect::string(), Expect::listOf('string')), + 'data' => Expect::array(), ])->castTo('array') ) ), @@ -70,17 +71,18 @@ public function loadConfiguration() } if ($config->users) { - $usersList = $usersRoles = []; + $usersList = $usersRoles = $usersData = []; foreach ($config->users as $username => $data) { $data = is_array($data) ? $data : ['password' => $data]; - $this->validateConfig(['password' => null, 'roles' => null], $data, $this->prefix("security.users.$username")); + $this->validateConfig(['password' => null, 'roles' => null, 'data' => []], $data, $this->prefix("security.users.$username")); $usersList[$username] = $data['password']; $usersRoles[$username] = $data['roles'] ?? null; + $usersData[$username] = $data['data'] ?? []; } $builder->addDefinition($this->prefix('authenticator')) ->setType(Nette\Security\IAuthenticator::class) - ->setFactory(Nette\Security\SimpleAuthenticator::class, [$usersList, $usersRoles]); + ->setFactory(Nette\Security\SimpleAuthenticator::class, [$usersList, $usersRoles, $usersData]); if ($this->name === 'security') { $builder->addAlias('nette.authenticator', $this->prefix('authenticator')); diff --git a/src/Security/SimpleAuthenticator.php b/src/Security/SimpleAuthenticator.php index b2f97325..9f0a1996 100644 --- a/src/Security/SimpleAuthenticator.php +++ b/src/Security/SimpleAuthenticator.php @@ -25,15 +25,20 @@ class SimpleAuthenticator implements IAuthenticator /** @var array */ private $usersRoles; + /** @var array */ + private $usersData; + /** * @param array $userlist list of pairs username => password * @param array $usersRoles list of pairs username => role[] + * @param array $usersData list of pairs username => mixed[] */ - public function __construct(array $userlist, array $usersRoles = []) + public function __construct(array $userlist, array $usersRoles = [], array $usersData = []) { $this->userlist = $userlist; $this->usersRoles = $usersRoles; + $this->usersData = $usersData; } @@ -48,7 +53,7 @@ public function authenticate(array $credentials): IIdentity foreach ($this->userlist as $name => $pass) { if (strcasecmp($name, $username) === 0) { if ((string) $pass === (string) $password) { - return new Identity($name, $this->usersRoles[$name] ?? null); + return new Identity($name, $this->usersRoles[$name] ?? null, $this->usersData[$name] ?? []); } else { throw new AuthenticationException('Invalid password.', self::INVALID_CREDENTIAL); } diff --git a/tests/Security/SimpleAuthenticator.Data.phpt b/tests/Security/SimpleAuthenticator.Data.phpt new file mode 100644 index 00000000..4cf1a6e5 --- /dev/null +++ b/tests/Security/SimpleAuthenticator.Data.phpt @@ -0,0 +1,37 @@ + 'john123', + 'admin' => 'admin123', + 'user' => 'user123', +]; +$usersData = [ + 'admin' => ['nick' => 'admin', 'email' => 'foo@bar.com'], + 'user' => ['nick' => 'user', 'email' => 'foo@bar.com'], +]; +$expectedData = [ + 'admin' => ['nick' => 'admin', 'email' => 'foo@bar.com'], + 'user' => ['nick' => 'user', 'email' => 'foo@bar.com'], + 'john' => [], +]; + +$authenticator = new SimpleAuthenticator($users, [], $usersData); + +foreach ($users as $username => $password) { + $identity = $authenticator->authenticate([$username, $password]); + Assert::equal($username, $identity->getId()); + Assert::equal($expectedData[$username], $identity->getData()); +}