Removed RPC stuff for Flashii ID.
This commit is contained in:
parent
8f63b57c0c
commit
584546a8f7
3 changed files with 1 additions and 181 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
20250202.1
|
||||
20250202.2
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
<?php
|
||||
namespace Misuzu\Hanyuu;
|
||||
|
||||
use RuntimeException;
|
||||
use Misuzu\CSRF;
|
||||
use Misuzu\Auth\AuthContext;
|
||||
use Misuzu\Users\{UsersContext,UserInfo};
|
||||
use RPCii\Server\{RpcHandler,RpcHandlerCommon,RpcAction};
|
||||
use Index\Colour\Colour;
|
||||
use Index\Config\Config;
|
||||
use Index\Urls\UrlRegistry;
|
||||
|
||||
final class HanyuuRpcHandler implements RpcHandler {
|
||||
use RpcHandlerCommon;
|
||||
|
||||
/** @param callable(): string $getBaseUrl */
|
||||
public function __construct(
|
||||
private $getBaseUrl,
|
||||
private Config $impersonateConfig,
|
||||
private UrlRegistry $urls,
|
||||
private UsersContext $usersCtx,
|
||||
private AuthContext $authCtx
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param array<string, ?mixed> $attrs
|
||||
* @return array{name: string, attrs: array<string, mixed>}
|
||||
*/
|
||||
private static function createPayload(string $name, array $attrs = []): array {
|
||||
$payload = ['name' => $name, 'attrs' => []];
|
||||
foreach($attrs as $name => $value) {
|
||||
if($value === null)
|
||||
continue;
|
||||
$payload['attrs'][(string)$name] = $value;
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/** @return array{name: string, attrs: array{code: string, text?: string}} */
|
||||
private static function createErrorPayload(string $code, ?string $text = null): array {
|
||||
$attrs = ['code' => $code];
|
||||
if($text !== null && $text !== '')
|
||||
$attrs['text'] = $text;
|
||||
|
||||
return self::createPayload('error', $attrs);
|
||||
}
|
||||
|
||||
private function canImpersonateUserId(UserInfo $impersonator, string $targetId): bool {
|
||||
if($impersonator->super)
|
||||
return true;
|
||||
|
||||
return in_array(
|
||||
$targetId,
|
||||
$this->impersonateConfig->getArray(sprintf('allow.u%s', $impersonator->id)),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/** @return array{name: string, attrs: array<string, mixed>} */
|
||||
#[RpcAction('mszhau:authCheck')]
|
||||
public function procAuthCheck(string $method, string $remoteAddr, string $token, string $avatars = ''): array {
|
||||
if($method !== 'Misuzu')
|
||||
return self::createErrorPayload('auth:check:method', 'Requested auth method is not supported.');
|
||||
|
||||
if(filter_var($remoteAddr, FILTER_VALIDATE_IP) === false)
|
||||
return self::createErrorPayload('auth:check:remote_addr', 'Provided remote address is not in a valid format.');
|
||||
|
||||
$avatarResolutions = trim($avatars);
|
||||
if($avatarResolutions === '') {
|
||||
$avatarResolutions = [];
|
||||
} else {
|
||||
$avatarResolutions = explode(',', $avatarResolutions);
|
||||
foreach($avatarResolutions as $key => $avatarRes) {
|
||||
if(!ctype_digit($avatarRes))
|
||||
return self::createErrorPayload('auth:check:avatars', 'Avatar resolution set must be a comma separated set of numbers or empty.');
|
||||
$avatarResolutions[$key] = (int)$avatarRes;
|
||||
}
|
||||
$avatarResolutions = array_unique($avatarResolutions);
|
||||
}
|
||||
|
||||
$baseUrl = ($this->getBaseUrl)();
|
||||
$loginUrl = $baseUrl . $this->urls->format('auth-login');
|
||||
$registerUrl = $baseUrl . $this->urls->format('auth-register');
|
||||
|
||||
$tokenPacker = $this->authCtx->createAuthTokenPacker();
|
||||
$tokenInfo = $tokenPacker->unpack(trim($token));
|
||||
if($tokenInfo->isEmpty)
|
||||
return self::createPayload('auth:check:fail', ['reason' => 'empty', 'login_url' => $loginUrl, 'register_url' => $registerUrl]);
|
||||
|
||||
try {
|
||||
$sessionInfo = $this->authCtx->sessions->getSession(sessionToken: $tokenInfo->sessionToken);
|
||||
} catch(RuntimeException $ex) {
|
||||
return self::createPayload('auth:check:fail', ['reason' => 'session', 'login_url' => $loginUrl, 'register_url' => $registerUrl]);
|
||||
}
|
||||
|
||||
if($sessionInfo->expired) {
|
||||
$this->authCtx->sessions->deleteSessions(sessionInfos: $sessionInfo);
|
||||
return self::createPayload('auth:check:fail', ['reason' => 'expired', 'login_url' => $loginUrl, 'register_url' => $registerUrl]);
|
||||
}
|
||||
|
||||
$this->authCtx->sessions->recordSessionActivity(sessionInfo: $sessionInfo, remoteAddr: $remoteAddr);
|
||||
|
||||
$userInfo = $userInfoReal = $this->usersCtx->users->getUser($sessionInfo->userId, 'id');
|
||||
if($tokenInfo->hasImpersonatedUserId && $this->canImpersonateUserId($userInfo, $tokenInfo->impersonatedUserId)) {
|
||||
try {
|
||||
$userInfo = $this->usersCtx->users->getUser($tokenInfo->impersonatedUserId, 'id');
|
||||
} catch(RuntimeException $ex) {
|
||||
$userInfo = $userInfoReal;
|
||||
}
|
||||
}
|
||||
|
||||
$response = [];
|
||||
$response['session'] = [
|
||||
'token' => $sessionInfo->token,
|
||||
'created_at' => $sessionInfo->createdTime,
|
||||
'expires_at' => $sessionInfo->expiresTime,
|
||||
'lifetime_extends' => $sessionInfo->shouldBumpExpires,
|
||||
];
|
||||
|
||||
$banInfo = $this->usersCtx->tryGetActiveBan($userInfo);
|
||||
if($banInfo !== null)
|
||||
$response['ban'] = [
|
||||
'severity' => $banInfo->severity,
|
||||
'reason' => $banInfo->publicReason,
|
||||
'created_at' => $banInfo->createdTime,
|
||||
'is_permanent' => $banInfo->permanent,
|
||||
'expires_at' => $banInfo->expiresTime,
|
||||
'duration_str' => $banInfo->durationString,
|
||||
'remaining_str' => $banInfo->remainingString,
|
||||
];
|
||||
|
||||
$gatherRequestedAvatars = function($userInfo) use ($avatarResolutions, $baseUrl) {
|
||||
$formatAvatarUrl = fn($res = 0) => (
|
||||
$baseUrl . $this->urls->format('user-avatar', ['user' => $userInfo->id, 'res' => $res])
|
||||
);
|
||||
|
||||
$avatars = ['original' => $formatAvatarUrl()];
|
||||
|
||||
foreach($avatarResolutions as $avatarRes)
|
||||
$avatars[sprintf('x%d', $avatarRes)] = $formatAvatarUrl($avatarRes);
|
||||
|
||||
return $avatars;
|
||||
};
|
||||
|
||||
$extractUserInfo = fn($userInfo) => [
|
||||
'id' => $userInfo->id,
|
||||
'name' => $userInfo->name,
|
||||
'colour' => (string)$this->usersCtx->users->getUserColour($userInfo),
|
||||
'rank' => $this->usersCtx->users->getUserRank($userInfo),
|
||||
'is_super' => $userInfo->super,
|
||||
'country_code' => $userInfo->countryCode,
|
||||
'is_deleted' => $userInfo->deleted,
|
||||
'has_totp' => $userInfo->hasTOTP,
|
||||
'profile_url' => $baseUrl . $this->urls->format('user-profile', ['user' => $userInfo->id]),
|
||||
'avatars' => $gatherRequestedAvatars($userInfo),
|
||||
];
|
||||
|
||||
$response['user'] = $extractUserInfo($userInfo);
|
||||
if($userInfo !== $userInfoReal) {
|
||||
$response['guise'] = $extractUserInfo($userInfoReal);
|
||||
|
||||
$csrf = CSRF::create($sessionInfo->token);
|
||||
$response['guise']['revert_url'] = $baseUrl . $this->urls->format('auth-revert', ['csrf' => $csrf->createToken()]);
|
||||
}
|
||||
|
||||
return self::createPayload('auth:check:success', $response);
|
||||
}
|
||||
}
|
|
@ -233,17 +233,6 @@ class MisuzuContext {
|
|||
));
|
||||
$rpcServer->register($this->deps->constructLazy(Emoticons\EmotesRpcHandler::class));
|
||||
$rpcServer->register($this->deps->constructLazy(Users\UsersRpcHandler::class));
|
||||
|
||||
$hanyuuRpcServer = new HttpRpcServer;
|
||||
$routingCtx->scopeTo('', '/_hanyuu')->register($hanyuuRpcServer->createRouteHandler(
|
||||
new HmacVerificationProvider(fn() => $this->config->getString('hanyuu.secret'))
|
||||
));
|
||||
|
||||
$hanyuuRpcServer->register($this->deps->constructLazy(
|
||||
Hanyuu\HanyuuRpcHandler::class,
|
||||
getBaseUrl: fn() => $this->config->getString('hanyuu.endpoint'),
|
||||
impersonateConfig: $this->config->scopeTo('impersonate')
|
||||
));
|
||||
}
|
||||
|
||||
public function registerRedirectorRoutes(RoutingContext $routingCtx): void {
|
||||
|
|
Loading…
Reference in a new issue