Skip to content

Commit 4306360

Browse files
committed
added Authenticator, successor for IAuthenticator
1 parent dc72899 commit 4306360

File tree

6 files changed

+155
-13
lines changed

6 files changed

+155
-13
lines changed

src/Security/Authenticator.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Nette Framework (https://nette.org)
5+
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Nette\Security;
11+
12+
13+
/**
14+
* Performs authentication.
15+
*/
16+
interface Authenticator extends IAuthenticator
17+
{
18+
/**
19+
* Performs an authentication.
20+
* @throws AuthenticationException
21+
*/
22+
function authenticate(string $user, string $password): IIdentity;
23+
}

src/Security/IAuthenticator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111

1212

1313
/**
14-
* Performs authentication.
14+
* @deprecated update to Nette\Security\Authenticator
15+
* @method IIdentity authenticate(array $credentials)
1516
*/
1617
interface IAuthenticator
1718
{
@@ -32,5 +33,5 @@ interface IAuthenticator
3233
* and returns IIdentity on success or throws AuthenticationException
3334
* @throws AuthenticationException
3435
*/
35-
function authenticate(array $credentials): IIdentity;
36+
//function authenticate(array $credentials): IIdentity;
3637
}

src/Security/User.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ public function login($user, string $password = null): void
8989
{
9090
$this->logout(true);
9191
if (!$user instanceof IIdentity) {
92-
$user = $this->getAuthenticator()->authenticate(func_get_args());
92+
$authenticator = $this->getAuthenticator();
93+
$user = $authenticator instanceof Authenticator
94+
? $authenticator->authenticate($user, $password)
95+
: $authenticator->authenticate(func_get_args());
9396
}
9497
$this->storage->setIdentity($user);
9598
$this->storage->setAuthenticated(true);
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Security\User authentication.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Nette\Security\IAuthenticator;
10+
use Nette\Security\SimpleIdentity;
11+
use Tester\Assert;
12+
13+
14+
require __DIR__ . '/../bootstrap.php';
15+
require __DIR__ . '/MockUserStorage.php';
16+
17+
// Setup environment
18+
$_COOKIE = [];
19+
ob_start();
20+
21+
22+
class Authenticator implements IAuthenticator
23+
{
24+
public function authenticate(array $credentials): Nette\Security\IIdentity
25+
{
26+
[$username, $password] = $credentials;
27+
if ($username !== 'john') {
28+
throw new Nette\Security\AuthenticationException('Unknown user', self::IDENTITY_NOT_FOUND);
29+
30+
} elseif ($password !== 'xxx') {
31+
throw new Nette\Security\AuthenticationException('Password not match', self::INVALID_CREDENTIAL);
32+
33+
} else {
34+
return new SimpleIdentity('John Doe', 'admin');
35+
}
36+
}
37+
}
38+
39+
40+
$user = new Nette\Security\User(new MockUserStorage);
41+
42+
$counter = (object) [
43+
'login' => 0,
44+
'logout' => 0,
45+
];
46+
47+
$user->onLoggedIn[] = function () use ($counter) {
48+
$counter->login++;
49+
};
50+
51+
$user->onLoggedOut[] = function () use ($counter) {
52+
$counter->logout++;
53+
};
54+
55+
56+
Assert::false($user->isLoggedIn());
57+
Assert::null($user->getIdentity());
58+
Assert::null($user->getId());
59+
60+
61+
// authenticate
62+
Assert::exception(function () use ($user) {
63+
// login without handler
64+
$user->login('jane', '');
65+
}, Nette\InvalidStateException::class, 'Authenticator has not been set.');
66+
67+
$handler = new Authenticator;
68+
$user->setAuthenticator($handler);
69+
70+
Assert::exception(function () use ($user) {
71+
// login as jane
72+
$user->login('jane', '');
73+
}, Nette\Security\AuthenticationException::class, 'Unknown user');
74+
75+
Assert::exception(function () use ($user) {
76+
// login as john
77+
$user->login('john', '');
78+
}, Nette\Security\AuthenticationException::class, 'Password not match');
79+
80+
// login as john#2
81+
$user->login('john', 'xxx');
82+
Assert::same(1, $counter->login);
83+
Assert::true($user->isLoggedIn());
84+
Assert::equal(new SimpleIdentity('John Doe', 'admin'), $user->getIdentity());
85+
Assert::same('John Doe', $user->getId());
86+
87+
// login as john#3
88+
$user->logout(true);
89+
Assert::same(1, $counter->logout);
90+
$user->login(new SimpleIdentity('John Doe', 'admin'));
91+
Assert::same(2, $counter->login);
92+
Assert::true($user->isLoggedIn());
93+
Assert::equal(new SimpleIdentity('John Doe', 'admin'), $user->getIdentity());
94+
95+
96+
// log out
97+
// logging out...
98+
$user->logout(false);
99+
Assert::same(2, $counter->logout);
100+
101+
Assert::false($user->isLoggedIn());
102+
Assert::equal(new SimpleIdentity('John Doe', 'admin'), $user->getIdentity());
103+
104+
105+
// logging out and clearing identity...
106+
$user->logout(true);
107+
Assert::same(2, $counter->logout); // not logged in -> logout event not triggered
108+
109+
Assert::false($user->isLoggedIn());
110+
Assert::null($user->getIdentity());
111+
112+
113+
// namespace
114+
// login as john#2?
115+
$user->login('john', 'xxx');
116+
Assert::same(3, $counter->login);
117+
Assert::true($user->isLoggedIn());

tests/Security/User.authentication.phpt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
declare(strict_types=1);
88

9-
use Nette\Security\IAuthenticator;
9+
use Nette\Security\IIdentity;
1010
use Nette\Security\SimpleIdentity;
1111
use Tester\Assert;
1212

@@ -19,11 +19,10 @@ $_COOKIE = [];
1919
ob_start();
2020

2121

22-
class Authenticator implements IAuthenticator
22+
class Authenticator implements Nette\Security\Authenticator
2323
{
24-
public function authenticate(array $credentials): Nette\Security\IIdentity
24+
public function authenticate(string $username, string $password): IIdentity
2525
{
26-
[$username, $password] = $credentials;
2726
if ($username !== 'john') {
2827
throw new Nette\Security\AuthenticationException('Unknown user', self::IDENTITY_NOT_FOUND);
2928

tests/Security/User.authorization.phpt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
declare(strict_types=1);
88

9-
use Nette\Security\IAuthenticator;
10-
use Nette\Security\Identity;
9+
use Nette\Security\IIdentity;
10+
use Nette\Security\SimpleIdentity;
1111
use Tester\Assert;
1212

1313

@@ -20,19 +20,18 @@ $_COOKIE = [];
2020
ob_start();
2121

2222

23-
class Authenticator implements IAuthenticator
23+
class Authenticator implements Nette\Security\Authenticator
2424
{
25-
public function authenticate(array $credentials): Nette\Security\IIdentity
25+
public function authenticate(string $username, string $password): IIdentity
2626
{
27-
[$username, $password] = $credentials;
2827
if ($username !== 'john') {
2928
throw new Nette\Security\AuthenticationException('Unknown user', self::IDENTITY_NOT_FOUND);
3029

3130
} elseif ($password !== 'xxx') {
3231
throw new Nette\Security\AuthenticationException('Password not match', self::INVALID_CREDENTIAL);
3332

3433
} else {
35-
return new Identity('John Doe', ['admin']);
34+
return new SimpleIdentity('John Doe', 'admin');
3635
}
3736
}
3837
}

0 commit comments

Comments
 (0)