Skip to content

Commit

Permalink
Add tests for rust himmelblaud build
Browse files Browse the repository at this point in the history
Signed-off-by: David Mulder <[email protected]>
Reviewed-by: Alexander Bokovoy <[email protected]>
  • Loading branch information
dmulder committed Oct 23, 2024
1 parent 89db2e5 commit ff0cf5e
Show file tree
Hide file tree
Showing 14 changed files with 947 additions and 11 deletions.
1 change: 1 addition & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions rust/himmelblaud/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ libc = { workspace = true }

[build-dependencies]
version = { path = "../version" }

[dev-dependencies]
tempfile = "3.12.0"
3 changes: 3 additions & 0 deletions rust/himmelblaud/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("cargo:rustc-env=LD_LIBRARY_PATH=../../bin/shared:../../bin/shared/private/");
}
148 changes: 146 additions & 2 deletions rust/himmelblaud/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ impl BasicCache {
}
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub(crate) struct UserEntry {
pub(crate) upn: String,
pub(crate) uuid: String,
Expand Down Expand Up @@ -294,6 +294,16 @@ impl GroupEntry {
}
}

#[cfg(test)]
impl GroupEntry {
pub fn new(uuid: &str) -> Self {
GroupEntry {
uuid: uuid.to_string(),
members: HashSet::new(),
}
}
}

pub(crate) struct GroupCache {
cache: BasicCache,
}
Expand Down Expand Up @@ -330,7 +340,7 @@ impl GroupCache {
pub(crate) fn merge_groups(
&mut self,
member: &str,
entries: Vec<GroupEntry>,
mut entries: Vec<GroupEntry>,
) -> Result<(), Box<NTSTATUS>> {
// We need to ensure the member is removed from non-intersecting
// groups, otherwise we don't honor group membership removals.
Expand Down Expand Up @@ -369,6 +379,11 @@ impl GroupCache {
}
}

// Ensure the member is added to the listed groups
for group in &mut entries {
group.add_member(member);
}

// Now add the new entries, merging with existing memberships
for group in entries {
match self.cache.fetch::<GroupEntry>(&group.uuid) {
Expand Down Expand Up @@ -513,3 +528,132 @@ impl PrivateCache {
self.cache.store_bytes(&device_id_tag, device_id.as_bytes())
}
}

#[cfg(test)]
mod tests {
use super::*;
use kanidm_hsm_crypto::soft::SoftTpm;
use std::str::FromStr;
use tempfile::tempdir;

#[test]
fn test_basic_cache_new() {
let dir = tempdir().unwrap();
let cache_path = dir.path().join("test.tdb");
let cache = BasicCache::new(cache_path.to_str().unwrap());
assert!(cache.is_ok());
}

#[test]
fn test_basic_cache_store_fetch_str() {
let dir = tempdir().unwrap();
let cache_path = dir.path().join("test.tdb");
let mut cache = BasicCache::new(cache_path.to_str().unwrap()).unwrap();

let key = "test_key";
let value = "test_value";
cache.store_bytes(key, value.as_bytes()).unwrap();
let fetched_value = cache.fetch_str(key).unwrap();
assert_eq!(fetched_value, value);
}

#[test]
fn test_basic_cache_store_fetch() {
let dir = tempdir().unwrap();
let cache_path = dir.path().join("test.tdb");
let mut cache = BasicCache::new(cache_path.to_str().unwrap()).unwrap();

let key = "test_key";
let value = UserEntry {
upn: "[email protected]".to_string(),
uuid: "f63a43c7-b783-4da9-acb4-89f8ebfc49e9".to_string(),
name: "Test User".to_string(),
};

cache.store(key, &value).unwrap();
let fetched_value: Option<UserEntry> = cache.fetch(key);
assert!(fetched_value.is_some());
let fetched_value = fetched_value.unwrap();
assert_eq!(fetched_value.upn, value.upn);
assert_eq!(fetched_value.uuid, value.uuid);
assert_eq!(fetched_value.name, value.name);
}

#[test]
fn test_user_cache_store_fetch() {
let dir = tempdir().unwrap();
let cache_path = dir.path().join("test.tdb");
let mut cache = UserCache::new(cache_path.to_str().unwrap()).unwrap();

let entry = UserEntry {
upn: "[email protected]".to_string(),
uuid: "f63a43c7-b783-4da9-acb4-89f8ebfc49e9".to_string(),
name: "Test User".to_string(),
};

cache.store(entry.clone()).unwrap();
let fetched_entry = cache.fetch(&entry.upn);
assert!(fetched_entry.is_some());
let fetched_entry = fetched_entry.unwrap();
assert_eq!(fetched_entry.upn, entry.upn);
assert_eq!(fetched_entry.uuid, entry.uuid);
assert_eq!(fetched_entry.name, entry.name);
}

#[test]
fn test_uid_cache_store_fetch() {
let dir = tempdir().unwrap();
let cache_path = dir.path().join("test.tdb");
let mut cache = UidCache::new(cache_path.to_str().unwrap()).unwrap();

let uid: uid_t = 1000;
let upn = "[email protected]";

cache.store(uid, upn).unwrap();
let fetched_upn = cache.fetch(uid);
assert!(fetched_upn.is_some());
assert_eq!(fetched_upn.unwrap(), upn);
}

#[test]
fn test_group_cache_store_fetch() {
let dir = tempdir().unwrap();
let cache_path = dir.path().join("test.tdb");
let mut cache = GroupCache::new(cache_path.to_str().unwrap()).unwrap();

let mut group = GroupEntry {
uuid: "5f8be63a-a379-4324-9f42-9ea40bed9d7f".to_string(),
members: HashSet::new(),
};
group.add_member("[email protected]");

cache.cache.store(&group.uuid, &group).unwrap();
let fetched_group = cache.fetch(&group.uuid);
assert!(fetched_group.is_some());
let fetched_group = fetched_group.unwrap();
assert_eq!(fetched_group.uuid, group.uuid);
assert!(fetched_group.members.contains("[email protected]"));
}

#[test]
fn test_private_cache_loadable_machine_key_fetch_or_create() {
let dir = tempdir().unwrap();
let cache_path = dir.path().join("test.tdb");
let mut cache =
PrivateCache::new(cache_path.to_str().unwrap()).unwrap();

let mut hsm = BoxedDynTpm::new(SoftTpm::new());
let auth_str = AuthValue::generate().expect("Failed to create hex pin");
let auth_value = AuthValue::from_str(&auth_str)
.expect("Unable to create auth value");

let result =
cache.loadable_machine_key_fetch_or_create(&mut hsm, &auth_value);
assert!(result.is_ok());

let fetched_key = cache
.cache
.fetch::<LoadableMachineKey>("loadable_machine_key");
assert!(fetched_key.is_some());
}
}
51 changes: 51 additions & 0 deletions rust/himmelblaud/src/himmelblaud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::cache::{GroupCache, PrivateCache, UidCache, UserCache};
#[cfg(not(test))]
use crate::himmelblaud::himmelblaud_pam_auth::AuthSession;
use bytes::{BufMut, BytesMut};
use dbg::{DBG_DEBUG, DBG_ERR, DBG_WARNING};
Expand All @@ -37,6 +38,7 @@ use tokio::net::UnixStream;
use tokio::sync::Mutex;
use tokio_util::codec::{Decoder, Encoder, Framed};

#[cfg(not(test))]
pub(crate) struct Resolver {
realm: String,
tenant_id: String,
Expand All @@ -52,6 +54,7 @@ pub(crate) struct Resolver {
client: Arc<Mutex<BrokerClientApplication>>,
}

#[cfg(not(test))]
impl Resolver {
pub(crate) fn new(
realm: &str,
Expand Down Expand Up @@ -84,6 +87,46 @@ impl Resolver {
}
}

// The test environment is unable to communicate with Entra ID, therefore
// we alter the resolver to only test the cache interactions.

#[cfg(test)]
pub(crate) struct Resolver {
realm: String,
tenant_id: String,
lp: LoadParm,
idmap: Idmap,
pcache: PrivateCache,
user_cache: UserCache,
uid_cache: UidCache,
group_cache: GroupCache,
}

#[cfg(test)]
impl Resolver {
pub(crate) fn new(
realm: &str,
tenant_id: &str,
lp: LoadParm,
idmap: Idmap,
pcache: PrivateCache,
user_cache: UserCache,
uid_cache: UidCache,
group_cache: GroupCache,
) -> Self {
Resolver {
realm: realm.to_string(),
tenant_id: tenant_id.to_string(),
lp,
idmap,
pcache,
user_cache,
uid_cache,
group_cache,
}
}
}

struct ClientCodec;

impl Decoder for ClientCodec {
Expand Down Expand Up @@ -142,11 +185,13 @@ pub(crate) async fn handle_client(
};

let mut reqs = Framed::new(stream, ClientCodec::new());
#[cfg(not(test))]
let mut pam_auth_session_state = None;

while let Some(Ok(req)) = reqs.next().await {
let mut resolver = resolver.lock().await;
let resp = match req {
#[cfg(not(test))]
Request::PamAuthenticateInit(account_id) => {
DBG_DEBUG!("pam authenticate init");

Expand All @@ -168,6 +213,7 @@ pub(crate) async fn handle_client(
}
}
}
#[cfg(not(test))]
Request::PamAuthenticateStep(pam_next_req) => {
DBG_DEBUG!("pam authenticate step");
match &mut pam_auth_session_state {
Expand Down Expand Up @@ -220,10 +266,13 @@ pub(crate) async fn handle_client(
resolver.getgrnam(&grp_id).await?
}
Request::NssGroupByGid(gid) => resolver.getgrgid(gid).await?,
#[cfg(not(test))]
Request::PamAccountAllowed(account_id) => {
resolver.pam_acct_mgmt(&account_id).await?
}
Request::PamAccountBeginSession(_account_id) => Response::Success,
#[cfg(test)]
_ => Response::Error,
};
reqs.send(resp).await?;
reqs.flush().await?;
Expand All @@ -240,5 +289,7 @@ mod himmelblaud_getgrnam;
mod himmelblaud_getpwent;
mod himmelblaud_getpwnam;
mod himmelblaud_getpwuid;
#[cfg(not(test))]
mod himmelblaud_pam_acct_mgmt;
#[cfg(not(test))]
mod himmelblaud_pam_auth;
Loading

0 comments on commit ff0cf5e

Please sign in to comment.