]> git.mxchange.org Git - friendica.git/blob - include/auth.php
7f1b1016e1fbcf0aa89e83780602520f6fc648d9
[friendica.git] / include / auth.php
1 <?php
2
3 use Friendica\App;
4 use Friendica\Core\System;
5 use Friendica\Core\Config;
6 use Friendica\Database\DBM;
7 use Friendica\Model\User;
8
9 require_once 'include/security.php';
10 require_once 'include/datetime.php';
11
12 // When the "Friendica" cookie is set, take the value to authenticate and renew the cookie.
13 if (isset($_COOKIE["Friendica"])) {
14         $data = json_decode($_COOKIE["Friendica"]);
15         if (isset($data->uid)) {
16
17                 $user = dba::select('user',
18                         [],
19                         [
20                                 'uid'             => $data->uid,
21                                 'blocked'         => false,
22                                 'account_expired' => false,
23                                 'account_removed' => false,
24                                 'verified'        => true,
25                         ],
26                         ['limit' => 1]
27                 );
28
29                 if (DBM::is_result($user)) {
30                         if ($data->hash != cookie_hash($user)) {
31                                 logger("Hash for user " . $data->uid . " doesn't fit.");
32                                 nuke_session();
33                                 goaway(System::baseUrl());
34                         }
35
36                         // Renew the cookie
37                         // Expires after 7 days by default,
38                         // can be set via system.auth_cookie_lifetime
39                         $authcookiedays = Config::get('system', 'auth_cookie_lifetime', 7);
40                         new_cookie($authcookiedays * 24 * 60 * 60, $user);
41
42                         // Do the authentification if not done by now
43                         if (!isset($_SESSION) || !isset($_SESSION['authenticated'])) {
44                                 authenticate_success($user);
45
46                                 if (Config::get('system', 'paranoia')) {
47                                         $_SESSION['addr'] = $data->ip;
48                                 }
49                         }
50                 }
51         }
52 }
53
54
55 // login/logout
56
57 if (isset($_SESSION) && x($_SESSION, 'authenticated') && (!x($_POST, 'auth-params') || ($_POST['auth-params'] !== 'login'))) {
58         if ((x($_POST, 'auth-params') && ($_POST['auth-params'] === 'logout')) || ($a->module === 'logout')) {
59                 // process logout request
60                 call_hooks("logging_out");
61                 nuke_session();
62                 info(t('Logged out.') . EOL);
63                 goaway(System::baseUrl());
64         }
65
66         if (x($_SESSION, 'visitor_id') && !x($_SESSION, 'uid')) {
67                 $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
68                         intval($_SESSION['visitor_id'])
69                 );
70                 if (DBM::is_result($r)) {
71                         $a->contact = $r[0];
72                 }
73         }
74
75         if (x($_SESSION, 'uid')) {
76                 // already logged in user returning
77                 $check = Config::get('system', 'paranoia');
78                 // extra paranoia - if the IP changed, log them out
79                 if ($check && ($_SESSION['addr'] != $_SERVER['REMOTE_ADDR'])) {
80                         logger('Session address changed. Paranoid setting in effect, blocking session. ' .
81                                 $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
82                         nuke_session();
83                         goaway(System::baseUrl());
84                 }
85
86                 $user = dba::select('user',
87                         [],
88                         [
89                                 'uid'             => $_SESSION['uid'],
90                                 'blocked'         => false,
91                                 'account_expired' => false,
92                                 'account_removed' => false,
93                                 'verified'        => true,
94                         ],
95                         ['limit' => 1]
96                 );
97                 if (!DBM::is_result($user)) {
98                         nuke_session();
99                         goaway(System::baseUrl());
100                 }
101
102                 // Make sure to refresh the last login time for the user if the user
103                 // stays logged in for a long time, e.g. with "Remember Me"
104                 $login_refresh = false;
105                 if (!x($_SESSION['last_login_date'])) {
106                         $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC');
107                 }
108                 if (strcmp(datetime_convert('UTC', 'UTC', 'now - 12 hours'), $_SESSION['last_login_date']) > 0) {
109                         $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC');
110                         $login_refresh = true;
111                 }
112                 authenticate_success($user, false, false, $login_refresh);
113         }
114 } else {
115         session_unset();
116         if (
117                 !(x($_POST, 'password') && strlen($_POST['password']))
118                 && (
119                         x($_POST, 'openid_url') && strlen($_POST['openid_url'])
120                         || x($_POST, 'username') && strlen($_POST['username'])
121                 )
122         ) {
123                 $noid = Config::get('system', 'no_openid');
124
125                 $openid_url = trim(strlen($_POST['openid_url']) ? $_POST['openid_url'] : $_POST['username']);
126
127                 // validate_url alters the calling parameter
128
129                 $temp_string = $openid_url;
130
131                 // if it's an email address or doesn't resolve to a URL, fail.
132
133                 if ($noid || strpos($temp_string, '@') || !validate_url($temp_string)) {
134                         $a = get_app();
135                         notice(t('Login failed.') . EOL);
136                         goaway(System::baseUrl());
137                         // NOTREACHED
138                 }
139
140                 // Otherwise it's probably an openid.
141
142                 try {
143                         require_once('library/openid.php');
144                         $openid = new LightOpenID;
145                         $openid->identity = $openid_url;
146                         $_SESSION['openid'] = $openid_url;
147                         $_SESSION['remember'] = $_POST['remember'];
148                         $openid->returnUrl = System::baseUrl(true) . '/openid';
149                         goaway($openid->authUrl());
150                 } catch (Exception $e) {
151                         notice(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.') . '<br /><br >' . t('The error message was:') . ' ' . $e->getMessage());
152                 }
153                 // NOTREACHED
154         }
155
156         if (x($_POST, 'auth-params') && $_POST['auth-params'] === 'login') {
157                 $record = null;
158
159                 $addon_auth = array(
160                         'username' => trim($_POST['username']),
161                         'password' => trim($_POST['password']),
162                         'authenticated' => 0,
163                         'user_record' => null
164                 );
165
166                 /**
167                  *
168                  * A plugin indicates successful login by setting 'authenticated' to non-zero value and returning a user record
169                  * Plugins should never set 'authenticated' except to indicate success - as hooks may be chained
170                  * and later plugins should not interfere with an earlier one that succeeded.
171                  *
172                  */
173                 call_hooks('authenticate', $addon_auth);
174
175                 if ($addon_auth['authenticated'] && count($addon_auth['user_record'])) {
176                         $record = $addon_auth['user_record'];
177                 } else {
178                         $user_id = User::authenticate(trim($_POST['username']), trim($_POST['password']));
179                         if ($user_id) {
180                                 $record = dba::select('user', [], ['uid' => $user_id], ['limit' => 1]);
181                         }
182                 }
183
184                 if (!$record || !count($record)) {
185                         logger('authenticate: failed login attempt: ' . notags(trim($_POST['username'])) . ' from IP ' . $_SERVER['REMOTE_ADDR']);
186                         notice(t('Login failed.') . EOL);
187                         goaway(System::baseUrl());
188                 }
189
190                 if (!$_POST['remember']) {
191                         new_cookie(0); // 0 means delete on browser exit
192                 }
193
194                 // if we haven't failed up this point, log them in.
195                 $_SESSION['remember'] = $_POST['remember'];
196                 $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC');
197                 authenticate_success($record, true, true);
198         }
199 }
200