2023-06-15 15:43:40 +03:00
|
|
|
from datetime import datetime
|
|
|
|
from secrets import token_hex
|
2023-06-14 22:21:13 +03:00
|
|
|
from typing import List
|
|
|
|
from uuid import uuid4
|
2023-06-15 15:43:40 +03:00
|
|
|
|
2023-06-14 22:21:13 +03:00
|
|
|
from asyncpg.exceptions import UniqueViolationError
|
2023-06-15 15:43:40 +03:00
|
|
|
from auth.auth_bearer import AuthBearer, get_current_user
|
|
|
|
from fastapi import APIRouter, Depends
|
2023-06-14 22:21:13 +03:00
|
|
|
from logger import get_logger
|
2023-06-19 23:46:25 +03:00
|
|
|
from models.settings import CommonsDep
|
2023-06-15 15:43:40 +03:00
|
|
|
from models.users import User
|
|
|
|
from pydantic import BaseModel
|
2023-06-14 22:21:13 +03:00
|
|
|
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class ApiKeyInfo(BaseModel):
|
|
|
|
key_id: str
|
|
|
|
creation_time: str
|
|
|
|
|
2023-06-23 11:36:55 +03:00
|
|
|
|
2023-06-14 22:21:13 +03:00
|
|
|
class ApiKey(BaseModel):
|
|
|
|
api_key: str
|
2023-07-02 03:19:30 +03:00
|
|
|
key_id: str
|
2023-06-23 11:36:55 +03:00
|
|
|
|
2023-06-14 22:21:13 +03:00
|
|
|
|
|
|
|
api_key_router = APIRouter()
|
|
|
|
|
2023-06-23 11:36:55 +03:00
|
|
|
|
|
|
|
@api_key_router.post(
|
|
|
|
"/api-key",
|
|
|
|
response_model=ApiKey,
|
|
|
|
dependencies=[Depends(AuthBearer())],
|
|
|
|
tags=["API Key"],
|
|
|
|
)
|
|
|
|
async def create_api_key(
|
|
|
|
commons: CommonsDep, current_user: User = Depends(get_current_user)
|
|
|
|
):
|
2023-06-15 15:43:40 +03:00
|
|
|
"""
|
|
|
|
Create new API key for the current user.
|
|
|
|
|
|
|
|
- `current_user`: The current authenticated user.
|
|
|
|
- Returns the newly created API key.
|
|
|
|
|
|
|
|
This endpoint generates a new API key for the current user. The API key is stored in the database and associated with
|
|
|
|
the user. It returns the newly created API key.
|
|
|
|
"""
|
2023-06-14 22:21:13 +03:00
|
|
|
|
2023-07-02 00:30:14 +03:00
|
|
|
new_key_id = uuid4()
|
2023-06-14 22:21:13 +03:00
|
|
|
new_api_key = token_hex(16)
|
|
|
|
api_key_inserted = False
|
|
|
|
|
|
|
|
while not api_key_inserted:
|
|
|
|
try:
|
|
|
|
# Attempt to insert new API key into database
|
2023-07-02 00:30:14 +03:00
|
|
|
commons["supabase"].table("api_keys").insert(
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"key_id": str(new_key_id),
|
|
|
|
"user_id": str(current_user.id),
|
|
|
|
"api_key": str(new_api_key),
|
|
|
|
"creation_time": datetime.utcnow().strftime(
|
|
|
|
"%Y-%m-%d %H:%M:%S"
|
|
|
|
),
|
|
|
|
"is_active": True,
|
|
|
|
}
|
|
|
|
]
|
|
|
|
).execute()
|
2023-06-14 22:21:13 +03:00
|
|
|
|
|
|
|
api_key_inserted = True
|
|
|
|
|
|
|
|
except UniqueViolationError:
|
|
|
|
# Generate a new API key if the current one is already in use
|
|
|
|
new_api_key = token_hex(16)
|
2023-07-02 00:30:14 +03:00
|
|
|
except Exception as e:
|
|
|
|
logger.error(f"Error creating new API key: {e}")
|
|
|
|
return {"api_key": "Error creating new API key."}
|
2023-06-14 22:21:13 +03:00
|
|
|
logger.info(f"Created new API key for user {current_user.email}.")
|
|
|
|
|
2023-07-02 03:19:30 +03:00
|
|
|
return {"api_key": new_api_key, "key_id": str(new_key_id)}
|
2023-06-14 22:21:13 +03:00
|
|
|
|
2023-06-23 11:36:55 +03:00
|
|
|
|
|
|
|
@api_key_router.delete(
|
|
|
|
"/api-key/{key_id}", dependencies=[Depends(AuthBearer())], tags=["API Key"]
|
|
|
|
)
|
|
|
|
async def delete_api_key(
|
|
|
|
key_id: str, commons: CommonsDep, current_user: User = Depends(get_current_user)
|
|
|
|
):
|
2023-06-15 15:43:40 +03:00
|
|
|
"""
|
|
|
|
Delete (deactivate) an API key for the current user.
|
|
|
|
|
|
|
|
- `key_id`: The ID of the API key to delete.
|
|
|
|
|
|
|
|
This endpoint deactivates and deletes the specified API key associated with the current user. The API key is marked
|
|
|
|
as inactive in the database.
|
|
|
|
|
|
|
|
"""
|
2023-06-14 22:21:13 +03:00
|
|
|
|
2023-07-02 00:30:14 +03:00
|
|
|
commons["supabase"].table("api_keys").update(
|
|
|
|
{
|
|
|
|
"is_active": False,
|
|
|
|
"deleted_time": datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
|
|
|
|
}
|
|
|
|
).match({"key_id": key_id, "user_id": current_user.id}).execute()
|
2023-06-14 22:21:13 +03:00
|
|
|
|
|
|
|
return {"message": "API key deleted."}
|
|
|
|
|
2023-06-23 11:36:55 +03:00
|
|
|
|
|
|
|
@api_key_router.get(
|
|
|
|
"/api-keys",
|
|
|
|
response_model=List[ApiKeyInfo],
|
|
|
|
dependencies=[Depends(AuthBearer())],
|
|
|
|
tags=["API Key"],
|
|
|
|
)
|
|
|
|
async def get_api_keys(
|
|
|
|
commons: CommonsDep, current_user: User = Depends(get_current_user)
|
|
|
|
):
|
2023-06-15 15:43:40 +03:00
|
|
|
"""
|
|
|
|
Get all active API keys for the current user.
|
|
|
|
|
|
|
|
- `current_user`: The current authenticated user.
|
|
|
|
- Returns a list of active API keys with their IDs and creation times.
|
|
|
|
|
|
|
|
This endpoint retrieves all the active API keys associated with the current user. It returns a list of API key objects
|
|
|
|
containing the key ID and creation time for each API key.
|
|
|
|
"""
|
2023-06-14 22:21:13 +03:00
|
|
|
|
2023-07-02 00:30:14 +03:00
|
|
|
response = (
|
|
|
|
commons["supabase"]
|
|
|
|
.table("api_keys")
|
|
|
|
.select("key_id, creation_time")
|
|
|
|
.filter("user_id", "eq", current_user.id)
|
|
|
|
.filter("is_active", "eq", True)
|
|
|
|
.execute()
|
|
|
|
)
|
2023-06-23 11:36:55 +03:00
|
|
|
return response.data
|