Can customize login background image
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -14,7 +14,6 @@ body {
|
|||||||
/* background */
|
/* background */
|
||||||
@media screen and (min-width: 767px) {
|
@media screen and (min-width: 767px) {
|
||||||
.bg-login {
|
.bg-login {
|
||||||
background-image: url(/assets/img/forest.jpg);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use crate::controllers::base_controller::{
|
|||||||
build_fatal_error_page, redirect_user, redirect_user_for_login,
|
build_fatal_error_page, redirect_user, redirect_user_for_login,
|
||||||
};
|
};
|
||||||
use crate::data::action_logger::{Action, ActionLogger};
|
use crate::data::action_logger::{Action, ActionLogger};
|
||||||
|
use crate::data::app_config::AppConfig;
|
||||||
use crate::data::force_2fa_auth::Force2FAAuth;
|
use crate::data::force_2fa_auth::Force2FAAuth;
|
||||||
use crate::data::login_redirect::{LoginRedirect, get_2fa_url};
|
use crate::data::login_redirect::{LoginRedirect, get_2fa_url};
|
||||||
use crate::data::provider::{Provider, ProvidersManager};
|
use crate::data::provider::{Provider, ProvidersManager};
|
||||||
@@ -21,46 +22,60 @@ use crate::data::user::User;
|
|||||||
use crate::data::webauthn_manager::WebAuthManagerReq;
|
use crate::data::webauthn_manager::WebAuthManagerReq;
|
||||||
use crate::utils::string_utils;
|
use crate::utils::string_utils;
|
||||||
|
|
||||||
pub struct BaseLoginPage<'a> {
|
pub struct BaseLoginPage {
|
||||||
pub danger: Option<String>,
|
pub danger: Option<String>,
|
||||||
pub success: Option<String>,
|
pub success: Option<String>,
|
||||||
|
pub background_image: &'static str,
|
||||||
pub page_title: &'static str,
|
pub page_title: &'static str,
|
||||||
pub app_name: &'static str,
|
pub app_name: &'static str,
|
||||||
pub redirect_uri: &'a LoginRedirect,
|
pub redirect_uri: LoginRedirect,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BaseLoginPage {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
page_title: "Login",
|
||||||
|
danger: None,
|
||||||
|
success: None,
|
||||||
|
background_image: &AppConfig::get().login_background_image,
|
||||||
|
app_name: APP_NAME,
|
||||||
|
redirect_uri: LoginRedirect::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "login/login.html")]
|
#[template(path = "login/login.html")]
|
||||||
struct LoginTemplate<'a> {
|
struct LoginTemplate {
|
||||||
p: BaseLoginPage<'a>,
|
p: BaseLoginPage,
|
||||||
login: String,
|
login: String,
|
||||||
providers: Vec<Provider>,
|
providers: Vec<Provider>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "login/password_reset.html")]
|
#[template(path = "login/password_reset.html")]
|
||||||
struct PasswordResetTemplate<'a> {
|
struct PasswordResetTemplate {
|
||||||
p: BaseLoginPage<'a>,
|
p: BaseLoginPage,
|
||||||
min_pass_len: usize,
|
min_pass_len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "login/choose_second_factor.html")]
|
#[template(path = "login/choose_second_factor.html")]
|
||||||
struct ChooseSecondFactorTemplate<'a> {
|
struct ChooseSecondFactorTemplate<'a> {
|
||||||
p: BaseLoginPage<'a>,
|
p: BaseLoginPage,
|
||||||
user: &'a User,
|
user: &'a User,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "login/otp_input.html")]
|
#[template(path = "login/otp_input.html")]
|
||||||
struct LoginWithOTPTemplate<'a> {
|
struct LoginWithOTPTemplate {
|
||||||
p: BaseLoginPage<'a>,
|
p: BaseLoginPage,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "login/webauthn_input.html")]
|
#[template(path = "login/webauthn_input.html")]
|
||||||
struct LoginWithWebauthnTemplate<'a> {
|
struct LoginWithWebauthnTemplate {
|
||||||
p: BaseLoginPage<'a>,
|
p: BaseLoginPage,
|
||||||
opaque_state: String,
|
opaque_state: String,
|
||||||
challenge_json: String,
|
challenge_json: String,
|
||||||
}
|
}
|
||||||
@@ -216,8 +231,8 @@ pub async fn login_route(
|
|||||||
page_title: "Login",
|
page_title: "Login",
|
||||||
danger,
|
danger,
|
||||||
success,
|
success,
|
||||||
app_name: APP_NAME,
|
redirect_uri: query.0.redirect,
|
||||||
redirect_uri: &query.redirect,
|
..Default::default()
|
||||||
},
|
},
|
||||||
login,
|
login,
|
||||||
providers: providers.cloned(),
|
providers: providers.cloned(),
|
||||||
@@ -289,9 +304,8 @@ pub async fn reset_password_route(
|
|||||||
p: BaseLoginPage {
|
p: BaseLoginPage {
|
||||||
page_title: "Password reset",
|
page_title: "Password reset",
|
||||||
danger,
|
danger,
|
||||||
success: None,
|
redirect_uri: query.0.redirect,
|
||||||
app_name: APP_NAME,
|
..Default::default()
|
||||||
redirect_uri: &query.redirect,
|
|
||||||
},
|
},
|
||||||
min_pass_len: MIN_PASS_LEN,
|
min_pass_len: MIN_PASS_LEN,
|
||||||
}
|
}
|
||||||
@@ -339,10 +353,8 @@ pub async fn choose_2fa_method(
|
|||||||
ChooseSecondFactorTemplate {
|
ChooseSecondFactorTemplate {
|
||||||
p: BaseLoginPage {
|
p: BaseLoginPage {
|
||||||
page_title: "Two factor authentication",
|
page_title: "Two factor authentication",
|
||||||
danger: None,
|
redirect_uri: query.0.redirect,
|
||||||
success: None,
|
..Default::default()
|
||||||
app_name: APP_NAME,
|
|
||||||
redirect_uri: &query.redirect,
|
|
||||||
},
|
},
|
||||||
user: &user,
|
user: &user,
|
||||||
}
|
}
|
||||||
@@ -430,8 +442,8 @@ pub async fn login_with_otp(
|
|||||||
danger,
|
danger,
|
||||||
success: None,
|
success: None,
|
||||||
page_title: "Two-Factor Auth",
|
page_title: "Two-Factor Auth",
|
||||||
app_name: APP_NAME,
|
redirect_uri: query.0.redirect,
|
||||||
redirect_uri: &query.redirect,
|
..Default::default()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
@@ -493,11 +505,9 @@ pub async fn login_with_webauthn(
|
|||||||
HttpResponse::Ok().body(
|
HttpResponse::Ok().body(
|
||||||
LoginWithWebauthnTemplate {
|
LoginWithWebauthnTemplate {
|
||||||
p: BaseLoginPage {
|
p: BaseLoginPage {
|
||||||
danger: None,
|
|
||||||
success: None,
|
|
||||||
page_title: "Two-Factor Auth",
|
page_title: "Two-Factor Auth",
|
||||||
app_name: APP_NAME,
|
redirect_uri: query.0.redirect,
|
||||||
redirect_uri: &query.redirect,
|
..Default::default()
|
||||||
},
|
},
|
||||||
opaque_state: challenge.opaque_state,
|
opaque_state: challenge.opaque_state,
|
||||||
challenge_json: urlencoding::encode(&challenge_json).to_string(),
|
challenge_json: urlencoding::encode(&challenge_json).to_string(),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::actors::bruteforce_actor::BruteForceActor;
|
|||||||
use crate::actors::providers_states_actor::{ProviderLoginState, ProvidersStatesActor};
|
use crate::actors::providers_states_actor::{ProviderLoginState, ProvidersStatesActor};
|
||||||
use crate::actors::users_actor::{LoginResult, UsersActor};
|
use crate::actors::users_actor::{LoginResult, UsersActor};
|
||||||
use crate::actors::{bruteforce_actor, providers_states_actor, users_actor};
|
use crate::actors::{bruteforce_actor, providers_states_actor, users_actor};
|
||||||
use crate::constants::{APP_NAME, MAX_FAILED_LOGIN_ATTEMPTS};
|
use crate::constants::MAX_FAILED_LOGIN_ATTEMPTS;
|
||||||
use crate::controllers::base_controller::{build_fatal_error_page, redirect_user};
|
use crate::controllers::base_controller::{build_fatal_error_page, redirect_user};
|
||||||
use crate::controllers::login_controller::BaseLoginPage;
|
use crate::controllers::login_controller::BaseLoginPage;
|
||||||
use crate::data::action_logger::{Action, ActionLogger};
|
use crate::data::action_logger::{Action, ActionLogger};
|
||||||
@@ -22,7 +22,7 @@ use crate::data::session_identity::{SessionIdentity, SessionStatus};
|
|||||||
#[derive(askama::Template)]
|
#[derive(askama::Template)]
|
||||||
#[template(path = "login/prov_login_error.html")]
|
#[template(path = "login/prov_login_error.html")]
|
||||||
struct ProviderLoginError<'a> {
|
struct ProviderLoginError<'a> {
|
||||||
p: BaseLoginPage<'a>,
|
p: BaseLoginPage,
|
||||||
message: &'a str,
|
message: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,11 +30,9 @@ impl<'a> ProviderLoginError<'a> {
|
|||||||
pub fn get(message: &'a str, redirect_uri: &'a LoginRedirect) -> HttpResponse {
|
pub fn get(message: &'a str, redirect_uri: &'a LoginRedirect) -> HttpResponse {
|
||||||
let body = Self {
|
let body = Self {
|
||||||
p: BaseLoginPage {
|
p: BaseLoginPage {
|
||||||
danger: None,
|
|
||||||
success: None,
|
|
||||||
page_title: "Upstream login",
|
page_title: "Upstream login",
|
||||||
app_name: APP_NAME,
|
redirect_uri: redirect_uri.clone(),
|
||||||
redirect_uri,
|
..Default::default()
|
||||||
},
|
},
|
||||||
message,
|
message,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ pub struct AppConfig {
|
|||||||
/// Action logger output format
|
/// Action logger output format
|
||||||
#[arg(long, env, default_value_t, value_enum)]
|
#[arg(long, env, default_value_t, value_enum)]
|
||||||
pub action_logger_format: ActionLoggerFormat,
|
pub action_logger_format: ActionLoggerFormat,
|
||||||
|
|
||||||
|
/// Login background image
|
||||||
|
#[arg(long, env, default_value = "/assets/img/forest.jpg")]
|
||||||
|
pub login_background_image: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
|
|||||||
@@ -30,6 +30,12 @@
|
|||||||
font-size: 3.5rem;
|
font-size: 3.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 767px) {
|
||||||
|
.bg-login {
|
||||||
|
background-image: url({{ p.background_image }});
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user