Add basic providers configuration
	
		
			
	
		
	
	
		
	
		
			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:
		@@ -6,6 +6,9 @@ pub const USERS_LIST_FILE: &str = "users.json";
 | 
			
		||||
/// File in storage containing clients list
 | 
			
		||||
pub const CLIENTS_LIST_FILE: &str = "clients.yaml";
 | 
			
		||||
 | 
			
		||||
/// File in storage containing providers list
 | 
			
		||||
pub const PROVIDERS_LIST_FILE: &str = "providers.yaml";
 | 
			
		||||
 | 
			
		||||
/// Default built-in credentials
 | 
			
		||||
pub const DEFAULT_ADMIN_USERNAME: &str = "admin";
 | 
			
		||||
pub const DEFAULT_ADMIN_PASSWORD: &str = "admin";
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ use crate::controllers::settings_controller::BaseSettingsPage;
 | 
			
		||||
use crate::data::action_logger::{Action, ActionLogger};
 | 
			
		||||
use crate::data::client::{Client, ClientID, ClientManager};
 | 
			
		||||
use crate::data::current_user::CurrentUser;
 | 
			
		||||
use crate::data::provider::{Provider, ProvidersManager};
 | 
			
		||||
use crate::data::user::{GeneralSettings, GrantedClients, User, UserID};
 | 
			
		||||
use crate::utils::string_utils::rand_str;
 | 
			
		||||
 | 
			
		||||
@@ -22,6 +23,13 @@ struct ClientsListTemplate {
 | 
			
		||||
    clients: Vec<Client>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Template)]
 | 
			
		||||
#[template(path = "settings/providers_list.html")]
 | 
			
		||||
struct ProvidersListTemplate {
 | 
			
		||||
    _p: BaseSettingsPage,
 | 
			
		||||
    providers: Vec<Provider>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Template)]
 | 
			
		||||
#[template(path = "settings/users_list.html")]
 | 
			
		||||
struct UsersListTemplate {
 | 
			
		||||
@@ -51,6 +59,20 @@ 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(),
 | 
			
		||||
        }
 | 
			
		||||
        .render()
 | 
			
		||||
        .unwrap(),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize, Debug)]
 | 
			
		||||
pub struct UpdateUserQuery {
 | 
			
		||||
    uid: UserID,
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ use std::path::{Path, PathBuf};
 | 
			
		||||
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
 | 
			
		||||
use crate::constants::{APP_NAME, CLIENTS_LIST_FILE, USERS_LIST_FILE};
 | 
			
		||||
use crate::constants::{APP_NAME, CLIENTS_LIST_FILE, PROVIDERS_LIST_FILE, USERS_LIST_FILE};
 | 
			
		||||
 | 
			
		||||
/// Basic OIDC provider
 | 
			
		||||
#[derive(Parser, Debug, Clone)]
 | 
			
		||||
@@ -72,6 +72,10 @@ impl AppConfig {
 | 
			
		||||
        self.storage_path().join(CLIENTS_LIST_FILE)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn providers_file(&self) -> PathBuf {
 | 
			
		||||
        self.storage_path().join(PROVIDERS_LIST_FILE)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn full_url(&self, uri: &str) -> String {
 | 
			
		||||
        if uri.starts_with('/') {
 | 
			
		||||
            format!("{}{}", self.website_origin, uri)
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ pub mod jwt_signer;
 | 
			
		||||
pub mod login_redirect;
 | 
			
		||||
pub mod open_id_user_info;
 | 
			
		||||
pub mod openid_config;
 | 
			
		||||
pub mod provider;
 | 
			
		||||
pub mod remote_ip;
 | 
			
		||||
pub mod session_identity;
 | 
			
		||||
pub mod totp_key;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								src/data/provider.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/data/provider.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
use crate::data::entity_manager::EntityManager;
 | 
			
		||||
use crate::utils::string_utils::apply_env_vars;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
 | 
			
		||||
pub struct ProviderID(pub String);
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
 | 
			
		||||
pub struct Provider {
 | 
			
		||||
    /// The ID of the provider
 | 
			
		||||
    pub id: ProviderID,
 | 
			
		||||
 | 
			
		||||
    /// The human-readable name of the client
 | 
			
		||||
    pub name: String,
 | 
			
		||||
 | 
			
		||||
    /// A logo presented to the users of the provider
 | 
			
		||||
    pub logo: String,
 | 
			
		||||
 | 
			
		||||
    /// The registration id of BasicOIDC on the provider
 | 
			
		||||
    pub client_id: String,
 | 
			
		||||
 | 
			
		||||
    /// The registration secret of BasicOIDC on the provider
 | 
			
		||||
    pub client_secret: String,
 | 
			
		||||
 | 
			
		||||
    /// Specify the URL of the OpenID configuration URL
 | 
			
		||||
    ///
 | 
			
		||||
    /// (.well-known/openid-configuration endpoint)
 | 
			
		||||
    pub configuration_url: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PartialEq for Provider {
 | 
			
		||||
    fn eq(&self, other: &Self) -> bool {
 | 
			
		||||
        self.id.eq(&other.id)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Eq for Provider {}
 | 
			
		||||
 | 
			
		||||
pub type ProvidersManager = EntityManager<Provider>;
 | 
			
		||||
 | 
			
		||||
impl EntityManager<Provider> {
 | 
			
		||||
    pub fn find_by_id(&self, u: &ProviderID) -> Option<Provider> {
 | 
			
		||||
        for entry in self.iter() {
 | 
			
		||||
            if entry.id.eq(u) {
 | 
			
		||||
                return Some(entry.clone());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        None
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn apply_environment_variables(&mut self) {
 | 
			
		||||
        for c in self.iter_mut() {
 | 
			
		||||
            c.id = ProviderID(apply_env_vars(&c.id.0));
 | 
			
		||||
            c.name = apply_env_vars(&c.name);
 | 
			
		||||
            c.logo = apply_env_vars(&c.logo);
 | 
			
		||||
            c.client_id = apply_env_vars(&c.client_id);
 | 
			
		||||
            c.client_secret = apply_env_vars(&c.client_secret);
 | 
			
		||||
            c.configuration_url = apply_env_vars(&c.configuration_url);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -20,6 +20,7 @@ use basic_oidc::data::app_config::AppConfig;
 | 
			
		||||
use basic_oidc::data::client::ClientManager;
 | 
			
		||||
use basic_oidc::data::entity_manager::EntityManager;
 | 
			
		||||
use basic_oidc::data::jwt_signer::JWTSigner;
 | 
			
		||||
use basic_oidc::data::provider::ProvidersManager;
 | 
			
		||||
use basic_oidc::data::user::User;
 | 
			
		||||
use basic_oidc::data::webauthn_manager::WebAuthManager;
 | 
			
		||||
use basic_oidc::middlewares::auth_middleware::AuthMiddleware;
 | 
			
		||||
@@ -77,6 +78,11 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
    clients.apply_environment_variables();
 | 
			
		||||
    let clients = Arc::new(clients);
 | 
			
		||||
 | 
			
		||||
    let mut providers = ProvidersManager::open_or_create(config.providers_file())
 | 
			
		||||
        .expect("Failed to load providers list!");
 | 
			
		||||
    providers.apply_environment_variables();
 | 
			
		||||
    let providers = Arc::new(providers);
 | 
			
		||||
 | 
			
		||||
    log::info!("Server will listen on {}", config.listen_address);
 | 
			
		||||
    let listen_address = config.listen_address.to_string();
 | 
			
		||||
 | 
			
		||||
@@ -101,6 +107,7 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
            .app_data(web::Data::new(bruteforce_actor.clone()))
 | 
			
		||||
            .app_data(web::Data::new(openid_sessions_actor.clone()))
 | 
			
		||||
            .app_data(web::Data::new(clients.clone()))
 | 
			
		||||
            .app_data(web::Data::new(providers.clone()))
 | 
			
		||||
            .app_data(web::Data::new(jwt_signer.clone()))
 | 
			
		||||
            .app_data(web::Data::new(webauthn_manager.clone()))
 | 
			
		||||
            .wrap(
 | 
			
		||||
@@ -207,6 +214,10 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
                "/admin/clients",
 | 
			
		||||
                web::get().to(admin_controller::clients_route),
 | 
			
		||||
            )
 | 
			
		||||
            .route(
 | 
			
		||||
                "/admin/providers",
 | 
			
		||||
                web::get().to(admin_controller::providers_route),
 | 
			
		||||
            )
 | 
			
		||||
            .route("/admin/users", web::get().to(admin_controller::users_route))
 | 
			
		||||
            .route(
 | 
			
		||||
                "/admin/users",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user