postrust_proxy/saas/handlers/
upstreams.rs1use crate::admin::api::ApiResponse;
4use crate::saas::auth::Auth;
5use crate::saas::handlers::{error_response, require_scope, SaasState};
6use crate::saas::types::{CreateBackendRequest, CreateUpstreamRequest, UpdateUpstreamRequest};
7use axum::{
8 extract::{Path, State},
9 http::StatusCode,
10 response::IntoResponse,
11 Json,
12};
13use uuid::Uuid;
14
15pub async fn list_upstreams(State(state): State<SaasState>, Auth(auth): Auth) -> impl IntoResponse {
17 if let Err(refusal) = require_scope(&auth, "upstreams:read") {
18 return refusal;
19 }
20
21 match state.domain_manager.list_upstreams(auth.tenant_id).await {
22 Ok(upstreams) => Json(ApiResponse::success(upstreams)).into_response(),
23 Err(e) => error_response(e).into_response(),
24 }
25}
26
27pub async fn create_upstream(
29 State(state): State<SaasState>,
30 Auth(auth): Auth,
31 Json(req): Json<CreateUpstreamRequest>,
32) -> impl IntoResponse {
33 if let Err(refusal) = require_scope(&auth, "upstreams:write") {
34 return refusal;
35 }
36
37 match state
38 .domain_manager
39 .create_upstream(auth.tenant_id, req)
40 .await
41 {
42 Ok(upstream) => (StatusCode::CREATED, Json(ApiResponse::success(upstream))).into_response(),
43 Err(e) => error_response(e).into_response(),
44 }
45}
46
47pub async fn get_upstream(
49 State(state): State<SaasState>,
50 Auth(auth): Auth,
51 Path(id): Path<Uuid>,
52) -> impl IntoResponse {
53 if let Err(refusal) = require_scope(&auth, "upstreams:read") {
54 return refusal;
55 }
56
57 match state.domain_manager.get_upstream(id, auth.tenant_id).await {
58 Ok(Some(upstream)) => Json(ApiResponse::success(upstream)).into_response(),
59 Ok(None) => (
60 StatusCode::NOT_FOUND,
61 Json(ApiResponse::<()>::error_with_code(
62 "not_found",
63 "Upstream not found",
64 )),
65 )
66 .into_response(),
67 Err(e) => error_response(e).into_response(),
68 }
69}
70
71pub async fn update_upstream(
73 State(state): State<SaasState>,
74 Auth(auth): Auth,
75 Path(id): Path<Uuid>,
76 Json(req): Json<UpdateUpstreamRequest>,
77) -> impl IntoResponse {
78 if let Err(refusal) = require_scope(&auth, "upstreams:write") {
79 return refusal;
80 }
81
82 match state
83 .domain_manager
84 .update_upstream(id, auth.tenant_id, req)
85 .await
86 {
87 Ok(Some(upstream)) => Json(ApiResponse::success(upstream)).into_response(),
88 Ok(None) => (
89 StatusCode::NOT_FOUND,
90 Json(ApiResponse::<()>::error_with_code(
91 "not_found",
92 "Upstream not found",
93 )),
94 )
95 .into_response(),
96 Err(e) => error_response(e).into_response(),
97 }
98}
99
100pub async fn delete_upstream(
102 State(state): State<SaasState>,
103 Auth(auth): Auth,
104 Path(id): Path<Uuid>,
105) -> impl IntoResponse {
106 if let Err(refusal) = require_scope(&auth, "upstreams:write") {
107 return refusal;
108 }
109
110 match state
111 .domain_manager
112 .delete_upstream(id, auth.tenant_id)
113 .await
114 {
115 Ok(true) => Json(ApiResponse::success(())).into_response(),
116 Ok(false) => (
117 StatusCode::NOT_FOUND,
118 Json(ApiResponse::<()>::error_with_code(
119 "not_found",
120 "Upstream not found",
121 )),
122 )
123 .into_response(),
124 Err(e) => error_response(e).into_response(),
125 }
126}
127
128pub async fn add_backend(
130 State(state): State<SaasState>,
131 Auth(auth): Auth,
132 Path(upstream_id): Path<Uuid>,
133 Json(req): Json<CreateBackendRequest>,
134) -> impl IntoResponse {
135 if let Err(refusal) = require_scope(&auth, "upstreams:write") {
136 return refusal;
137 }
138
139 match state
140 .domain_manager
141 .add_backend(upstream_id, auth.tenant_id, req)
142 .await
143 {
144 Ok(backend) => (StatusCode::CREATED, Json(ApiResponse::success(backend))).into_response(),
145 Err(e) => error_response(e).into_response(),
146 }
147}
148
149pub async fn remove_backend(
151 State(state): State<SaasState>,
152 Auth(auth): Auth,
153 Path((upstream_id, backend_id)): Path<(Uuid, Uuid)>,
154) -> impl IntoResponse {
155 if let Err(refusal) = require_scope(&auth, "upstreams:write") {
156 return refusal;
157 }
158
159 match state
160 .domain_manager
161 .remove_backend(backend_id, upstream_id, auth.tenant_id)
162 .await
163 {
164 Ok(true) => Json(ApiResponse::success(())).into_response(),
165 Ok(false) => (
166 StatusCode::NOT_FOUND,
167 Json(ApiResponse::<()>::error_with_code(
168 "not_found",
169 "Backend not found",
170 )),
171 )
172 .into_response(),
173 Err(e) => error_response(e).into_response(),
174 }
175}