actix_web_admin/handlers/
auth.rs1use actix_session::Session;
2use actix_web::{web, HttpResponse, Responder};
3use serde::Deserialize;
4use tera::{Context, Tera};
5use crate::resource::{AdminTitle, AdminPrefix};
6
7#[derive(Clone)]
8pub struct SimpleAuth {
9 pub username: String,
10 pub password: String,
11}
12
13impl SimpleAuth {
14 pub fn check(&self, username: &str, password: &str) -> bool {
15 self.username == username && self.password == password
16 }
17}
18
19#[derive(Deserialize)]
20pub struct LoginRequest {
21 pub username: String,
22 pub password: String,
23}
24
25pub async fn login_page(tmpl: web::Data<Tera>, title: web::Data<AdminTitle>, prefix: web::Data<AdminPrefix>) -> impl Responder {
26 let mut ctx = Context::new();
27 ctx.insert("title", &title.0);
28 ctx.insert("page_title", "Login");
29 ctx.insert("path_dashboard", &format!("/{}/", prefix.0));
30 ctx.insert("path_logout", &format!("/{}/logout", prefix.0));
31 ctx.insert("resources", &Vec::<crate::resource::ResourceInfo>::new());
32
33 match tmpl.render("login.html", &ctx) {
34 Ok(rendered) => HttpResponse::Ok().content_type("text/html").body(rendered),
35 Err(_) => HttpResponse::InternalServerError().finish(),
36 }
37}
38
39pub async fn login(
40 session: Session,
41 auth: web::Data<SimpleAuth>,
42 form: web::Form<LoginRequest>,
43 tmpl: web::Data<Tera>,
44 title: web::Data<AdminTitle>,
45 prefix: web::Data<AdminPrefix>,
46) -> impl Responder {
47 if auth.check(&form.username, &form.password) {
48 if let Err(_) = session.insert("admin_user", &form.username) {
50 return HttpResponse::InternalServerError().body("Session error");
51 }
52 return HttpResponse::Found()
53 .insert_header(("Location", "/admin/"))
54 .finish();
55 }
56
57 let mut ctx = Context::new();
58 ctx.insert("title", &title.0);
59 ctx.insert("page_title", "Login");
60 ctx.insert("path_dashboard", &format!("/{}/", prefix.0));
61 ctx.insert("path_logout", &format!("/{}/logout", prefix.0));
62 ctx.insert("resources", &Vec::<crate::resource::ResourceInfo>::new());
63 ctx.insert("error", "Invalid username or password");
64
65 match tmpl.render("login.html", &ctx) {
66 Ok(rendered) => HttpResponse::Unauthorized().content_type("text/html").body(rendered),
67 Err(_) => HttpResponse::InternalServerError().finish(),
68 }
69}
70
71pub async fn logout(session: Session, prefix: web::Data<AdminPrefix>) -> impl Responder {
72 session.purge();
73 HttpResponse::Found()
74 .insert_header(("Location", "/admin/login"))
75 .finish()
76}