2024-07-13 13:41:23 +02:00
|
|
|
// SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
|
|
|
|
use actix_identity::Identity;
|
|
|
|
use actix_web::{error, get, post, web, HttpMessage, HttpRequest, HttpResponse, Responder};
|
|
|
|
use maud::html;
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
|
|
use super::templates;
|
|
|
|
|
|
|
|
pub fn config(cfg: &mut web::ServiceConfig) {
|
|
|
|
cfg.service(login_form).service(login).service(logout);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/login")]
|
|
|
|
async fn login_form(req: HttpRequest, user: Option<Identity>) -> HttpResponse {
|
|
|
|
if user.is_some() {
|
|
|
|
return web::Redirect::to("/")
|
|
|
|
.see_other()
|
|
|
|
.respond_to(&req)
|
|
|
|
.map_into_boxed_body();
|
|
|
|
}
|
|
|
|
|
|
|
|
templates::base(
|
|
|
|
templates::TemplateConfig {
|
|
|
|
path: "/login",
|
|
|
|
title: Some("Login"),
|
|
|
|
page_title: Some(Box::new("Login")),
|
|
|
|
user,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
html! {
|
|
|
|
form .w-25.mb-4 method="POST" {
|
|
|
|
div .mb-3 {
|
|
|
|
label .form-label for="password" { "Password" };
|
|
|
|
input .form-control type="password" id="password" name="password";
|
|
|
|
}
|
|
|
|
button .btn.btn-primary type="submit" { "Login" }
|
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.respond_to(&req)
|
|
|
|
.map_into_boxed_body()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
struct LoginForm {
|
|
|
|
password: String,
|
|
|
|
}
|
|
|
|
|
2024-07-14 13:38:36 +02:00
|
|
|
#[derive(Deserialize)]
|
|
|
|
struct LoginQuery {
|
|
|
|
redirect_to: Option<String>,
|
|
|
|
}
|
|
|
|
|
2024-07-13 13:41:23 +02:00
|
|
|
#[post("/login")]
|
|
|
|
async fn login(
|
|
|
|
req: HttpRequest,
|
|
|
|
form: web::Form<LoginForm>,
|
2024-07-14 13:38:36 +02:00
|
|
|
query: web::Query<LoginQuery>,
|
2024-07-13 13:41:23 +02:00
|
|
|
) -> Result<impl Responder, error::Error> {
|
|
|
|
// Very basic authentication for now (only password, hardcoded in environment variable)
|
|
|
|
if form.password
|
|
|
|
== std::env::var("SUPERUSER_PASSWORD")
|
|
|
|
.map_err(|_| error::ErrorInternalServerError("login disabled (no password set)"))?
|
|
|
|
{
|
|
|
|
Identity::login(&req.extensions(), "superuser".into())
|
|
|
|
.map_err(error::ErrorInternalServerError)?;
|
2024-07-14 13:38:36 +02:00
|
|
|
Ok(
|
|
|
|
web::Redirect::to(query.into_inner().redirect_to.unwrap_or("/".to_string()))
|
|
|
|
.see_other(),
|
|
|
|
)
|
2024-07-13 13:41:23 +02:00
|
|
|
} else {
|
2024-07-14 13:38:36 +02:00
|
|
|
Ok(web::Redirect::to(req.uri().to_string()).see_other())
|
2024-07-13 13:41:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[post("/logout")]
|
|
|
|
async fn logout(user: Identity) -> impl Responder {
|
|
|
|
user.logout();
|
|
|
|
|
|
|
|
web::Redirect::to("/login".to_owned()).see_other()
|
|
|
|
}
|