BasicOIDC/src/controllers/settings_controller.rs

133 lines
4.3 KiB
Rust
Raw Normal View History

2022-04-04 15:39:23 +00:00
use actix::Addr;
use actix_identity::Identity;
use actix_web::{HttpResponse, Responder, web};
use askama::Template;
2022-04-05 15:17:34 +00:00
use crate::actors::{bruteforce_actor, users_actor};
use crate::actors::bruteforce_actor::BruteForceActor;
2022-04-04 15:39:23 +00:00
use crate::actors::users_actor::UsersActor;
2022-04-05 15:17:34 +00:00
use crate::constants::{APP_NAME, MAX_FAILED_LOGIN_ATTEMPTS, MIN_PASS_LEN};
use crate::data::remote_ip::RemoteIP;
2022-04-04 15:39:23 +00:00
use crate::data::session_identity::SessionIdentity;
use crate::data::user::User;
#[derive(Template)]
#[template(path = "settings/base_settings_page.html")]
struct BaseSettingsPage {
danger_message: Option<String>,
success_message: Option<String>,
page_title: &'static str,
app_name: &'static str,
is_admin: bool,
user_name: String,
}
impl BaseSettingsPage {
2022-04-05 15:17:34 +00:00
async fn get(page_title: &'static str, user: &User,
danger_message: Option<String>, success_message: Option<String>) -> BaseSettingsPage {
2022-04-04 15:39:23 +00:00
Self {
2022-04-05 15:17:34 +00:00
danger_message,
success_message,
page_title,
2022-04-04 15:39:23 +00:00
app_name: APP_NAME,
is_admin: user.admin,
user_name: user.username.to_string(),
}
}
}
#[derive(Template)]
#[template(path = "settings/account_details.html")]
struct AccountDetailsPage {
_parent: BaseSettingsPage,
user_id: String,
first_name: String,
last_name: String,
username: String,
email: String,
}
2022-04-05 15:17:34 +00:00
#[derive(Template)]
#[template(path = "settings/change_password.html")]
struct ChangePasswordPage {
_parent: BaseSettingsPage,
min_pwd_len: usize,
}
2022-04-04 15:39:23 +00:00
/// Account details page
2022-04-05 15:17:34 +00:00
pub async fn account_settings_details_route(id: Identity, users: web::Data<Addr<UsersActor>>) -> impl Responder {
let user: User = users.send(
2022-04-04 15:39:23 +00:00
users_actor::GetUserRequest(SessionIdentity(&id).user_id())
).await.unwrap().0.unwrap();
HttpResponse::Ok()
.body(AccountDetailsPage {
2022-04-05 15:17:34 +00:00
_parent: BaseSettingsPage::get("Account details", &user, None, None).await,
2022-04-04 15:39:23 +00:00
user_id: user.uid,
first_name: user.first_name,
last_name: user.last_last,
username: user.username,
email: user.email,
}.render().unwrap())
2022-04-05 15:17:34 +00:00
}
#[derive(serde::Deserialize)]
pub struct PassChangeRequest {
pub old_pass: String,
pub new_pass: String,
}
/// Change password route
pub async fn change_password_route(id: Identity,
users: web::Data<Addr<UsersActor>>,
req: Option<web::Form<PassChangeRequest>>,
bruteforce: web::Data<Addr<BruteForceActor>>,
remote_ip: RemoteIP) -> impl Responder {
let mut danger = None;
let mut success = None;
let user: User = users.send(
users_actor::GetUserRequest(SessionIdentity(&id).user_id())
).await.unwrap().0.unwrap();
let failed_attempts = bruteforce.send(bruteforce_actor::CountFailedAttempt { ip: remote_ip.into() }).await.unwrap();
if failed_attempts > MAX_FAILED_LOGIN_ATTEMPTS {
danger = Some("Too many invalid password attempts. Please try to change your password later.".to_string());
} else if let Some(req) = req {
// Invalid password
if !user.verify_password(&req.old_pass) {
danger = Some("Old password is invalid!".to_string());
bruteforce.send(bruteforce_actor::RecordFailedAttempt { ip: remote_ip.into() }).await.unwrap();
}
// Password too short
else if req.new_pass.len() < MIN_PASS_LEN {
danger = Some("New password is too short!".to_string());
}
// Change password
else {
let res = users.send(
users_actor::ChangePasswordRequest {
user_id: user.uid.clone(),
new_password: req.new_pass.to_string(),
temporary: false,
}
).await.unwrap().0;
if !res {
danger = Some("An error occurred while trying to change your password!".to_string());
} else {
success = Some("Your password was successfully changed!".to_string());
}
}
}
HttpResponse::Ok()
.body(ChangePasswordPage {
_parent: BaseSettingsPage::get("Change password", &user, danger, success).await,
min_pwd_len: MIN_PASS_LEN,
}.render().unwrap())
2022-04-04 15:39:23 +00:00
}