Changed the way msz_auth is handled.

Going forward msz_auth is always assumed to be present, even while the user is not logged in.
If the cookie is not present a default, empty value will be used.
The msz_uid and msz_sid cookies are also still upconverted for some reason but are no longer removed even though there's no active sessions that can possibly have those anymore.
As with the previous change, shit may be broken so report any Anomalies you come across, through flashii-issues@flash.moe if necessary.
This commit is contained in:
flash 2023-08-03 01:35:08 +00:00
parent e000c21987
commit 9ae2a6a39b
17 changed files with 618 additions and 372 deletions
public

View file

@ -2,6 +2,9 @@
namespace Misuzu;
use RuntimeException;
use Misuzu\Auth\AuthTokenBuilder;
use Misuzu\Auth\AuthTokenCookie;
use Misuzu\Auth\AuthTokenInfo;
require_once __DIR__ . '/../misuzu.php';
@ -51,7 +54,6 @@ $globals = $cfg->getValues([
'site.url:s',
'eeprom.path:s',
'eeprom.app:s',
['auth.secret:s', 'meow'],
['csrf.secret:s', 'soup'],
]);
@ -74,50 +76,55 @@ unset($mszAssetsInfo);
Template::addPath(MSZ_TEMPLATES);
AuthToken::setSecretKey($globals['auth.secret']);
$tokenPacker = $msz->createAuthTokenPacker();
if(isset($_COOKIE['msz_uid']) && isset($_COOKIE['msz_sid'])) {
$authToken = new AuthToken;
$authToken->setUserId(filter_input(INPUT_COOKIE, 'msz_uid', FILTER_SANITIZE_NUMBER_INT) ?? '0');
$authToken->setSessionToken(filter_input(INPUT_COOKIE, 'msz_sid') ?? '');
if(filter_has_var(INPUT_COOKIE, 'msz_auth'))
$tokenInfo = $tokenPacker->unpack(filter_input(INPUT_COOKIE, 'msz_auth'));
elseif(filter_has_var(INPUT_COOKIE, 'msz_uid') && filter_has_var(INPUT_COOKIE, 'msz_sid')) {
$tokenBuilder = new AuthTokenBuilder;
$tokenBuilder->setUserId((string)filter_input(INPUT_COOKIE, 'msz_uid', FILTER_SANITIZE_NUMBER_INT));
$tokenBuilder->setSessionToken((string)filter_input(INPUT_COOKIE, 'msz_sid'));
$tokenInfo = $tokenBuilder->toInfo();
$tokenBuilder = null;
} else
$tokenInfo = AuthTokenInfo::empty();
if($authToken->isValid())
$authToken->applyCookie(strtotime('1 year'));
$userInfo = null;
$sessionInfo = null;
$userInfoReal = null;
AuthToken::nukeCookieLegacy();
}
if($tokenInfo->hasUserId() && $tokenInfo->hasSessionToken()) {
$users = $msz->getUsers();
$sessions = $msz->getSessions();
$tokenBuilder = new AuthTokenBuilder($tokenInfo);
if(!isset($authToken))
$authToken = AuthToken::unpack(filter_input(INPUT_COOKIE, 'msz_auth') ?? '');
$users = $msz->getUsers();
$sessions = $msz->getSessions();
if($authToken->isValid()) {
try {
$sessionInfo = $sessions->getSession(sessionToken: $authToken->getSessionToken());
$sessionInfo = $sessions->getSession(sessionToken: $tokenInfo->getSessionToken());
if($sessionInfo->hasExpired()) {
$sessions->deleteSessions(sessionInfos: $sessionInfo);
} elseif($sessionInfo->getUserId() === $authToken->getUserId()) {
$userInfo = $users->getUser($authToken->getUserId(), 'id');
$tokenBuilder->removeUserId();
$tokenBuilder->removeSessionToken();
} elseif($sessionInfo->getUserId() === $tokenInfo->getUserId()) {
$userInfo = $users->getUser($tokenInfo->getUserId(), 'id');
if(!$userInfo->isDeleted()) {
if($userInfo->isDeleted()) {
$tokenBuilder->removeUserId();
$tokenBuilder->removeSessionToken();
} else {
$users->recordUserActivity($userInfo, remoteAddr: $_SERVER['REMOTE_ADDR']);
$sessions->recordSessionActivity(sessionInfo: $sessionInfo, remoteAddr: $_SERVER['REMOTE_ADDR']);
if($sessionInfo->shouldBumpExpires())
$authToken->applyCookie($sessionInfo->getExpiresTime());
$tokenBuilder->setEdited();
if($authToken->hasImpersonatedUserId()) {
if($tokenInfo->hasImpersonatedUserId()) {
$allowToImpersonate = $userInfo->isSuperUser();
$impersonatedUserId = $authToken->getImpersonatedUserId();
$impersonatedUserId = $tokenInfo->getImpersonatedUserId();
if(!$allowToImpersonate) {
$allowImpersonateUsers = $cfg->getArray(sprintf('impersonate.allow.u%s', $userInfo->getId()));
$allowToImpersonate = in_array((string)$impersonatedUserId, $allowImpersonateUsers, true);
}
$removeImpersonationData = !$allowToImpersonate;
if($allowToImpersonate) {
$userInfoReal = $userInfo;
@ -125,24 +132,30 @@ if($authToken->isValid()) {
$userInfo = $users->getUser($impersonatedUserId, 'id');
} catch(RuntimeException $ex) {
$userInfo = $userInfoReal;
$removeImpersonationData = true;
$userInfoReal = null;
$tokenBuilder->removeImpersonatedUserId();
}
}
if($removeImpersonationData) {
$authToken->removeImpersonatedUserId();
$authToken->applyCookie();
}
} else $tokenBuilder->removeImpersonatedUserId();
}
$msz->setAuthInfo($authToken, $userInfo, $userInfoReal ?? null);
}
}
} catch(RuntimeException $ex) {
AuthToken::nukeCookie();
$tokenBuilder->removeUserId();
$tokenBuilder->removeSessionToken();
$tokenBuilder->removeImpersonatedUserId();
$userInfo = null;
$sessionInfo = null;
$userInfoReal = null;
}
if($tokenBuilder->isEdited()) {
$tokenInfo = $tokenBuilder->toInfo();
AuthTokenCookie::apply($tokenPacker->pack($tokenInfo));
}
}
$msz->getAuthInfo()->setInfo($tokenInfo, $userInfo, $sessionInfo, $userInfoReal);
if(!empty($userInfo))
$userInfo = $users->getUser((string)$userInfo->getId(), 'id');
if(!empty($userInfoReal))
@ -150,7 +163,7 @@ if(!empty($userInfoReal))
CSRF::init(
$globals['csrf.secret'],
($msz->isLoggedIn() ? $authToken->getSessionToken() : $_SERVER['REMOTE_ADDR'])
($msz->isLoggedIn() ? $sessionInfo->getToken() : $_SERVER['REMOTE_ADDR'])
);
if(!empty($userInfo)) {