|
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 |
|
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_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.