You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
45 lines
1.2 KiB
Rust
45 lines
1.2 KiB
Rust
use actix_web::{post, web, HttpResponse};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::core::*;
|
|
use crate::model::Account;
|
|
use crate::state::AppState;
|
|
use crate::util::password::ClearPassword;
|
|
use crate::util::{password, token};
|
|
|
|
#[derive(Deserialize)]
|
|
struct AuthRequest {
|
|
email: String,
|
|
password: ClearPassword,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct AuthResponse {
|
|
token: String,
|
|
account: Account,
|
|
}
|
|
|
|
#[post("")]
|
|
async fn auth(body: web::Json<AuthRequest>, state: AppState) -> Result<HttpResponse> {
|
|
let body = body.into_inner();
|
|
// make sure unknown email address returns the same error as invalid password
|
|
let user = state
|
|
.repo
|
|
.users
|
|
.by_email(body.email)
|
|
.await
|
|
.map_err(|e| match e {
|
|
Error::NotFound => Error::BadCredentials,
|
|
e => e,
|
|
})?;
|
|
password::verify(&body.password, &user.password)?;
|
|
let account = state.repo.accounts.by_id(user.account_id).await?;
|
|
let token = token::issue(&state, &account)?;
|
|
info!(target: "auth", "Successful login for user {}", &account.name);
|
|
Ok(HttpResponse::Ok().json(AuthResponse { account, token }))
|
|
}
|
|
|
|
pub fn configure(cfg: &mut web::ServiceConfig) {
|
|
cfg.service(auth);
|
|
}
|