Coverage for opt/mealie/lib/python3.12/site-packages/mealie/routes/households/controller_invitations.py: 84%
34 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 03:04 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 03:04 +0000
1from typing import Annotated
3from fastapi import APIRouter, Header, HTTPException, status
5from mealie.core.security import url_safe_token
6from mealie.routes._base import BaseUserController, controller
7from mealie.schema.household.invite_token import (
8 CreateInviteToken,
9 EmailInitationResponse,
10 EmailInvitation,
11 ReadInviteToken,
12 SaveInviteToken,
13)
14from mealie.schema.response.pagination import PaginationQuery
15from mealie.services.email.email_service import EmailService
17router = APIRouter(prefix="/households/invitations", tags=["Households: Invitations"])
20@controller(router)
21class GroupInvitationsController(BaseUserController):
22 @router.get("", response_model=list[ReadInviteToken])
23 def get_invite_tokens(self):
24 return self.repos.group_invite_tokens.page_all(PaginationQuery(page=1, per_page=-1)).items
26 @router.post("", response_model=ReadInviteToken, status_code=status.HTTP_201_CREATED)
27 def create_invite_token(self, body: CreateInviteToken):
28 if not self.user.can_invite: 28 ↛ 29line 28 didn't jump to line 29 because the condition on line 28 was never true
29 raise HTTPException(
30 status.HTTP_403_FORBIDDEN,
31 detail="User is not allowed to create invite tokens",
32 )
34 body.group_id = body.group_id or self.group_id
35 body.household_id = body.household_id or self.household_id
37 if not self.user.admin and (body.group_id != self.group_id or body.household_id != self.household_id): 37 ↛ 38line 37 didn't jump to line 38 because the condition on line 37 was never true
38 raise HTTPException(
39 status.HTTP_403_FORBIDDEN,
40 detail="Only admins can create invite tokens for other groups or households",
41 )
43 token = SaveInviteToken(
44 uses_left=body.uses, group_id=body.group_id, household_id=body.household_id, token=url_safe_token()
45 )
46 return self.repos.group_invite_tokens.create(token)
48 @router.post("/email", response_model=EmailInitationResponse)
49 def email_invitation(
50 self,
51 invite: EmailInvitation,
52 accept_language: Annotated[str | None, Header()] = None,
53 ):
54 email_service = EmailService(locale=accept_language)
55 url = f"{self.settings.BASE_URL}/register?token={invite.token}"
57 success = False
58 error = None
59 try:
60 success = email_service.send_invitation(address=invite.email, invitation_url=url)
61 except Exception as e:
62 error = str(e)
64 return EmailInitationResponse(success=success, error=error)