"""Postfächer einrichten und Zahlungs-Mails abholen.""" from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from ..database import get_db from ..deps import get_current_user, get_owned from ..models import Account, MailSender, MailSource, User from ..schemas import MailSenderIn, MailSenderOut, MailSourceIn, MailSourceOut from ..services import geheimnis, mail_import router = APIRouter(prefix="/mail", tags=["mail"]) def _aus(quelle: MailSource) -> MailSourceOut: out = MailSourceOut.model_validate(quelle) out.password_set = bool(quelle.password_enc) return out @router.get("/sources", response_model=list[MailSourceOut]) def list_sources(db: Session = Depends(get_db), user: User = Depends(get_current_user)): quellen = ( db.query(MailSource).filter(MailSource.owner_id == user.id).order_by(MailSource.id).all() ) return [_aus(q) for q in quellen] @router.post("/sources", response_model=MailSourceOut, status_code=status.HTTP_201_CREATED) def create_source( payload: MailSourceIn, db: Session = Depends(get_db), user: User = Depends(get_current_user) ): if not payload.password: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Passwort fehlt") quelle = MailSource( owner_id=user.id, **payload.model_dump(exclude={"password"}), password_enc=geheimnis.verschluesseln(payload.password), ) db.add(quelle) db.commit() db.refresh(quelle) return _aus(quelle) @router.put("/sources/{source_id}", response_model=MailSourceOut) def update_source( source_id: int, payload: MailSourceIn, db: Session = Depends(get_db), user: User = Depends(get_current_user), ): quelle = get_owned(db, MailSource, source_id, user) for schluessel, wert in payload.model_dump(exclude={"password"}).items(): setattr(quelle, schluessel, wert) # Leeres Passwortfeld heisst „unverändert" – sonst müsste man es bei jeder # Kleinigkeit erneut eintippen. if payload.password: quelle.password_enc = geheimnis.verschluesseln(payload.password) db.commit() db.refresh(quelle) return _aus(quelle) @router.delete("/sources/{source_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_source(source_id: int, db: Session = Depends(get_db), user: User = Depends(get_current_user)): db.delete(get_owned(db, MailSource, source_id, user)) db.commit() @router.post("/sources/{source_id}/test") def test_source(source_id: int, db: Session = Depends(get_db), user: User = Depends(get_current_user)): """Verbindung prüfen und die Ordner des Postfachs zurückgeben.""" quelle = get_owned(db, MailSource, source_id, user) try: return mail_import.teste(quelle) except mail_import.MailFehler as e: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) from e @router.post("/sources/{source_id}/fetch") def fetch_source(source_id: int, db: Session = Depends(get_db), user: User = Depends(get_current_user)): quelle = get_owned(db, MailSource, source_id, user) try: return mail_import.hole_neue(db, quelle) except mail_import.MailFehler as e: quelle.last_error = str(e)[:500] db.commit() raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) from e # --- Absender-Zuordnung ------------------------------------------------------ @router.get("/sources/{source_id}/senders", response_model=list[MailSenderOut]) def list_senders(source_id: int, db: Session = Depends(get_db), user: User = Depends(get_current_user)): get_owned(db, MailSource, source_id, user) return ( db.query(MailSender) .filter(MailSender.source_id == source_id) .order_by(MailSender.id) .all() ) @router.post("/sources/{source_id}/senders", response_model=MailSenderOut, status_code=status.HTTP_201_CREATED) def create_sender( source_id: int, payload: MailSenderIn, db: Session = Depends(get_db), user: User = Depends(get_current_user), ): get_owned(db, MailSource, source_id, user) if payload.account_id is not None: get_owned(db, Account, payload.account_id, user) absender = MailSender(source_id=source_id, owner_id=user.id, **payload.model_dump()) db.add(absender) db.commit() db.refresh(absender) return absender @router.delete("/senders/{sender_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_sender(sender_id: int, db: Session = Depends(get_db), user: User = Depends(get_current_user)): db.delete(get_owned(db, MailSender, sender_id, user)) db.commit()