PluginProbe
Loginizer / trunk
Loginizer vtrunk
2.1.0 2.0.9 2.0.8 1.9.8 1.9.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 All 74 releases
loginizer / lib / hybridauth / Adapter / OpenID.php

OpenID.php in Loginizer trunk, at lib/hybridauth/Adapter/OpenID.php

284 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*!
3 * Hybridauth
4 * https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
5 * (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
6 */
7
8 namespace Hybridauth\Adapter;
9
10 use Hybridauth\Exception\InvalidOpenidIdentifierException;
11 use Hybridauth\Exception\AuthorizationDeniedException;
12 use Hybridauth\Exception\UnexpectedApiResponseException;
13 use Hybridauth\Data;
14 use Hybridauth\HttpClient;
15 use Hybridauth\User;
16 use Hybridauth\Thirdparty\OpenID\LightOpenID;
17
18 /**
19 * This class can be used to simplify the authentication flow of OpenID based service providers.
20 *
21 * Subclasses (i.e., providers adapters) can either use the already provided methods or override
22 * them when necessary.
23 */
24 abstract class OpenID extends AbstractAdapter implements AdapterInterface
25 {
26 /**
27 * LightOpenID instance
28 *
29 * @var object
30 */
31 protected $openIdClient = null;
32
33 /**
34 * Openid provider identifier
35 *
36 * @var string
37 */
38 protected $openidIdentifier = '';
39
40 /**
41 * IPD API Documentation
42 *
43 * OPTIONAL.
44 *
45 * @var string
46 */
47 protected $apiDocumentation = '';
48
49 /**
50 * {@inheritdoc}
51 */
52 protected function configure()
53 {
54 if ($this->config->exists('openid_identifier')) {
55 $this->openidIdentifier = $this->config->get('openid_identifier');
56 }
57
58 if (empty($this->openidIdentifier)) {
59 throw new InvalidOpenidIdentifierException('OpenID adapter requires an openid_identifier.', 4);
60 }
61
62 $this->setCallback($this->config->get('callback'));
63 $this->setApiEndpoints($this->config->get('endpoints'));
64 }
65
66 /**
67 * {@inheritdoc}
68 */
69 protected function initialize()
70 {
71 $hostPort = parse_url($this->callback, PHP_URL_PORT);
72 $hostUrl = parse_url($this->callback, PHP_URL_HOST);
73
74 if ($hostPort) {
75 $hostUrl .= ':' . $hostPort;
76 }
77
78 // @fixme: add proxy
79 $this->openIdClient = new LightOpenID($hostUrl, null);
80 }
81
82 /**
83 * {@inheritdoc}
84 */
85 public function authenticate()
86 {
87 $this->logger->info(sprintf('%s::authenticate()', get_class($this)));
88
89 if ($this->isConnected()) {
90 return true;
91 }
92
93 if (empty($_REQUEST['openid_mode'])) {
94 $this->authenticateBegin();
95 } else {
96 return $this->authenticateFinish();
97 }
98
99 return null;
100 }
101
102 /**
103 * {@inheritdoc}
104 */
105 public function isConnected()
106 {
107 return (bool)$this->storage->get($this->providerId . '.user');
108 }
109
110 /**
111 * {@inheritdoc}
112 */
113 public function disconnect()
114 {
115 $this->storage->delete($this->providerId . '.user');
116
117 return true;
118 }
119
120 /**
121 * Initiate the authorization protocol
122 *
123 * Include and instantiate LightOpenID
124 */
125 protected function authenticateBegin()
126 {
127 $this->openIdClient->identity = $this->openidIdentifier;
128 $this->openIdClient->returnUrl = $this->callback;
129 $this->openIdClient->required = [
130 'namePerson/first',
131 'namePerson/last',
132 'namePerson/friendly',
133 'namePerson',
134 'contact/email',
135 'birthDate',
136 'birthDate/birthDay',
137 'birthDate/birthMonth',
138 'birthDate/birthYear',
139 'person/gender',
140 'pref/language',
141 'contact/postalCode/home',
142 'contact/city/home',
143 'contact/country/home',
144
145 'media/image/default',
146 ];
147
148 $authUrl = $this->openIdClient->authUrl();
149
150 $this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
151
152 HttpClient\Util::redirect($authUrl);
153 }
154
155 /**
156 * Finalize the authorization process.
157 *
158 * @throws AuthorizationDeniedException
159 * @throws UnexpectedApiResponseException
160 */
161 protected function authenticateFinish()
162 {
163 $this->logger->debug(
164 sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
165 [HttpClient\Util::getCurrentUrl(true)]
166 );
167
168 if ($this->openIdClient->mode == 'cancel') {
169 throw new AuthorizationDeniedException('User has cancelled the authentication.');
170 }
171
172 if (!$this->openIdClient->validate()) {
173 throw new UnexpectedApiResponseException('Invalid response received.');
174 }
175
176 $openidAttributes = $this->openIdClient->getAttributes();
177
178 if (!$this->openIdClient->identity) {
179 throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
180 }
181
182 $userProfile = $this->fetchUserProfile($openidAttributes);
183
184 /* with openid providers we only get user profiles once, so we store it */
185 $this->storage->set($this->providerId . '.user', $userProfile);
186 }
187
188 /**
189 * Fetch user profile from received openid attributes
190 *
191 * @param array $openidAttributes
192 *
193 * @return User\Profile
194 */
195 protected function fetchUserProfile($openidAttributes)
196 {
197 $data = new Data\Collection($openidAttributes);
198
199 $userProfile = new User\Profile();
200
201 $userProfile->identifier = $this->openIdClient->identity;
202
203 $userProfile->firstName = $data->get('namePerson/first');
204 $userProfile->lastName = $data->get('namePerson/last');
205 $userProfile->email = $data->get('contact/email');
206 $userProfile->language = $data->get('pref/language');
207 $userProfile->country = $data->get('contact/country/home');
208 $userProfile->zip = $data->get('contact/postalCode/home');
209 $userProfile->gender = $data->get('person/gender');
210 $userProfile->photoURL = $data->get('media/image/default');
211 $userProfile->birthDay = $data->get('birthDate/birthDay');
212 $userProfile->birthMonth = $data->get('birthDate/birthMonth');
213 $userProfile->birthYear = $data->get('birthDate/birthDate');
214
215 $userProfile = $this->fetchUserGender($userProfile, $data->get('person/gender'));
216
217 $userProfile = $this->fetchUserDisplayName($userProfile, $data);
218
219 return $userProfile;
220 }
221
222 /**
223 * Extract users display names
224 *
225 * @param User\Profile $userProfile
226 * @param Data\Collection $data
227 *
228 * @return User\Profile
229 */
230 protected function fetchUserDisplayName(User\Profile $userProfile, Data\Collection $data)
231 {
232 $userProfile->displayName = $data->get('namePerson');
233
234 $userProfile->displayName = $userProfile->displayName
235 ? $userProfile->displayName
236 : $data->get('namePerson/friendly');
237
238 $userProfile->displayName = $userProfile->displayName
239 ? $userProfile->displayName
240 : trim($userProfile->firstName . ' ' . $userProfile->lastName);
241
242 return $userProfile;
243 }
244
245 /**
246 * Extract users gender
247 *
248 * @param User\Profile $userProfile
249 * @param string $gender
250 *
251 * @return User\Profile
252 */
253 protected function fetchUserGender(User\Profile $userProfile, $gender)
254 {
255 $gender = strtolower((string)$gender);
256
257 if ('f' == $gender) {
258 $gender = 'female';
259 }
260
261 if ('m' == $gender) {
262 $gender = 'male';
263 }
264
265 $userProfile->gender = $gender;
266
267 return $userProfile;
268 }
269
270 /**
271 * OpenID only provide the user profile one. This method will attempt to retrieve the profile from storage.
272 */
273 public function getUserProfile()
274 {
275 $userProfile = $this->storage->get($this->providerId . '.user');
276
277 if (!is_object($userProfile)) {
278 throw new UnexpectedApiResponseException('Provider returned an unexpected response.');
279 }
280
281 return $userProfile;
282 }
283 }
284