Skip to content

Commit

Permalink
Utilize the graph code in msal
Browse files Browse the repository at this point in the history
Signed-off-by: David Mulder <dmulder@samba.org>
  • Loading branch information
dmulder committed May 23, 2024
1 parent 825460f commit bb12347
Show file tree
Hide file tree
Showing 13 changed files with 20 additions and 575 deletions.
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ members = [
"src/daemon",
"src/cli",
"src/common",
"src/graph",
"src/pam",
"src/nss",
"src/glue",
Expand Down Expand Up @@ -38,7 +37,6 @@ tracing = "^0.1.37"
himmelblau_unix_common = { path = "src/common" }
kanidm_unix_common = { path = "src/glue" }
msal = { version = "0.2.3" }
graph = { path = "src/graph" }
clap = { version = "^4.5", features = ["derive", "env"] }
clap_complete = "^4.4.1"
reqwest = { version = "^0.12.2", features = ["json"] }
Expand Down
1 change: 0 additions & 1 deletion src/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ serde_json = { workspace = true }
tracing = { workspace = true }
configparser = "^3.0.2"
msal = { workspace = true }
graph = { workspace = true }
reqwest = { workspace = true }
pem = { workspace = true }
kanidm-hsm-crypto = { workspace = true }
Expand Down
104 changes: 3 additions & 101 deletions src/common/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
use anyhow::{anyhow, Result};
use configparser::ini::Ini;
use std::fmt;
use std::io::Error;
use std::path::PathBuf;
use tracing::{debug, error};

use crate::constants::{
DEFAULT_AUTHORITY_HOST, DEFAULT_CACHE_TIMEOUT, DEFAULT_CONFIG_PATH, DEFAULT_CONN_TIMEOUT,
DEFAULT_DB_PATH, DEFAULT_GRAPH, DEFAULT_HELLO_ENABLED, DEFAULT_HOME_ALIAS, DEFAULT_HOME_ATTR,
BROKER_APP_ID, DEFAULT_CACHE_TIMEOUT, DEFAULT_CONFIG_PATH, DEFAULT_CONN_TIMEOUT,
DEFAULT_DB_PATH, DEFAULT_HELLO_ENABLED, DEFAULT_HOME_ALIAS, DEFAULT_HOME_ATTR,
DEFAULT_HOME_PREFIX, DEFAULT_HSM_PIN_PATH, DEFAULT_ID_ATTR_MAP, DEFAULT_ODC_PROVIDER,
DEFAULT_SELINUX, DEFAULT_SHELL, DEFAULT_SOCK_PATH, DEFAULT_TASK_SOCK_PATH,
DEFAULT_USE_ETC_SKEL, SERVER_CONFIG_PATH,
};
use crate::unix_config::{HomeAttr, HsmType};
use graph::constants::BROKER_APP_ID;
use graph::misc::request_federation_provider;
use idmap::DEFAULT_IDMAP_RANGE;
use std::env;

Expand Down Expand Up @@ -62,65 +59,6 @@ fn match_bool(val: Option<String>, default: bool) -> bool {
}
}

struct FederationProvider {
odc_provider: String,
domain: String,
tenant_id: Option<String>,
authority_host: Option<String>,
graph: Option<String>,
}

impl FederationProvider {
fn new(odc_provider: &str, domain: &str) -> Self {
FederationProvider {
odc_provider: odc_provider.to_string(),
domain: domain.to_string(),
tenant_id: None,
authority_host: None,
graph: None,
}
}

async fn set(&mut self) -> Result<()> {
let (authority_host, tenant_id, graph) =
request_federation_provider(&self.odc_provider, &self.domain).await?;
self.tenant_id = Some(tenant_id);
self.authority_host = Some(authority_host);
self.graph = Some(graph);
Ok(())
}

async fn get_tenant_id(&mut self) -> Result<String> {
if self.tenant_id.is_none() {
self.set().await?;
}
match &self.tenant_id {
Some(tenant_id) => Ok(tenant_id.to_string()),
None => Err(anyhow!("Failed fetching tenant_id")),
}
}

async fn get_authority_host(&mut self) -> Result<String> {
if self.authority_host.is_none() {
self.set().await?;
}
match &self.authority_host {
Some(authority_host) => Ok(authority_host.to_string()),
None => Err(anyhow!("Failed fetching authority_host")),
}
}

async fn get_graph(&mut self) -> Result<String> {
if self.graph.is_none() {
self.set().await?;
}
match &self.graph {
Some(graph) => Ok(graph.to_string()),
None => Err(anyhow!("Failed fetching graph")),
}
}
}

impl HimmelblauConfig {
pub fn new(config_path: Option<&str>) -> Result<HimmelblauConfig, String> {
let mut sconfig = Ini::new();
Expand Down Expand Up @@ -225,7 +163,7 @@ impl HimmelblauConfig {
}
}

fn get_odc_provider(&self, domain: &str) -> String {
pub fn get_odc_provider(&self, domain: &str) -> String {
match self.config.get(domain, "odc_provider") {
Some(val) => val,
None => match self.config.get("global", "odc_provider") {
Expand All @@ -235,42 +173,6 @@ impl HimmelblauConfig {
}
}

pub async fn get_tenant_id_authority_and_graph(
&self,
domain: &str,
) -> Result<(String, String, String)> {
let mut federation_provider =
FederationProvider::new(&self.get_odc_provider(domain), domain);
let tenant_id = match self.config.get(domain, "tenant_id") {
Some(val) => val,
None => match federation_provider.get_tenant_id().await {
Ok(val) => val,
Err(e) => return Err(anyhow!("Failed fetching tenant_id: {}", e)),
},
};
let authority_host = match self.config.get(domain, "authority_host") {
Some(val) => val,
None => match self.config.get("global", "authority_host") {
Some(val) => val,
None => match federation_provider.get_authority_host().await {
Ok(val) => val,
Err(_) => String::from(DEFAULT_AUTHORITY_HOST),
},
},
};
let graph = match self.config.get(domain, "graph") {
Some(val) => val,
None => match self.config.get("global", "graph") {
Some(val) => val,
None => match federation_provider.get_graph().await {
Ok(val) => val,
Err(_) => String::from(DEFAULT_GRAPH),
},
},
};
Ok((authority_host, tenant_id, graph))
}

pub fn get_app_id(&self, domain: &str) -> String {
match self.config.get(domain, "app_id") {
Some(val) => val,
Expand Down
2 changes: 2 additions & 0 deletions src/common/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ pub const DEFAULT_SELINUX: bool = true;
pub const DEFAULT_HSM_PIN_PATH: &str = "/var/lib/himmelblaud/hsm-pin";
pub const DEFAULT_HELLO_ENABLED: bool = true;
pub const DEFAULT_ID_ATTR_MAP: IdAttr = IdAttr::Name;
pub const BROKER_APP_ID: &str = "29d9ed98-a469-4536-ade2-f981bc1d605e";
pub const BROKER_CLIENT_IDENT: &str = "38aa3b87-a06d-4817-b275-7a316988d93b";
39 changes: 15 additions & 24 deletions src/common/src/idprovider/himmelblau.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::idprovider::interface::tpm;
use crate::unix_proto::{DeviceAuthorizationResponse, PamAuthRequest};
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use graph::user::{request_user_groups, DirectoryObject};
use idmap::SssIdmap;
use kanidm_hsm_crypto::{LoadableIdentityKey, LoadableMsOapxbcRsaKey, PinValue, SealedData, Tpm};
use msal::auth::{
Expand All @@ -20,6 +19,7 @@ use msal::auth::{
};
use msal::discovery::EnrollAttrs;
use msal::error::{MsalError, AUTH_PENDING, DEVICE_AUTH_FAIL, REQUIRES_MFA};
use msal::graph::{DirectoryObject, Graph};
use reqwest;
use std::collections::HashMap;
use std::sync::Arc;
Expand Down Expand Up @@ -92,11 +92,11 @@ impl HimmelblauMultiProvider {
debug!("Adding provider for domain {}", domain);
let range = cfg.get_idmap_range(&domain);
let mut idmap_lk = idmap.write().await;
let (authority_host, tenant_id, graph) =
match cfg.get_tenant_id_authority_and_graph(&domain).await {
Ok(res) => res,
Err(e) => return Err(anyhow!("{}", e)),
};
let graph = Graph::new(&cfg.get_odc_provider(&domain), &domain)
.await
.map_err(|e| anyhow!("{:?}", e))?;
let authority_host = graph.authority_host();
let tenant_id = graph.tenant_id();
idmap_lk
.add_gen_domain(&domain, &tenant_id, range)
.map_err(|e| anyhow!("{:?}", e))?;
Expand All @@ -109,7 +109,7 @@ impl HimmelblauMultiProvider {
&tenant_id,
&domain,
&authority_host,
&graph,
graph,
&idmap,
)
.map_err(|_| anyhow!("Failed to initialize the provider"))?;
Expand Down Expand Up @@ -329,7 +329,7 @@ pub struct HimmelblauProvider {
tenant_id: String,
domain: String,
authority_host: String,
graph_url: String,
graph: Graph,
refresh_cache: RefreshCache,
idmap: Arc<RwLock<SssIdmap>>,
}
Expand All @@ -341,7 +341,7 @@ impl HimmelblauProvider {
tenant_id: &str,
domain: &str,
authority_host: &str,
graph_url: &str,
graph: Graph,
idmap: &Arc<RwLock<SssIdmap>>,
) -> Result<Self, IdpError> {
Ok(HimmelblauProvider {
Expand All @@ -350,7 +350,7 @@ impl HimmelblauProvider {
tenant_id: tenant_id.to_string(),
domain: domain.to_string(),
authority_host: authority_host.to_string(),
graph_url: graph_url.to_string(),
graph,
refresh_cache: RefreshCache::new(),
idmap: idmap.clone(),
})
Expand Down Expand Up @@ -1300,7 +1300,7 @@ impl HimmelblauProvider {
};
match &value.access_token {
Some(access_token) => {
groups = match request_user_groups(&self.graph_url, access_token).await {
groups = match self.graph.request_user_groups(access_token).await {
Ok(groups) => {
let mut gt_groups = vec![];
for g in groups {
Expand Down Expand Up @@ -1366,23 +1366,19 @@ impl HimmelblauProvider {
value: DirectoryObject,
) -> Result<GroupToken> {
let config = self.config.read().await;
let name = match value.get("display_name") {
let name = match value.display_name {
Some(name) => name,
None => return Err(anyhow!("Failed retrieving group display_name")),
};
let id = match value.get("id") {
Some(id) => {
Uuid::parse_str(id).map_err(|e| anyhow!("Failed parsing user uuid: {}", e))?
}
None => return Err(anyhow!("Failed retrieving group uuid")),
};
let id =
Uuid::parse_str(&value.id).map_err(|e| anyhow!("Failed parsing user uuid: {}", e))?;
let idmap = self.idmap.read().await;
let gidnumber = match config.get_id_attr_map() {
IdAttr::Uuid => idmap
.object_id_to_unix_id(&self.tenant_id, &id)
.map_err(|e| anyhow!("Failed fetching gid for {}: {:?}", id, e))?,
IdAttr::Name => idmap
.gen_to_unix(&self.tenant_id, name)
.gen_to_unix(&self.tenant_id, &name)
.map_err(|e| anyhow!("Failed fetching gid for {}: {:?}", name, e))?,
};

Expand Down Expand Up @@ -1436,11 +1432,6 @@ impl HimmelblauProvider {
"Setting domain {} config device_id to {}",
self.domain, &device_id
);
config.set(&self.domain, "graph", &self.graph_url);
debug!(
"Setting domain {} config graph to {}",
self.domain, &self.graph_url
);
config.set(&self.domain, "tenant_id", &self.tenant_id);
debug!(
"Setting domain {} config tenant_id to {}",
Expand Down
33 changes: 0 additions & 33 deletions src/graph/Cargo.toml

This file was deleted.

0 comments on commit bb12347

Please sign in to comment.