mz_frontegg_mock/handlers/
tenant.rs1use std::sync::Arc;
17
18use axum::Json;
19use axum::extract::{Path, State};
20use axum::http::StatusCode;
21use chrono::Utc;
22use serde::Deserialize;
23use uuid::Uuid;
24
25use crate::models::{TenantConfig, TenantResponse};
26use crate::server::Context;
27
28pub async fn handle_list_tenants(State(context): State<Arc<Context>>) -> Json<Vec<TenantResponse>> {
32 let tenants = context.tenants.lock().unwrap();
33 Json(tenants.values().map(TenantResponse::from).collect())
34}
35
36pub async fn handle_get_tenant(
42 State(context): State<Arc<Context>>,
43 Path(id): Path<Uuid>,
44) -> Json<Vec<TenantResponse>> {
45 let tenants = context.tenants.lock().unwrap();
46 Json(
47 tenants
48 .get(&id)
49 .map(TenantResponse::from)
50 .into_iter()
51 .collect(),
52 )
53}
54
55#[derive(Debug, Deserialize)]
57#[serde(rename_all = "camelCase")]
58pub struct CreateTenantRequest {
59 #[serde(default = "Uuid::new_v4")]
60 pub tenant_id: Uuid,
61 pub name: String,
62 #[serde(default)]
63 pub metadata: serde_json::Value,
64 pub creator_name: Option<String>,
65 pub creator_email: Option<String>,
66}
67
68pub async fn handle_create_tenant(
72 State(context): State<Arc<Context>>,
73 Json(body): Json<CreateTenantRequest>,
74) -> Result<Json<TenantResponse>, StatusCode> {
75 let now = Utc::now();
76 let metadata = match body.metadata {
77 serde_json::Value::Null => serde_json::json!({}),
78 metadata => metadata,
79 };
80 let tenant = TenantConfig {
81 id: body.tenant_id,
82 name: body.name,
83 metadata,
84 creator_name: body.creator_name,
85 creator_email: body.creator_email,
86 created_at: now,
87 updated_at: now,
88 deleted_at: None,
89 };
90
91 let mut tenants = context.tenants.lock().unwrap();
92 if tenants.contains_key(&tenant.id) {
93 return Err(StatusCode::CONFLICT);
94 }
95 let response = TenantResponse::from(&tenant);
96 tenants.insert(tenant.id, tenant);
97 Ok(Json(response))
98}
99
100pub async fn handle_delete_tenant(
104 State(context): State<Arc<Context>>,
105 Path(id): Path<Uuid>,
106) -> StatusCode {
107 let removed = context.tenants.lock().unwrap().remove(&id);
108 match removed {
109 Some(_) => StatusCode::OK,
110 None => StatusCode::NOT_FOUND,
111 }
112}
113
114#[derive(Debug, Deserialize)]
116pub struct SetTenantMetadataRequest {
117 pub metadata: serde_json::Value,
118}
119
120pub async fn handle_set_tenant_metadata(
125 State(context): State<Arc<Context>>,
126 Path(id): Path<Uuid>,
127 Json(body): Json<SetTenantMetadataRequest>,
128) -> Result<Json<TenantResponse>, StatusCode> {
129 let mut tenants = context.tenants.lock().unwrap();
130 let tenant = tenants.get_mut(&id).ok_or(StatusCode::NOT_FOUND)?;
131
132 match (tenant.metadata.as_object_mut(), body.metadata) {
133 (Some(existing), serde_json::Value::Object(new)) => existing.extend(new),
134 (_, new) => tenant.metadata = new,
135 }
136 tenant.updated_at = Utc::now();
137
138 Ok(Json(TenantResponse::from(&*tenant)))
139}
140
141pub async fn handle_delete_tenant_metadata(
145 State(context): State<Arc<Context>>,
146 Path((id, key)): Path<(Uuid, String)>,
147) -> Result<Json<TenantResponse>, StatusCode> {
148 let mut tenants = context.tenants.lock().unwrap();
149 let tenant = tenants.get_mut(&id).ok_or(StatusCode::NOT_FOUND)?;
150
151 if let Some(existing) = tenant.metadata.as_object_mut() {
152 existing.remove(&key);
153 }
154 tenant.updated_at = Utc::now();
155
156 Ok(Json(TenantResponse::from(&*tenant)))
157}