diff --git a/.idea/php.xml b/.idea/php.xml index 40e05a1..b5023d4 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -1,5 +1,15 @@ + + + + + + @@ -17,9 +27,15 @@ + + + + \ No newline at end of file diff --git a/app/App.php b/app/App.php index 0e3fb49..f05f3ff 100644 --- a/app/App.php +++ b/app/App.php @@ -21,14 +21,14 @@ class App public static function getTemplate(): Engine { static $templates = new Engine(__DIR__ . '/../templates'); - $me = self::me(); - $isLogin = self::checkU(); + $me = static::me(); + $isLogin = static::checkU(); $templates->addData([ 'me' => $me, 'whoami' => "$me->username#$me->userDiscriminator", 'noStatus' => false, 'isLogin' => $isLogin, - 'isAllowed' => $isLogin && $me !== null && self::isAllowed($me->userId), + 'isAllowed' => $isLogin && $me !== null && static::isAllowed($me->userId), ]); return $templates; } @@ -40,10 +40,10 @@ class App public static function checkU(): bool { - $token = self::getU(); + $token = static::getU(); if ($token === null) return false; if ($token->timestamp + $token->expires_in < time()) return false; - return self::me() !== null; + return static::me() !== null; } public static function setU(Token $token): void @@ -80,7 +80,7 @@ class App public static function requireAuth(): void { - if (!self::checkU()) { + if (!static::checkU()) { header('location: /login.php'); http_response_code(302); exit; @@ -89,7 +89,7 @@ class App public static function requireNonAuth(): void { - if (self::checkU()) { + if (static::checkU()) { header('location: /'); http_response_code(302); exit; @@ -98,10 +98,10 @@ class App public static function requireAllowed(): void { - self::requireAuth(); - $me = self::me(); - if ($me === null || !self::isAllowed($me->userId)) { - self::template([ + static::requireAuth(); + $me = static::me(); + if ($me === null || !static::isAllowed($me->userId)) { + static::template([ 'title' => '您無權限使用本系統', 'body' => << @@ -117,7 +117,7 @@ HTML, { try { $token = Auth::getTokenByCode($code); - if ($token !== null) self::setU($token); + if ($token !== null) static::setU($token); } catch (Exception) { error_log('Failed to getTokenByCode.'); } @@ -126,9 +126,11 @@ HTML, public static function me(): ?Me { try { - $u = self::getU(); + $u = static::getU(); if ($u === null) return null; - return Auth::getMe($u); + $cachedMe = Redis::getCachedMe($_COOKIE['u']); + if ($cachedMe === null) return Redis::cacheMe($_COOKIE['u'], Auth::getMe($u)); + return $cachedMe; } catch (Exception) { error_log('Failed to getMe.'); return null; @@ -139,8 +141,8 @@ HTML, public static function template(array $params): void { $status = ''; - if (self::checkU() && !$params['no_status']) { - $me = self::me(); + if (static::checkU() && !$params['no_status']) { + $me = static::me(); $status = <<您已使用 $me->username#$me->userDiscriminator 登入,點選此處以登出系統。 HTML; @@ -181,13 +183,13 @@ HTML; public static function isAllowed(string $userId): bool { - return in_array($userId, self::allowedUsers); + return in_array($userId, static::allowedUsers); } #[NoReturn] public static function render(string $name, array $data = []): void { - $html = self::getTemplate()->render($name, $data); + $html = static::getTemplate()->render($name, $data); header('Content-Type: text/html; charset=utf-8'); header('Content-Length: ' . strlen($html)); diff --git a/app/Auth.php b/app/Auth.php index e982b89..b0d46d9 100644 --- a/app/Auth.php +++ b/app/Auth.php @@ -42,7 +42,7 @@ class Auth { $query_string = http_build_query([ 'client_id' => $_ENV['DISCORD_CLIENT_ID'], - 'redirect_uri' => self::DISCORD_REDIRECT_URI, + 'redirect_uri' => static::DISCORD_REDIRECT_URI, 'response_type' => 'code', 'scope' => 'identify', ]); @@ -60,7 +60,7 @@ class Auth 'client_secret' => $_ENV['DISCORD_CLIENT_SECRET'], 'grant_type' => 'authorization_code', 'code' => $code, - 'redirect_uri' => self::DISCORD_REDIRECT_URI, + 'redirect_uri' => static::DISCORD_REDIRECT_URI, ]), ], ]))); diff --git a/app/FileViewer.php b/app/FileViewer.php index e90b65b..11ee8f4 100644 --- a/app/FileViewer.php +++ b/app/FileViewer.php @@ -29,7 +29,7 @@ abstract class FileViewer $directory = static::directory(); $filename = "$directory/$file"; - if (!in_array($file, self::list()) || !file_exists($filename) || !is_file($filename)) return null; + if (!in_array($file, static::list()) || !file_exists($filename) || !is_file($filename)) return null; $extension = pathinfo($filename, PATHINFO_EXTENSION); $content = file_get_contents($filename); diff --git a/app/Redis.php b/app/Redis.php new file mode 100644 index 0000000..5981b3c --- /dev/null +++ b/app/Redis.php @@ -0,0 +1,54 @@ +connect('127.0.0.1'); + } + return static::$redis; + } + + protected static function getKey(string $u): string + { + return static::PREFIX . md5($u); + } + + public static function getCachedMe(string $u): ?Me + { + try { + $redis = static::connect(); + return unserialize($redis->get(static::getKey($u))) ?: null; + } catch (\RedisException $e) { + trigger_error($e->getMessage()); + return null; + } + } + + public static function cacheMe(string $u, ?Me $me): ?Me + { + try { + $redis = static::connect(); + $redis->setEx(static::getKey($u), static::TTL, serialize($me)); + return $me; + } catch (\RedisException $e) { + trigger_error($e->getMessage()); + return null; + } + } +} diff --git a/composer.json b/composer.json index 489df28..2426099 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ ], "require": { "ext-iconv": "*", + "ext-redis": "*", "ext-sodium": "*", "ext-zlib": "*", "components/font-awesome": "^6.1", diff --git a/composer.lock b/composer.lock index 4a443b7..47588c1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "528c716c3d44b77191eaef0461fe108d", + "content-hash": "94e36763cae319a07395535f9c2373eb", "packages": [ { "name": "components/font-awesome", @@ -734,6 +734,7 @@ "prefer-lowest": false, "platform": { "ext-iconv": "*", + "ext-redis": "*", "ext-sodium": "*", "ext-zlib": "*" },