use crate::dbs::DB; use crate::err::Error; use crate::net::input::bytes_to_utf8; use crate::net::output; use crate::net::session; use bytes::Bytes; use serde::Serialize; use surrealdb::dbs::Session; use surrealdb::sql::Value; use warp::Filter; const MAX: u64 = 1024; // 1 KiB #[derive(Serialize)] struct Success { code: u16, details: String, token: Option, } impl Success { fn new(token: Option) -> Success { Success { token, code: 200, details: String::from("Authentication succeeded"), } } } #[allow(opaque_hidden_inferred_bound)] pub fn config() -> impl Filter + Clone { // Set base path let base = warp::path("signup").and(warp::path::end()); // Set opts method let opts = base.and(warp::options()).map(warp::reply); // Set post method let post = base .and(warp::post()) .and(warp::header::optional::(http::header::ACCEPT.as_str())) .and(warp::body::content_length_limit(MAX)) .and(warp::body::bytes()) .and(session::build()) .and_then(handler); // Specify route opts.or(post) } async fn handler( output: Option, body: Bytes, mut session: Session, ) -> Result { // Get a database reference let kvs = DB.get().unwrap(); // Convert the HTTP body into text let data = bytes_to_utf8(&body)?; // Parse the provided data as JSON match surrealdb::sql::json(data) { // The provided value was an object Ok(Value::Object(vars)) => { match surrealdb::iam::signup::signup(kvs, &mut session, vars).await.map_err(Error::from) { // Authentication was successful Ok(v) => match output.as_deref() { // Return nothing None => Ok(output::none()), // Text serialization Some("text/plain") => Ok(output::text(v.unwrap_or_default())), // Simple serialization Some("application/json") => Ok(output::json(&Success::new(v))), Some("application/cbor") => Ok(output::cbor(&Success::new(v))), Some("application/pack") => Ok(output::pack(&Success::new(v))), // Internal serialization Some("application/surrealdb") => Ok(output::full(&Success::new(v))), // An incorrect content-type was requested _ => Err(warp::reject::custom(Error::InvalidType)), }, // There was an error with authentication Err(e) => Err(warp::reject::custom(e)), } } // The provided value was not an object _ => Err(warp::reject::custom(Error::Request)), } }