]> git.mxchange.org Git - friendica.git/blob - src/Core/Authentication.php
Merge pull request #6219 from MrPetovan/task/remove-x
[friendica.git] / src / Core / Authentication.php
1 <?php
2 /**
3  * @file /src/Core/Authentication.php
4  */
5
6 namespace Friendica\Core;
7
8 use Friendica\BaseObject;
9 use Friendica\Core\Addon;
10 use Friendica\Core\Config;
11 use Friendica\Core\L10n;
12 use Friendica\Core\Logger;
13 use Friendica\Core\PConfig;
14 use Friendica\Database\DBA;
15 use Friendica\Model\User;
16 use Friendica\Util\DateTimeFormat;
17
18 /**
19 * Handle Authentification, Session and Cookies
20 */
21 class Authentication extends BaseObject
22 {
23         /**
24          * @brief Calculate the hash that is needed for the "Friendica" cookie
25          *
26          * @param array $user Record from "user" table
27          *
28          * @return string Hashed data
29          */
30         public static function getCookieHashForUser($user)
31         {
32                 return(hash("sha256", Config::get("system", "site_prvkey") .
33                                 $user["prvkey"] .
34                                 $user["password"]));
35         }
36
37         /**
38          * @brief Set the "Friendica" cookie
39          *
40          * @param int $time
41          * @param array $user Record from "user" table
42          */
43         public static  function setCookie($time, $user = [])
44         {
45                 if ($time != 0) {
46                         $time = $time + time();
47                 }
48
49                 if ($user) {
50                         $value = json_encode(["uid" => $user["uid"],
51                                 "hash" => self::getCookieHashForUser($user),
52                                 "ip" => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0')]);
53                 } else {
54                         $value = "";
55                 }
56
57                 setcookie("Friendica", $value, $time, "/", "", (Config::get('system', 'ssl_policy') == SSL_POLICY_FULL), true);
58         }
59
60         /**
61          * @brief Sets the provided user's authenticated session
62          *
63          * @todo Should be moved to Friendica\Core\Session once it's created
64          *
65          * @param type $user_record
66          * @param type $login_initial
67          * @param type $interactive
68          * @param type $login_refresh
69          */
70         public static function setAuthenticatedSessionForUser($user_record, $login_initial = false, $interactive = false, $login_refresh = false)
71         {
72                 $a = self::getApp();
73
74                 $_SESSION['uid'] = $user_record['uid'];
75                 $_SESSION['theme'] = $user_record['theme'];
76                 $_SESSION['mobile-theme'] = PConfig::get($user_record['uid'], 'system', 'mobile_theme');
77                 $_SESSION['authenticated'] = 1;
78                 $_SESSION['page_flags'] = $user_record['page-flags'];
79                 $_SESSION['my_url'] = $a->getbaseUrl() . '/profile/' . $user_record['nickname'];
80                 $_SESSION['my_address'] = $user_record['nickname'] . '@' . substr($a->getbaseUrl(), strpos($a->getbaseUrl(), '://') + 3);
81                 $_SESSION['addr'] = defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0');
82
83                 $a->user = $user_record;
84
85                 if ($interactive) {
86                         if ($a->user['login_date'] <= DBA::NULL_DATETIME) {
87                                 $_SESSION['return_path'] = 'profile_photo/new';
88                                 $a->module = 'profile_photo';
89                                 info(L10n::t("Welcome ") . $a->user['username'] . EOL);
90                                 info(L10n::t('Please upload a profile photo.') . EOL);
91                         } else {
92                                 info(L10n::t("Welcome back ") . $a->user['username'] . EOL);
93                         }
94                 }
95
96                 $member_since = strtotime($a->user['register_date']);
97                 if (time() < ($member_since + ( 60 * 60 * 24 * 14))) {
98                         $_SESSION['new_member'] = true;
99                 } else {
100                         $_SESSION['new_member'] = false;
101                 }
102                 if (strlen($a->user['timezone'])) {
103                         date_default_timezone_set($a->user['timezone']);
104                         $a->timezone = $a->user['timezone'];
105                 }
106
107                 $masterUid = $user_record['uid'];
108
109                 if (!empty($_SESSION['submanage'])) {
110                         $user = DBA::selectFirst('user', ['uid'], ['uid' => $_SESSION['submanage']]);
111                         if (DBA::isResult($user)) {
112                                 $masterUid = $user['uid'];
113                         }
114                 }
115
116                 $a->identities = User::identities($masterUid);
117
118                 if ($login_initial) {
119                         Logger::log('auth_identities: ' . print_r($a->identities, true), Logger::DEBUG);
120                 }
121                 if ($login_refresh) {
122                         Logger::log('auth_identities refresh: ' . print_r($a->identities, true), Logger::DEBUG);
123                 }
124
125                 $contact = DBA::selectFirst('contact', [], ['uid' => $_SESSION['uid'], 'self' => true]);
126                 if (DBA::isResult($contact)) {
127                         $a->contact = $contact;
128                         $a->cid = $contact['id'];
129                         $_SESSION['cid'] = $a->cid;
130                 }
131
132                 header('X-Account-Management-Status: active; name="' . $a->user['username'] . '"; id="' . $a->user['nickname'] . '"');
133
134                 if ($login_initial || $login_refresh) {
135                         DBA::update('user', ['login_date' => DateTimeFormat::utcNow()], ['uid' => $_SESSION['uid']]);
136
137                         // Set the login date for all identities of the user
138                         DBA::update('user', ['login_date' => DateTimeFormat::utcNow()],
139                                 ['parent-uid' => $masterUid, 'account_removed' => false]);
140                 }
141
142                 if ($login_initial) {
143                         /*
144                          * If the user specified to remember the authentication, then set a cookie
145                          * that expires after one week (the default is when the browser is closed).
146                          * The cookie will be renewed automatically.
147                          * The week ensures that sessions will expire after some inactivity.
148                          */
149                         if (!empty($_SESSION['remember'])) {
150                                 Logger::log('Injecting cookie for remembered user ' . $a->user['nickname']);
151                                 self::setCookie(604800, $user_record);
152                                 unset($_SESSION['remember']);
153                         }
154                 }
155
156                 if ($login_initial) {
157                         Addon::callHooks('logged_in', $a->user);
158
159                         if (($a->module !== 'home') && isset($_SESSION['return_path'])) {
160                                 $a->internalRedirect($_SESSION['return_path']);
161                         }
162                 }
163         }
164
165         /**
166          * @brief Kills the "Friendica" cookie and all session data
167          */
168         public static function deleteSession()
169         {
170                 self::setCookie(-3600); // make sure cookie is deleted on browser close, as a security measure
171                 session_unset();
172                 session_destroy();
173         }
174 }
175