Split auth stuff off into own context.

This commit is contained in:
Pachira 2023-09-08 00:43:00 +00:00
parent c5a284f360
commit 8b0f960c86
11 changed files with 94 additions and 68 deletions

View file

@ -10,9 +10,10 @@ if($authInfo->isLoggedIn()) {
return;
}
$authCtx = $msz->getAuthContext();
$users = $msz->getUsersContext()->getUsers();
$sessions = $msz->getSessions();
$loginAttempts = $msz->getLoginAttempts();
$sessions = $authCtx->getSessions();
$loginAttempts = $authCtx->getLoginAttempts();
if(!empty($_GET['resolve'])) {
header('Content-Type: application/json; charset=utf-8');
@ -121,7 +122,7 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
}
if($userInfo->hasTOTPKey()) {
$tfaToken = $msz->getTFASessions()->createToken($userInfo);
$tfaToken = $authCtx->getTwoFactorAuthSessions()->createToken($userInfo);
url_redirect('auth-two-factor', [
'token' => $tfaToken,
]);

View file

@ -12,7 +12,8 @@ if($authInfo->isLoggedIn()) {
$tokenInfo = $authInfo->getTokenInfo();
$msz->getSessions()->deleteSessions(sessionTokens: $tokenInfo->getSessionToken());
$authCtx = $msz->getAuthContext();
$authCtx->getSessions()->deleteSessions(sessionTokens: $tokenInfo->getSessionToken());
$tokenBuilder = $tokenInfo->toBuilder();
$tokenBuilder->removeUserId();

View file

@ -10,9 +10,10 @@ if($authInfo->isLoggedIn()) {
return;
}
$authCtx = $msz->getAuthContext();
$users = $msz->getUsersContext()->getUsers();
$recoveryTokens = $msz->getRecoveryTokens();
$loginAttempts = $msz->getLoginAttempts();
$recoveryTokens = $authCtx->getRecoveryTokens();
$loginAttempts = $authCtx->getLoginAttempts();
$reset = !empty($_POST['reset']) && is_array($_POST['reset']) ? $_POST['reset'] : [];
$forgot = !empty($_POST['forgot']) && is_array($_POST['forgot']) ? $_POST['forgot'] : [];

View file

@ -10,6 +10,7 @@ if($authInfo->isLoggedIn()) {
return;
}
$authCtx = $msz->getAuthContext();
$usersCtx = $msz->getUsersContext();
$users = $usersCtx->getUsers();
$roles = $usersCtx->getRoles();
@ -31,7 +32,7 @@ $countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
// for fast matching
$restricted = '';
$loginAttempts = $msz->getLoginAttempts();
$loginAttempts = $authCtx->getLoginAttempts();
$remainingAttempts = $loginAttempts->countRemainingAttempts($ipAddress);
while(!$restricted && !empty($register)) {

View file

@ -11,10 +11,11 @@ if($authInfo->isLoggedIn()) {
return;
}
$authCtx = $msz->getAuthContext();
$users = $msz->getUsersContext()->getUsers();
$sessions = $msz->getSessions();
$tfaSessions = $msz->getTFASessions();
$loginAttempts = $msz->getLoginAttempts();
$sessions = $authCtx->getSessions();
$tfaSessions = $authCtx->getTwoFactorAuthSessions();
$loginAttempts = $authCtx->getLoginAttempts();
$ipAddress = $_SERVER['REMOTE_ADDR'];
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';

View file

@ -8,7 +8,8 @@ $currentUser = $authInfo->getUserInfo();
if($currentUser === null)
Template::throwError(401);
$loginAttempts = $msz->getLoginAttempts();
$authCtx = $msz->getAuthContext();
$loginAttempts = $authCtx->getLoginAttempts();
$auditLog = $msz->getAuditLog();
$loginHistoryPagination = new Pagination($loginAttempts->countAttempts(userInfo: $currentUser), 5, 'hp');

View file

@ -8,7 +8,8 @@ if(!$authInfo->isLoggedIn())
Template::throwError(401);
$errors = [];
$sessions = $msz->getSessions();
$authCtx = $msz->getAuthContext();
$sessions = $authCtx->getSessions();
$currentUser = $authInfo->getUserInfo();
$activeSessionId = $authInfo->getSessionId();

View file

@ -39,7 +39,7 @@ if(file_exists(MSZ_ROOT . '/.migrating')) {
exit;
}
$tokenPacker = $msz->createAuthTokenPacker();
$tokenPacker = $msz->getAuthContext()->createAuthTokenPacker();
if(filter_has_var(INPUT_COOKIE, 'msz_auth'))
$tokenInfo = $tokenPacker->unpack(filter_input(INPUT_COOKIE, 'msz_auth'));
@ -58,7 +58,7 @@ $userInfoReal = null;
if($tokenInfo->hasUserId() && $tokenInfo->hasSessionToken()) {
$users = $msz->getUsersContext()->getUsers();
$sessions = $msz->getSessions();
$sessions = $msz->getAuthContext()->getSessions();
$tokenBuilder = new AuthTokenBuilder($tokenInfo);
try {

42
src/Auth/AuthContext.php Normal file
View file

@ -0,0 +1,42 @@
<?php
namespace Misuzu\Auth;
use Index\Data\IDbConnection;
use Misuzu\Config\IConfig;
class AuthContext {
private Sessions $sessions;
private LoginAttempts $loginAttempts;
private RecoveryTokens $recoveryTokens;
private TwoFactorAuthSessions $tfaSessions;
private IConfig $config;
public function __construct(IDbConnection $dbConn, IConfig $config) {
$this->config = $config;
$this->sessions = new Sessions($dbConn);
$this->loginAttempts = new LoginAttempts($dbConn);
$this->recoveryTokens = new RecoveryTokens($dbConn);
$this->tfaSessions = new TwoFactorAuthSessions($dbConn);
}
public function getSessions(): Sessions {
return $this->sessions;
}
public function getLoginAttempts(): LoginAttempts {
return $this->loginAttempts;
}
public function getRecoveryTokens(): RecoveryTokens {
return $this->recoveryTokens;
}
public function getTwoFactorAuthSessions(): TwoFactorAuthSessions {
return $this->tfaSessions;
}
public function createAuthTokenPacker(): AuthTokenPacker {
return new AuthTokenPacker($this->config->getString('secret', 'meow'));
}
}

View file

@ -10,12 +10,9 @@ use Index\Http\HttpRequest;
use Index\Routing\Router;
use Sasae\SasaeEnvironment;
use Misuzu\Template;
use Misuzu\Auth\AuthContext;
use Misuzu\Auth\AuthInfo;
use Misuzu\Auth\AuthTokenPacker;
use Misuzu\Auth\LoginAttempts;
use Misuzu\Auth\RecoveryTokens;
use Misuzu\Auth\Sessions;
use Misuzu\Auth\TwoFactorAuthSessions;
use Misuzu\AuditLog\AuditLog;
use Misuzu\Changelog\Changelog;
use Misuzu\Changelog\ChangelogRoutes;
@ -59,11 +56,7 @@ class MisuzuContext {
private Comments $comments;
private Sessions $sessions;
private LoginAttempts $loginAttempts;
private RecoveryTokens $recoveryTokens;
private TwoFactorAuthSessions $tfaSessions;
private AuthContext $authCtx;
private UsersContext $usersCtx;
private ProfileFields $profileFields;
@ -76,22 +69,20 @@ class MisuzuContext {
$this->dbConn = $dbConn;
$this->config = $config;
$this->usersCtx = new UsersContext($this->dbConn);
$this->perms = new Permissions($this->dbConn);
$this->perms = new Permissions($dbConn);
$this->authInfo = new AuthInfo($this->perms);
$this->auditLog = new AuditLog($this->dbConn);
$this->changelog = new Changelog($this->dbConn);
$this->comments = new Comments($this->dbConn);
$this->counters = new Counters($this->dbConn);
$this->emotes = new Emotes($this->dbConn);
$this->forum = new Forum($this->dbConn);
$this->loginAttempts = new LoginAttempts($this->dbConn);
$this->news = new News($this->dbConn);
$this->profileFields = new ProfileFields($this->dbConn);
$this->recoveryTokens = new RecoveryTokens($this->dbConn);
$this->sessions = new Sessions($this->dbConn);
$this->tfaSessions = new TwoFactorAuthSessions($this->dbConn);
$this->authCtx = new AuthContext($dbConn, $config->scopeTo('auth'));
$this->usersCtx = new UsersContext($dbConn);
$this->auditLog = new AuditLog($dbConn);
$this->changelog = new Changelog($dbConn);
$this->comments = new Comments($dbConn);
$this->counters = new Counters($dbConn);
$this->emotes = new Emotes($dbConn);
$this->forum = new Forum($dbConn);
$this->news = new News($dbConn);
$this->profileFields = new ProfileFields($dbConn);
}
public function getDbConn(): IDbConnection {
@ -139,22 +130,6 @@ class MisuzuContext {
return $this->auditLog;
}
public function getLoginAttempts(): LoginAttempts {
return $this->loginAttempts;
}
public function getRecoveryTokens(): RecoveryTokens {
return $this->recoveryTokens;
}
public function getTFASessions(): TwoFactorAuthSessions {
return $this->tfaSessions;
}
public function getSessions(): Sessions {
return $this->sessions;
}
public function getCounters(): Counters {
return $this->counters;
}
@ -171,6 +146,10 @@ class MisuzuContext {
return $this->perms;
}
public function getAuthContext(): AuthContext {
return $this->authCtx;
}
public function getUsersContext(): UsersContext {
return $this->usersCtx;
}
@ -310,11 +289,10 @@ class MisuzuContext {
$this->router->register(new SharpChatRoutes(
$this->config->scopeTo('sockChat'),
$this->usersCtx,
$this->authCtx,
$this->emotes,
$this->sessions,
$this->perms,
$this->authInfo,
$this->createAuthTokenPacker(...)
$this->authInfo
));
$this->router->register(new SatoriRoutes(

View file

@ -1,13 +1,13 @@
<?php
namespace Misuzu\SharpChat;
use Closure;
use RuntimeException;
use Index\Colour\Colour;
use Index\Routing\IRouter;
use Index\Routing\IRouteHandler;
use Index\Routing\Route;
use Misuzu\Tools;
use Misuzu\Auth\AuthContext;
use Misuzu\Auth\AuthInfo;
use Misuzu\Auth\Sessions;
use Misuzu\Config\IConfig;
@ -22,11 +22,10 @@ final class SharpChatRoutes implements IRouteHandler {
public function __construct(
private IConfig $config,
private UsersContext $usersCtx,
private AuthContext $authCtx,
private Emotes $emotes,
private Sessions $sessions,
private Permissions $perms,
private AuthInfo $authInfo,
private Closure $createAuthTokenPacker // this sucks lol
private AuthInfo $authInfo
) {
$this->hashKey = $this->config->getString('hashKey', 'woomy');
}
@ -61,7 +60,7 @@ final class SharpChatRoutes implements IRouteHandler {
}
#[Route('GET', '/_sockchat/login')]
public function getLogin($response, $request): void {
public function getLogin($response, $request) {
if(!$this->authInfo->isLoggedIn()) {
$response->redirect(url('auth-login'));
return;
@ -104,7 +103,7 @@ final class SharpChatRoutes implements IRouteHandler {
return ['ok' => false, 'err' => 'token'];
try {
$sessionInfo = $this->sessions->getSession(sessionToken: $tokenInfo->getSessionToken());
$sessionInfo = $this->authCtx->getSessions()->getSession(sessionToken: $tokenInfo->getSessionToken());
} catch(RuntimeException $ex) {
return ['ok' => false, 'err' => 'session'];
}
@ -119,7 +118,7 @@ final class SharpChatRoutes implements IRouteHandler {
? $tokenInfo->getImpersonatedUserId()
: $userInfo->getId();
$tokenPacker = ($this->createAuthTokenPacker)();
$tokenPacker = $this->authCtx->createAuthTokenPacker();
return [
'ok' => true,
@ -184,7 +183,7 @@ final class SharpChatRoutes implements IRouteHandler {
return ['success' => false, 'reason' => 'hash'];
if($authMethod === 'SESS' || $authMethod === 'Misuzu') {
$tokenPacker = ($this->createAuthTokenPacker)();
$tokenPacker = $this->authCtx->createAuthTokenPacker();
$tokenInfo = $tokenPacker->unpack($authToken);
if($tokenInfo->isEmpty()) {
// don't support using the raw session key for Misuzu format
@ -196,17 +195,17 @@ final class SharpChatRoutes implements IRouteHandler {
$sessionToken = $tokenInfo->getSessionToken();
try {
$sessionInfo = $this->sessions->getSession(sessionToken: $sessionToken);
$sessionInfo = $this->authCtx->getSessions()->getSession(sessionToken: $sessionToken);
} catch(RuntimeException $ex) {
return ['success' => false, 'reason' => 'token'];
}
if($sessionInfo->hasExpired()) {
$this->sessions->deleteSessions(sessionInfos: $sessionInfo);
$this->authCtx->getSessions()->deleteSessions(sessionInfos: $sessionInfo);
return ['success' => false, 'reason' => 'expired'];
}
$this->sessions->recordSessionActivity(sessionInfo: $sessionInfo, remoteAddr: $ipAddress);
$this->authCtx->getSessions()->recordSessionActivity(sessionInfo: $sessionInfo, remoteAddr: $ipAddress);
$userInfo = $this->usersCtx->getUsers()->getUser($sessionInfo->getUserId(), 'id');
if($tokenInfo->hasImpersonatedUserId() && $userInfo->isSuperUser()) {