use crate::{ get_user_from_token, routes::api::v1::{CreateDomain, UpdateDomainData}, State, }; use axum::{extract::Path, response::IntoResponse, http::StatusCode, Extension, Json}; use axum_extra::extract::CookieJar; use tetratto_core::model::{ auth::AchievementName, littleweb::{Domain, ServiceFsMime}, oauth, ApiReturn, Error, }; pub async fn get_request( Path(id): Path, Extension(data): Extension, ) -> impl IntoResponse { let data = &(data.read().await).0; match data.get_domain_by_id(id).await { Ok(x) => Json(ApiReturn { ok: true, message: "Success".to_string(), payload: Some(x), }), Err(e) => return Json(e.into()), } } pub async fn list_request(jar: CookieJar, Extension(data): Extension) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::UserReadDomains) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data.get_domains_by_user(user.id).await { Ok(x) => Json(ApiReturn { ok: true, message: "Success".to_string(), payload: Some(x), }), Err(e) => Json(e.into()), } } pub async fn create_request( jar: CookieJar, Extension(data): Extension, Json(req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; let mut user = match get_user_from_token!(jar, data, oauth::AppScope::UserCreateDomains) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; // award achievement if let Err(e) = data .add_achievement(&mut user, AchievementName::CreateDomain.into(), true) .await { return Json(e.into()); } // ... match data .create_domain(Domain::new(req.name, req.tld, user.id)) .await { Ok(x) => Json(ApiReturn { ok: true, message: "Domain created".to_string(), payload: x.id.to_string(), }), Err(e) => Json(e.into()), } } pub async fn update_data_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, Json(req): Json, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageDomains) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data.update_domain_data(id, &user, req.data).await { Ok(_) => Json(ApiReturn { ok: true, message: "Domain updated".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn delete_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let data = &(data.read().await).0; let user = match get_user_from_token!(jar, data, oauth::AppScope::UserManageDomains) { Some(ua) => ua, None => return Json(Error::NotAllowed.into()), }; match data.delete_domain(id, &user).await { Ok(_) => Json(ApiReturn { ok: true, message: "Domain deleted".to_string(), payload: (), }), Err(e) => Json(e.into()), } } pub async fn get_file_request( Path(mut addr): Path, Extension(data): Extension, ) -> impl IntoResponse { if !addr.starts_with("atto://") { addr = format!("atto://{addr}"); } // ... let data = &(data.read().await).0; let (subdomain, domain, tld, path) = Domain::from_str(&addr); // resolve domain let domain = match data.get_domain_by_name_tld(&domain, &tld).await { Ok(x) => x, Err(e) => { return Err((StatusCode::BAD_REQUEST, e.to_string())); } }; // resolve service let service = match domain.service(&subdomain) { Some(id) => match data.get_service_by_id(id).await { Ok(x) => x, Err(e) => { return Err((StatusCode::BAD_REQUEST, e.to_string())); } }, None => { return Err(( StatusCode::NOT_FOUND, Error::GeneralNotFound("service".to_string()).to_string(), )); } }; // resolve file match service.file(&path) { Some((f, _)) => Ok(( [("Content-Type".to_string(), f.mime.to_string())], if f.mime == ServiceFsMime::Html { f.content.replace( "", &format!( "", data.0.0.host ), ) } else { f.content } .replace("atto://", "/api/v1/net/atto://"), )), None => { return Err(( StatusCode::NOT_FOUND, Error::GeneralNotFound("file".to_string()).to_string(), )); } } }