Skip to main content

postrust_proxy/saas/handlers/
domains.rs

1//! Domain API handlers.
2
3use crate::admin::api::ApiResponse;
4use crate::saas::auth::Auth;
5use crate::saas::handlers::{error_response, SaasState};
6use crate::saas::types::CreateDomainRequest;
7use axum::{
8    extract::{Path, State},
9    http::StatusCode,
10    response::IntoResponse,
11    Json,
12};
13use uuid::Uuid;
14
15/// List all domains for the authenticated tenant.
16pub async fn list_domains(State(state): State<SaasState>, Auth(auth): Auth) -> impl IntoResponse {
17    match state.domain_manager.list_domains(auth.tenant_id).await {
18        Ok(domains) => Json(ApiResponse::success(domains)).into_response(),
19        Err(e) => error_response(e).into_response(),
20    }
21}
22
23/// Create a new domain.
24pub async fn create_domain(
25    State(state): State<SaasState>,
26    Auth(auth): Auth,
27    Json(req): Json<CreateDomainRequest>,
28) -> impl IntoResponse {
29    if !auth.can_write("domains") {
30        return (
31            StatusCode::FORBIDDEN,
32            Json(ApiResponse::<()>::error("Insufficient permissions")),
33        )
34            .into_response();
35    }
36
37    match state
38        .domain_manager
39        .create_domain(auth.tenant_id, req)
40        .await
41    {
42        Ok(domain_response) => (
43            StatusCode::CREATED,
44            Json(ApiResponse::success(domain_response)),
45        )
46            .into_response(),
47        Err(e) => error_response(e).into_response(),
48    }
49}
50
51/// Get a domain by ID.
52pub async fn get_domain(
53    State(state): State<SaasState>,
54    Auth(auth): Auth,
55    Path(id): Path<Uuid>,
56) -> impl IntoResponse {
57    match state.domain_manager.get_domain(id, auth.tenant_id).await {
58        Ok(Some(domain)) => Json(ApiResponse::success(domain)).into_response(),
59        Ok(None) => (
60            StatusCode::NOT_FOUND,
61            Json(ApiResponse::<()>::error("Domain not found")),
62        )
63            .into_response(),
64        Err(e) => error_response(e).into_response(),
65    }
66}
67
68/// Delete a domain.
69pub async fn delete_domain(
70    State(state): State<SaasState>,
71    Auth(auth): Auth,
72    Path(id): Path<Uuid>,
73) -> impl IntoResponse {
74    if !auth.can_write("domains") {
75        return (
76            StatusCode::FORBIDDEN,
77            Json(ApiResponse::<()>::error("Insufficient permissions")),
78        )
79            .into_response();
80    }
81
82    match state.domain_manager.delete_domain(id, auth.tenant_id).await {
83        Ok(true) => Json(ApiResponse::success(())).into_response(),
84        Ok(false) => (
85            StatusCode::NOT_FOUND,
86            Json(ApiResponse::<()>::error("Domain not found")),
87        )
88            .into_response(),
89        Err(e) => error_response(e).into_response(),
90    }
91}
92
93/// Trigger domain verification.
94pub async fn verify_domain(
95    State(state): State<SaasState>,
96    Auth(auth): Auth,
97    Path(id): Path<Uuid>,
98) -> impl IntoResponse {
99    if !auth.can_write("domains") {
100        return (
101            StatusCode::FORBIDDEN,
102            Json(ApiResponse::<()>::error("Insufficient permissions")),
103        )
104            .into_response();
105    }
106
107    match state.domain_manager.verify_domain(id, auth.tenant_id).await {
108        Ok(result) => Json(ApiResponse::success(result)).into_response(),
109        Err(e) => error_response(e).into_response(),
110    }
111}
112
113/// Enable a verified domain.
114pub async fn enable_domain(
115    State(state): State<SaasState>,
116    Auth(auth): Auth,
117    Path(id): Path<Uuid>,
118) -> impl IntoResponse {
119    if !auth.can_write("domains") {
120        return (
121            StatusCode::FORBIDDEN,
122            Json(ApiResponse::<()>::error("Insufficient permissions")),
123        )
124            .into_response();
125    }
126
127    match state.domain_manager.enable_domain(id, auth.tenant_id).await {
128        Ok(true) => Json(ApiResponse::success(())).into_response(),
129        Ok(false) => (
130            StatusCode::BAD_REQUEST,
131            Json(ApiResponse::<()>::error(
132                "Could not enable domain. Is it verified?",
133            )),
134        )
135            .into_response(),
136        Err(e) => error_response(e).into_response(),
137    }
138}
139
140/// Disable a domain.
141pub async fn disable_domain(
142    State(state): State<SaasState>,
143    Auth(auth): Auth,
144    Path(id): Path<Uuid>,
145) -> impl IntoResponse {
146    if !auth.can_write("domains") {
147        return (
148            StatusCode::FORBIDDEN,
149            Json(ApiResponse::<()>::error("Insufficient permissions")),
150        )
151            .into_response();
152    }
153
154    match state
155        .domain_manager
156        .disable_domain(id, auth.tenant_id)
157        .await
158    {
159        Ok(true) => Json(ApiResponse::success(())).into_response(),
160        Ok(false) => (
161            StatusCode::NOT_FOUND,
162            Json(ApiResponse::<()>::error("Domain not found")),
163        )
164            .into_response(),
165        Err(e) => error_response(e).into_response(),
166    }
167}