222 lines
6.5 KiB
Python
222 lines
6.5 KiB
Python
from typing import Optional
|
|
from uuid import UUID
|
|
|
|
from fastapi import APIRouter, Depends, Path, Query, status
|
|
|
|
from app.api.dependencies.auth import get_current_active_admin, get_current_active_user
|
|
from app.api.dependencies.factory import Factory
|
|
from app.core.params import CommonParams
|
|
from app.schemas.base import PaginatedResponse
|
|
from app.schemas.credential_schema import (
|
|
CredentialCreateSchema,
|
|
CredentialSchema,
|
|
CredentialUpdateSchema,
|
|
CredentialWithSensitiveDataSchema,
|
|
)
|
|
from app.schemas.user_schema import UserSchema
|
|
from app.services import CredentialService
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post(
|
|
"/credentials",
|
|
summary="Buat kredensial baru",
|
|
status_code=status.HTTP_201_CREATED,
|
|
)
|
|
async def create_credential(
|
|
data: CredentialCreateSchema,
|
|
current_user: UserSchema = Depends(get_current_active_admin),
|
|
service: CredentialService = Depends(Factory().get_credential_service),
|
|
):
|
|
"""
|
|
Buat kredensial baru dengan data yang terenkripsi.
|
|
|
|
Endpoint ini hanya dapat diakses oleh admin.
|
|
|
|
**Data sensitive yang didukung:**
|
|
|
|
- Database:
|
|
- host, port, username, password, database_name
|
|
- MinIO:
|
|
- endpoint, access_key, secret_key, secure, bucket_name
|
|
- API:
|
|
- base_url, api_key
|
|
- SSH:
|
|
- host, port, username, password (atau private_key)
|
|
- SMTP:
|
|
- host, port, username, password, use_tls
|
|
- FTP:
|
|
- host, port, username, password
|
|
"""
|
|
result = await service.create_credential(
|
|
name=data.name,
|
|
credential_type=data.credential_type,
|
|
sensitive_data=data.sensitive_data,
|
|
credential_metadata=data.credential_metadata,
|
|
description=data.description,
|
|
is_default=data.is_default,
|
|
user_id=current_user.id,
|
|
)
|
|
return result
|
|
|
|
|
|
@router.get(
|
|
"/credentials",
|
|
response_model=PaginatedResponse[CredentialSchema],
|
|
summary="Dapatkan daftar kredensial",
|
|
dependencies=[Depends(get_current_active_user)],
|
|
)
|
|
async def get_credentials(
|
|
credential_type: Optional[str] = Query(None, description="Filter berdasarkan tipe kredensial"),
|
|
include_inactive: bool = Query(False, description="Sertakan kredensial yang tidak aktif"),
|
|
params: CommonParams = Depends(),
|
|
service: CredentialService = Depends(Factory().get_credential_service),
|
|
):
|
|
"""
|
|
Dapatkan daftar kredensial dengan filtering and pagination.
|
|
"""
|
|
filter_params = params.filter or []
|
|
sort = params.sort
|
|
search = params.search
|
|
group_by = params.group_by
|
|
limit = params.limit
|
|
offset = params.offset
|
|
|
|
if credential_type:
|
|
filter_params.append(f"credential_type={credential_type}")
|
|
|
|
if not include_inactive:
|
|
filter_params.append(f"is_active=true")
|
|
|
|
credentials, total = await service.find_all(
|
|
filters=filter_params, sort=sort, search=search, group_by=group_by, limit=limit, offset=offset
|
|
)
|
|
|
|
return PaginatedResponse(
|
|
items=[credential for credential in credentials],
|
|
total=total,
|
|
limit=limit,
|
|
offset=offset,
|
|
has_more=offset + limit < total,
|
|
)
|
|
|
|
|
|
@router.get(
|
|
"/credentials/{credential_id}",
|
|
response_model=CredentialSchema,
|
|
summary="Dapatkan kredensial dengan data terdekripsi",
|
|
dependencies=[Depends(get_current_active_user)],
|
|
)
|
|
async def get_credential(
|
|
credential_id: UUID = Path(..., description="ID kredensial"),
|
|
service: CredentialService = Depends(Factory().get_credential_service),
|
|
):
|
|
"""
|
|
Dapatkan kredensial dengan data sensitif yang sudah didekripsi.
|
|
|
|
Endpoint ini hanya dapat diakses oleh admin.
|
|
"""
|
|
credential = await service.find_by_id(credential_id)
|
|
|
|
return credential
|
|
|
|
|
|
@router.get(
|
|
"/credentials/{credential_id}/decrypted",
|
|
response_model=CredentialWithSensitiveDataSchema,
|
|
summary="Dapatkan kredensial dengan data terdekripsi",
|
|
dependencies=[Depends(get_current_active_user)],
|
|
)
|
|
async def get_credential_decrypted(
|
|
credential_id: UUID = Path(..., description="ID kredensial"),
|
|
service: CredentialService = Depends(Factory().get_credential_service),
|
|
):
|
|
"""
|
|
Dapatkan kredensial dengan data sensitif yang sudah didekripsi.
|
|
|
|
Endpoint ini hanya dapat diakses oleh admin.
|
|
"""
|
|
credential = await service.get_credential_with_decrypted_data(credential_id)
|
|
|
|
return credential
|
|
|
|
|
|
@router.patch(
|
|
"/credentials/{credential_id}",
|
|
summary="Update kredensial",
|
|
)
|
|
async def update_credential(
|
|
credential_id: UUID,
|
|
data: CredentialUpdateSchema,
|
|
current_user: UserSchema = Depends(get_current_active_admin),
|
|
service: CredentialService = Depends(Factory().get_credential_service),
|
|
):
|
|
"""
|
|
Update kredensial.
|
|
|
|
Data sensitif bisa diupdate secara parsial. Field yang tidak disebutkan
|
|
dalam data.sensitive_data tidak akan diubah.
|
|
|
|
Endpoint ini hanya dapat diakses oleh admin.
|
|
"""
|
|
updated = await service.update_credential(credential_id, data.dict(exclude_unset=True), current_user.id)
|
|
return updated
|
|
|
|
|
|
@router.delete("/credentials/{credential_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_credential(
|
|
credential_id: UUID,
|
|
user: UserSchema = Depends(get_current_active_admin),
|
|
service: CredentialService = Depends(Factory().get_credential_service),
|
|
):
|
|
await service.delete(user, credential_id)
|
|
|
|
|
|
# @router.post(
|
|
# "/{credential_id}/test",
|
|
# response_model=CredentialTestResult,
|
|
# summary="Test koneksi menggunakan kredensial"
|
|
# )
|
|
# async def test_credential(
|
|
# credential_id: UUID,
|
|
# current_user: UserSchema = Depends(get_current_active_user),
|
|
# service: CredentialService = Depends(Factory().get_credential_service)
|
|
# ):
|
|
# """
|
|
# Test koneksi menggunakan kredensial.
|
|
|
|
# Hasil test berisi flag sukses dan detail tambahan.
|
|
# """
|
|
# result = await service.test_credential(
|
|
# service.db, credential_id, current_user.id
|
|
# )
|
|
# return result
|
|
|
|
|
|
# @router.delete(
|
|
# "/{credential_id}",
|
|
# status_code=status.HTTP_204_NO_CONTENT,
|
|
# summary="Hapus kredensial"
|
|
# )
|
|
# async def delete_credential(
|
|
# credential_id: UUID,
|
|
# current_user: UserSchema = Depends(get_current_admin_user),
|
|
# service: CredentialService = Depends(Factory().get_credential_service)
|
|
# ):
|
|
# """
|
|
# Hapus kredensial secara permanen.
|
|
|
|
# Endpoint ini hanya dapat diakses oleh admin.
|
|
# """
|
|
# credential = await service.find_by_id(service.db, credential_id)
|
|
# if not credential:
|
|
# raise HTTPException(
|
|
# status_code=status.HTTP_404_NOT_FOUND,
|
|
# detail="Credential not found"
|
|
# )
|
|
|
|
# await service.delete(service.db, credential_id)
|
|
|
|
# return None
|