surrealpatch/src/net/signup.rs
2023-06-09 13:45:07 +00:00

92 lines
2.6 KiB
Rust

use crate::dbs::DB;
use crate::err::Error;
use crate::net::input::bytes_to_utf8;
use crate::net::output;
use crate::net::session;
use crate::net::CF;
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,
#[serde(skip_serializing_if = "Option::is_none")]
token: Option<String>,
}
impl Success {
fn new(token: Option<String>) -> Success {
Success {
token,
code: 200,
details: String::from("Authentication succeeded"),
}
}
}
#[allow(opaque_hidden_inferred_bound)]
pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + 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::<String>(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<String>,
body: Bytes,
mut session: Session,
) -> Result<impl warp::Reply, warp::Rejection> {
// Get a database reference
let kvs = DB.get().unwrap();
// Get the config options
let opts = CF.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, opts.strict, &mut session, vars)
.await
.map_err(Error::from)
{
// Authentication was successful
Ok(v) => match output.as_deref() {
// 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/bung") => Ok(output::full(&Success::new(v))),
// Text serialization
Some("text/plain") => Ok(output::text(v.unwrap_or_default())),
// Return nothing
None => Ok(output::none()),
// 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)),
}
}