diff --git a/public_html/dispatch.php b/public_html/dispatch.php index 64667d9e..476ef729 100644 --- a/public_html/dispatch.php +++ b/public_html/dispatch.php @@ -157,7 +157,8 @@ $context->transport = new StdClass; StatusHelper::init(); session_start(); -AuthController::doLogIn(); +if (!Auth::isLoggedIn()) + Auth::tryAutoLogin(); try { diff --git a/src/Access.php b/src/Access.php index 48d64fa7..e6f20a01 100644 --- a/src/Access.php +++ b/src/Access.php @@ -37,7 +37,7 @@ class Access if (php_sapi_name() == 'cli') return true; - $user = getContext()->user; + $user = Auth::getCurrentUser(); $minAccessRank = AccessRank::Admin; $key = TextCaseConverter::convert(Privilege::toString($privilege), @@ -66,19 +66,18 @@ class Access throw new SimpleException('Insufficient privileges'); } + public static function assertEmailConfirmation() + { + $user = Auth::getCurrentUser(); + if (!$user->emailConfirmed) + throw new SimpleException('Need e-mail address confirmation to continue'); + } + public static function getIdentity($user) { if (!$user) return 'all'; - $userFromContext = getContext()->user; - return $user->id == $userFromContext->id ? 'own' : 'all'; - } - - public static function assertEmailConfirmation() - { - $user = getContext()->user; - if (!$user->emailConfirmed) - throw new SimpleException('Need e-mail address confirmation to continue'); + return $user->id == Auth::getCurrentUser()->id ? 'own' : 'all'; } public static function getAllowedSafety() @@ -86,11 +85,10 @@ class Access if (php_sapi_name() == 'cli') return PostSafety::getAll(); - $context = getContext(); - return array_filter(PostSafety::getAll(), function($safety) use ($context) + return array_filter(PostSafety::getAll(), function($safety) { return Access::check(Privilege::ListPosts, PostSafety::toString($safety)) - and $context->user->hasEnabledSafety($safety); + and Auth::getCurrentUser()->hasEnabledSafety($safety); }); } } diff --git a/src/Auth.php b/src/Auth.php new file mode 100644 index 00000000..a2c90fd2 --- /dev/null +++ b/src/Auth.php @@ -0,0 +1,92 @@ +passSalt); + if ($passwordHash != $dbUser->passHash) + throw new SimpleException('Invalid password'); + + if (!$dbUser->staffConfirmed and $config->registration->staffActivation) + throw new SimpleException('Staff hasn\'t confirmed your registration yet'); + + if ($dbUser->banned) + throw new SimpleException('You are banned'); + + if ($config->registration->needEmailForRegistering) + Access::requireEmail($dbUser); + + if ($remember) + { + $token = implode('|', [base64_encode($name), base64_encode($password)]); + setcookie('auth', TextHelper::encrypt($token), time() + 365 * 24 * 3600, '/'); + } + + self::setCurrentUser($dbUser); + } + + public static function tryAutoLogin() + { + if (!isset($_COOKIE['auth'])) + return; + + $token = TextHelper::decrypt($_COOKIE['auth']); + list ($name, $password) = array_map('base64_decode', explode('|', $token)); + try + { + self::login($name, $password, false); + return true; + } + catch (Exception $e) + { + return false; + } + } + + public static function isLoggedIn() + { + return isset($_SESSION['logged-in']) and $_SESSION['logged-in']; + } + + public static function setCurrentUser($user) + { + if ($user == null) + { + self::setCurrentUser(self::getAnonymousUser()); + } + else + { + $_SESSION['logged-in'] = $user->accessRank != AccessRank::Anonymous; + $_SESSION['user'] = serialize($user); + } + } + + public static function getCurrentUser() + { + return self::isLoggedIn() + ? unserialize($_SESSION['user']) + : self::getAnonymousUser(); + } + + private static function getAnonymousUser() + { + $dummy = UserModel::spawn(); + $dummy->name = UserModel::getAnonymousName(); + $dummy->accessRank = AccessRank::Anonymous; + return $dummy; + } +} diff --git a/src/Controllers/AuthController.php b/src/Controllers/AuthController.php index 4234547a..e53e8e27 100644 --- a/src/Controllers/AuthController.php +++ b/src/Controllers/AuthController.php @@ -1,61 +1,13 @@ passSalt); - if ($passwordHash != $dbUser->passHash) - throw new SimpleException('Invalid password'); - - if (!$dbUser->staffConfirmed and $config->registration->staffActivation) - throw new SimpleException('Staff hasn\'t confirmed your registration yet'); - - if ($dbUser->banned) - throw new SimpleException('You are banned'); - - if ($config->registration->needEmailForRegistering) - Access::requireEmail($dbUser); - - $context->user = $dbUser; - self::doReLog(); - return $dbUser; - } - - public static function tryAutoLogin() - { - if (!isset($_COOKIE['auth'])) - return; - - $token = TextHelper::decrypt($_COOKIE['auth']); - list ($name, $password) = array_map('base64_decode', explode('|', $token)); - return self::tryLogin($name, $password); - } - public function loginAction() { $context = getContext(); $context->handleExceptions = true; //check if already logged in - if ($context->loggedIn) + if (Auth::isLoggedIn()) { self::redirectAfterLog(); return; @@ -66,13 +18,9 @@ class AuthController $suppliedName = InputHelper::get('name'); $suppliedPassword = InputHelper::get('password'); - $dbUser = self::tryLogin($suppliedName, $suppliedPassword); + $remember = boolval(InputHelper::get('remember')); + $dbUser = Auth::login($suppliedName, $suppliedPassword, $remember); - if (InputHelper::get('remember')) - { - $token = implode('|', [base64_encode($suppliedName), base64_encode($suppliedPassword)]); - setcookie('auth', TextHelper::encrypt($token), time() + 365 * 24 * 3600, '/'); - } StatusHelper::success(); self::redirectAfterLog(); } @@ -82,59 +30,10 @@ class AuthController $context = getContext(); $context->viewName = null; $context->layoutName = null; - self::doLogOut(); - setcookie('auth', false, 0, '/'); + Auth::logout(); \Chibi\Util\Url::forward(\Chibi\Router::linkTo(['IndexController', 'indexAction'])); } - public static function doLogOut() - { - unset($_SESSION['user']); - } - - public static function doLogIn() - { - $context = getContext(); - if (!isset($_SESSION['user'])) - { - if (!empty($context->user) and $context->user->id) - { - $dbUser = UserModel::findById($context->user->id); - $dbUser->lastLoginDate = time(); - UserModel::save($dbUser); - $_SESSION['user'] = serialize($dbUser); - } - else - { - $dummy = UserModel::spawn(); - $dummy->name = UserModel::getAnonymousName(); - $dummy->accessRank = AccessRank::Anonymous; - $_SESSION['user'] = serialize($dummy); - } - } - - $context->user = unserialize($_SESSION['user']); - $context->loggedIn = $context->user->accessRank != AccessRank::Anonymous; - if (!$context->loggedIn) - { - try - { - self::tryAutoLogin(); - } - catch (Exception $e) - { - } - } - } - - public static function doReLog() - { - $context = getContext(); - if ($context->user !== null) - self::doLogOut(); - self::doLogIn(); - } - public static function observeWorkFinish() { if (strpos(\Chibi\Util\Headers::get('Content-Type'), 'text/html') === false) @@ -146,4 +45,15 @@ class AuthController return; $_SESSION['login-redirect-url'] = $context->query; } + + private static function redirectAfterLog() + { + if (isset($_SESSION['login-redirect-url'])) + { + \Chibi\Util\Url::forward(\Chibi\Util\Url::makeAbsolute($_SESSION['login-redirect-url'])); + unset($_SESSION['login-redirect-url']); + return; + } + \Chibi\Util\Url::forward(\Chibi\Router::linkTo(['IndexController', 'indexAction'])); + } } diff --git a/src/Controllers/CommentController.php b/src/Controllers/CommentController.php index 20571ff7..0b33b914 100644 --- a/src/Controllers/CommentController.php +++ b/src/Controllers/CommentController.php @@ -48,8 +48,8 @@ class CommentController $comment = CommentModel::spawn(); $comment->setPost($post); - if ($context->loggedIn) - $comment->setCommenter($context->user); + if (Auth::isLoggedIn()) + $comment->setCommenter(Auth::getCurrentUser()); else $comment->setCommenter(null); $comment->commentDate = time(); diff --git a/src/Controllers/PostController.php b/src/Controllers/PostController.php index 2495eccf..4c06c666 100644 --- a/src/Controllers/PostController.php +++ b/src/Controllers/PostController.php @@ -39,7 +39,7 @@ class PostController $context->massTagQuery = $query; if (!Access::check(Privilege::MassTag, 'all')) - $query = trim($query . ' submit:' . $context->user->name); + $query = trim($query . ' submit:' . Auth::getCurrentUser()->name); } $posts = PostSearchService::getEntities($query, $postsPerPage, $page); @@ -136,8 +136,8 @@ class PostController //basic stuff $anonymous = InputHelper::get('anonymous'); - if ($context->loggedIn and !$anonymous) - $post->setUploader($context->user); + if (Auth::isLoggedIn() and !$anonymous) + $post->setUploader(Auth::getCurrentUser()); //store the post to get the ID in the logs PostModel::forgeId($post); @@ -267,11 +267,11 @@ class PostController if (!InputHelper::get('submit')) return; - if (!$context->loggedIn) + if (!Auth::isLoggedIn()) throw new SimpleException('Not logged in'); - UserModel::updateUserScore($context->user, $post, 1); - UserModel::addToUserFavorites($context->user, $post); + UserModel::updateUserScore(Auth::getCurrentUser(), $post, 1); + UserModel::addToUserFavorites(Auth::getCurrentUser(), $post); StatusHelper::success(); } @@ -284,10 +284,10 @@ class PostController if (!InputHelper::get('submit')) return; - if (!$context->loggedIn) + if (!Auth::isLoggedIn()) throw new SimpleException('Not logged in'); - UserModel::removeFromUserFavorites($context->user, $post); + UserModel::removeFromUserFavorites(Auth::getCurrentUser(), $post); StatusHelper::success(); } @@ -300,10 +300,10 @@ class PostController if (!InputHelper::get('submit')) return; - if (!$context->loggedIn) + if (!Auth::isLoggedIn()) throw new SimpleException('Not logged in'); - UserModel::updateUserScore($context->user, $post, $score); + UserModel::updateUserScore(Auth::getCurrentUser(), $post, $score); StatusHelper::success(); } @@ -314,7 +314,7 @@ class PostController Access::assert(Privilege::FeaturePost, Access::getIdentity($post->getUploader())); PropertyModel::set(PropertyModel::FeaturedPostId, $post->id); PropertyModel::set(PropertyModel::FeaturedPostDate, time()); - PropertyModel::set(PropertyModel::FeaturedPostUserName, $context->user->name); + PropertyModel::set(PropertyModel::FeaturedPostUserName, Auth::getCurrentUser()->name); StatusHelper::success(); LogHelper::log('{user} featured {post} on main page', ['post' => TextHelper::reprPost($post)]); } @@ -346,8 +346,8 @@ class PostController $context->transport->lastSearchQuery, $id); } - $favorite = $context->user->hasFavorited($post); - $score = $context->user->getScore($post); + $favorite = Auth::getCurrentUser()->hasFavorited($post); + $score = Auth::getCurrentUser()->getScore($post); $flagged = in_array(TextHelper::reprPost($post), SessionHelper::get('flagged', [])); $context->favorite = $favorite; diff --git a/src/Controllers/UserController.php b/src/Controllers/UserController.php index 6d2e8629..6ab1a233 100644 --- a/src/Controllers/UserController.php +++ b/src/Controllers/UserController.php @@ -119,7 +119,7 @@ class UserController return; $name = $user->name; - if ($context->user->id == $user->id) + if (Auth::getCurrentUser()->id == $user->id) { $suppliedPasswordHash = UserModel::hashPassword($suppliedCurrentPassword, $user->passSalt); if ($suppliedPasswordHash != $user->passHash) @@ -128,8 +128,8 @@ class UserController $oldId = $user->id; UserModel::remove($user); - if ($oldId == $context->user->id) - AuthController::doLogOut(); + if ($oldId == Auth::getCurrentUser()->id) + Auth::logOut(); \Chibi\Util\Url::forward(\Chibi\Router::linkTo(['IndexController', 'indexAction'])); LogHelper::log('{user} removed {subject}\'s account', ['subject' => TextHelper::reprUser($name)]); @@ -165,9 +165,8 @@ class UserController if ($user->accessRank != AccessRank::Anonymous) UserModel::save($user); - if ($user->id == $context->user->id) - $context->user = $user; - AuthController::doReLog(); + if ($user->id == Auth::getCurrentUser()->id) + Auth::setCurrentUser($user); StatusHelper::success('Browsing settings updated!'); } @@ -232,7 +231,7 @@ class UserController Access::getIdentity($user)); $suppliedEmail = UserModel::validateEmail($suppliedEmail); - if ($context->user->id == $user->id) + if (Auth::getCurrentUser()->id == $user->id) { $user->emailUnconfirmed = $suppliedEmail; if (!empty($user->emailUnconfirmed)) @@ -262,15 +261,15 @@ class UserController 'rank' => AccessRank::toString($suppliedAccessRank)]); } - if ($context->user->id == $user->id) + if (Auth::getCurrentUser()->id == $user->id) { $suppliedPasswordHash = UserModel::hashPassword($suppliedCurrentPassword, $user->passSalt); if ($suppliedPasswordHash != $currentPasswordHash) throw new SimpleException('Must supply valid current password'); } UserModel::save($user); - if ($context->user->id == $user->id) - AuthController::doReLog(); + if (Auth::getCurrentUser()->id == $user->id) + Auth::setCurrentUser($user); if ($confirmMail) self::sendEmailChangeConfirmation($user); @@ -330,20 +329,20 @@ class UserController public function toggleSafetyAction($safety) { - $context = getContext(); + $user = Auth::getCurrentUser(); + Access::assert( Privilege::ChangeUserSettings, - Access::getIdentity($context->user)); + Access::getIdentity($user)); if (!in_array($safety, PostSafety::getAll())) throw new SimpleExcetpion('Invalid safety'); - $context->user->enableSafety($safety, - !$context->user->hasEnabledSafety($safety)); + $user->enableSafety($safety, !$user->hasEnabledSafety($safety)); - if ($context->user->accessRank != AccessRank::Anonymous) - UserModel::save($context->user); - AuthController::doReLog(); + if ($user->accessRank != AccessRank::Anonymous) + UserModel::save($user); + Auth::setCurrentUser($user); StatusHelper::success(); } @@ -354,7 +353,7 @@ class UserController $context->handleExceptions = true; //check if already logged in - if ($context->loggedIn) + if (Auth::isLoggedIn()) { \Chibi\Util\Url::forward(\Chibi\Router::linkTo(['IndexController', 'indexAction'])); return; @@ -425,8 +424,7 @@ class UserController if (!getConfig()->registration->needEmailForRegistering and !getConfig()->registration->staffActivation) { - $context->user = $dbUser; - AuthController::doReLog(); + Auth::setCurrentUser($dbUser); } } @@ -454,8 +452,7 @@ class UserController if (!getConfig()->registration->staffActivation) { - $context->user = $dbUser; - AuthController::doReLog(); + Auth::setCurrentUser($dbUser); } } @@ -484,8 +481,7 @@ class UserController $message = 'Password reset successful. Your new password is **' . $randomPassword . '**.'; StatusHelper::success($message); - $context->user = $dbUser; - AuthController::doReLog(); + Auth::setCurrentUser($dbUser); } public function passwordResetProxyAction() diff --git a/src/Helpers/LogHelper.php b/src/Helpers/LogHelper.php index ee110410..2a1bf35d 100644 --- a/src/Helpers/LogHelper.php +++ b/src/Helpers/LogHelper.php @@ -71,10 +71,9 @@ class LogEvent $this->text = $text; $this->ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'; - $context = getContext(); $tokens['anon'] = UserModel::getAnonymousName(); - if ($context->loggedIn and isset($context->user)) - $tokens['user'] = TextHelper::reprUser($context->user->name); + if (Auth::isLoggedIn()) + $tokens['user'] = TextHelper::reprUser(Auth::getCurrentUser()->name); else $tokens['user'] = $tokens['anon']; $this->tokens = $tokens; diff --git a/src/Models/SearchParsers/PostSearchParser.php b/src/Models/SearchParsers/PostSearchParser.php index 2ee3e6b3..3058a539 100644 --- a/src/Models/SearchParsers/PostSearchParser.php +++ b/src/Models/SearchParsers/PostSearchParser.php @@ -24,7 +24,7 @@ class PostSearchParser extends AbstractSearchParser protected function processTeardown() { - if (getContext()->user->hasEnabledHidingDislikedPosts() and !$this->showDisliked) + if (Auth::getCurrentUser()->hasEnabledHidingDislikedPosts() and !$this->showDisliked) $this->processComplexToken('special', 'disliked', true); if (!Access::check(Privilege::ListPosts, 'hidden') or !$this->showHidden) @@ -146,11 +146,12 @@ class PostSearchParser extends AbstractSearchParser elseif ($key == 'special') { - $context = getContext(); + $activeUser = Auth::getCurrentUser(); + $value = strtolower($value); if (in_array($value, ['fav', 'favs', 'favd'])) { - return $this->prepareCriterionForComplexToken('fav', $context->user->name); + return $this->prepareCriterionForComplexToken('fav', $activeUser->name); } elseif (in_array($value, ['like', 'liked', 'likes'])) @@ -159,7 +160,7 @@ class PostSearchParser extends AbstractSearchParser { $this->statement->addLeftOuterJoin('post_score', (new Sql\ConjunctionFunctor) ->add(new Sql\EqualsFunctor('post_score.post_id', 'post.id')) - ->add(new Sql\EqualsFunctor('post_score.user_id', new Sql\Binding($context->user->id)))); + ->add(new Sql\EqualsFunctor('post_score.user_id', new Sql\Binding($activeUser->id)))); } return new Sql\EqualsFunctor(new Sql\IfNullFunctor('post_score.score', '0'), '1'); } @@ -171,7 +172,7 @@ class PostSearchParser extends AbstractSearchParser { $this->statement->addLeftOuterJoin('post_score', (new Sql\ConjunctionFunctor) ->add(new Sql\EqualsFunctor('post_score.post_id', 'post.id')) - ->add(new Sql\EqualsFunctor('post_score.user_id', new Sql\Binding($context->user->id)))); + ->add(new Sql\EqualsFunctor('post_score.user_id', new Sql\Binding($activeUser->id)))); } return new Sql\EqualsFunctor(new Sql\IfNullFunctor('post_score.score', '0'), '-1'); } diff --git a/src/Views/paginator.phtml b/src/Views/paginator.phtml index d1b27395..2dfdc3f6 100644 --- a/src/Views/paginator.phtml +++ b/src/Views/paginator.phtml @@ -42,7 +42,7 @@ if (!function_exists('pageUrl')) context->user->hasEnabledEndlessScrolling()) + if (Auth::getCurrentUser()->hasEnabledEndlessScrolling()) Assets::addScript('paginator-endless.js'); ?> diff --git a/src/Views/post-small.phtml b/src/Views/post-small.phtml index 0c5bdc95..7492b57f 100644 --- a/src/Views/post-small.phtml +++ b/src/Views/post-small.phtml @@ -41,7 +41,7 @@ if ($masstag) context->user->hasEnabledPostTagTitles()): ?> + hasEnabledPostTagTitles()): ?> title="context->post->getTags()) ?>" href=" $this->context->post->id]) ?>"> diff --git a/src/Views/top-navigation.phtml b/src/Views/top-navigation.phtml index cefab913..0fd64c9e 100644 --- a/src/Views/top-navigation.phtml +++ b/src/Views/top-navigation.phtml @@ -57,10 +57,10 @@ \Chibi\Router::linkTo(['UserController', 'listAction']), $activeController == 'user' and $activeAction != 'registration' and (!isset($this->context->route->arguments['name']) or - $this->context->route->arguments['name'] != $this->context->user->name)); + $this->context->route->arguments['name'] != Auth::getCurrentUser()->name)); } - if (!$this->context->loggedIn) + if (!Auth::isLoggedIn()) { $registerNavItem( 'Log in', @@ -76,9 +76,9 @@ { $registerNavItem( 'My account', - \Chibi\Router::linkTo(['UserController', 'viewAction'], ['name' => $this->context->user->name]), + \Chibi\Router::linkTo(['UserController', 'viewAction'], ['name' => Auth::getCurrentUser()->name]), $activeController == 'user' and isset($this->context->route->arguments['name']) and - $this->context->route->arguments['name'] == $this->context->user->name); + $this->context->route->arguments['name'] == Auth::getCurrentUser()->name); $registerNavItem( 'Log out', @@ -104,7 +104,7 @@ } ?> - context->user))): ?> +