You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
NORM/FHIR_OCR_POC/test_api_security.py

108 lines
4.1 KiB
Python

#!/usr/bin/env python
"""
Test script for API security.
This script tests the security features of the API by attempting to access endpoints
with and without proper authentication.
"""
import requests
import argparse
import logging
import json
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)
def test_api_security(base_url):
"""
Test API security features.
Args:
base_url: Base URL of the API
"""
logger.info("Testing API security...")
# Test health endpoint (should be accessible without authentication)
logger.info("\nTesting health endpoint (public)...")
health_url = f"{base_url}/health"
response = requests.get(health_url)
logger.info(f"Status code: {response.status_code}")
if response.status_code == 200:
logger.info("Success! Health endpoint is publicly accessible as expected.")
else:
logger.error("Error: Health endpoint should be publicly accessible.")
# Test token endpoint
logger.info("\nTesting token endpoint...")
token_url = f"{base_url}/auth/token"
# Test with invalid credentials
logger.info("Testing with empty username...")
response = requests.post(token_url, json={"username": "", "password": "password"})
logger.info(f"Status code: {response.status_code}")
if response.status_code == 400:
logger.info("Success! Token endpoint rejected empty username as expected.")
else:
logger.error("Error: Token endpoint should reject empty username.")
# Test with valid credentials
logger.info("Testing with valid username...")
response = requests.post(token_url, json={"username": "admin", "password": "password"})
logger.info(f"Status code: {response.status_code}")
if response.status_code == 200:
token_data = response.json()
access_token = token_data.get("access_token")
logger.info("Success! Received valid token.")
# Test protected endpoint without token
logger.info("\nTesting protected endpoint without token...")
patients_url = f"{base_url}/fhir/Patient"
response = requests.get(patients_url)
logger.info(f"Status code: {response.status_code}")
if response.status_code in (401, 403):
logger.info("Success! Access denied without token as expected.")
else:
logger.error("Error: Protected endpoint should deny access without token.")
# Test protected endpoint with token
logger.info("\nTesting protected endpoint with token...")
headers = {"Authorization": f"Bearer {access_token}"}
response = requests.get(patients_url, headers=headers)
logger.info(f"Status code: {response.status_code}")
if response.status_code == 200:
logger.info("Success! Access granted with token as expected.")
else:
logger.error("Error: Protected endpoint should grant access with token.")
# Test admin-only endpoint with user token
logger.info("\nTesting role-based access control...")
# For this POC, we use a generic endpoint that requires admin role
delete_url = f"{base_url}/fhir/Patient/non-existent-id"
response = requests.delete(delete_url, headers=headers)
if response.status_code == 403:
logger.info("Success! Regular user denied access to admin endpoint as expected.")
elif response.status_code == 404:
logger.info("Success! Admin user granted access to admin endpoint as expected.")
else:
logger.error(f"Unexpected response code: {response.status_code}")
else:
logger.error("Error: Could not obtain token for testing.")
logger.info("\nAPI security testing completed.")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Test API security')
parser.add_argument('--url', default='http://localhost:8000', help='Base URL of the API')
args = parser.parse_args()
test_api_security(args.url)