Integrity Verification & BTreeSet
This commit is contained in:
		
							parent
							
								
									ef9f0fd31c
								
							
						
					
					
						commit
						f4776e3c8b
					
				
							
								
								
									
										36
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										36
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -60,9 +60,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "anstream"
 | 
					name = "anstream"
 | 
				
			||||||
version = "0.6.18"
 | 
					version = "0.6.19"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
 | 
					checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "anstyle",
 | 
					 "anstyle",
 | 
				
			||||||
 "anstyle-parse",
 | 
					 "anstyle-parse",
 | 
				
			||||||
@ -75,33 +75,33 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "anstyle"
 | 
					name = "anstyle"
 | 
				
			||||||
version = "1.0.10"
 | 
					version = "1.0.11"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
 | 
					checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "anstyle-parse"
 | 
					name = "anstyle-parse"
 | 
				
			||||||
version = "0.2.6"
 | 
					version = "0.2.7"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
 | 
					checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "utf8parse",
 | 
					 "utf8parse",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "anstyle-query"
 | 
					name = "anstyle-query"
 | 
				
			||||||
version = "1.1.2"
 | 
					version = "1.1.3"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
 | 
					checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "windows-sys 0.59.0",
 | 
					 "windows-sys 0.59.0",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "anstyle-wincon"
 | 
					name = "anstyle-wincon"
 | 
				
			||||||
version = "3.0.8"
 | 
					version = "3.0.9"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
 | 
					checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "anstyle",
 | 
					 "anstyle",
 | 
				
			||||||
 "once_cell_polyfill",
 | 
					 "once_cell_polyfill",
 | 
				
			||||||
@ -267,9 +267,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "axum-jwt-login"
 | 
					name = "axum-jwt-login"
 | 
				
			||||||
version = "0.1.1"
 | 
					version = "0.1.2"
 | 
				
			||||||
source = "sparse+https://crates.esteil.dedyn.io/api/v1/crates/"
 | 
					source = "sparse+https://crates.esteil.dedyn.io/api/v1/crates/"
 | 
				
			||||||
checksum = "b45378650bae1dfcc3ed411ffc7b2bfe5977f6c3de5f140993b1ee2979cccc4c"
 | 
					checksum = "7866571ffba399da64ce58fab21c6eb0ad76a312ec7d546d5dfada2435ab26ea"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "axum",
 | 
					 "axum",
 | 
				
			||||||
 "chrono",
 | 
					 "chrono",
 | 
				
			||||||
@ -322,9 +322,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "base64ct"
 | 
					name = "base64ct"
 | 
				
			||||||
version = "1.7.3"
 | 
					version = "1.8.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3"
 | 
					checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "bitflags"
 | 
					name = "bitflags"
 | 
				
			||||||
@ -489,9 +489,9 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "colorchoice"
 | 
					name = "colorchoice"
 | 
				
			||||||
version = "1.0.3"
 | 
					version = "1.0.4"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
 | 
					checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "colored"
 | 
					name = "colored"
 | 
				
			||||||
@ -1187,9 +1187,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "hyper-util"
 | 
					name = "hyper-util"
 | 
				
			||||||
version = "0.1.13"
 | 
					version = "0.1.14"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8"
 | 
					checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 "futures-core",
 | 
					 "futures-core",
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@ colored = "3.0.0"
 | 
				
			|||||||
uuid = { version = "1.17.0", features = ["v4"] }
 | 
					uuid = { version = "1.17.0", features = ["v4"] }
 | 
				
			||||||
blake3 = "1.1.18"
 | 
					blake3 = "1.1.18"
 | 
				
			||||||
minisign = "0.7.9"
 | 
					minisign = "0.7.9"
 | 
				
			||||||
axum-jwt-login = { version = "0.1.1", registry = "kellnr" }
 | 
					axum-jwt-login = { version = "0.1.2", registry = "kellnr" }
 | 
				
			||||||
rust-argon2 = "2.1.0"
 | 
					rust-argon2 = "2.1.0"
 | 
				
			||||||
rand = "0.9.1"
 | 
					rand = "0.9.1"
 | 
				
			||||||
ldap3 = "0.11.5"
 | 
					ldap3 = "0.11.5"
 | 
				
			||||||
 | 
				
			|||||||
@ -17,13 +17,13 @@ pub struct IntegrityVerifier {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl IntegrityVerifier {
 | 
					impl IntegrityVerifier {
 | 
				
			||||||
    pub fn new() -> Result<Self, ApiError> {
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
        Ok(Self {
 | 
					        Self {
 | 
				
			||||||
            mac: Hasher::new_derive_key(include_str!("./verification_secret")),
 | 
					            mac: Hasher::new_derive_key(include_str!("./verification_secret")),
 | 
				
			||||||
        })
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn sign<T>(&self, data: &T) -> Result<Hash, ApiError>
 | 
					    pub fn sign<T>(&self, data: &T) -> Hash
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        T: CustomHash,
 | 
					        T: CustomHash,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -33,7 +33,7 @@ impl IntegrityVerifier {
 | 
				
			|||||||
        let signature = mac.finalize();
 | 
					        let signature = mac.finalize();
 | 
				
			||||||
        mac.reset();
 | 
					        mac.reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(signature)
 | 
					        signature
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn verify<T>(&self, data: &T, signature: Hash) -> Result<(), ApiError>
 | 
					    pub fn verify<T>(&self, data: &T, signature: Hash) -> Result<(), ApiError>
 | 
				
			||||||
@ -73,14 +73,14 @@ mod test {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let verifier = IntegrityVerifier::new().unwrap();
 | 
					        let verifier = IntegrityVerifier::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut item = TestData {
 | 
					        let mut item = TestData {
 | 
				
			||||||
            one: 24,
 | 
					            one: 24,
 | 
				
			||||||
            two: "MyTesting".to_string(),
 | 
					            two: "MyTesting".to_string(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let signature = verifier.sign(&item).unwrap();
 | 
					        let signature = verifier.sign(&item);
 | 
				
			||||||
        assert!(verifier.verify(&item, signature).is_ok());
 | 
					        assert!(verifier.verify(&item, signature).is_ok());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        item.two = "Wrong".to_string();
 | 
					        item.two = "Wrong".to_string();
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
use std::collections::HashSet;
 | 
					use std::collections::BTreeSet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use axum_jwt_login::ApiKey as ApiKeyTrait;
 | 
					use axum_jwt_login::ApiKey as ApiKeyTrait;
 | 
				
			||||||
use blake3::{Hash, Hasher};
 | 
					use blake3::{Hash, Hasher};
 | 
				
			||||||
@ -59,7 +59,7 @@ impl ApiKey {
 | 
				
			|||||||
    pub fn create(
 | 
					    pub fn create(
 | 
				
			||||||
        name: &str,
 | 
					        name: &str,
 | 
				
			||||||
        requires_auth: bool,
 | 
					        requires_auth: bool,
 | 
				
			||||||
        permissions: HashSet<Permission>,
 | 
					        permissions: BTreeSet<Permission>,
 | 
				
			||||||
        config: &Configuration,
 | 
					        config: &Configuration,
 | 
				
			||||||
    ) -> Result<(String, Self), ApiError> {
 | 
					    ) -> Result<(String, Self), ApiError> {
 | 
				
			||||||
        // create uuid
 | 
					        // create uuid
 | 
				
			||||||
@ -128,14 +128,14 @@ impl ApiKeyTrait for ApiKey {
 | 
				
			|||||||
    fn requires_user_auth(&self) -> bool {
 | 
					    fn requires_user_auth(&self) -> bool {
 | 
				
			||||||
        self.auth_required
 | 
					        self.auth_required
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn get_permissions(&self) -> HashSet<Self::Permission> {
 | 
					    fn get_permissions(&self) -> BTreeSet<Self::Permission> {
 | 
				
			||||||
        self.permissions.0.clone()
 | 
					        self.permissions.0.clone()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod test {
 | 
					mod test {
 | 
				
			||||||
    use std::collections::HashSet;
 | 
					    use std::collections::BTreeSet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    use crate::config::Configuration;
 | 
					    use crate::config::Configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -148,7 +148,7 @@ mod test {
 | 
				
			|||||||
            ..Default::default()
 | 
					            ..Default::default()
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let (key, api_key) =
 | 
					        let (key, api_key) =
 | 
				
			||||||
            ApiKey::create("name", true, HashSet::new(), &config).expect("Error creating API Key");
 | 
					            ApiKey::create("name", true, BTreeSet::new(), &config).expect("Error creating API Key");
 | 
				
			||||||
        println!("{key}, {api_key:?}");
 | 
					        println!("{key}, {api_key:?}");
 | 
				
			||||||
        assert_eq!(Ok(()), api_key.validate(&key));
 | 
					        assert_eq!(Ok(()), api_key.validate(&key));
 | 
				
			||||||
        assert_ne!(Ok(()), api_key.validate("124"));
 | 
					        assert_ne!(Ok(()), api_key.validate("124"));
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    collections::{HashMap, HashSet},
 | 
					    collections::{BTreeSet, HashMap, HashSet},
 | 
				
			||||||
    fmt,
 | 
					    fmt,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -12,7 +12,10 @@ use ts_rs::TS;
 | 
				
			|||||||
use utoipa::ToSchema;
 | 
					use utoipa::ToSchema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    api::routes::{departments::models::ShortDepartment, models::Status},
 | 
					    api::{
 | 
				
			||||||
 | 
					        backend::integrity_verification::CustomHash,
 | 
				
			||||||
 | 
					        routes::{departments::models::ShortDepartment, models::Status},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    errors::ApiError,
 | 
					    errors::ApiError,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -104,6 +107,17 @@ impl fmt::Debug for User {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl CustomHash for User {
 | 
				
			||||||
 | 
					    fn updater(&self, hasher: &mut blake3::Hasher) {
 | 
				
			||||||
 | 
					        hasher.update(self.user_id.as_bytes());
 | 
				
			||||||
 | 
					        hasher.update(self.name.as_bytes());
 | 
				
			||||||
 | 
					        hasher.update(self.surname.as_bytes());
 | 
				
			||||||
 | 
					        for permission in &self.permissions.0 {
 | 
				
			||||||
 | 
					            hasher.update(permission.to_string().as_bytes());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl UserPermissions for User {
 | 
					impl UserPermissions for User {
 | 
				
			||||||
    type Error = ApiError;
 | 
					    type Error = ApiError;
 | 
				
			||||||
    type Permission = Permission;
 | 
					    type Permission = Permission;
 | 
				
			||||||
@ -113,10 +127,10 @@ impl UserPermissions for User {
 | 
				
			|||||||
        self.user_id.clone()
 | 
					        self.user_id.clone()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn get_user_permissions(&self) -> Result<HashSet<Self::Permission>, Self::Error> {
 | 
					    fn get_user_permissions(&self) -> Result<BTreeSet<Self::Permission>, Self::Error> {
 | 
				
			||||||
        Ok(self.permissions.0.iter().cloned().collect())
 | 
					        Ok(self.permissions.0.iter().cloned().collect())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn get_group_permissions(&self) -> Result<HashSet<Self::Permission>, Self::Error> {
 | 
					    fn get_group_permissions(&self) -> Result<BTreeSet<Self::Permission>, Self::Error> {
 | 
				
			||||||
        Ok(self.group_permissions.0.iter().cloned().collect())
 | 
					        Ok(self.group_permissions.0.iter().cloned().collect())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,13 @@
 | 
				
			|||||||
use std::{collections::HashSet, convert::Infallible, fmt::Display, str::FromStr};
 | 
					use std::{collections::BTreeSet, convert::Infallible, fmt::Display, str::FromStr};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
use strum::EnumString;
 | 
					use strum::EnumString;
 | 
				
			||||||
use ts_rs::TS;
 | 
					use ts_rs::TS;
 | 
				
			||||||
use utoipa::ToSchema;
 | 
					use utoipa::ToSchema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, TS, ToSchema)]
 | 
					#[derive(
 | 
				
			||||||
 | 
					    Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord, TS, ToSchema,
 | 
				
			||||||
 | 
					)]
 | 
				
			||||||
pub enum Permission {
 | 
					pub enum Permission {
 | 
				
			||||||
    Read(PermissionDetail),
 | 
					    Read(PermissionDetail),
 | 
				
			||||||
    Write(PermissionDetail),
 | 
					    Write(PermissionDetail),
 | 
				
			||||||
@ -52,6 +54,8 @@ impl Display for Permission {
 | 
				
			|||||||
    Deserialize,
 | 
					    Deserialize,
 | 
				
			||||||
    PartialEq,
 | 
					    PartialEq,
 | 
				
			||||||
    Eq,
 | 
					    Eq,
 | 
				
			||||||
 | 
					    PartialOrd,
 | 
				
			||||||
 | 
					    Ord,
 | 
				
			||||||
    Hash,
 | 
					    Hash,
 | 
				
			||||||
    EnumString,
 | 
					    EnumString,
 | 
				
			||||||
    strum::Display,
 | 
					    strum::Display,
 | 
				
			||||||
@ -70,17 +74,17 @@ pub enum PermissionDetail {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS, ToSchema)]
 | 
					#[derive(Debug, Clone, Serialize, Deserialize, TS, ToSchema)]
 | 
				
			||||||
pub struct PermissionContainer(pub HashSet<Permission>);
 | 
					pub struct PermissionContainer(pub BTreeSet<Permission>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<Option<Vec<String>>> for PermissionContainer {
 | 
					impl From<Option<Vec<String>>> for PermissionContainer {
 | 
				
			||||||
    fn from(value: Option<Vec<String>>) -> Self {
 | 
					    fn from(value: Option<Vec<String>>) -> Self {
 | 
				
			||||||
        let set = match value {
 | 
					        let set = match value {
 | 
				
			||||||
            Some(values) => HashSet::from_iter(
 | 
					            Some(values) => BTreeSet::from_iter(
 | 
				
			||||||
                values
 | 
					                values
 | 
				
			||||||
                    .iter()
 | 
					                    .iter()
 | 
				
			||||||
                    .map(|s| Permission::from_str(s).unwrap_or(Permission::None)),
 | 
					                    .map(|s| Permission::from_str(s).unwrap_or(Permission::None)),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            None => HashSet::new(),
 | 
					            None => BTreeSet::new(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self(set)
 | 
					        Self(set)
 | 
				
			||||||
@ -89,9 +93,24 @@ impl From<Option<Vec<String>>> for PermissionContainer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod test {
 | 
					mod test {
 | 
				
			||||||
    use std::str::FromStr;
 | 
					    use std::{
 | 
				
			||||||
 | 
					        collections::{BTreeSet, HashSet},
 | 
				
			||||||
 | 
					        str::FromStr,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    use crate::api::routes::users::permissions::PermissionDetail;
 | 
					    use chrono::Local;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use crate::api::{
 | 
				
			||||||
 | 
					        backend::integrity_verification::IntegrityVerifier,
 | 
				
			||||||
 | 
					        routes::{
 | 
				
			||||||
 | 
					            departments::models::ShortDepartment,
 | 
				
			||||||
 | 
					            models::Status,
 | 
				
			||||||
 | 
					            users::{
 | 
				
			||||||
 | 
					                models::{DepartmentContainer, GroupContainer, User},
 | 
				
			||||||
 | 
					                permissions::{PermissionContainer, PermissionDetail},
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    use super::Permission;
 | 
					    use super::Permission;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -103,4 +122,41 @@ mod test {
 | 
				
			|||||||
        let parsed = Permission::from_str("Write:Users").unwrap();
 | 
					        let parsed = Permission::from_str("Write:Users").unwrap();
 | 
				
			||||||
        assert_eq!(parsed, Permission::Write(PermissionDetail::Users));
 | 
					        assert_eq!(parsed, Permission::Write(PermissionDetail::Users));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[tokio::test]
 | 
				
			||||||
 | 
					    async fn test_integrity_validation() {
 | 
				
			||||||
 | 
					        let mut user = User {
 | 
				
			||||||
 | 
					            user_id: "id".to_string(),
 | 
				
			||||||
 | 
					            active_directory_auth: false,
 | 
				
			||||||
 | 
					            password: "Some PW".to_string(),
 | 
				
			||||||
 | 
					            name: "Clark".to_string(),
 | 
				
			||||||
 | 
					            surname: "Kent".to_string(),
 | 
				
			||||||
 | 
					            email: "Superman@heros.com".to_string(),
 | 
				
			||||||
 | 
					            department: DepartmentContainer(Some(ShortDepartment {
 | 
				
			||||||
 | 
					                id: 1,
 | 
				
			||||||
 | 
					                name: "Some name".to_string(),
 | 
				
			||||||
 | 
					                description: None,
 | 
				
			||||||
 | 
					            })),
 | 
				
			||||||
 | 
					            groups: GroupContainer(HashSet::new()),
 | 
				
			||||||
 | 
					            group_permissions: PermissionContainer(BTreeSet::new()),
 | 
				
			||||||
 | 
					            permissions: PermissionContainer(BTreeSet::from_iter([Permission::Read(
 | 
				
			||||||
 | 
					                PermissionDetail::Departments,
 | 
				
			||||||
 | 
					            )])),
 | 
				
			||||||
 | 
					            status_flag: Status::Active,
 | 
				
			||||||
 | 
					            creation_date: Local::now().naive_local(),
 | 
				
			||||||
 | 
					            last_change: Local::now().naive_local(),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let verifier = IntegrityVerifier::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let hash = verifier.sign(&user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert!(verifier.verify(&user, hash).is_ok());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        user.permissions
 | 
				
			||||||
 | 
					            .0
 | 
				
			||||||
 | 
					            .insert(Permission::Write(PermissionDetail::Units));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert!(verifier.verify(&user, hash).is_err());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
use std::{collections::HashSet, path::PathBuf};
 | 
					use std::{collections::BTreeSet, path::PathBuf};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use clap::{command, Parser, Subcommand};
 | 
					use clap::{command, Parser, Subcommand};
 | 
				
			||||||
use colored::Colorize;
 | 
					use colored::Colorize;
 | 
				
			||||||
@ -134,7 +134,7 @@ impl Cli {
 | 
				
			|||||||
                    } => {
 | 
					                    } => {
 | 
				
			||||||
                        // create API Key
 | 
					                        // create API Key
 | 
				
			||||||
                        let (key_secret, key) =
 | 
					                        let (key_secret, key) =
 | 
				
			||||||
                            ApiKey::create(name, *requires_auth, HashSet::new(), config)
 | 
					                            ApiKey::create(name, *requires_auth, BTreeSet::new(), config)
 | 
				
			||||||
                                .change_context(AppError)?;
 | 
					                                .change_context(AppError)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        // Add API Key to Database
 | 
					                        // Add API Key to Database
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user