|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* This file is part of the login-cidadao project or it's bundles. |
|
4
|
|
|
* |
|
5
|
|
|
* (c) Guilherme Donato <guilhermednt on github> |
|
6
|
|
|
* |
|
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
8
|
|
|
* file that was distributed with this source code. |
|
9
|
|
|
*/ |
|
10
|
|
|
|
|
11
|
|
|
namespace LoginCidadao\OpenIDBundle\Controller; |
|
12
|
|
|
|
|
13
|
|
|
use FOS\OAuthServerBundle\Event\OAuthEvent; |
|
14
|
|
|
use LoginCidadao\CoreBundle\Model\PersonInterface; |
|
15
|
|
|
use LoginCidadao\OpenIDBundle\Event\AuthorizationEvent; |
|
16
|
|
|
use LoginCidadao\OpenIDBundle\LoginCidadaoOpenIDEvents; |
|
17
|
|
|
use LoginCidadao\OpenIDBundle\Manager\ClientManager; |
|
18
|
|
|
use LoginCidadao\OAuthBundle\Service\OrganizationService; |
|
19
|
|
|
use LoginCidadao\OAuthBundle\Model\OrganizationInterface; |
|
20
|
|
|
use LoginCidadao\OAuthBundle\Model\ClientInterface; |
|
21
|
|
|
use OAuth2\Server; |
|
22
|
|
|
use OAuth2\ServerBundle\Controller\AuthorizeController as BaseController; |
|
23
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
|
24
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; |
|
25
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; |
|
26
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcher; |
|
27
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
|
28
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* Class AuthorizeController |
|
32
|
|
|
* @package LoginCidadao\OpenIDBundle\Controller |
|
33
|
|
|
* @codeCoverageIgnore |
|
34
|
|
|
*/ |
|
35
|
|
|
class AuthorizeController extends BaseController |
|
36
|
|
|
{ |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* @Route("/openid/connect/authorize", name="_authorize_handle") |
|
40
|
|
|
* @Method({"POST"}) |
|
41
|
|
|
*/ |
|
42
|
|
|
public function handleAuthorizeAction() |
|
43
|
|
|
{ |
|
44
|
|
|
$request = $this->getRequest(); |
|
|
|
|
|
|
45
|
|
|
$implodedScope = implode(' ', $request->request->get('scope')); |
|
46
|
|
|
$request->request->set('scope', $implodedScope); |
|
47
|
|
|
|
|
48
|
|
|
$isAuthorized = $request->request->has('accepted') |
|
49
|
|
|
|| !$request->request->has('rejected'); |
|
50
|
|
|
|
|
51
|
|
|
$response = $this->handleAuthorize($this->getOAuth2Server(), $isAuthorized); |
|
52
|
|
|
|
|
53
|
|
|
$event = new OAuthEvent( |
|
54
|
|
|
$this->getUser(), |
|
55
|
|
|
$this->getClient($request), $isAuthorized |
|
56
|
|
|
); |
|
57
|
|
|
|
|
58
|
|
|
/** @var EventDispatcherInterface $dispatcher */ |
|
59
|
|
|
$dispatcher = $this->get('event_dispatcher'); |
|
60
|
|
|
$dispatcher->dispatch(OAuthEvent::POST_AUTHORIZATION_PROCESS, $event); |
|
61
|
|
|
|
|
62
|
|
|
return $response; |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
/** |
|
66
|
|
|
* Render the Authorization fragment |
|
67
|
|
|
* |
|
68
|
|
|
* @Template() |
|
69
|
|
|
* |
|
70
|
|
|
* @deprecated |
|
71
|
|
|
*/ |
|
72
|
|
|
public function authorizeAction() |
|
73
|
|
|
{ |
|
74
|
|
|
throw new \RuntimeException('This class should not be used!'); |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
/** |
|
78
|
|
|
* @Route("/openid/connect/authorize", name="_authorize_validate") |
|
79
|
|
|
* @Method({"GET"}) |
|
80
|
|
|
* @Template("LoginCidadaoOpenIDBundle:Authorize:authorize.html.twig") |
|
81
|
|
|
*/ |
|
82
|
|
|
public function validateAuthorizeAction() |
|
83
|
|
|
{ |
|
84
|
|
|
$request = $this->getRequest(); |
|
|
|
|
|
|
85
|
|
|
$client = $this->getClient($request); |
|
86
|
|
|
|
|
87
|
|
|
if (!$client instanceof \FOS\OAuthServerBundle\Model\ClientInterface) { |
|
88
|
|
|
return parent::validateAuthorizeAction(); |
|
89
|
|
|
} |
|
90
|
|
|
|
|
91
|
|
|
/** @var PersonInterface $person */ |
|
92
|
|
|
$person = $this->getUser(); |
|
93
|
|
|
|
|
94
|
|
|
/** @var EventDispatcher $dispatcher */ |
|
95
|
|
|
$dispatcher = $this->get('event_dispatcher'); |
|
96
|
|
|
|
|
97
|
|
|
$event = new OAuthEvent($person, $client); |
|
98
|
|
|
$dispatcher->dispatch(OAuthEvent::PRE_AUTHORIZATION_PROCESS, $event); |
|
99
|
|
|
|
|
100
|
|
|
$isAuthorized = $event->isAuthorizedClient(); |
|
101
|
|
|
$askConsent = $request->get('prompt', null) == 'consent'; |
|
102
|
|
|
|
|
103
|
|
|
if ($isAuthorized && !$askConsent) { |
|
104
|
|
|
return $this->handleAuthorize($this->getOAuth2Server(), $isAuthorized); |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
$authEvent = new AuthorizationEvent($person, $client, $request->get('scope')); |
|
108
|
|
|
$dispatcher->dispatch(LoginCidadaoOpenIDEvents::NEW_AUTHORIZATION_REQUEST, $authEvent); |
|
109
|
|
|
$remoteClaims = $authEvent->getRemoteClaims(); |
|
110
|
|
|
|
|
111
|
|
|
/** @var OrganizationService $organizationService */ |
|
112
|
|
|
$organizationService = $this->get('organization'); |
|
113
|
|
|
$warnUntrusted = $this->shouldWarnUntrusted($client); |
|
114
|
|
|
$metadata = $this->getMetadata($client); |
|
115
|
|
|
$organization = $organizationService->getOrganization($metadata); |
|
116
|
|
|
|
|
117
|
|
|
// Call the lib's original Controller |
|
118
|
|
|
$parentResponse = parent::validateAuthorizeAction(); |
|
119
|
|
|
if (!is_array($parentResponse)) { |
|
120
|
|
|
return $parentResponse; |
|
121
|
|
|
} |
|
122
|
|
|
$parentResponse['scopes'] = $this->removeRemoteScope($parentResponse['scopes']); |
|
123
|
|
|
|
|
124
|
|
|
$response = array_merge([ |
|
125
|
|
|
'qs' => [ |
|
126
|
|
|
'client_id' => $client->getPublicId(), |
|
127
|
|
|
'scope' => $parentResponse['scopes'], |
|
128
|
|
|
'response_type' => $request->get('response_type'), |
|
129
|
|
|
'redirect_uri' => $request->get('redirect_uri'), |
|
130
|
|
|
'state' => $request->get('state'), |
|
131
|
|
|
'nonce' => $request->get('nonce'), |
|
132
|
|
|
], |
|
133
|
|
|
'remoteClaims' => $remoteClaims, |
|
134
|
|
|
'client' => $client, |
|
135
|
|
|
'metadata' => $metadata, |
|
136
|
|
|
'organization' => $organization, |
|
137
|
|
|
'warnUntrusted' => $warnUntrusted, |
|
138
|
|
|
], $parentResponse); |
|
139
|
|
|
|
|
140
|
|
|
return $response; |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
private function handleAuthorize(Server $server, $isAuthorized) |
|
144
|
|
|
{ |
|
145
|
|
|
/** @var \OAuth2\Request $request */ |
|
146
|
|
|
$request = $this->get('oauth2.request'); |
|
147
|
|
|
|
|
148
|
|
|
/** @var \OAuth2\Response $response */ |
|
149
|
|
|
$response = $this->get('oauth2.response'); |
|
150
|
|
|
|
|
151
|
|
|
return $server->handleAuthorizeRequest( |
|
152
|
|
|
$request, |
|
153
|
|
|
$response, |
|
154
|
|
|
$isAuthorized, |
|
155
|
|
|
$this->getUser()->getId() |
|
156
|
|
|
); |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
private function getClient($fullId) |
|
160
|
|
|
{ |
|
161
|
|
|
if ($fullId instanceof Request) { |
|
162
|
|
|
$fullId = $fullId->get('client_id'); |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
/** @var ClientManager $clientManager */ |
|
166
|
|
|
$clientManager = $this->get('lc.client_manager'); |
|
167
|
|
|
|
|
168
|
|
|
return $clientManager->getClientById($fullId); |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
|
|
private function shouldWarnUntrusted(ClientInterface $client = null) |
|
172
|
|
|
{ |
|
173
|
|
|
$warnUntrusted = $this->getParameter('warn_untrusted'); |
|
174
|
|
|
|
|
175
|
|
|
if ($client) { |
|
176
|
|
|
$metadata = $this->getMetadata($client); |
|
177
|
|
|
|
|
178
|
|
|
if ($metadata && $metadata->getOrganization() instanceof OrganizationInterface) { |
|
179
|
|
|
$isTrusted = $metadata->getOrganization()->isTrusted(); |
|
180
|
|
|
} else { |
|
181
|
|
|
$isTrusted = false; |
|
182
|
|
|
} |
|
183
|
|
|
} else { |
|
184
|
|
|
$isTrusted = false; |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
if ($isTrusted || !$warnUntrusted) { |
|
188
|
|
|
return false; // do not warn |
|
189
|
|
|
} |
|
190
|
|
|
|
|
191
|
|
|
return true; // warn |
|
192
|
|
|
} |
|
193
|
|
|
|
|
194
|
|
|
private function getMetadata(ClientInterface $client = null) |
|
195
|
|
|
{ |
|
196
|
|
|
if (!$client) { |
|
197
|
|
|
return null; |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
$repo = $this->getDoctrine()->getRepository('LoginCidadaoOpenIDBundle:ClientMetadata'); |
|
201
|
|
|
|
|
202
|
|
|
return $repo->findOneBy(['client' => $client]); |
|
203
|
|
|
} |
|
204
|
|
|
|
|
205
|
|
|
/** |
|
206
|
|
|
* @return object|Server |
|
207
|
|
|
*/ |
|
208
|
|
|
private function getOAuth2Server() |
|
209
|
|
|
{ |
|
210
|
|
|
return $this->get('oauth2.server'); |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
/** |
|
214
|
|
|
* @param array $scopes |
|
215
|
|
|
* @return array |
|
216
|
|
|
*/ |
|
217
|
|
|
private function removeRemoteScope(array $scopes) |
|
218
|
|
|
{ |
|
219
|
|
|
return array_filter($scopes, function ($scope) { |
|
220
|
|
|
if (preg_match('/^tag:/', $scope) === 1) { |
|
221
|
|
|
return false; |
|
222
|
|
|
} |
|
223
|
|
|
|
|
224
|
|
|
return true; |
|
225
|
|
|
}); |
|
226
|
|
|
} |
|
227
|
|
|
} |
|
228
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.