Skip to content

Commit

Permalink
feat: read status attribute with TRUE or FALSE string value
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaslihotzki-f committed Nov 4, 2024
1 parent 94261a7 commit bebd9f2
Showing 1 changed file with 89 additions and 13 deletions.
102 changes: 89 additions & 13 deletions src/sources/ldap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,32 @@ impl LdapSource {

/// Construct a user from an LDAP SearchEntry
pub(crate) fn parse_user(&self, entry: SearchEntry) -> Result<User> {
let status_as_int = match read_search_entry(&entry, &self.ldap_config.attributes.status)? {
StringOrBytes::String(status) => status.parse::<i32>()?,
StringOrBytes::Bytes(status) => {
i32::from_be_bytes(status.try_into().map_err(|err: Vec<u8>| {
let err_string = String::from_utf8_lossy(&err).to_string();
anyhow!(err_string).context("failed to convert to i32 flag")
})?)
let disable_bitmask = {
use std::ops::BitOr;
self.ldap_config.attributes.disable_bitmasks.iter().fold(0, i32::bitor)
};

let status = read_search_entry(&entry, &self.ldap_config.attributes.status)?;
let enabled = if disable_bitmask != 0 {
disable_bitmask
& match status {
StringOrBytes::String(status) => status.parse::<i32>()?,
StringOrBytes::Bytes(status) => {
i32::from_be_bytes(status.try_into().map_err(|err: Vec<u8>| {
let err_string = String::from_utf8_lossy(&err).to_string();
anyhow!(err_string).context("failed to convert to i32 flag")
})?)

Check warning on line 127 in src/sources/ldap.rs

View check run for this annotation

Codecov / codecov/patch

src/sources/ldap.rs#L123-L127

Added lines #L123 - L127 were not covered by tests
}
} == 0
} else if let StringOrBytes::String(status) = status {
match &status[..] {
"TRUE" => true,
"FALSE" => false,
_ => bail!("Cannot parse status without disable_bitmasks: {:?}", status),

Check warning on line 134 in src/sources/ldap.rs

View check run for this annotation

Codecov / codecov/patch

src/sources/ldap.rs#L134

Added line #L134 was not covered by tests
}
} else {
bail!("Binary status without disable_bitmasks");

Check warning on line 137 in src/sources/ldap.rs

View check run for this annotation

Codecov / codecov/patch

src/sources/ldap.rs#L137

Added line #L137 was not covered by tests
};
let enabled = !self
.ldap_config
.attributes
.disable_bitmasks
.iter()
.any(|flag| status_as_int & flag != 0);

let first_name = read_search_entry(&entry, &self.ldap_config.attributes.first_name)?;
let last_name = read_search_entry(&entry, &self.ldap_config.attributes.last_name)?;
Expand Down Expand Up @@ -414,6 +425,46 @@ mod tests {
feature_flags: []
"#};

const EXAMPLE_CONFIG_NO_DISABLE_BITMASKS: &str = indoc! {r#"
zitadel:
url: http://localhost:8080
key_file: tests/environment/zitadel/service-user.json
organization_id: 1
project_id: 1
idp_id: 1
sources:
ldap:
url: ldap://localhost:1389
base_dn: ou=testorg,dc=example,dc=org
bind_dn: cn=admin,dc=example,dc=org
bind_password: adminpassword
user_filter: "(objectClass=shadowAccount)"
timeout: 5
check_for_deleted_entries: true
use_attribute_filter: true
attributes:
first_name: "cn"
last_name: "sn"
preferred_username: "displayName"
email: "mail"
phone: "telephoneNumber"
user_id: "uid"
status:
name: "shadowFlag"
is_binary: false
disable_bitmasks: []
tls:
client_key: ./tests/environment/certs/client.key
client_certificate: ./tests/environment/certs/client.crt
server_certificate: ./tests/environment/certs/server.crt
danger_disable_tls_verify: false
danger_use_start_tls: false
cache_path: ./test
feature_flags: []
"#};

fn load_config() -> Config {
serde_yaml::from_str(EXAMPLE_CONFIG).expect("invalid config")
}
Expand Down Expand Up @@ -571,4 +622,29 @@ mod tests {
assert_eq!(user.external_user_id, StringOrBytes::String("testuser".to_owned()));
assert!(user.enabled);
}

#[tokio::test]
async fn test_text_enabled() {
let config: Config =
serde_yaml::from_str(EXAMPLE_CONFIG_NO_DISABLE_BITMASKS).expect("invalid config");
let ldap_source =
LdapSource { ldap_config: config.sources.ldap.unwrap(), is_dry_run: false };

for (attr, parsed) in [("TRUE", true), ("FALSE", false)] {
let entry = SearchEntry {
dn: "uid=testuser,ou=testorg,dc=example,dc=org".to_owned(),
attrs: {
let mut user = new_user();
user.insert("shadowFlag".to_owned(), vec![attr.to_owned()]);
user
},
bin_attrs: HashMap::new(),
};

let result = ldap_source.parse_user(entry);
assert!(result.is_ok(), "Failed to parse user: {:?}", result);
let user = result.unwrap();
assert_eq!(user.enabled, parsed);
}
}
}

0 comments on commit bebd9f2

Please sign in to comment.