Added server side stuff for Satori hooks.
This commit is contained in:
parent
e813f2a90e
commit
57081d858d
3 changed files with 172 additions and 2 deletions
|
@ -5,7 +5,6 @@ use InvalidArgumentException;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Index\ByteFormat;
|
use Index\ByteFormat;
|
||||||
use Misuzu\Parsers\Parser;
|
use Misuzu\Parsers\Parser;
|
||||||
use Misuzu\Profile\ProfileFields;
|
|
||||||
use Misuzu\Users\User;
|
use Misuzu\Users\User;
|
||||||
use Misuzu\Users\Assets\UserBackgroundAsset;
|
use Misuzu\Users\Assets\UserBackgroundAsset;
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ $notices = [];
|
||||||
|
|
||||||
$activeBanInfo = $msz->tryGetActiveBan($profileUser);
|
$activeBanInfo = $msz->tryGetActiveBan($profileUser);
|
||||||
$isBanned = $activeBanInfo !== null;
|
$isBanned = $activeBanInfo !== null;
|
||||||
$profileFields = new ProfileFields($db);
|
$profileFields = $msz->getProfileFields();
|
||||||
$viewingOwnProfile = $currentUserId === $profileUser->getId();
|
$viewingOwnProfile = $currentUserId === $profileUser->getId();
|
||||||
$userPerms = perms_get_user($currentUserId)[MSZ_PERMS_USER];
|
$userPerms = perms_get_user($currentUserId)[MSZ_PERMS_USER];
|
||||||
$canManageWarnings = perms_check($userPerms, MSZ_PERM_USER_MANAGE_WARNINGS);
|
$canManageWarnings = perms_check($userPerms, MSZ_PERM_USER_MANAGE_WARNINGS);
|
||||||
|
|
|
@ -13,6 +13,8 @@ use Misuzu\Config\IConfig;
|
||||||
use Misuzu\Counters\Counters;
|
use Misuzu\Counters\Counters;
|
||||||
use Misuzu\Emoticons\Emotes;
|
use Misuzu\Emoticons\Emotes;
|
||||||
use Misuzu\News\News;
|
use Misuzu\News\News;
|
||||||
|
use Misuzu\Profile\ProfileFields;
|
||||||
|
use Misuzu\Satori\SatoriRoutes;
|
||||||
use Misuzu\SharpChat\SharpChatRoutes;
|
use Misuzu\SharpChat\SharpChatRoutes;
|
||||||
use Misuzu\Users\Bans;
|
use Misuzu\Users\Bans;
|
||||||
use Misuzu\Users\BanInfo;
|
use Misuzu\Users\BanInfo;
|
||||||
|
@ -54,6 +56,7 @@ class MisuzuContext {
|
||||||
private Users $users;
|
private Users $users;
|
||||||
private Sessions $sessions;
|
private Sessions $sessions;
|
||||||
private Counters $counters;
|
private Counters $counters;
|
||||||
|
private ProfileFields $profileFields;
|
||||||
|
|
||||||
public function __construct(IDbConnection $dbConn, IConfig $config) {
|
public function __construct(IDbConnection $dbConn, IConfig $config) {
|
||||||
$this->dbConn = $dbConn;
|
$this->dbConn = $dbConn;
|
||||||
|
@ -73,6 +76,7 @@ class MisuzuContext {
|
||||||
$this->users = new Users($this->dbConn);
|
$this->users = new Users($this->dbConn);
|
||||||
$this->sessions = new Sessions($this->dbConn);
|
$this->sessions = new Sessions($this->dbConn);
|
||||||
$this->counters = new Counters($this->dbConn);
|
$this->counters = new Counters($this->dbConn);
|
||||||
|
$this->profileFields = new ProfileFields($this->dbConn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDbConn(): IDbConnection {
|
public function getDbConn(): IDbConnection {
|
||||||
|
@ -160,6 +164,10 @@ class MisuzuContext {
|
||||||
return $this->counters;
|
return $this->counters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getProfileFields(): ProfileFields {
|
||||||
|
return $this->profileFields;
|
||||||
|
}
|
||||||
|
|
||||||
private array $activeBansCache = [];
|
private array $activeBansCache = [];
|
||||||
|
|
||||||
public function tryGetActiveBan(User|string|null $userInfo = null): ?BanInfo {
|
public function tryGetActiveBan(User|string|null $userInfo = null): ?BanInfo {
|
||||||
|
@ -256,6 +264,7 @@ class MisuzuContext {
|
||||||
$this->router->post('/forum/mark-as-read', $mszCompatHandler('Forum', 'markAsReadPOST'));
|
$this->router->post('/forum/mark-as-read', $mszCompatHandler('Forum', 'markAsReadPOST'));
|
||||||
|
|
||||||
new SharpChatRoutes($this->router, $this->config->scopeTo('sockChat'), $this->bans, $this->emotes, $this->sessions);
|
new SharpChatRoutes($this->router, $this->config->scopeTo('sockChat'), $this->bans, $this->emotes, $this->sessions);
|
||||||
|
new SatoriRoutes($this->dbConn, $this->config->scopeTo('satori'), $this->router, $this->profileFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registerLegacyRedirects(): void {
|
private function registerLegacyRedirects(): void {
|
||||||
|
|
162
src/Satori/SatoriRoutes.php
Normal file
162
src/Satori/SatoriRoutes.php
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Satori;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use Index\Data\DbTools;
|
||||||
|
use Index\Data\IDbConnection;
|
||||||
|
use Index\Http\HttpFx;
|
||||||
|
use Index\Routing\IRouter;
|
||||||
|
use Misuzu\Config\IConfig;
|
||||||
|
use Misuzu\Profile\ProfileFields;
|
||||||
|
|
||||||
|
final class SatoriRoutes {
|
||||||
|
private IDbConnection $dbConn;
|
||||||
|
private IConfig $config;
|
||||||
|
private ProfileFields $profileFields;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
IDbConnection $dbConn,
|
||||||
|
IConfig $config,
|
||||||
|
IRouter $router,
|
||||||
|
ProfileFields $profileFields
|
||||||
|
) {
|
||||||
|
$this->dbConn = $dbConn;
|
||||||
|
$this->config = $config;
|
||||||
|
$this->profileFields = $profileFields;
|
||||||
|
|
||||||
|
// Simplify default error pages
|
||||||
|
if($router instanceof HttpFx)
|
||||||
|
$router->use('/_satori', function() use($router) {
|
||||||
|
$router->addErrorHandler(400, function($response) {
|
||||||
|
$response->setContent('HTTP 400');
|
||||||
|
});
|
||||||
|
$router->addErrorHandler(403, function($response) {
|
||||||
|
$response->setContent('HTTP 403');
|
||||||
|
});
|
||||||
|
$router->addErrorHandler(404, function($response) {
|
||||||
|
$response->setContent('HTTP 404');
|
||||||
|
});
|
||||||
|
$router->addErrorHandler(500, function($response) {
|
||||||
|
$response->setContent('HTTP 500');
|
||||||
|
});
|
||||||
|
$router->addErrorHandler(503, function($response) {
|
||||||
|
$response->setContent('HTTP 503');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$router->use('/_satori', [$this, 'verifyRequest']);
|
||||||
|
$router->get('/_satori/get-profile-field', [$this, 'getProfileField']);
|
||||||
|
$router->get('/_satori/get-recent-forum-posts', [$this, 'getRecentForumPosts']);
|
||||||
|
$router->get('/_satori/get-recent-registrations', [$this, 'getRecentRegistrations']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyRequest($response, $request) {
|
||||||
|
$secretKey = $this->config->getString('secret');
|
||||||
|
|
||||||
|
if(!empty($secretKey)) {
|
||||||
|
$userTime = (int)$request->getHeaderLine('X-Satori-Time');
|
||||||
|
$userHash = base64_decode((string)$request->getHeaderLine('X-Satori-Hash'));
|
||||||
|
|
||||||
|
$currentTime = time();
|
||||||
|
if(empty($userHash) || $userTime < $currentTime - 60 || $userTime > $currentTime + 60)
|
||||||
|
return 403;
|
||||||
|
|
||||||
|
$verifyText = (string)$userTime . '#' . $request->getPath() . '?' . $request->getParamString();
|
||||||
|
$verifyHash = hash_hmac('sha256', $verifyText, $secretKey, true);
|
||||||
|
|
||||||
|
if(!hash_equals($verifyHash, $userHash))
|
||||||
|
return 403;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProfileField($response, $request): array {
|
||||||
|
$userId = (string)$request->getParam('user', FILTER_SANITIZE_NUMBER_INT);
|
||||||
|
$fieldId = (string)$request->getParam('field', FILTER_SANITIZE_NUMBER_INT);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$fieldValue = $this->profileFields->getFieldValue($fieldId, $userId);
|
||||||
|
} catch(RuntimeException $ex) {
|
||||||
|
return ['error' => 105];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'field_value' => $fieldValue->getValue(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRecentForumPosts($response, $request): array {
|
||||||
|
$categoryIds = $this->config->getArray('forum.categories');
|
||||||
|
if(empty($categoryIds))
|
||||||
|
return [];
|
||||||
|
|
||||||
|
$batchSize = $this->config->getInteger('forum.batch', 6);
|
||||||
|
$backlogDays = $this->config->getInteger('forum.backlog', 7);
|
||||||
|
$startId = (string)$request->getParam('start', FILTER_SANITIZE_NUMBER_INT);
|
||||||
|
|
||||||
|
$args = 0;
|
||||||
|
$stmt = $this->dbConn->prepare(sprintf(
|
||||||
|
'SELECT fp.post_id, ft.topic_id, ft.topic_title, fc.forum_id, fc.forum_name, u.user_id, u.username,'
|
||||||
|
. ' COALESCE(u.user_colour, r.role_colour), (SELECT MIN(post_id) = fp.post_id FROM msz_forum_posts WHERE topic_id = fp.topic_id)'
|
||||||
|
. ' FROM msz_forum_posts AS fp'
|
||||||
|
. ' LEFT JOIN msz_users AS u ON u.user_id = fp.user_id'
|
||||||
|
. ' LEFT JOIN msz_roles AS r ON r.role_id = u.display_role'
|
||||||
|
. ' LEFT JOIN msz_forum_topics AS ft ON ft.topic_id = fp.topic_id'
|
||||||
|
. ' LEFT JOIN msz_forum_categories AS fc ON fc.forum_id = fp.forum_id'
|
||||||
|
. ' WHERE post_id > ? AND post_deleted IS NULL AND post_created >= NOW() - INTERVAL ? DAY'
|
||||||
|
. ' AND fp.forum_id IN (%s)'
|
||||||
|
. ' ORDER BY post_id LIMIT ?',
|
||||||
|
DbTools::prepareListString($categoryIds)
|
||||||
|
));
|
||||||
|
$stmt->addParameter(++$args, $startId);
|
||||||
|
$stmt->addParameter(++$args, $backlogDays);
|
||||||
|
foreach($categoryIds as $categoryId)
|
||||||
|
$stmt->addParameter(++$args, $categoryId);
|
||||||
|
$stmt->addParameter(++$args, $batchSize);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
$posts = [];
|
||||||
|
$result = $stmt->getResult();
|
||||||
|
|
||||||
|
while($result->next())
|
||||||
|
$posts[] = [
|
||||||
|
'post_id' => $result->getInteger(0),
|
||||||
|
'topic_id' => $result->getInteger(1),
|
||||||
|
'topic_title' => $result->getString(2),
|
||||||
|
'forum_id' => $result->getInteger(3),
|
||||||
|
'forum_name' => $result->getString(4),
|
||||||
|
'user_id' => $result->getInteger(5),
|
||||||
|
'username' => $result->getString(6),
|
||||||
|
'user_colour' => $result->getInteger(7),
|
||||||
|
'is_opening_post' => $result->getInteger(8),
|
||||||
|
];
|
||||||
|
|
||||||
|
return $posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRecentRegistrations($response, $request) {
|
||||||
|
$batchSize = $this->config->getInteger('users.batch', 10);
|
||||||
|
$backlogDays = $this->config->getInteger('users.backlog', 7);
|
||||||
|
$startId = (string)$request->getParam('start', FILTER_SANITIZE_NUMBER_INT);
|
||||||
|
|
||||||
|
$stmt = $this->dbConn->prepare(
|
||||||
|
'SELECT user_id, username FROM msz_users'
|
||||||
|
. ' WHERE user_id > ? AND user_created >= NOW() - INTERVAL ? DAY'
|
||||||
|
. ' ORDER BY user_id LIMIT ?'
|
||||||
|
);
|
||||||
|
$stmt->addParameter(1, $startId);
|
||||||
|
$stmt->addParameter(2, $backlogDays);
|
||||||
|
$stmt->addParameter(3, $batchSize);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
$users = [];
|
||||||
|
$result = $stmt->getResult();
|
||||||
|
|
||||||
|
while($result->next())
|
||||||
|
$users[] = [
|
||||||
|
'user_id' => $result->getInteger(0),
|
||||||
|
'username' => $result->getString(1),
|
||||||
|
];
|
||||||
|
|
||||||
|
return $users;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue