213 lines
6.7 KiB
Rust
213 lines
6.7 KiB
Rust
use std::{collections::HashMap, str::FromStr};
|
|
|
|
use axum::{
|
|
body::Full,
|
|
extract::Path,
|
|
handler::Handler,
|
|
http::{header, StatusCode},
|
|
response::{self, Html, IntoResponse, Redirect, Response},
|
|
routing, Extension, Form, Json, Router,
|
|
};
|
|
use warp::{http::HeaderValue, hyper::Uri, path::Tail, Filter, Rejection, Reply};
|
|
|
|
use crate::svc::auth::AuthError;
|
|
|
|
use super::{
|
|
servek::{Server, ServerError},
|
|
CreateProfileRequest, LoginRequest, Notification,
|
|
};
|
|
use rust_embed::RustEmbed;
|
|
|
|
#[derive(RustEmbed)]
|
|
#[folder = "static"]
|
|
struct StaticData;
|
|
|
|
impl Server {
|
|
async fn index() -> impl IntoResponse {
|
|
(
|
|
StatusCode::OK,
|
|
response::Html(include_str!("../../templates/html/index.html")),
|
|
)
|
|
}
|
|
|
|
pub(super) fn register_html(&self, router: &Router) -> Router {
|
|
router
|
|
.clone()
|
|
.route("/", routing::get(Self::index))
|
|
.route("/login", routing::get(Self::login_page))
|
|
.route(
|
|
"/signup",
|
|
routing::get(Self::signup_page).post(Self::create_user),
|
|
)
|
|
.route("/static/*file", routing::get(Self::static_handler))
|
|
.fallback(routing::get(Self::handler_404))
|
|
}
|
|
|
|
async fn handler_404() -> impl IntoResponse {
|
|
(
|
|
StatusCode::OK,
|
|
response::Html(include_str!("../../templates/html/404.html")),
|
|
)
|
|
}
|
|
|
|
fn login_page_with(
|
|
&self,
|
|
tag_name: String,
|
|
message: String,
|
|
) -> Result<response::Html<String>, ServerError> {
|
|
Ok(self
|
|
.hb
|
|
.render(
|
|
"login",
|
|
&serde_json::json!(Notification { message, tag_name }),
|
|
)
|
|
.map(|html| response::Html(html))?)
|
|
}
|
|
|
|
async fn login_page(
|
|
Extension(srv): Extension<Server>,
|
|
) -> Result<impl IntoResponse, ServerError> {
|
|
Ok((
|
|
StatusCode::OK,
|
|
response::Html(srv.hb.render("login", &serde_json::json!(()))?),
|
|
))
|
|
}
|
|
|
|
// async fn login(
|
|
// Extension(srv): Extension<Server>,
|
|
// Form(login): Form<LoginRequest>,
|
|
// ) -> Result<impl IntoResponse, ServerError> {
|
|
// if login.username == "" || login.password == "" {
|
|
// return srv.login_page_with(
|
|
// "error-partial".to_owned(),
|
|
// "credentials required".to_owned(),
|
|
// );
|
|
// }
|
|
// let token = srv.auth.login(login.username, login.password).await?;
|
|
// }
|
|
|
|
// async fn login(
|
|
// srv: Server,
|
|
// Form(body): Form<HashMap<String, String>>,
|
|
// ) -> Result<response::Html<String>, ServerError> {
|
|
// let user = body
|
|
// .get("username")
|
|
// .ok_or(ServerError::BadRequest("no username provided".to_owned()))?;
|
|
// let pass = body
|
|
// .get("password")
|
|
// .ok_or(ServerError::BadRequest("no password provided".to_owned()))?;
|
|
|
|
// let token = srv
|
|
// .auth
|
|
// .login(user.clone(), pass.clone())
|
|
// .await
|
|
// .map(|html| response::Html(html));
|
|
// if let Err(e) = &token {
|
|
// if let AuthError::InvalidCredentials = e {
|
|
// return srv.login_with_error("invalid credentials".to_owned());
|
|
// }
|
|
// }
|
|
// Ok(token?)
|
|
// }
|
|
|
|
fn with_server(
|
|
srv: Server,
|
|
) -> impl Filter<Extract = (Server,), Error = std::convert::Infallible> + Clone {
|
|
warp::any().map(move || srv.clone())
|
|
}
|
|
|
|
// fn profile(&self) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
|
// warp::get().and(
|
|
// warp::path!("@" / String)
|
|
// .and(Self::with_server(self.clone()))
|
|
// .and_then(|username: String, srv: Server| async move {
|
|
// srv.hb
|
|
// .render(
|
|
// "profile",
|
|
// &serde_json::json!(srv
|
|
// .profiler
|
|
// .profile(username)
|
|
// .await
|
|
// .map_err(|e| ServerError::from(e))?),
|
|
// )
|
|
// .map(|html| warp::reply::html(html))
|
|
// .map_err(|e| ServerError::from(e).rejection())
|
|
// }),
|
|
// )
|
|
// }
|
|
|
|
async fn create_user(
|
|
Extension(srv): Extension<Server>,
|
|
Form(body): Form<CreateProfileRequest>,
|
|
) -> Result<impl IntoResponse, ServerError> {
|
|
if body.username == "" {
|
|
return srv.signup_page_with("error-partial".to_owned(), "empty username".to_owned());
|
|
}
|
|
if body.password == "" {
|
|
return srv.signup_page_with("error-partial".to_owned(), "empty password".to_owned());
|
|
}
|
|
if body.email == "" {
|
|
return srv.signup_page_with("error-partial".to_owned(), "empty email".to_owned());
|
|
}
|
|
srv.profiler
|
|
.create_user(body.username, body.password, body.email)
|
|
.await?;
|
|
srv.signup_page_with("success-partial".to_owned(), "signup successful".to_owned())
|
|
}
|
|
|
|
async fn signup_page(
|
|
Extension(srv): Extension<Server>,
|
|
) -> Result<impl IntoResponse, ServerError> {
|
|
Ok((
|
|
StatusCode::OK,
|
|
response::Html(srv.hb.render("signup", &serde_json::json!(()))?),
|
|
))
|
|
}
|
|
|
|
fn signup_page_with(
|
|
&self,
|
|
tag_name: String,
|
|
message: String,
|
|
) -> Result<impl IntoResponse, ServerError> {
|
|
Ok((
|
|
StatusCode::OK,
|
|
response::Html(self.hb.render(
|
|
"signup",
|
|
&serde_json::json!(Notification { message, tag_name }),
|
|
)?),
|
|
))
|
|
}
|
|
|
|
async fn static_handler(Path(mut path): Path<String>) -> impl IntoResponse {
|
|
path.remove(0);
|
|
println!("getting path: {}", path);
|
|
StaticFile(path)
|
|
}
|
|
}
|
|
|
|
pub struct StaticFile<T>(pub T);
|
|
|
|
impl<T> IntoResponse for StaticFile<T>
|
|
where
|
|
T: Into<String>,
|
|
{
|
|
fn into_response(self) -> axum::response::Response {
|
|
let path = self.0.into();
|
|
|
|
match StaticData::get(path.as_str()) {
|
|
Some(content) => {
|
|
let body = axum::body::boxed(Full::from(content.data));
|
|
let mime = mime_guess::from_path(path).first_or_octet_stream();
|
|
Response::builder()
|
|
.header(header::CONTENT_TYPE, mime.as_ref())
|
|
.body(body)
|
|
.unwrap()
|
|
}
|
|
None => Response::builder()
|
|
.status(StatusCode::NOT_FOUND)
|
|
.body(axum::body::boxed(Full::from("404")))
|
|
.unwrap(),
|
|
}
|
|
}
|
|
}
|