|
1 | 1 | import sqlite3 |
2 | 2 |
|
| 3 | +from fastapi import Depends |
| 4 | + |
3 | 5 | from app.core.exceptions import APIException |
4 | 6 | from app.core.security import AES256 |
5 | 7 | from app.core.status import CommonCode |
6 | | -from app.core.utils import generate_prefixed_uuid, get_db_path |
| 8 | +from app.core.utils import generate_prefixed_uuid |
| 9 | +from app.repository.api_key_repository import APIKeyRepository, api_key_repository |
7 | 10 | from app.schemas.api_key.create_model import APIKeyCreate |
8 | 11 | from app.schemas.api_key.db_model import APIKeyInDB |
9 | 12 |
|
| 13 | +api_key_repository_dependency = Depends(lambda: api_key_repository) |
| 14 | + |
| 15 | + |
| 16 | +class APIKeyService: |
| 17 | + def store_api_key( |
| 18 | + self, credential_data: APIKeyCreate, repository: APIKeyRepository = api_key_repository |
| 19 | + ) -> APIKeyInDB: |
| 20 | + """API_KEY를 암호화하고 repository를 통해 데이터베이스에 저장합니다.""" |
| 21 | + try: |
| 22 | + encrypted_key = AES256.encrypt(credential_data.api_key) |
| 23 | + new_id = generate_prefixed_uuid("QGENIE") |
| 24 | + |
| 25 | + created_row = repository.create_api_key( |
| 26 | + new_id=new_id, |
| 27 | + service_name=credential_data.service_name.value, |
| 28 | + encrypted_key=encrypted_key, |
| 29 | + ) |
| 30 | + |
| 31 | + if not created_row: |
| 32 | + raise APIException(CommonCode.FAIL_TO_VERIFY_CREATION) |
| 33 | + |
| 34 | + return created_row |
| 35 | + |
| 36 | + except sqlite3.IntegrityError as e: |
| 37 | + # UNIQUE 제약 조건 위반 (service_name) |
| 38 | + raise APIException(CommonCode.DUPLICATION) from e |
| 39 | + except sqlite3.Error as e: |
| 40 | + # "database is locked" 오류를 명시적으로 처리 |
| 41 | + if "database is locked" in str(e): |
| 42 | + raise APIException(CommonCode.DB_BUSY) from e |
| 43 | + # 기타 모든 sqlite3 오류 |
| 44 | + raise APIException(CommonCode.FAIL) from e |
| 45 | + |
10 | 46 |
|
11 | | -def store_api_key(credential_data: APIKeyCreate) -> APIKeyInDB: |
12 | | - """API_KEY를 암호화하여 데이터베이스에 저장합니다.""" |
13 | | - |
14 | | - encrypted_key = AES256.encrypt(credential_data.api_key) |
15 | | - new_id = generate_prefixed_uuid("QGENIE") |
16 | | - |
17 | | - db_path = get_db_path() |
18 | | - conn = None |
19 | | - try: |
20 | | - # timeout을 10초로 설정하여 BUSY 상태에서 대기하도록 함 |
21 | | - conn = sqlite3.connect(str(db_path), timeout=10) |
22 | | - conn.row_factory = sqlite3.Row |
23 | | - cursor = conn.cursor() |
24 | | - |
25 | | - cursor.execute( |
26 | | - """ |
27 | | - INSERT INTO ai_credential (id, service_name, api_key) |
28 | | - VALUES (?, ?, ?) |
29 | | - """, |
30 | | - (new_id, credential_data.service_name, encrypted_key), |
31 | | - ) |
32 | | - conn.commit() |
33 | | - |
34 | | - cursor.execute("SELECT * FROM ai_credential WHERE id = ?", (new_id,)) |
35 | | - created_row = cursor.fetchone() |
36 | | - |
37 | | - if not created_row: |
38 | | - raise APIException(CommonCode.FAIL_TO_VERIFY_CREATION) |
39 | | - |
40 | | - return APIKeyInDB.model_validate(dict(created_row)) |
41 | | - |
42 | | - except sqlite3.IntegrityError as e: |
43 | | - # UNIQUE 제약 조건 위반 (service_name) |
44 | | - raise APIException(CommonCode.DUPLICATION) from e |
45 | | - except sqlite3.Error as e: |
46 | | - # "database is locked" 오류를 명시적으로 처리 |
47 | | - if "database is locked" in str(e): |
48 | | - raise APIException(CommonCode.DB_BUSY) from e |
49 | | - # 기타 모든 sqlite3 오류 |
50 | | - raise APIException(CommonCode.FAIL) from e |
51 | | - finally: |
52 | | - if conn: |
53 | | - conn.close() |
| 47 | +api_key_service = APIKeyService() |
0 commit comments