Removed leftovers from chat token system.
This commit is contained in:
parent
4a3a28629b
commit
fb77a936f5
5 changed files with 28 additions and 121 deletions
26
database/2022_01_13_005600_nuke_chat_tokens_table.php
Normal file
26
database/2022_01_13_005600_nuke_chat_tokens_table.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\DatabaseMigrations\NukeChatTokensTable;
|
||||||
|
|
||||||
|
use PDO;
|
||||||
|
|
||||||
|
function migrate_up(PDO $conn): void {
|
||||||
|
$conn->exec("DROP TABLE `msz_user_chat_tokens`");
|
||||||
|
}
|
||||||
|
|
||||||
|
function migrate_down(PDO $conn): void {
|
||||||
|
$conn->exec("
|
||||||
|
CREATE TABLE `msz_user_chat_tokens` (
|
||||||
|
`user_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`token_string` CHAR(64) NOT NULL,
|
||||||
|
`token_created` TIMESTAMP NOT NULL DEFAULT current_timestamp(),
|
||||||
|
UNIQUE INDEX `user_chat_token_string_unique` (`token_string`),
|
||||||
|
INDEX `user_chat_token_user_foreign` (`user_id`),
|
||||||
|
INDEX `user_chat_token_created_key` (`token_created`),
|
||||||
|
CONSTRAINT `user_chat_token_user_foreign`
|
||||||
|
FOREIGN KEY (`user_id`)
|
||||||
|
REFERENCES `msz_users` (`user_id`)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE
|
||||||
|
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
|
||||||
|
");
|
||||||
|
}
|
|
@ -63,7 +63,6 @@ if(isset($_POST['action']) && is_string($_POST['action'])) {
|
||||||
db_to_zip($archive, $currentUserId, 'sessions.json', 'SELECT *, INET6_NTOA(`session_ip`) AS `session_ip`, INET6_NTOA(`session_ip_last`) AS `session_ip_last` FROM `msz_sessions` WHERE `user_id` = :user_id');
|
db_to_zip($archive, $currentUserId, 'sessions.json', 'SELECT *, INET6_NTOA(`session_ip`) AS `session_ip`, INET6_NTOA(`session_ip_last`) AS `session_ip_last` FROM `msz_sessions` WHERE `user_id` = :user_id');
|
||||||
db_to_zip($archive, $currentUserId, 'users.json', 'SELECT *, NULL AS `password`, NULL AS `user_totp_key`, INET6_NTOA(`register_ip`) AS `register_ip`, INET6_NTOA(`last_ip`) AS `last_ip` FROM `msz_users` WHERE `user_id` = :user_id');
|
db_to_zip($archive, $currentUserId, 'users.json', 'SELECT *, NULL AS `password`, NULL AS `user_totp_key`, INET6_NTOA(`register_ip`) AS `register_ip`, INET6_NTOA(`last_ip`) AS `last_ip` FROM `msz_users` WHERE `user_id` = :user_id');
|
||||||
db_to_zip($archive, $currentUserId, 'users_password_resets.json', 'SELECT *, INET6_NTOA(`reset_ip`) AS `reset_ip` FROM `msz_users_password_resets` WHERE `user_id` = :user_id');
|
db_to_zip($archive, $currentUserId, 'users_password_resets.json', 'SELECT *, INET6_NTOA(`reset_ip`) AS `reset_ip` FROM `msz_users_password_resets` WHERE `user_id` = :user_id');
|
||||||
db_to_zip($archive, $currentUserId, 'user_chat_tokens.json', 'SELECT * FROM `msz_user_chat_tokens` WHERE `user_id` = :user_id');
|
|
||||||
db_to_zip($archive, $currentUserId, 'user_roles.json', 'SELECT * FROM `msz_user_roles` WHERE `user_id` = :user_id');
|
db_to_zip($archive, $currentUserId, 'user_roles.json', 'SELECT * FROM `msz_user_roles` WHERE `user_id` = :user_id');
|
||||||
db_to_zip($archive, $currentUserId, 'user_warnings.json', 'SELECT *, INET6_NTOA(`user_ip`) AS `user_ip`, NULL AS `issuer_id`, NULL AS `issuer_ip`, NULL AS `warning_note_private` FROM `msz_user_warnings` WHERE `user_id` = :user_id');
|
db_to_zip($archive, $currentUserId, 'user_warnings.json', 'SELECT *, INET6_NTOA(`user_ip`) AS `user_ip`, NULL AS `issuer_id`, NULL AS `issuer_ip`, NULL AS `warning_note_private` FROM `msz_user_warnings` WHERE `user_id` = :user_id');
|
||||||
|
|
||||||
|
|
|
@ -100,14 +100,6 @@ class CronCommand implements CommandInterface {
|
||||||
WHERE `reset_requested` < NOW() - INTERVAL 1 WEEK
|
WHERE `reset_requested` < NOW() - INTERVAL 1 WEEK
|
||||||
",
|
",
|
||||||
],
|
],
|
||||||
[
|
|
||||||
'name' => 'Remove old chat login tokens.',
|
|
||||||
'type' => 'sql',
|
|
||||||
'command' => "
|
|
||||||
DELETE FROM `msz_user_chat_tokens`
|
|
||||||
WHERE `token_created` < NOW() - INTERVAL 1 WEEK
|
|
||||||
",
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
'name' => 'Clean up login history.',
|
'name' => 'Clean up login history.',
|
||||||
'type' => 'sql',
|
'type' => 'sql',
|
||||||
|
|
|
@ -11,9 +11,6 @@ use Misuzu\Emoticon;
|
||||||
use Misuzu\Stream;
|
use Misuzu\Stream;
|
||||||
use Misuzu\Users\User;
|
use Misuzu\Users\User;
|
||||||
use Misuzu\Users\UserNotFoundException;
|
use Misuzu\Users\UserNotFoundException;
|
||||||
use Misuzu\Users\UserChatToken;
|
|
||||||
use Misuzu\Users\UserChatTokenNotFoundException;
|
|
||||||
use Misuzu\Users\UserChatTokenCreationFailedException;
|
|
||||||
use Misuzu\Users\UserSession;
|
use Misuzu\Users\UserSession;
|
||||||
use Misuzu\Users\UserSessionNotFoundException;
|
use Misuzu\Users\UserSessionNotFoundException;
|
||||||
use Misuzu\Users\UserWarning;
|
use Misuzu\Users\UserWarning;
|
||||||
|
@ -325,13 +322,7 @@ final class SockChatHandler extends Handler {
|
||||||
|
|
||||||
$authMethod = mb_substr($authInfo->token, 0, 5);
|
$authMethod = mb_substr($authInfo->token, 0, 5);
|
||||||
|
|
||||||
if($authMethod === 'PASS:') {
|
if($authMethod === 'SESS:') {
|
||||||
//if(time() > 1577750400)
|
|
||||||
return ['success' => false, 'reason' => 'unsupported'];
|
|
||||||
|
|
||||||
//if(user_password_verify_db($authInfo->user_id, mb_substr($authInfo->token, 5)))
|
|
||||||
// $userId = $authInfo->user_id;
|
|
||||||
} elseif($authMethod === 'SESS:') {
|
|
||||||
$sessionToken = mb_substr($authInfo->token, 5);
|
$sessionToken = mb_substr($authInfo->token, 5);
|
||||||
|
|
||||||
$authToken = AuthToken::unpack($sessionToken);
|
$authToken = AuthToken::unpack($sessionToken);
|
||||||
|
@ -354,16 +345,7 @@ final class SockChatHandler extends Handler {
|
||||||
|
|
||||||
$sessionInfo->bump();
|
$sessionInfo->bump();
|
||||||
} else {
|
} else {
|
||||||
try {
|
return ['success' => false, 'reason' => 'unsupported'];
|
||||||
$token = UserChatToken::byExact($userInfo, $authInfo->token);
|
|
||||||
} catch(UserChatTokenNotFoundException $ex) {
|
|
||||||
return ['success' => false, 'reason' => 'token'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if($token->hasExpired()) {
|
|
||||||
$token->delete();
|
|
||||||
return ['success' => false, 'reason' => 'expired'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$userInfo->bumpActivity($authInfo->ip);
|
$userInfo->bumpActivity($authInfo->ip);
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Misuzu\Users;
|
|
||||||
|
|
||||||
use Misuzu\DB;
|
|
||||||
|
|
||||||
class UserChatTokenException extends UsersException {}
|
|
||||||
class UserChatTokenNotFoundException extends UserChatTokenException {}
|
|
||||||
class UserChatTokenCreationFailedException extends UserChatTokenException {}
|
|
||||||
|
|
||||||
class UserChatToken {
|
|
||||||
// Database fields
|
|
||||||
private $user_id = -1;
|
|
||||||
private $token_string = '';
|
|
||||||
private $token_created = null;
|
|
||||||
|
|
||||||
private $user = null;
|
|
||||||
|
|
||||||
public const TOKEN_WIDTH = 32;
|
|
||||||
public const TOKEN_LIFETIME = 60 * 60 * 24 * 7;
|
|
||||||
|
|
||||||
public const TABLE = 'user_chat_tokens';
|
|
||||||
private const QUERY_SELECT = 'SELECT %1$s FROM `' . DB::PREFIX . self::TABLE . '` AS '. self::TABLE;
|
|
||||||
private const SELECT = '%1$s.`user_id`, %1$s.`token_string`'
|
|
||||||
. ', UNIX_TIMESTAMP(%1$s.`token_created`) AS `token_created`';
|
|
||||||
|
|
||||||
public function getUserId(): int {
|
|
||||||
return $this->user_id < 1 ? -1 : $this->user_id;
|
|
||||||
}
|
|
||||||
public function getUser(): User {
|
|
||||||
if($this->user === null)
|
|
||||||
$this->user = User::byId($this->getUserId());
|
|
||||||
return $this->user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getToken(): string {
|
|
||||||
return $this->token_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCreatedTime(): int {
|
|
||||||
return $this->token_created === null ? -1 : $this->token_created;
|
|
||||||
}
|
|
||||||
public function getExpirationTime(): int {
|
|
||||||
return $this->getCreatedTime() + self::TOKEN_LIFETIME;
|
|
||||||
}
|
|
||||||
public function hasExpired(): bool {
|
|
||||||
return $this->getExpirationTime() <= time();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete(): void {
|
|
||||||
DB::prepare('
|
|
||||||
DELETE FROM `msz_user_chat_tokens`
|
|
||||||
WHERE `user_id` = :user,
|
|
||||||
AND `token_string` = :token
|
|
||||||
')->bind('user', $this->getUserId())
|
|
||||||
->bind('token', $this->getToken())
|
|
||||||
->execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function generateToken(): string {
|
|
||||||
return bin2hex(random_bytes(self::TOKEN_WIDTH));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function create(User $user): self {
|
|
||||||
$token = self::generateToken();
|
|
||||||
$create = DB::prepare('
|
|
||||||
INSERT INTO `msz_user_chat_tokens` (`user_id`, `token_string`)
|
|
||||||
VALUES (:user, :token)
|
|
||||||
') ->bind('user', $user->getId())
|
|
||||||
->bind('token', $token)
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
if(!$create)
|
|
||||||
throw new UserChatTokenCreationFailedException;
|
|
||||||
|
|
||||||
return self::byExact($user, $token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function byQueryBase(): string {
|
|
||||||
return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE));
|
|
||||||
}
|
|
||||||
public static function byExact(User $user, string $token): self {
|
|
||||||
$tokenInfo = DB::prepare(self::byQueryBase() . ' WHERE `user_id` = :user AND `token_string` = :token')
|
|
||||||
->bind('user', $user->getId())
|
|
||||||
->bind('token', $token)
|
|
||||||
->fetchObject(self::class);
|
|
||||||
|
|
||||||
if(!$tokenInfo)
|
|
||||||
throw new UserChatTokenNotFoundException;
|
|
||||||
|
|
||||||
return $tokenInfo;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue