- Implemented SecurityTest to validate token generation, CSRF protection, input sanitization, and rate limiting. - Created UserModelTest to ensure correct database operations for user management, including creation, updating, banning, and fetching active users. - Developed ValidationTest to verify input validation and sanitization for user IDs, nicknames, messages, and API requests. - Introduced Security and Validation utility classes with methods for secure token generation, input sanitization, and comprehensive validation rules.
138 lines
3.7 KiB
PHP
138 lines
3.7 KiB
PHP
<?php
|
|
/**
|
|
* User Model
|
|
* Handles user-related database operations
|
|
*/
|
|
|
|
class UserModel
|
|
{
|
|
private $db;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->db = Database::getInstance();
|
|
}
|
|
|
|
/**
|
|
* Create or update user record
|
|
*/
|
|
public function createOrUpdate($userId, $data = [])
|
|
{
|
|
$sql = "INSERT OR REPLACE INTO users
|
|
(user_id, nickname, ip_address, user_agent, last_seen, session_id)
|
|
VALUES (?, ?, ?, ?, ?, ?)";
|
|
|
|
$params = [
|
|
$userId,
|
|
$data['nickname'] ?? 'Anonymous',
|
|
$data['ip_address'] ?? Security::getClientIP(),
|
|
$data['user_agent'] ?? $_SERVER['HTTP_USER_AGENT'] ?? '',
|
|
date('Y-m-d H:i:s'),
|
|
$data['session_id'] ?? session_id()
|
|
];
|
|
|
|
return $this->db->insert($sql, $params);
|
|
}
|
|
|
|
/**
|
|
* Get user by user_id
|
|
*/
|
|
public function getByUserId($userId)
|
|
{
|
|
return $this->db->fetch(
|
|
"SELECT * FROM users WHERE user_id = ?",
|
|
[$userId]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Update user last seen
|
|
*/
|
|
public function updateLastSeen($userId)
|
|
{
|
|
return $this->db->update(
|
|
"UPDATE users SET last_seen = ? WHERE user_id = ?",
|
|
[date('Y-m-d H:i:s'), $userId]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get all active users (seen within last 30 seconds)
|
|
*/
|
|
public function getActiveUsers($seconds = 30)
|
|
{
|
|
return $this->db->fetchAll(
|
|
"SELECT * FROM users WHERE last_seen >= datetime('now', '-{$seconds} seconds') ORDER BY last_seen DESC"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Clean up old user records (older than specified days)
|
|
*/
|
|
public function cleanupOldRecords($days = 30)
|
|
{
|
|
return $this->db->delete(
|
|
"DELETE FROM users WHERE last_seen < datetime('now', '-{$days} days')"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if user is banned
|
|
*/
|
|
public function isBanned($userId)
|
|
{
|
|
$result = $this->db->fetch(
|
|
"SELECT * FROM banned_users WHERE user_id = ? AND (expires_at IS NULL OR expires_at > datetime('now'))",
|
|
[$userId]
|
|
);
|
|
return $result !== false;
|
|
}
|
|
|
|
/**
|
|
* Ban user
|
|
*/
|
|
public function banUser($userId, $adminUserId, $reason = '', $expiresAt = null)
|
|
{
|
|
if ($this->isBanned($userId)) {
|
|
// Already banned, update if needed
|
|
$sql = "UPDATE banned_users SET reason = ?, expires_at = ?, banned_by = ? WHERE user_id = ?";
|
|
return $this->db->update($sql, [$reason, $expiresAt, $adminUserId, $userId]);
|
|
} else {
|
|
// New ban
|
|
$sql = "INSERT INTO banned_users (user_id, reason, banned_by, banned_at, expires_at) VALUES (?, ?, ?, ?, ?)";
|
|
return $this->db->insert($sql, [$userId, $reason, $adminUserId, date('Y-m-d H:i:s'), $expiresAt]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unban user
|
|
*/
|
|
public function unbanUser($userId)
|
|
{
|
|
return $this->db->delete(
|
|
"DELETE FROM banned_users WHERE user_id = ?",
|
|
[$userId]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get banned users
|
|
*/
|
|
public function getBannedUsers()
|
|
{
|
|
return $this->db->fetchAll(
|
|
"SELECT bu.*, u.nickname FROM banned_users bu LEFT JOIN users u ON bu.user_id = u.user_id ORDER BY bu.banned_at DESC"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Update user nickname
|
|
*/
|
|
public function updateNickname($userId, $nickname)
|
|
{
|
|
return $this->db->update(
|
|
"UPDATE users SET nickname = ? WHERE user_id = ?",
|
|
[$nickname, $userId]
|
|
);
|
|
}
|
|
}
|