/* * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ use crate::{ Directories, Directory, UnavailableDirectory, backend::{ldap::LdapDirectory, oidc::OpenIdDirectory, sql::SqlDirectory}, }; use registry::schema::{ prelude::ObjectType, structs::{self, Authentication}, }; use std::{collections::HashMap, sync::Arc}; use store::registry::bootstrap::Bootstrap; impl Directories { pub async fn build(bp: &mut Bootstrap) -> Self { let mut directories = HashMap::default(); for directory in bp.list_infallible::().await { let id = directory.id; let directory_type = directory.object.object_type(); let result = match directory.object { structs::Directory::Ldap(directory) => LdapDirectory::open(directory).await, structs::Directory::Sql(directory) => { SqlDirectory::open(directory, &bp.data_store).await } structs::Directory::Oidc(directory) => OpenIdDirectory::open(directory).await, }; let directory = match result { Ok(directory) => directory, Err(err) => { bp.build_error(id, err.clone()); Directory::Unavailable(UnavailableDirectory::new(directory_type, err)) } }; directories.insert(id.id().id() as u32, Arc::new(directory)); } let auth = bp.setting_infallible::().await; let default_directory = if let Some(directory_id) = auth.directory_id { match directories.get(&(directory_id.id() as u32)) { Some(default_directory) => default_directory.clone().into(), None => { bp.build_error( ObjectType::Authentication.singleton(), format!("Default directory with ID {} not found", directory_id), ); // inbuxa: DIR-5: a missing default is unavailable, never the // internal directory Some(Arc::new(Directory::Unavailable(UnavailableDirectory::new( registry::schema::enums::DirectoryType::Ldap, format!("Default directory with ID {} not found", directory_id), )))) } } } else { None }; Directories { default_directory, directories, } } }