Update copyright
[friendica.git/.git] / src / Module / Security / OpenID.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2021, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Module\Security;
23
24 use Friendica\BaseModule;
25 use Friendica\DI;
26 use Friendica\Util\Strings;
27 use LightOpenID;
28
29 /**
30  * Performs an login with OpenID
31  */
32 class OpenID extends BaseModule
33 {
34         public static function content(array $parameters = [])
35         {
36                 if (DI::config()->get('system', 'no_openid')) {
37                         DI::baseUrl()->redirect();
38                 }
39
40                 DI::logger()->debug('mod_openid.', ['request' => $_REQUEST]);
41
42                 $session = DI::session();
43
44                 if (!empty($_GET['openid_mode']) && !empty($session->get('openid'))) {
45
46                         $openid = new LightOpenID(DI::baseUrl()->getHostname());
47
48                         $l10n = DI::l10n();
49
50                         if ($openid->validate()) {
51                                 $authId = $openid->data['openid_identity'];
52
53                                 if (empty($authId)) {
54                                         DI::logger()->info($l10n->t('OpenID protocol error. No ID returned'));
55                                         DI::baseUrl()->redirect();
56                                 }
57
58                                 // NOTE: we search both for normalised and non-normalised form of $authid
59                                 //       because the normalization step was removed from setting
60                                 //       mod/settings.php in 8367cad so it might have left mixed
61                                 //       records in the user table
62                                 //
63                                 $condition = ['blocked' => false, 'account_expired' => false, 'account_removed' => false, 'verified' => true,
64                                               'openid' => [$authId, Strings::normaliseOpenID($authId)]];
65
66                                 $dba = DI::dba();
67
68                                 $user  = $dba->selectFirst('user', [], $condition);
69                                 if ($dba->isResult($user)) {
70
71                                         // successful OpenID login
72                                         $session->remove('openid');
73
74                                         DI::auth()->setForUser(DI::app(), $user, true, true);
75
76                                         // just in case there was no return url set
77                                         // and we fell through
78                                         DI::baseUrl()->redirect();
79                                 }
80
81                                 // Successful OpenID login - but we can't match it to an existing account.
82                                 $session->remove('register');
83                                 $session->set('openid_attributes', $openid->getAttributes());
84                                 $session->set('openid_identity', $authId);
85
86                                 // Detect the server URL
87                                 $open_id_obj = new LightOpenID(DI::baseUrl()->getHostName());
88                                 $open_id_obj->identity = $authId;
89                                 $session->set('openid_server', $open_id_obj->discover($open_id_obj->identity));
90
91                                 if (intval(DI::config()->get('config', 'register_policy')) === \Friendica\Module\Register::CLOSED) {
92                                         notice($l10n->t('Account not found. Please login to your existing account to add the OpenID to it.'));
93                                 } else {
94                                         notice($l10n->t('Account not found. Please register a new account or login to your existing account to add the OpenID to it.'));
95                                 }
96
97                                 DI::baseUrl()->redirect('login');
98                         }
99                 }
100         }
101 }