Add authentication from upstream providers (#107)
All checks were successful
continuous-integration/drone/push Build is passing
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:
@ -6,35 +6,46 @@ use actix_web::{web, HttpResponse, Responder};
|
||||
use askama::Template;
|
||||
|
||||
use crate::actors::users_actor;
|
||||
use crate::actors::users_actor::UsersActor;
|
||||
use crate::actors::users_actor::{AuthorizedAuthenticationSources, UsersActor};
|
||||
use crate::constants::TEMPORARY_PASSWORDS_LEN;
|
||||
use crate::controllers::settings_controller::BaseSettingsPage;
|
||||
use crate::data::action_logger::{Action, ActionLogger};
|
||||
use crate::data::app_config::AppConfig;
|
||||
use crate::data::client::{Client, ClientID, ClientManager};
|
||||
use crate::data::current_user::CurrentUser;
|
||||
use crate::data::provider::{Provider, ProviderID, ProvidersManager};
|
||||
use crate::data::user::{GeneralSettings, GrantedClients, User, UserID};
|
||||
use crate::utils::string_utils::rand_str;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "settings/clients_list.html")]
|
||||
struct ClientsListTemplate {
|
||||
_p: BaseSettingsPage,
|
||||
struct ClientsListTemplate<'a> {
|
||||
_p: BaseSettingsPage<'a>,
|
||||
clients: Vec<Client>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "settings/providers_list.html")]
|
||||
struct ProvidersListTemplate<'a> {
|
||||
_p: BaseSettingsPage<'a>,
|
||||
providers: Vec<Provider>,
|
||||
redirect_url: String,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "settings/users_list.html")]
|
||||
struct UsersListTemplate {
|
||||
_p: BaseSettingsPage,
|
||||
struct UsersListTemplate<'a> {
|
||||
_p: BaseSettingsPage<'a>,
|
||||
users: Vec<User>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "settings/edit_user.html")]
|
||||
struct EditUserTemplate {
|
||||
_p: BaseSettingsPage,
|
||||
struct EditUserTemplate<'a> {
|
||||
_p: BaseSettingsPage<'a>,
|
||||
u: User,
|
||||
clients: Vec<Client>,
|
||||
providers: Vec<Provider>,
|
||||
}
|
||||
|
||||
pub async fn clients_route(
|
||||
@ -51,6 +62,21 @@ pub async fn clients_route(
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn providers_route(
|
||||
user: CurrentUser,
|
||||
providers: web::Data<Arc<ProvidersManager>>,
|
||||
) -> impl Responder {
|
||||
HttpResponse::Ok().body(
|
||||
ProvidersListTemplate {
|
||||
_p: BaseSettingsPage::get("OpenID Providers list", &user, None, None),
|
||||
providers: providers.cloned(),
|
||||
redirect_url: AppConfig::get().oidc_provider_redirect_url(),
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
pub struct UpdateUserQuery {
|
||||
uid: UserID,
|
||||
@ -62,6 +88,8 @@ pub struct UpdateUserQuery {
|
||||
enabled: Option<String>,
|
||||
two_factor_exemption_after_successful_login: Option<String>,
|
||||
admin: Option<String>,
|
||||
allow_local_login: Option<String>,
|
||||
authorized_sources: String,
|
||||
grant_type: String,
|
||||
granted_clients: String,
|
||||
two_factor: String,
|
||||
@ -136,6 +164,29 @@ pub async fn users_route(
|
||||
}
|
||||
}
|
||||
|
||||
// Update the list of authorized authentication sources
|
||||
let auth_sources = AuthorizedAuthenticationSources {
|
||||
local: update.0.allow_local_login.is_some(),
|
||||
upstream: match update.0.authorized_sources.as_str() {
|
||||
"" => vec![],
|
||||
s => s.split(',').map(|s| ProviderID(s.to_string())).collect(),
|
||||
},
|
||||
};
|
||||
|
||||
if edited_user.authorized_authentication_sources() != auth_sources {
|
||||
logger.log(Action::AdminSetAuthorizedAuthenticationSources(
|
||||
&edited_user,
|
||||
&auth_sources,
|
||||
));
|
||||
users
|
||||
.send(users_actor::SetAuthorizedAuthenticationSources(
|
||||
edited_user.uid.clone(),
|
||||
auth_sources,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Update list of granted clients
|
||||
let granted_clients = match update.0.grant_type.as_str() {
|
||||
"all_clients" => GrantedClients::AllClients,
|
||||
@ -240,6 +291,7 @@ pub async fn users_route(
|
||||
pub async fn create_user(
|
||||
admin: CurrentUser,
|
||||
clients: web::Data<Arc<ClientManager>>,
|
||||
providers: web::Data<Arc<ProvidersManager>>,
|
||||
) -> impl Responder {
|
||||
let user = User {
|
||||
authorized_clients: Some(
|
||||
@ -257,6 +309,7 @@ pub async fn create_user(
|
||||
_p: BaseSettingsPage::get("Create a new user", admin.deref(), None, None),
|
||||
u: user,
|
||||
clients: clients.cloned(),
|
||||
providers: providers.cloned(),
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
@ -271,6 +324,7 @@ pub struct EditUserQuery {
|
||||
pub async fn edit_user(
|
||||
admin: CurrentUser,
|
||||
clients: web::Data<Arc<ClientManager>>,
|
||||
providers: web::Data<Arc<ProvidersManager>>,
|
||||
users: web::Data<Addr<UsersActor>>,
|
||||
query: web::Query<EditUserQuery>,
|
||||
) -> impl Responder {
|
||||
@ -293,6 +347,7 @@ pub async fn edit_user(
|
||||
),
|
||||
u: edited_account.unwrap_or_default(),
|
||||
clients: clients.cloned(),
|
||||
providers: providers.cloned(),
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
|
Reference in New Issue
Block a user