Add authentication from upstream providers (#107)
All checks were successful
continuous-integration/drone/push Build is passing

Let BasicOIDC delegate authentication to upstream providers (Google, GitHub, GitLab, Keycloak...)

Reviewed-on: #107
This commit is contained in:
2023-04-27 10:10:28 +00:00
parent 4f7c56a4b8
commit 9b18b787a9
39 changed files with 1740 additions and 189 deletions

View File

@ -2,6 +2,7 @@ use actix::Addr;
use actix_identity::Identity;
use actix_web::{web, HttpRequest, HttpResponse, Responder};
use askama::Template;
use std::sync::Arc;
use crate::actors::bruteforce_actor::BruteForceActor;
use crate::actors::users_actor::{LoginResult, UsersActor};
@ -12,17 +13,18 @@ use crate::controllers::base_controller::{
};
use crate::data::action_logger::{Action, ActionLogger};
use crate::data::login_redirect::LoginRedirect;
use crate::data::provider::{Provider, ProvidersManager};
use crate::data::remote_ip::RemoteIP;
use crate::data::session_identity::{SessionIdentity, SessionStatus};
use crate::data::user::User;
use crate::data::webauthn_manager::WebAuthManagerReq;
struct BaseLoginPage<'a> {
danger: Option<String>,
success: Option<String>,
page_title: &'static str,
app_name: &'static str,
redirect_uri: &'a LoginRedirect,
pub struct BaseLoginPage<'a> {
pub danger: Option<String>,
pub success: Option<String>,
pub page_title: &'static str,
pub app_name: &'static str,
pub redirect_uri: &'a LoginRedirect,
}
#[derive(Template)]
@ -30,6 +32,7 @@ struct BaseLoginPage<'a> {
struct LoginTemplate<'a> {
_p: BaseLoginPage<'a>,
login: String,
providers: Vec<Provider>,
}
#[derive(Template)]
@ -77,6 +80,7 @@ pub struct LoginRequestQuery {
#[allow(clippy::too_many_arguments)]
pub async fn login_route(
remote_ip: RemoteIP,
providers: web::Data<Arc<ProvidersManager>>,
users: web::Data<Addr<UsersActor>>,
bruteforce: web::Data<Addr<BruteForceActor>>,
query: web::Query<LoginRequestQuery>,
@ -121,7 +125,7 @@ pub async fn login_route(
query.redirect.get_encoded()
));
}
// Check if the user has to valide a second factor
// Check if the user has to validate a second factor
else if SessionIdentity(id.as_ref()).need_2fa_auth() {
return redirect_user(&format!(
"/2fa_auth?redirect={}",
@ -132,7 +136,7 @@ pub async fn login_route(
else if let Some(req) = &req {
login = req.login.clone();
let response: LoginResult = users
.send(users_actor::LoginRequest {
.send(users_actor::LocalLoginRequest {
login: login.clone(),
password: req.password.clone(),
})
@ -163,6 +167,12 @@ pub async fn login_route(
danger = Some("Your account is disabled!".to_string());
}
LoginResult::LocalAuthForbidden => {
log::warn!("Failed login for username {} : attempted to use local auth, but it is forbidden", &login);
logger.log(Action::TryLocalLoginFromUnauthorizedAccount(&login));
danger = Some("You cannot login from local auth with your account!".to_string());
}
LoginResult::Error => {
danger = Some("An unkown error occured while trying to sign you in!".to_string());
}
@ -197,6 +207,7 @@ pub async fn login_route(
redirect_uri: &query.redirect,
},
login,
providers: providers.cloned(),
}
.render()
.unwrap(),