Security API
The Security API provides endpoints for managing security features in the UBU Finance backend.
Overview
The Security API allows administrators to monitor and manage security features such as IP whitelisting, account lockout, and security status. These endpoints are protected by role-based access control and require admin privileges.
Authentication
All Security API endpoints require authentication with a valid JWT token. The token must be included in the Authorization header with the Bearer scheme.
Endpoints
Get Security Status
Returns the current security status, including metrics for rate limit hits, IP whitelist blocks, and account lockouts.
Endpoint: GET /api/admin/security/status
Permissions Required: admin
Response:
{
"security_status": {
"rate_limit_hits": {
"192.168.1.1": 5,
"203.0.113.1": 10
},
"ip_whitelist_blocks": {
"203.0.113.2": 3
},
"account_lockouts": {
"user123": 2
},
"total_security_events": 20
},
"config": {
"rate_limit": {
"enabled": true,
"max_requests": 100,
"window_seconds": 60
},
"ip_whitelist": {
"enabled": true,
"allow_localhost": true
},
"account_lockout": {
"enabled": true,
"max_failed_attempts": 5,
"lockout_duration_seconds": 1800
}
}
}
Test Security Components
Tests all security components and returns the results.
Endpoint: GET /api/admin/security/test
Permissions Required: admin
Response:
{
"rate_limiter": {
"status": "ok",
"message": "Rate limiter is working correctly"
},
"ip_whitelist": {
"status": "ok",
"message": "IP whitelist is working correctly"
},
"account_lockout": {
"status": "ok",
"message": "Account lockout is working correctly"
}
}
Add IP to Whitelist
Adds an IP address to the whitelist.
Endpoint: POST /api/admin/security/whitelist/add/{ip}
Permissions Required: admin
URL Parameters:
ip: The IP address to add to the whitelist. Can be a single IP (e.g.,192.168.1.1) or a CIDR range (e.g.,192.168.1.0/24).
Response:
Error Responses:
400 Bad Request: If the IP address format is invalid.403 Forbidden: If the user doesn't have admin privileges.500 Internal Server Error: If there's an error adding the IP to the whitelist.
Remove IP from Whitelist
Removes an IP address from the whitelist.
Endpoint: POST /api/admin/security/whitelist/remove/{ip}
Permissions Required: admin
URL Parameters:
ip: The IP address to remove from the whitelist.
Response:
Error Responses:
400 Bad Request: If the IP address format is invalid.403 Forbidden: If the user doesn't have admin privileges.500 Internal Server Error: If there's an error removing the IP from the whitelist.
Unlock Account
Unlocks a user account that has been locked due to too many failed login attempts.
Endpoint: POST /api/admin/security/account/unlock/{username}
Permissions Required: admin
URL Parameters:
username: The username of the account to unlock.
Response:
Error Responses:
403 Forbidden: If the user doesn't have admin privileges.404 Not Found: If the user doesn't exist.500 Internal Server Error: If there's an error unlocking the account.
Client Implementation Examples
Getting Security Status
import requests
def get_security_status(base_url, token):
url = f"{base_url}/api/admin/security/status"
headers = {
"Authorization": f"Bearer {token}"
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json()
else:
print(f"Failed to get security status: {response.json()}")
return None
async function getSecurityStatus(baseUrl, token) {
const url = `${baseUrl}/api/admin/security/status`;
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
try {
const response = await fetch(url, {
method: 'GET',
headers: headers
});
if (response.ok) {
return await response.json();
} else {
const data = await response.json();
console.error(`Failed to get security status: ${data.detail}`);
return null;
}
} catch (error) {
console.error(`Error getting security status: ${error}`);
return null;
}
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class SecurityClient
{
private readonly HttpClient _client;
private readonly string _baseUrl;
public SecurityClient(string baseUrl)
{
_client = new HttpClient();
_baseUrl = baseUrl;
}
public async Task<object> GetSecurityStatusAsync(string token)
{
string url = $"{_baseUrl}/api/admin/security/status";
_client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
try
{
HttpResponseMessage response = await _client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject(content);
}
else
{
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Failed to get security status: {content}");
return null;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error getting security status: {ex.Message}");
return null;
}
}
}
Testing Security Components
import requests
def test_security_components(base_url, token):
url = f"{base_url}/api/admin/security/test"
headers = {
"Authorization": f"Bearer {token}"
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
results = response.json()
# Print results
for feature, result in results.items():
status = "✅" if result["status"] == "ok" else "❌"
print(f"{status} {feature}: {result['message']}")
return results
else:
print(f"Failed to test security components: {response.json()}")
return None
async function testSecurityComponents(baseUrl, token) {
const url = `${baseUrl}/api/admin/security/test`;
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
try {
const response = await fetch(url, {
method: 'GET',
headers: headers
});
if (response.ok) {
const results = await response.json();
// Print results
for (const [feature, result] of Object.entries(results)) {
const status = result.status === "ok" ? "✅" : "❌";
console.log(`${status} ${feature}: ${result.message}`);
}
return results;
} else {
const data = await response.json();
console.error(`Failed to test security components: ${data.detail}`);
return null;
}
} catch (error) {
console.error(`Error testing security components: ${error}`);
return null;
}
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Collections.Generic;
public class SecurityClient
{
private readonly HttpClient _client;
private readonly string _baseUrl;
public SecurityClient(string baseUrl)
{
_client = new HttpClient();
_baseUrl = baseUrl;
}
public class SecurityTestResult
{
public string status { get; set; }
public string message { get; set; }
}
public async Task<Dictionary<string, SecurityTestResult>> TestSecurityComponentsAsync(string token)
{
string url = $"{_baseUrl}/api/admin/security/test";
_client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
try
{
HttpResponseMessage response = await _client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
var results = JsonConvert.DeserializeObject<Dictionary<string, SecurityTestResult>>(content);
// Print results
foreach (var kvp in results)
{
string status = kvp.Value.status == "ok" ? "✅" : "❌";
Console.WriteLine($"{status} {kvp.Key}: {kvp.Value.message}");
}
return results;
}
else
{
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Failed to test security components: {content}");
return null;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error testing security components: {ex.Message}");
return null;
}
}
}
Error Handling
The Security API returns standard HTTP status codes and JSON error responses:
400 Bad Request: The request was invalid or malformed.401 Unauthorized: Authentication is required or the provided credentials are invalid.403 Forbidden: The authenticated user doesn't have permission to access the requested resource.404 Not Found: The requested resource doesn't exist.429 Too Many Requests: The client has sent too many requests in a given amount of time.500 Internal Server Error: An unexpected error occurred on the server.
Error responses have the following format:
Best Practices
- Use HTTPS: Always use HTTPS to encrypt API requests and responses.
- Secure API Keys: Store API keys securely and never expose them in client-side code.
- Implement Proper Authentication: Use the provided authentication mechanisms and never bypass them.
- Handle Rate Limiting: Implement exponential backoff when receiving rate limit responses.
- Monitor API Usage: Monitor API usage to detect unusual patterns that might indicate abuse.
- Validate Input: Always validate input to prevent injection attacks.
- Handle Errors Gracefully: Provide a good user experience when errors occur.