Skip to content

Commit

Permalink
fix: Hex encode uid in CSV import
Browse files Browse the repository at this point in the history
  • Loading branch information
jannden committed Nov 18, 2024
1 parent 65d5928 commit 77543e0
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async fn main() -> ExitCode {
#[allow(clippy::print_stderr)]
async fn run_sync() -> Result<()> {
let config = {
let config_path = std::env::var("FAMEDLY_LDAP_SYNC_CONFIG").unwrap_or("config.yaml".into());
let config_path = std::env::var("FAMEDLY_SYNC_CONFIG").unwrap_or("config.yaml".into());
let config_path = Path::new(&config_path);
match Config::new(config_path) {
Ok(config) => config,
Expand Down
2 changes: 1 addition & 1 deletion src/sources/csv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl CsvData {
last_name: csv_data.last_name,
phone: if csv_data.phone.is_empty() { None } else { Some(csv_data.phone) },
preferred_username: Some(csv_data.email.clone()),
external_user_id: csv_data.email,
external_user_id: hex::encode(csv_data.email),
enabled: true,
}
}
Expand Down
20 changes: 0 additions & 20 deletions src/user.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! User data helpers
use anyhow::{anyhow, Context, Result};
use base64::prelude::{Engine, BASE64_STANDARD};
use uuid::{uuid, Uuid};
use zitadel_rust_client::v2::users::HumanUser;

Expand Down Expand Up @@ -79,25 +78,6 @@ impl User {
pub fn get_famedly_uuid(&self) -> Result<String> {
Ok(Uuid::new_v5(&FAMEDLY_NAMESPACE, self.get_external_id_bytes()?.as_slice()).to_string())
}

/// Get a base64-encoded external user ID, if the ID is raw bytes,
/// or a UTF-8 string if not.
///
/// Note: This encoding scheme is inherently broken, because it is
/// impossible to tell apart base64 encoded strings from
/// non-base64 encoded strings. We can therefore never know if the
/// ID should be decoded or not when re-parsing it, and it may
/// create collisions (although this is unlikely).
///
/// Only use this for Zitadel support.
pub fn get_string_id(&self) -> Result<String> {
let id = self.get_external_id_bytes()?;
Ok(if let Ok(encoded_id) = String::from_utf8(id.clone()) {
encoded_id
} else {
BASE64_STANDARD.encode(id)
})
}
}

impl PartialEq for User {
Expand Down
24 changes: 23 additions & 1 deletion src/zitadel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use std::path::PathBuf;

use anyhow::{anyhow, Context, Result};
use base64::prelude::{Engine, BASE64_STANDARD};
use futures::{Stream, StreamExt};
use serde::Deserialize;
use url::Url;
Expand Down Expand Up @@ -162,7 +163,10 @@ impl Zitadel {

if self.feature_flags.is_enabled(FeatureFlag::SsoLogin) {
user.set_idp_links(vec![IdpLink::new()
.with_user_id(imported_user.get_string_id().context("Failed to set IDP user ID")?)
.with_user_id(
get_string_id(imported_user.get_external_id_bytes()?)
.context("Failed to set IDP user ID")?,
)
.with_idp_id(self.zitadel_config.idp_id.clone())
// TODO: Figure out if this is the correct value; empty is not permitted
.with_user_name(imported_user.email.clone())]);
Expand Down Expand Up @@ -306,6 +310,24 @@ fn search_result_to_user(user: ZitadelUser) -> Result<User> {
Ok(user)
}

/// Get a base64-encoded external user ID, if the ID is raw bytes,
/// or a UTF-8 string if not.
///
/// Note: This encoding scheme is inherently broken, because it is
/// impossible to tell apart base64 encoded strings from
/// non-base64 encoded strings. We can therefore never know if the
/// ID should be decoded or not when re-parsing it, and it may
/// create collisions (although this is unlikely).
///
/// Only use this for Zitadel support.
pub fn get_string_id(external_id_bytes: Vec<u8>) -> Result<String> {
Ok(if let Ok(encoded_id) = String::from_utf8(external_id_bytes.clone()) {
encoded_id
} else {
BASE64_STANDARD.encode(external_id_bytes)
})
}

/// Configuration related to Famedly Zitadel
#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct ZitadelConfig {
Expand Down

0 comments on commit 77543e0

Please sign in to comment.