Split auth stuff off into own context.
This commit is contained in:
parent
c5a284f360
commit
8b0f960c86
11 changed files with 94 additions and 68 deletions
|
@ -10,9 +10,10 @@ if($authInfo->isLoggedIn()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$authCtx = $msz->getAuthContext();
|
||||||
$users = $msz->getUsersContext()->getUsers();
|
$users = $msz->getUsersContext()->getUsers();
|
||||||
$sessions = $msz->getSessions();
|
$sessions = $authCtx->getSessions();
|
||||||
$loginAttempts = $msz->getLoginAttempts();
|
$loginAttempts = $authCtx->getLoginAttempts();
|
||||||
|
|
||||||
if(!empty($_GET['resolve'])) {
|
if(!empty($_GET['resolve'])) {
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
@ -121,7 +122,7 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if($userInfo->hasTOTPKey()) {
|
if($userInfo->hasTOTPKey()) {
|
||||||
$tfaToken = $msz->getTFASessions()->createToken($userInfo);
|
$tfaToken = $authCtx->getTwoFactorAuthSessions()->createToken($userInfo);
|
||||||
url_redirect('auth-two-factor', [
|
url_redirect('auth-two-factor', [
|
||||||
'token' => $tfaToken,
|
'token' => $tfaToken,
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -12,7 +12,8 @@ if($authInfo->isLoggedIn()) {
|
||||||
|
|
||||||
$tokenInfo = $authInfo->getTokenInfo();
|
$tokenInfo = $authInfo->getTokenInfo();
|
||||||
|
|
||||||
$msz->getSessions()->deleteSessions(sessionTokens: $tokenInfo->getSessionToken());
|
$authCtx = $msz->getAuthContext();
|
||||||
|
$authCtx->getSessions()->deleteSessions(sessionTokens: $tokenInfo->getSessionToken());
|
||||||
|
|
||||||
$tokenBuilder = $tokenInfo->toBuilder();
|
$tokenBuilder = $tokenInfo->toBuilder();
|
||||||
$tokenBuilder->removeUserId();
|
$tokenBuilder->removeUserId();
|
||||||
|
|
|
@ -10,9 +10,10 @@ if($authInfo->isLoggedIn()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$authCtx = $msz->getAuthContext();
|
||||||
$users = $msz->getUsersContext()->getUsers();
|
$users = $msz->getUsersContext()->getUsers();
|
||||||
$recoveryTokens = $msz->getRecoveryTokens();
|
$recoveryTokens = $authCtx->getRecoveryTokens();
|
||||||
$loginAttempts = $msz->getLoginAttempts();
|
$loginAttempts = $authCtx->getLoginAttempts();
|
||||||
|
|
||||||
$reset = !empty($_POST['reset']) && is_array($_POST['reset']) ? $_POST['reset'] : [];
|
$reset = !empty($_POST['reset']) && is_array($_POST['reset']) ? $_POST['reset'] : [];
|
||||||
$forgot = !empty($_POST['forgot']) && is_array($_POST['forgot']) ? $_POST['forgot'] : [];
|
$forgot = !empty($_POST['forgot']) && is_array($_POST['forgot']) ? $_POST['forgot'] : [];
|
||||||
|
|
|
@ -10,6 +10,7 @@ if($authInfo->isLoggedIn()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$authCtx = $msz->getAuthContext();
|
||||||
$usersCtx = $msz->getUsersContext();
|
$usersCtx = $msz->getUsersContext();
|
||||||
$users = $usersCtx->getUsers();
|
$users = $usersCtx->getUsers();
|
||||||
$roles = $usersCtx->getRoles();
|
$roles = $usersCtx->getRoles();
|
||||||
|
@ -31,7 +32,7 @@ $countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
|
||||||
// for fast matching
|
// for fast matching
|
||||||
$restricted = '';
|
$restricted = '';
|
||||||
|
|
||||||
$loginAttempts = $msz->getLoginAttempts();
|
$loginAttempts = $authCtx->getLoginAttempts();
|
||||||
$remainingAttempts = $loginAttempts->countRemainingAttempts($ipAddress);
|
$remainingAttempts = $loginAttempts->countRemainingAttempts($ipAddress);
|
||||||
|
|
||||||
while(!$restricted && !empty($register)) {
|
while(!$restricted && !empty($register)) {
|
||||||
|
|
|
@ -11,10 +11,11 @@ if($authInfo->isLoggedIn()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$authCtx = $msz->getAuthContext();
|
||||||
$users = $msz->getUsersContext()->getUsers();
|
$users = $msz->getUsersContext()->getUsers();
|
||||||
$sessions = $msz->getSessions();
|
$sessions = $authCtx->getSessions();
|
||||||
$tfaSessions = $msz->getTFASessions();
|
$tfaSessions = $authCtx->getTwoFactorAuthSessions();
|
||||||
$loginAttempts = $msz->getLoginAttempts();
|
$loginAttempts = $authCtx->getLoginAttempts();
|
||||||
|
|
||||||
$ipAddress = $_SERVER['REMOTE_ADDR'];
|
$ipAddress = $_SERVER['REMOTE_ADDR'];
|
||||||
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
|
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
|
||||||
|
|
|
@ -8,7 +8,8 @@ $currentUser = $authInfo->getUserInfo();
|
||||||
if($currentUser === null)
|
if($currentUser === null)
|
||||||
Template::throwError(401);
|
Template::throwError(401);
|
||||||
|
|
||||||
$loginAttempts = $msz->getLoginAttempts();
|
$authCtx = $msz->getAuthContext();
|
||||||
|
$loginAttempts = $authCtx->getLoginAttempts();
|
||||||
$auditLog = $msz->getAuditLog();
|
$auditLog = $msz->getAuditLog();
|
||||||
|
|
||||||
$loginHistoryPagination = new Pagination($loginAttempts->countAttempts(userInfo: $currentUser), 5, 'hp');
|
$loginHistoryPagination = new Pagination($loginAttempts->countAttempts(userInfo: $currentUser), 5, 'hp');
|
||||||
|
|
|
@ -8,7 +8,8 @@ if(!$authInfo->isLoggedIn())
|
||||||
Template::throwError(401);
|
Template::throwError(401);
|
||||||
|
|
||||||
$errors = [];
|
$errors = [];
|
||||||
$sessions = $msz->getSessions();
|
$authCtx = $msz->getAuthContext();
|
||||||
|
$sessions = $authCtx->getSessions();
|
||||||
$currentUser = $authInfo->getUserInfo();
|
$currentUser = $authInfo->getUserInfo();
|
||||||
$activeSessionId = $authInfo->getSessionId();
|
$activeSessionId = $authInfo->getSessionId();
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ if(file_exists(MSZ_ROOT . '/.migrating')) {
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tokenPacker = $msz->createAuthTokenPacker();
|
$tokenPacker = $msz->getAuthContext()->createAuthTokenPacker();
|
||||||
|
|
||||||
if(filter_has_var(INPUT_COOKIE, 'msz_auth'))
|
if(filter_has_var(INPUT_COOKIE, 'msz_auth'))
|
||||||
$tokenInfo = $tokenPacker->unpack(filter_input(INPUT_COOKIE, 'msz_auth'));
|
$tokenInfo = $tokenPacker->unpack(filter_input(INPUT_COOKIE, 'msz_auth'));
|
||||||
|
@ -58,7 +58,7 @@ $userInfoReal = null;
|
||||||
|
|
||||||
if($tokenInfo->hasUserId() && $tokenInfo->hasSessionToken()) {
|
if($tokenInfo->hasUserId() && $tokenInfo->hasSessionToken()) {
|
||||||
$users = $msz->getUsersContext()->getUsers();
|
$users = $msz->getUsersContext()->getUsers();
|
||||||
$sessions = $msz->getSessions();
|
$sessions = $msz->getAuthContext()->getSessions();
|
||||||
$tokenBuilder = new AuthTokenBuilder($tokenInfo);
|
$tokenBuilder = new AuthTokenBuilder($tokenInfo);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
42
src/Auth/AuthContext.php
Normal file
42
src/Auth/AuthContext.php
Normal 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'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,12 +10,9 @@ use Index\Http\HttpRequest;
|
||||||
use Index\Routing\Router;
|
use Index\Routing\Router;
|
||||||
use Sasae\SasaeEnvironment;
|
use Sasae\SasaeEnvironment;
|
||||||
use Misuzu\Template;
|
use Misuzu\Template;
|
||||||
|
use Misuzu\Auth\AuthContext;
|
||||||
use Misuzu\Auth\AuthInfo;
|
use Misuzu\Auth\AuthInfo;
|
||||||
use Misuzu\Auth\AuthTokenPacker;
|
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\AuditLog\AuditLog;
|
||||||
use Misuzu\Changelog\Changelog;
|
use Misuzu\Changelog\Changelog;
|
||||||
use Misuzu\Changelog\ChangelogRoutes;
|
use Misuzu\Changelog\ChangelogRoutes;
|
||||||
|
@ -59,11 +56,7 @@ class MisuzuContext {
|
||||||
|
|
||||||
private Comments $comments;
|
private Comments $comments;
|
||||||
|
|
||||||
private Sessions $sessions;
|
private AuthContext $authCtx;
|
||||||
private LoginAttempts $loginAttempts;
|
|
||||||
private RecoveryTokens $recoveryTokens;
|
|
||||||
private TwoFactorAuthSessions $tfaSessions;
|
|
||||||
|
|
||||||
private UsersContext $usersCtx;
|
private UsersContext $usersCtx;
|
||||||
|
|
||||||
private ProfileFields $profileFields;
|
private ProfileFields $profileFields;
|
||||||
|
@ -76,22 +69,20 @@ class MisuzuContext {
|
||||||
$this->dbConn = $dbConn;
|
$this->dbConn = $dbConn;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
|
||||||
$this->usersCtx = new UsersContext($this->dbConn);
|
$this->perms = new Permissions($dbConn);
|
||||||
|
|
||||||
$this->perms = new Permissions($this->dbConn);
|
|
||||||
$this->authInfo = new AuthInfo($this->perms);
|
$this->authInfo = new AuthInfo($this->perms);
|
||||||
$this->auditLog = new AuditLog($this->dbConn);
|
|
||||||
$this->changelog = new Changelog($this->dbConn);
|
$this->authCtx = new AuthContext($dbConn, $config->scopeTo('auth'));
|
||||||
$this->comments = new Comments($this->dbConn);
|
$this->usersCtx = new UsersContext($dbConn);
|
||||||
$this->counters = new Counters($this->dbConn);
|
|
||||||
$this->emotes = new Emotes($this->dbConn);
|
$this->auditLog = new AuditLog($dbConn);
|
||||||
$this->forum = new Forum($this->dbConn);
|
$this->changelog = new Changelog($dbConn);
|
||||||
$this->loginAttempts = new LoginAttempts($this->dbConn);
|
$this->comments = new Comments($dbConn);
|
||||||
$this->news = new News($this->dbConn);
|
$this->counters = new Counters($dbConn);
|
||||||
$this->profileFields = new ProfileFields($this->dbConn);
|
$this->emotes = new Emotes($dbConn);
|
||||||
$this->recoveryTokens = new RecoveryTokens($this->dbConn);
|
$this->forum = new Forum($dbConn);
|
||||||
$this->sessions = new Sessions($this->dbConn);
|
$this->news = new News($dbConn);
|
||||||
$this->tfaSessions = new TwoFactorAuthSessions($this->dbConn);
|
$this->profileFields = new ProfileFields($dbConn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDbConn(): IDbConnection {
|
public function getDbConn(): IDbConnection {
|
||||||
|
@ -139,22 +130,6 @@ class MisuzuContext {
|
||||||
return $this->auditLog;
|
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 {
|
public function getCounters(): Counters {
|
||||||
return $this->counters;
|
return $this->counters;
|
||||||
}
|
}
|
||||||
|
@ -171,6 +146,10 @@ class MisuzuContext {
|
||||||
return $this->perms;
|
return $this->perms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAuthContext(): AuthContext {
|
||||||
|
return $this->authCtx;
|
||||||
|
}
|
||||||
|
|
||||||
public function getUsersContext(): UsersContext {
|
public function getUsersContext(): UsersContext {
|
||||||
return $this->usersCtx;
|
return $this->usersCtx;
|
||||||
}
|
}
|
||||||
|
@ -310,11 +289,10 @@ class MisuzuContext {
|
||||||
$this->router->register(new SharpChatRoutes(
|
$this->router->register(new SharpChatRoutes(
|
||||||
$this->config->scopeTo('sockChat'),
|
$this->config->scopeTo('sockChat'),
|
||||||
$this->usersCtx,
|
$this->usersCtx,
|
||||||
|
$this->authCtx,
|
||||||
$this->emotes,
|
$this->emotes,
|
||||||
$this->sessions,
|
|
||||||
$this->perms,
|
$this->perms,
|
||||||
$this->authInfo,
|
$this->authInfo
|
||||||
$this->createAuthTokenPacker(...)
|
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->router->register(new SatoriRoutes(
|
$this->router->register(new SatoriRoutes(
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Misuzu\SharpChat;
|
namespace Misuzu\SharpChat;
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Index\Colour\Colour;
|
use Index\Colour\Colour;
|
||||||
use Index\Routing\IRouter;
|
use Index\Routing\IRouter;
|
||||||
use Index\Routing\IRouteHandler;
|
use Index\Routing\IRouteHandler;
|
||||||
use Index\Routing\Route;
|
use Index\Routing\Route;
|
||||||
use Misuzu\Tools;
|
use Misuzu\Tools;
|
||||||
|
use Misuzu\Auth\AuthContext;
|
||||||
use Misuzu\Auth\AuthInfo;
|
use Misuzu\Auth\AuthInfo;
|
||||||
use Misuzu\Auth\Sessions;
|
use Misuzu\Auth\Sessions;
|
||||||
use Misuzu\Config\IConfig;
|
use Misuzu\Config\IConfig;
|
||||||
|
@ -22,11 +22,10 @@ final class SharpChatRoutes implements IRouteHandler {
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private IConfig $config,
|
private IConfig $config,
|
||||||
private UsersContext $usersCtx,
|
private UsersContext $usersCtx,
|
||||||
|
private AuthContext $authCtx,
|
||||||
private Emotes $emotes,
|
private Emotes $emotes,
|
||||||
private Sessions $sessions,
|
|
||||||
private Permissions $perms,
|
private Permissions $perms,
|
||||||
private AuthInfo $authInfo,
|
private AuthInfo $authInfo
|
||||||
private Closure $createAuthTokenPacker // this sucks lol
|
|
||||||
) {
|
) {
|
||||||
$this->hashKey = $this->config->getString('hashKey', 'woomy');
|
$this->hashKey = $this->config->getString('hashKey', 'woomy');
|
||||||
}
|
}
|
||||||
|
@ -61,7 +60,7 @@ final class SharpChatRoutes implements IRouteHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('GET', '/_sockchat/login')]
|
#[Route('GET', '/_sockchat/login')]
|
||||||
public function getLogin($response, $request): void {
|
public function getLogin($response, $request) {
|
||||||
if(!$this->authInfo->isLoggedIn()) {
|
if(!$this->authInfo->isLoggedIn()) {
|
||||||
$response->redirect(url('auth-login'));
|
$response->redirect(url('auth-login'));
|
||||||
return;
|
return;
|
||||||
|
@ -104,7 +103,7 @@ final class SharpChatRoutes implements IRouteHandler {
|
||||||
return ['ok' => false, 'err' => 'token'];
|
return ['ok' => false, 'err' => 'token'];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$sessionInfo = $this->sessions->getSession(sessionToken: $tokenInfo->getSessionToken());
|
$sessionInfo = $this->authCtx->getSessions()->getSession(sessionToken: $tokenInfo->getSessionToken());
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
return ['ok' => false, 'err' => 'session'];
|
return ['ok' => false, 'err' => 'session'];
|
||||||
}
|
}
|
||||||
|
@ -119,7 +118,7 @@ final class SharpChatRoutes implements IRouteHandler {
|
||||||
? $tokenInfo->getImpersonatedUserId()
|
? $tokenInfo->getImpersonatedUserId()
|
||||||
: $userInfo->getId();
|
: $userInfo->getId();
|
||||||
|
|
||||||
$tokenPacker = ($this->createAuthTokenPacker)();
|
$tokenPacker = $this->authCtx->createAuthTokenPacker();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'ok' => true,
|
'ok' => true,
|
||||||
|
@ -184,7 +183,7 @@ final class SharpChatRoutes implements IRouteHandler {
|
||||||
return ['success' => false, 'reason' => 'hash'];
|
return ['success' => false, 'reason' => 'hash'];
|
||||||
|
|
||||||
if($authMethod === 'SESS' || $authMethod === 'Misuzu') {
|
if($authMethod === 'SESS' || $authMethod === 'Misuzu') {
|
||||||
$tokenPacker = ($this->createAuthTokenPacker)();
|
$tokenPacker = $this->authCtx->createAuthTokenPacker();
|
||||||
$tokenInfo = $tokenPacker->unpack($authToken);
|
$tokenInfo = $tokenPacker->unpack($authToken);
|
||||||
if($tokenInfo->isEmpty()) {
|
if($tokenInfo->isEmpty()) {
|
||||||
// don't support using the raw session key for Misuzu format
|
// don't support using the raw session key for Misuzu format
|
||||||
|
@ -196,17 +195,17 @@ final class SharpChatRoutes implements IRouteHandler {
|
||||||
$sessionToken = $tokenInfo->getSessionToken();
|
$sessionToken = $tokenInfo->getSessionToken();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$sessionInfo = $this->sessions->getSession(sessionToken: $sessionToken);
|
$sessionInfo = $this->authCtx->getSessions()->getSession(sessionToken: $sessionToken);
|
||||||
} catch(RuntimeException $ex) {
|
} catch(RuntimeException $ex) {
|
||||||
return ['success' => false, 'reason' => 'token'];
|
return ['success' => false, 'reason' => 'token'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if($sessionInfo->hasExpired()) {
|
if($sessionInfo->hasExpired()) {
|
||||||
$this->sessions->deleteSessions(sessionInfos: $sessionInfo);
|
$this->authCtx->getSessions()->deleteSessions(sessionInfos: $sessionInfo);
|
||||||
return ['success' => false, 'reason' => 'expired'];
|
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');
|
$userInfo = $this->usersCtx->getUsers()->getUser($sessionInfo->getUserId(), 'id');
|
||||||
if($tokenInfo->hasImpersonatedUserId() && $userInfo->isSuperUser()) {
|
if($tokenInfo->hasImpersonatedUserId() && $userInfo->isSuperUser()) {
|
||||||
|
|
Loading…
Reference in a new issue