diff --git a/include/api.php b/include/api.php index f360dc4116..eccd77675e 100644 --- a/include/api.php +++ b/include/api.php @@ -11,7 +11,6 @@ use Friendica\Content\ContactSelector; use Friendica\Content\Feature; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; -use Friendica\Core\Authentication; use Friendica\Core\Config; use Friendica\Core\Hook; use Friendica\Core\L10n; @@ -19,6 +18,7 @@ use Friendica\Core\Logger; use Friendica\Core\NotificationsManager; use Friendica\Core\PConfig; use Friendica\Core\Protocol; +use Friendica\Core\Session; use Friendica\Core\System; use Friendica\Core\Worker; use Friendica\Database\DBA; @@ -250,7 +250,7 @@ function api_login(App $a) throw new UnauthorizedException("This API requires login"); } - Authentication::setAuthenticatedSessionForUser($record); + Session::setAuthenticatedForUser($a, $record); $_SESSION["allow_api"] = true; diff --git a/mod/manage.php b/mod/manage.php index 52ddfdf032..58590264a5 100644 --- a/mod/manage.php +++ b/mod/manage.php @@ -2,11 +2,12 @@ /** * @file mod/manage.php */ + use Friendica\App; -use Friendica\Core\Authentication; use Friendica\Core\Hook; use Friendica\Core\L10n; use Friendica\Core\Renderer; +use Friendica\Core\Session; use Friendica\Database\DBA; function manage_post(App $a) { @@ -108,7 +109,7 @@ function manage_post(App $a) { unset($_SESSION['sysmsg_info']); } - Authentication::setAuthenticatedSessionForUser($r[0], true, true); + Session::setAuthenticatedForUser($a, $r[0], true, true); if ($limited_id) { $_SESSION['submanage'] = $original_id; diff --git a/mod/openid.php b/mod/openid.php index 7300c686b4..def34ff08f 100644 --- a/mod/openid.php +++ b/mod/openid.php @@ -4,10 +4,10 @@ */ use Friendica\App; -use Friendica\Core\Authentication; use Friendica\Core\Config; use Friendica\Core\L10n; use Friendica\Core\Logger; +use Friendica\Core\Session; use Friendica\Database\DBA; use Friendica\Util\Strings; @@ -52,7 +52,7 @@ function openid_content(App $a) { unset($_SESSION['openid']); - Authentication::setAuthenticatedSessionForUser($r[0],true,true); + Session::setAuthenticatedForUser($a, $r[0],true,true); // just in case there was no return url set // and we fell through diff --git a/src/Core/Authentication.php b/src/Core/Authentication.php index 1963d34b4e..1826602df4 100644 --- a/src/Core/Authentication.php +++ b/src/Core/Authentication.php @@ -6,10 +6,7 @@ namespace Friendica\Core; use Friendica\BaseObject; -use Friendica\Database\DBA; -use Friendica\Model\User; use Friendica\Util\BaseURL; -use Friendica\Util\DateTimeFormat; /** * Handle Authentification, Session and Cookies @@ -55,112 +52,6 @@ class Authentication extends BaseObject setcookie("Friendica", $value, $time, "/", "", (Config::get('system', 'ssl_policy') == BaseUrl::SSL_POLICY_FULL), true); } - /** - * @brief Sets the provided user's authenticated session - * - * @todo Should be moved to Friendica\Core\Session once it's created - * - * @param array $user_record - * @param bool $login_initial - * @param bool $interactive - * @param bool $login_refresh - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - public static function setAuthenticatedSessionForUser($user_record, $login_initial = false, $interactive = false, $login_refresh = false) - { - $a = self::getApp(); - - $_SESSION['uid'] = $user_record['uid']; - $_SESSION['theme'] = $user_record['theme']; - $_SESSION['mobile-theme'] = PConfig::get($user_record['uid'], 'system', 'mobile_theme'); - $_SESSION['authenticated'] = 1; - $_SESSION['page_flags'] = $user_record['page-flags']; - $_SESSION['my_url'] = $a->getbaseUrl() . '/profile/' . $user_record['nickname']; - $_SESSION['my_address'] = $user_record['nickname'] . '@' . substr($a->getbaseUrl(), strpos($a->getbaseUrl(), '://') + 3); - $_SESSION['addr'] = defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0'); - - $a->user = $user_record; - - if ($interactive) { - if ($a->user['login_date'] <= DBA::NULL_DATETIME) { - $_SESSION['return_path'] = 'profile_photo/new'; - $a->module = 'profile_photo'; - info(L10n::t("Welcome ") . $a->user['username'] . EOL); - info(L10n::t('Please upload a profile photo.') . EOL); - } else { - info(L10n::t("Welcome back ") . $a->user['username'] . EOL); - } - } - - $member_since = strtotime($a->user['register_date']); - if (time() < ($member_since + ( 60 * 60 * 24 * 14))) { - $_SESSION['new_member'] = true; - } else { - $_SESSION['new_member'] = false; - } - if (strlen($a->user['timezone'])) { - date_default_timezone_set($a->user['timezone']); - $a->timezone = $a->user['timezone']; - } - - $masterUid = $user_record['uid']; - - if (!empty($_SESSION['submanage'])) { - $user = DBA::selectFirst('user', ['uid'], ['uid' => $_SESSION['submanage']]); - if (DBA::isResult($user)) { - $masterUid = $user['uid']; - } - } - - $a->identities = User::identities($masterUid); - - if ($login_initial) { - Logger::log('auth_identities: ' . print_r($a->identities, true), Logger::DEBUG); - } - if ($login_refresh) { - Logger::log('auth_identities refresh: ' . print_r($a->identities, true), Logger::DEBUG); - } - - $contact = DBA::selectFirst('contact', [], ['uid' => $_SESSION['uid'], 'self' => true]); - if (DBA::isResult($contact)) { - $a->contact = $contact; - $a->cid = $contact['id']; - $_SESSION['cid'] = $a->cid; - } - - header('X-Account-Management-Status: active; name="' . $a->user['username'] . '"; id="' . $a->user['nickname'] . '"'); - - if ($login_initial || $login_refresh) { - DBA::update('user', ['login_date' => DateTimeFormat::utcNow()], ['uid' => $_SESSION['uid']]); - - // Set the login date for all identities of the user - DBA::update('user', ['login_date' => DateTimeFormat::utcNow()], - ['parent-uid' => $masterUid, 'account_removed' => false]); - } - - if ($login_initial) { - /* - * If the user specified to remember the authentication, then set a cookie - * that expires after one week (the default is when the browser is closed). - * The cookie will be renewed automatically. - * The week ensures that sessions will expire after some inactivity. - */ - if (!empty($_SESSION['remember'])) { - Logger::log('Injecting cookie for remembered user ' . $a->user['nickname']); - self::setCookie(604800, $user_record); - unset($_SESSION['remember']); - } - } - - if ($login_initial) { - Hook::callAll('logged_in', $a->user); - - if (($a->module !== 'home') && isset($_SESSION['return_path'])) { - $a->internalRedirect($_SESSION['return_path']); - } - } - } - /** * @brief Kills the "Friendica" cookie and all session data */ diff --git a/src/Core/Session.php b/src/Core/Session.php index f1da864bb1..9dadbb1682 100644 --- a/src/Core/Session.php +++ b/src/Core/Session.php @@ -5,9 +5,13 @@ */ namespace Friendica\Core; +use Friendica\App; use Friendica\Core\Session\CacheSessionHandler; use Friendica\Core\Session\DatabaseSessionHandler; +use Friendica\Database\DBA; +use Friendica\Model\User; use Friendica\Util\BaseURL; +use Friendica\Util\DateTimeFormat; /** * High-level Session service class @@ -25,7 +29,7 @@ class Session ini_set('session.use_only_cookies', 1); ini_set('session.cookie_httponly', 1); - if (Config::get('system', 'ssl_policy') == BaseUrl::SSL_POLICY_FULL) { + if (Config::get('system', 'ssl_policy') == BaseURL::SSL_POLICY_FULL) { ini_set('session.cookie_secure', 1); } @@ -66,8 +70,140 @@ class Session return $return; } + /** + * Sets a single session variable. + * Overrides value of existing key. + * + * @param string $name + * @param mixed $value + */ public static function set($name, $value) { $_SESSION[$name] = $value; } + + /** + * Sets multiple session variables. + * Overrides values for existing keys. + * + * @param array $values + */ + public static function setMultiple(array $values) + { + $_SESSION = $values + $_SESSION; + } + + /** + * Removes a session variable. + * Ignores missing keys. + * + * @param $name + */ + public static function remove($name) + { + unset($_SESSION[$name]); + } + + /** + * @brief Sets the provided user's authenticated session + * + * @param App $a + * @param array $user_record + * @param bool $login_initial + * @param bool $interactive + * @param bool $login_refresh + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + public static function setAuthenticatedForUser(App $a, array $user_record, $login_initial = false, $interactive = false, $login_refresh = false) + { + self::setMultiple([ + 'uid' => $user_record['uid'], + 'theme' => $user_record['theme'], + 'mobile-theme' => PConfig::get($user_record['uid'], 'system', 'mobile_theme'), + 'authenticated' => 1, + 'page_flags' => $user_record['page-flags'], + 'my_url' => $a->getBaseURL() . '/profile/' . $user_record['nickname'], + 'my_address' => $user_record['nickname'] . '@' . substr($a->getBaseURL(), strpos($a->getBaseURL(), '://') + 3), + 'addr' => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0'), + ]); + + $member_since = strtotime($user_record['register_date']); + self::set('new_member', time() < ($member_since + ( 60 * 60 * 24 * 14))); + + if (strlen($user_record['timezone'])) { + date_default_timezone_set($user_record['timezone']); + $a->timezone = $user_record['timezone']; + } + + $masterUid = $user_record['uid']; + + if (!empty($_SESSION['submanage'])) { + $user = DBA::selectFirst('user', ['uid'], ['uid' => $_SESSION['submanage']]); + if (DBA::isResult($user)) { + $masterUid = $user['uid']; + } + } + + $a->identities = User::identities($masterUid); + + if ($login_initial) { + $a->getLogger()->info('auth_identities: ' . print_r($a->identities, true)); + } + + if ($login_refresh) { + $a->getLogger()->info('auth_identities refresh: ' . print_r($a->identities, true)); + } + + $contact = DBA::selectFirst('contact', [], ['uid' => $_SESSION['uid'], 'self' => true]); + if (DBA::isResult($contact)) { + $a->contact = $contact; + $a->cid = $contact['id']; + self::set('cid', $a->cid); + } + + header('X-Account-Management-Status: active; name="' . $user_record['username'] . '"; id="' . $user_record['nickname'] . '"'); + + if ($login_initial || $login_refresh) { + DBA::update('user', ['login_date' => DateTimeFormat::utcNow()], ['uid' => $_SESSION['uid']]); + + // Set the login date for all identities of the user + DBA::update('user', ['login_date' => DateTimeFormat::utcNow()], + ['parent-uid' => $masterUid, 'account_removed' => false]); + } + + if ($login_initial) { + /* + * If the user specified to remember the authentication, then set a cookie + * that expires after one week (the default is when the browser is closed). + * The cookie will be renewed automatically. + * The week ensures that sessions will expire after some inactivity. + */ + ; + if (self::get('remember')) { + $a->getLogger()->info('Injecting cookie for remembered user ' . $user_record['nickname']); + Authentication::setCookie(604800, $user_record); + self::remove('remember'); + } + } + + if ($interactive) { + if ($user_record['login_date'] <= DBA::NULL_DATETIME) { + info(L10n::t('Welcome %s', $user_record['username'])); + info(L10n::t('Please upload a profile photo.')); + $a->internalRedirect('profile_photo/new'); + } else { + info(L10n::t("Welcome back %s", $user_record['username'])); + } + } + + $a->user = $user_record; + + if ($login_initial) { + Hook::callAll('logged_in', $a->user); + + if ($a->module !== 'home' && self::exists('return_path')) { + $a->internalRedirect(self::get('return_path')); + } + } + } } diff --git a/src/Module/Login.php b/src/Module/Login.php index b0897f2d76..7a3b6ae457 100644 --- a/src/Module/Login.php +++ b/src/Module/Login.php @@ -12,6 +12,7 @@ use Friendica\Core\Hook; use Friendica\Core\L10n; use Friendica\Core\Logger; use Friendica\Core\Renderer; +use Friendica\Core\Session; use Friendica\Core\System; use Friendica\Database\DBA; use Friendica\Model\User; @@ -160,7 +161,8 @@ class Login extends BaseModule // if we haven't failed up this point, log them in. $_SESSION['remember'] = $remember; $_SESSION['last_login_date'] = DateTimeFormat::utcNow(); - Authentication::setAuthenticatedSessionForUser($record, true, true); + + Session::setAuthenticatedForUser($a, $record, true, true); if (!empty($_SESSION['return_path'])) { $return_path = $_SESSION['return_path']; @@ -210,7 +212,7 @@ class Login extends BaseModule // Do the authentification if not done by now if (!isset($_SESSION) || !isset($_SESSION['authenticated'])) { - Authentication::setAuthenticatedSessionForUser($user); + Session::setAuthenticatedForUser($a, $user); if (Config::get('system', 'paranoia')) { $_SESSION['addr'] = $data->ip; @@ -263,7 +265,8 @@ class Login extends BaseModule $_SESSION['last_login_date'] = DateTimeFormat::utcNow(); $login_refresh = true; } - Authentication::setAuthenticatedSessionForUser($user, false, false, $login_refresh); + + Session::setAuthenticatedForUser($a, $user, false, false, $login_refresh); } } }