SSO Update :)
This commit is contained in:
229
models/ApiKeyModel.php
Normal file
229
models/ApiKeyModel.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
/**
|
||||
* ApiKeyModel - Handles API key generation and validation
|
||||
*/
|
||||
class ApiKeyModel {
|
||||
private $conn;
|
||||
|
||||
public function __construct($conn) {
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new API key
|
||||
*
|
||||
* @param string $keyName Descriptive name for the key
|
||||
* @param int $createdBy User ID who created the key
|
||||
* @param int|null $expiresInDays Number of days until expiration (null for no expiration)
|
||||
* @return array Array with 'success', 'api_key' (plaintext), 'key_prefix', 'error'
|
||||
*/
|
||||
public function createKey($keyName, $createdBy, $expiresInDays = null) {
|
||||
// Generate random API key (32 bytes = 64 hex characters)
|
||||
$apiKey = bin2hex(random_bytes(32));
|
||||
|
||||
// Create key prefix (first 8 characters) for identification
|
||||
$keyPrefix = substr($apiKey, 0, 8);
|
||||
|
||||
// Hash the API key for storage
|
||||
$keyHash = hash('sha256', $apiKey);
|
||||
|
||||
// Calculate expiration date if specified
|
||||
$expiresAt = null;
|
||||
if ($expiresInDays !== null) {
|
||||
$expiresAt = date('Y-m-d H:i:s', strtotime("+$expiresInDays days"));
|
||||
}
|
||||
|
||||
// Insert API key into database
|
||||
$stmt = $this->conn->prepare(
|
||||
"INSERT INTO api_keys (key_name, key_hash, key_prefix, created_by, expires_at) VALUES (?, ?, ?, ?, ?)"
|
||||
);
|
||||
$stmt->bind_param("sssis", $keyName, $keyHash, $keyPrefix, $createdBy, $expiresAt);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$keyId = $this->conn->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'api_key' => $apiKey, // Return plaintext key ONCE
|
||||
'key_prefix' => $keyPrefix,
|
||||
'key_id' => $keyId,
|
||||
'expires_at' => $expiresAt
|
||||
];
|
||||
} else {
|
||||
$error = $this->conn->error;
|
||||
$stmt->close();
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $error
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an API key
|
||||
*
|
||||
* @param string $apiKey Plaintext API key to validate
|
||||
* @return array|null API key record if valid, null if invalid
|
||||
*/
|
||||
public function validateKey($apiKey) {
|
||||
if (empty($apiKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Hash the provided key
|
||||
$keyHash = hash('sha256', $apiKey);
|
||||
|
||||
// Query for matching key
|
||||
$stmt = $this->conn->prepare(
|
||||
"SELECT * FROM api_keys WHERE key_hash = ? AND is_active = 1"
|
||||
);
|
||||
$stmt->bind_param("s", $keyHash);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows === 0) {
|
||||
$stmt->close();
|
||||
return null;
|
||||
}
|
||||
|
||||
$keyData = $result->fetch_assoc();
|
||||
$stmt->close();
|
||||
|
||||
// Check expiration
|
||||
if ($keyData['expires_at'] !== null) {
|
||||
$expiresAt = strtotime($keyData['expires_at']);
|
||||
if ($expiresAt < time()) {
|
||||
return null; // Key has expired
|
||||
}
|
||||
}
|
||||
|
||||
// Update last_used timestamp
|
||||
$this->updateLastUsed($keyData['api_key_id']);
|
||||
|
||||
return $keyData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update last_used timestamp for an API key
|
||||
*
|
||||
* @param int $keyId API key ID
|
||||
* @return bool Success status
|
||||
*/
|
||||
private function updateLastUsed($keyId) {
|
||||
$stmt = $this->conn->prepare("UPDATE api_keys SET last_used = NOW() WHERE api_key_id = ?");
|
||||
$stmt->bind_param("i", $keyId);
|
||||
$success = $stmt->execute();
|
||||
$stmt->close();
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke an API key (set is_active to false)
|
||||
*
|
||||
* @param int $keyId API key ID
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function revokeKey($keyId) {
|
||||
$stmt = $this->conn->prepare("UPDATE api_keys SET is_active = 0 WHERE api_key_id = ?");
|
||||
$stmt->bind_param("i", $keyId);
|
||||
$success = $stmt->execute();
|
||||
$stmt->close();
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an API key permanently
|
||||
*
|
||||
* @param int $keyId API key ID
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function deleteKey($keyId) {
|
||||
$stmt = $this->conn->prepare("DELETE FROM api_keys WHERE api_key_id = ?");
|
||||
$stmt->bind_param("i", $keyId);
|
||||
$success = $stmt->execute();
|
||||
$stmt->close();
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all API keys (for admin panel)
|
||||
*
|
||||
* @return array Array of API key records (without hashes)
|
||||
*/
|
||||
public function getAllKeys() {
|
||||
$stmt = $this->conn->prepare(
|
||||
"SELECT ak.*, u.username, u.display_name
|
||||
FROM api_keys ak
|
||||
LEFT JOIN users u ON ak.created_by = u.user_id
|
||||
ORDER BY ak.created_at DESC"
|
||||
);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
$keys = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
// Remove key_hash from response for security
|
||||
unset($row['key_hash']);
|
||||
$keys[] = $row;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get API key by ID
|
||||
*
|
||||
* @param int $keyId API key ID
|
||||
* @return array|null API key record (without hash) or null if not found
|
||||
*/
|
||||
public function getKeyById($keyId) {
|
||||
$stmt = $this->conn->prepare(
|
||||
"SELECT ak.*, u.username, u.display_name
|
||||
FROM api_keys ak
|
||||
LEFT JOIN users u ON ak.created_by = u.user_id
|
||||
WHERE ak.api_key_id = ?"
|
||||
);
|
||||
$stmt->bind_param("i", $keyId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
$key = $result->fetch_assoc();
|
||||
// Remove key_hash from response for security
|
||||
unset($key['key_hash']);
|
||||
$stmt->close();
|
||||
return $key;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get keys created by a specific user
|
||||
*
|
||||
* @param int $userId User ID
|
||||
* @return array Array of API key records
|
||||
*/
|
||||
public function getKeysByUser($userId) {
|
||||
$stmt = $this->conn->prepare(
|
||||
"SELECT * FROM api_keys WHERE created_by = ? ORDER BY created_at DESC"
|
||||
);
|
||||
$stmt->bind_param("i", $userId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
$keys = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
// Remove key_hash from response for security
|
||||
unset($row['key_hash']);
|
||||
$keys[] = $row;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
return $keys;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user