220 lines
7.1 KiB
PHP
Executable File
220 lines
7.1 KiB
PHP
Executable File
<?php
|
|
|
|
require_once('UserDataSet.php');
|
|
require_once('AuthService.php');
|
|
|
|
/**
|
|
* User class - Handles user authentication and session management
|
|
*
|
|
* This class manages user authentication using JWT tokens and provides
|
|
* methods for logging in, logging out, and checking user permissions.
|
|
* I've implemented this based on JWT authentication
|
|
*/
|
|
class User {
|
|
/**
|
|
* Class properties
|
|
* @var string $_username - The user's username
|
|
* @var bool $_loggedIn - Whether the user is currently logged in
|
|
* @var string $_userId - The user's unique ID
|
|
* @var int $_accessLevel - The user's access level (admin = 1, regular user = 2)
|
|
* @var AuthService $_authService - Service for JWT token handling
|
|
*/
|
|
protected $_username, $_loggedIn, $_userId, $_accessLevel;
|
|
protected $_authService;
|
|
|
|
/**
|
|
* Gets the current user's username
|
|
*
|
|
* @return string The username of the current user
|
|
*/
|
|
public function getUsername() {
|
|
return $this->_username;
|
|
}
|
|
|
|
/**
|
|
* Gets the current user's ID
|
|
*
|
|
* @return string The ID of the current user
|
|
*/
|
|
public function getUserId() {
|
|
return $this->_userId;
|
|
}
|
|
|
|
/**
|
|
* Constructor - Initialises user from JWT token if available
|
|
*
|
|
* Checks for a JWT token in the Authorization header and validates it.
|
|
* If valid, sets user properties based on the token payload.
|
|
* Also starts a session if needed for CAPTCHA verification during registration.
|
|
*/
|
|
public function __construct() {
|
|
// Initialise default values
|
|
$this->_username = "None";
|
|
$this->_loggedIn = false;
|
|
$this->_userId = "0";
|
|
$this->_accessLevel = null;
|
|
$this->_authService = new AuthService();
|
|
|
|
// Check for JWT token in Authorization header
|
|
$headers = getallheaders();
|
|
$token = isset($headers['Authorization']) ? str_replace('Bearer ', '', $headers['Authorization']) : null;
|
|
|
|
// Validate token if it exists
|
|
if ($token) {
|
|
$payload = $this->_authService->validateToken($token);
|
|
if ($payload) {
|
|
$this->_username = $payload['username'];
|
|
$this->_userId = $payload['uid'];
|
|
$this->_accessLevel = $payload['accessLevel'];
|
|
$this->_loggedIn = true;
|
|
}
|
|
}
|
|
|
|
// Start session only if needed for CAPTCHA
|
|
if (session_status() === PHP_SESSION_NONE && isset($_GET['page']) && $_GET['page'] === 'register') {
|
|
session_start();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the user's access level
|
|
*
|
|
* @param int $level The access level to set (admin = 1, regular user = 2)
|
|
* @return void
|
|
*/
|
|
private function setAccessLevel($level) {
|
|
$this->_accessLevel = $level;
|
|
}
|
|
|
|
/**
|
|
* Gets the user's access level
|
|
*
|
|
* @return int|null The user's access level (admin = 1, regular user = 2) or null if not set
|
|
*/
|
|
public function getAccessLevel() {
|
|
return $this->_accessLevel;
|
|
}
|
|
|
|
/**
|
|
* Authenticates a user using username and password
|
|
*
|
|
* Checks credentials against the database and generates a JWT token if valid.
|
|
* Sets user properties if authentication is successful.
|
|
*
|
|
* @param string $username The username to authenticate
|
|
* @param string $password The password to verify
|
|
* @return string|bool JWT token if authentication was successful, false otherwise
|
|
*/
|
|
public function Authenticate($username, $password)
|
|
{
|
|
$users = new UserDataSet();
|
|
$userDataSet = $users->checkUserCredentials($username, $password);
|
|
|
|
if(count($userDataSet) > 0) {
|
|
$userData = $userDataSet[0];
|
|
$accessLevel = $users->checkAccessLevel($username);
|
|
|
|
// Generate JWT token
|
|
$token = $this->_authService->generateToken([
|
|
'id' => $userData->getId(),
|
|
'username' => $userData->getUsername(),
|
|
'userType' => $accessLevel
|
|
]);
|
|
|
|
// Set user properties
|
|
$this->_loggedIn = true;
|
|
$this->_username = $username;
|
|
$this->_userId = $userData->getId();
|
|
$this->_accessLevel = $accessLevel;
|
|
|
|
return $token;
|
|
}
|
|
else {
|
|
$this->_loggedIn = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Logs the user out
|
|
*
|
|
* Resets all user properties to their default values.
|
|
* Note: This doesn't invalidate the JWT token - handled client-side
|
|
* by removing the token from storage.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function logout() {
|
|
// Reset user properties
|
|
$this->_loggedIn = false;
|
|
$this->_username = "None";
|
|
$this->_userId = "0";
|
|
$this->_accessLevel = null;
|
|
}
|
|
|
|
/**
|
|
* Checks if the user is currently logged in
|
|
*
|
|
* @return bool True if the user is logged in, false otherwise
|
|
*/
|
|
public function isLoggedIn(): bool
|
|
{
|
|
return $this->_loggedIn;
|
|
}
|
|
|
|
/**
|
|
* Static method to check if a request is authenticated
|
|
*
|
|
* This method can be called from any controller to check if the request
|
|
* has a valid JWT token. It returns the payload if authenticated or
|
|
* sends an error response and returns false if not.
|
|
*
|
|
* @param bool $required Whether authentication is required (defaults to true)
|
|
* @return array|false The payload if authenticated, false otherwise
|
|
*/
|
|
public static function checkAuth(bool $required = true)
|
|
{
|
|
$authService = new AuthService();
|
|
|
|
// Get the token from the Authorization header
|
|
$headers = getallheaders();
|
|
$token = isset($headers['Authorization']) ? str_replace('Bearer ', '', $headers['Authorization']) : null;
|
|
|
|
// Validate the token
|
|
$payload = $token ? $authService->validateToken($token) : null;
|
|
|
|
// If authentication is required and no valid token, return error
|
|
if ($required && !$payload) {
|
|
header('Content-Type: application/json');
|
|
http_response_code(401);
|
|
echo json_encode(['error' => 'Authentication required']);
|
|
return false;
|
|
}
|
|
|
|
return $payload;
|
|
}
|
|
|
|
/**
|
|
* Static method to check if a request is from an admin
|
|
*
|
|
* This method can be called from any controller to check if the request
|
|
* has a valid JWT token with admin access level. It returns the payload
|
|
* if authenticated as admin or sends an error response and returns false if not.
|
|
*
|
|
* @return array|false The payload if authenticated as admin, false otherwise
|
|
*/
|
|
public static function checkAdmin()
|
|
{
|
|
$payload = self::checkAuth(true);
|
|
|
|
if ($payload && isset($payload['accessLevel']) && $payload['accessLevel'] == 1) {
|
|
return $payload;
|
|
}
|
|
|
|
header('Content-Type: application/json');
|
|
http_response_code(403);
|
|
echo json_encode(['error' => 'Admin access required']);
|
|
return false;
|
|
}
|
|
}
|