domain migration
This commit is contained in:
parent
192b810eb4
commit
c04a6ce6fe
26 changed files with 777 additions and 125 deletions
|
|
@ -15,6 +15,8 @@ from app.config import get_settings
|
|||
from app.database import get_postgres_session
|
||||
from app.models import Account
|
||||
from app.schemas import AccountRegister, AccountRead, AuthResponse, LoginRequest
|
||||
from app.services.domain_policy import assert_company_domain_allowed
|
||||
from app.services.domain_provisioning import account_is_domain_owner
|
||||
from app.services.domain_provisioning import (
|
||||
get_domain_by_name,
|
||||
provision_mail_domain,
|
||||
|
|
@ -50,7 +52,7 @@ def validate_password(value: str) -> None:
|
|||
|
||||
|
||||
def build_email(payload: AccountRegister) -> tuple[str, str | None]:
|
||||
domain = "getall.help"
|
||||
domain = settings.platform_domain
|
||||
company_domain = None
|
||||
|
||||
if payload.account_type == "company":
|
||||
|
|
@ -59,12 +61,16 @@ def build_email(payload: AccountRegister) -> tuple[str, str | None]:
|
|||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="Company domain is required for company accounts.",
|
||||
)
|
||||
domain = payload.company_domain.strip().lower().removeprefix("@")
|
||||
if not domain_pattern.fullmatch(domain):
|
||||
try:
|
||||
domain = assert_company_domain_allowed(
|
||||
payload.company_domain,
|
||||
settings.platform_domain,
|
||||
)
|
||||
except ValueError as error:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="Enter a valid company domain, such as example.com.",
|
||||
)
|
||||
detail=str(error),
|
||||
) from error
|
||||
company_domain = domain
|
||||
|
||||
email = f"{payload.email_name.lower()}@{domain}"
|
||||
|
|
@ -88,6 +94,21 @@ def create_access_token(account: Account) -> str:
|
|||
)
|
||||
|
||||
|
||||
async def account_read(
|
||||
session: AsyncSession,
|
||||
account: Account,
|
||||
) -> AccountRead:
|
||||
is_owner = await account_is_domain_owner(
|
||||
session,
|
||||
account.id,
|
||||
account.company_domain,
|
||||
)
|
||||
return AccountRead.model_validate(
|
||||
account,
|
||||
update={"is_domain_owner": is_owner},
|
||||
)
|
||||
|
||||
|
||||
async def get_current_account(
|
||||
credentials: HTTPAuthorizationCredentials | None = Depends(bearer_scheme),
|
||||
session: AsyncSession = Depends(get_postgres_session),
|
||||
|
|
@ -180,7 +201,7 @@ async def register(
|
|||
await session.refresh(account)
|
||||
return AuthResponse(
|
||||
access_token=create_access_token(account),
|
||||
account=AccountRead.model_validate(account),
|
||||
account=await account_read(session, account),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -203,10 +224,13 @@ async def login(
|
|||
)
|
||||
return AuthResponse(
|
||||
access_token=create_access_token(account),
|
||||
account=AccountRead.model_validate(account),
|
||||
account=await account_read(session, account),
|
||||
)
|
||||
|
||||
|
||||
@router.get("/me", response_model=AccountRead)
|
||||
async def get_me(account: Account = Depends(get_current_account)) -> Account:
|
||||
return account
|
||||
async def get_me(
|
||||
account: Account = Depends(get_current_account),
|
||||
session: AsyncSession = Depends(get_postgres_session),
|
||||
) -> AccountRead:
|
||||
return await account_read(session, account)
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ from app.schemas import (
|
|||
SmtpCredentialRead,
|
||||
)
|
||||
from app.services.dns_verification import verify_company_dns
|
||||
from app.services.domain_policy import assert_company_domain_allowed
|
||||
from app.services.domain_provisioning import (
|
||||
activate_company_domain,
|
||||
create_smtp_credential,
|
||||
ensure_ownership_dns_record,
|
||||
ensure_platform_domain,
|
||||
get_account_company_domain,
|
||||
provision_mail_domain,
|
||||
|
|
@ -102,12 +104,14 @@ async def verify_my_company_dns(
|
|||
checks=[],
|
||||
)
|
||||
|
||||
verification_token = await ensure_ownership_dns_record(session, domain)
|
||||
checks = verify_company_dns(
|
||||
domain_name=domain.domain_name,
|
||||
shared_mail_host=settings.smtp_public_host,
|
||||
dkim_selector=domain.dkim_selector,
|
||||
dkim_public_key=domain.dkim_public_key,
|
||||
platform_spf_include=settings.platform_spf_include,
|
||||
verification_token=verification_token,
|
||||
)
|
||||
verified = all(check["verified"] for check in checks)
|
||||
if verified:
|
||||
|
|
@ -151,19 +155,16 @@ async def register_company_domain(
|
|||
) -> MailDomain:
|
||||
settings = get_settings()
|
||||
try:
|
||||
normalized = validate_domain(payload.domain_name)
|
||||
normalized = assert_company_domain_allowed(
|
||||
payload.domain_name,
|
||||
settings.platform_domain,
|
||||
)
|
||||
except ValueError as error:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail=str(error),
|
||||
) from error
|
||||
|
||||
if normalized == settings.platform_domain:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="Use the platform domain endpoint for getall.help.",
|
||||
)
|
||||
|
||||
existing = await session.scalar(
|
||||
select(MailDomain).where(MailDomain.domain_name == normalized)
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue