1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* airlock authkey based consultant user provider |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
namespace Graviton\SecurityBundle\Authentication\Provider; |
7
|
|
|
|
8
|
|
|
use \Graviton\RestBundle\Model\ModelInterface; |
9
|
|
|
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; |
10
|
|
|
use Symfony\Component\Security\Core\User\UserInterface; |
11
|
|
|
use Symfony\Component\Security\Core\User\UserProviderInterface; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Class AirlockAuthenticationKeyConsultantProvider |
15
|
|
|
* |
16
|
|
|
* @author List of contributors <https://github.com/libgraviton/graviton/graphs/contributors> |
17
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GNU Public License |
18
|
|
|
* @link http://swisscom.ch |
19
|
|
|
*/ |
20
|
|
|
class AuthenticationProvider implements UserProviderInterface |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* @var ModelInterface |
24
|
|
|
*/ |
25
|
|
|
private $documentModel; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @var String |
29
|
|
|
*/ |
30
|
|
|
private $queryField; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @param ModelInterface $model The documentModel |
34
|
|
|
* @param string $queryField Field to search by |
35
|
|
|
*/ |
36
|
|
|
public function __construct(ModelInterface $model, $queryField) |
37
|
|
|
{ |
38
|
|
|
$this->documentModel = $model; |
39
|
|
|
$this->queryField = $queryField; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Loads the user for the given username. |
44
|
|
|
* |
45
|
|
|
* This method must throw UsernameNotFoundException if the user is not |
46
|
|
|
* found. |
47
|
|
|
* |
48
|
|
|
* @param string $username the consultants username |
49
|
|
|
* |
50
|
|
|
* @return \Symfony\Component\Security\Core\User\UserInterface |
51
|
|
|
* |
52
|
|
|
* @see \Symfony\Component\Security\Core\Exception\UsernameNotFoundException |
53
|
|
|
* |
54
|
|
|
* @throws \Symfony\Component\Security\Core\Exception\UsernameNotFoundException if the user is not found |
55
|
|
|
*/ |
56
|
|
|
public function loadUserByUsername($username) |
57
|
|
|
{ |
58
|
|
|
if (!$this->queryField) { |
59
|
|
|
return false; |
|
|
|
|
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
$user = $this->documentModel->getRepository()->findOneBy(array($this->queryField => $username)); |
63
|
|
|
|
64
|
|
|
return $user ? $user : false; |
|
|
|
|
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Refreshes the user for the account interface. |
69
|
|
|
* |
70
|
|
|
* It is up to the implementation to decide if the user data should be |
71
|
|
|
* totally reloaded (e.g. from the database), or if the UserInterface |
72
|
|
|
* object can just be merged into some internal array of users / identity |
73
|
|
|
* map. |
74
|
|
|
* |
75
|
|
|
* @param \Symfony\Component\Security\Core\User\UserInterface $user user to refresh |
76
|
|
|
* |
77
|
|
|
* @return \Symfony\Component\Security\Core\User\UserInterface |
78
|
|
|
* |
79
|
|
|
* @throws \Symfony\Component\Security\Core\Exception\UnsupportedUserException if the account is not supported |
80
|
|
|
*/ |
81
|
|
|
public function refreshUser(UserInterface $user) |
82
|
|
|
{ |
83
|
|
|
// this is used for storing authentication in the session |
84
|
|
|
// but in this example, the token is sent in each request, |
85
|
|
|
// so authentication can be stateless. Throwing this exception |
86
|
|
|
// is proper to make things stateless |
87
|
|
|
throw new UnsupportedUserException(); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Whether this provider supports the given user class. |
92
|
|
|
* |
93
|
|
|
* @param string $class class to check for support |
94
|
|
|
* |
95
|
|
|
* @return bool |
96
|
|
|
*/ |
97
|
|
|
public function supportsClass($class) |
98
|
|
|
{ |
99
|
|
|
return $class instanceof \Symfony\Component\Security\Core\User\UserInterface; |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.