feat(FN-007): implement credential storage with Fernet encryption
- Add DatabaseCredentialStorage with async CRUD operations - Create Credential SQLAlchemy model with encrypted values - Update GitCredential and AccessTokenCredential to support async - Fix SSH key encryption to use Fernet instead of base64 placeholder
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import uuid
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.git.credentials import CredentialStorage, GitCredential
|
||||
from app.models.credential import Credential
|
||||
|
||||
|
||||
class DatabaseCredentialStorage(CredentialStorage):
|
||||
def __init__(self, session: AsyncSession) -> None:
|
||||
self.session = session
|
||||
|
||||
async def create(self, credential: GitCredential) -> uuid.UUID:
|
||||
row = Credential(
|
||||
id=credential.id,
|
||||
kind=str(credential.kind),
|
||||
encrypted_payload=credential.encrypted_payload,
|
||||
)
|
||||
self.session.add(row)
|
||||
await self.session.flush()
|
||||
return row.id
|
||||
|
||||
async def get(self, credential_id: uuid.UUID) -> GitCredential | None:
|
||||
row = await self.session.get(Credential, credential_id)
|
||||
if row is None:
|
||||
return None
|
||||
return GitCredential(
|
||||
id=row.id,
|
||||
kind=row.kind,
|
||||
encrypted_payload=row.encrypted_payload,
|
||||
created_at=row.created_at,
|
||||
updated_at=row.updated_at,
|
||||
)
|
||||
|
||||
async def delete(self, credential_id: uuid.UUID) -> None:
|
||||
row = await self.session.get(Credential, credential_id)
|
||||
if row is not None:
|
||||
await self.session.delete(row)
|
||||
await self.session.flush()
|
||||
Reference in New Issue
Block a user