Add OIDC sign-in, group-derived roles and declarative instance configuration
Workspaces, group mappings and sign-in methods now come from a configuration file synchronized at startup; workspaces dropped from it are disabled, never deleted. Instance administrators (a new role) see and help every workspace and may delete disabled ones; workspace administrators and employees are derived from the user's groups at every SSO sign-in or administrator edit, and the employee permission set belongs to the workspace. Self-registration is gone: users come from SSO (only when their groups map) or from the administrator. Break-glass bootstrap accounts get an HMAC-derived hourly password that all replicas agree on. First SSO sign-in links a matching email contact to the user. The demo runs on the same model with a generated per-start password. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
e37d583179
commit
4764f3545f
68 files changed
+7220
-964
No files matched your search
@@ -8,6 +8,9 @@ pub type Names = BTreeMap<String, String>;
|
||||
pub fn remember(names: &mut Names, doc: &WorkspaceDocument) {
|
||||
for person in &doc.people {
|
||||
names.insert(person.id.to_string(), person.display_name.clone());
|
||||
for alias in &person.aliases {
|
||||
names.insert(alias.to_string(), person.display_name.clone());
|
||||
}
|
||||
if let Some(id) = person.user_id {
|
||||
names.insert(id.to_string(), person.display_name.clone());
|
||||
}
|
||||
@@ -87,4 +90,22 @@ mod tests {
|
||||
assert_eq!(resolved["unknown_id"], "missing");
|
||||
assert_eq!(raw["from_user"], id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merged_contact_ids_keep_resolving_to_the_person() {
|
||||
let (old, new) = (uuid::Uuid::new_v4(), uuid::Uuid::new_v4());
|
||||
let mut doc = WorkspaceDocument::new("Team".into());
|
||||
doc.people.push(crate::domain::Person {
|
||||
id: new,
|
||||
user_id: Some(new),
|
||||
display_name: "Dana".into(),
|
||||
email: Some("dana@example.com".into()),
|
||||
country: None,
|
||||
aliases: vec![old],
|
||||
});
|
||||
let mut names = Names::new();
|
||||
remember(&mut names, &doc);
|
||||
assert_eq!(names[&old.to_string()], "Dana");
|
||||
assert_eq!(names[&new.to_string()], "Dana");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user