KANIDM_GROUP_PREFIX: plain group names in content on a shared Kanidm
Test / test (pull_request) Successful in 1m14s
Test / test (pull_request) Successful in 1m14s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6b72ae568a
commit
f2b131ebbb
+11
-4
@@ -184,6 +184,12 @@ fn name_from_search(body: &str) -> Option<String> {
|
||||
pub struct Kanidm {
|
||||
base: String,
|
||||
token: String,
|
||||
/// What this site's groups are called in a Kanidm it shares with
|
||||
/// other sites: `KANIDM_GROUP_PREFIX=klingenberg_` makes the
|
||||
/// content's `kunder` the group `klingenberg_kunder` there. The
|
||||
/// OAuth2 client's claim map takes the prefix off again, so content
|
||||
/// and policy never see it. Empty for a Kanidm of the site's own.
|
||||
group_prefix: String,
|
||||
}
|
||||
|
||||
impl Kanidm {
|
||||
@@ -192,7 +198,8 @@ impl Kanidm {
|
||||
pub fn from_env() -> Option<Self> {
|
||||
let base = std::env::var("KANIDM_URL").ok()?.trim_end_matches('/').to_string();
|
||||
let token = std::env::var("KANIDM_API_TOKEN").ok().filter(|t| !t.is_empty())?;
|
||||
Some(Kanidm { base, token })
|
||||
let group_prefix = std::env::var("KANIDM_GROUP_PREFIX").unwrap_or_default().trim().to_string();
|
||||
Some(Kanidm { base, token, group_prefix })
|
||||
}
|
||||
|
||||
async fn call(&self, method: openidconnect::reqwest::Method, path: &str, body: Option<serde_json::Value>) -> anyhow::Result<(u16, String)> {
|
||||
@@ -262,7 +269,7 @@ impl Kanidm {
|
||||
|
||||
/// Who is in a group, by account name.
|
||||
pub async fn members(&self, group: &str) -> anyhow::Result<Vec<String>> {
|
||||
let (status, text) = self.call(openidconnect::reqwest::Method::GET, &format!("/v1/group/{group}/_attr/member"), None).await?;
|
||||
let (status, text) = self.call(openidconnect::reqwest::Method::GET, &format!("/v1/group/{}{group}/_attr/member", self.group_prefix), None).await?;
|
||||
if !(200..300).contains(&status) {
|
||||
anyhow::bail!("kanidm: reading the members of {group}: http {status}: {text}");
|
||||
}
|
||||
@@ -273,7 +280,7 @@ impl Kanidm {
|
||||
/// service account manages, like adding them was.
|
||||
pub async fn remove_member(&self, group: &str, username: &str) -> anyhow::Result<()> {
|
||||
let (status, text) = self
|
||||
.call(openidconnect::reqwest::Method::DELETE, &format!("/v1/group/{group}/_attr/member"), Some(serde_json::json!([username])))
|
||||
.call(openidconnect::reqwest::Method::DELETE, &format!("/v1/group/{}{group}/_attr/member", self.group_prefix), Some(serde_json::json!([username])))
|
||||
.await?;
|
||||
if !(200..300).contains(&status) {
|
||||
anyhow::bail!("kanidm: removing {username} from {group}: http {status}: {text}");
|
||||
@@ -340,7 +347,7 @@ impl Kanidm {
|
||||
// tidying up after itself.
|
||||
already_member = !created && self.members(group).await.is_ok_and(|m| m.contains(&username));
|
||||
let (status, text) = self
|
||||
.call(openidconnect::reqwest::Method::POST, &format!("/v1/group/{group}/_attr/member"), Some(serde_json::json!([username])))
|
||||
.call(openidconnect::reqwest::Method::POST, &format!("/v1/group/{}{group}/_attr/member", self.group_prefix), Some(serde_json::json!([username])))
|
||||
.await?;
|
||||
if !(200..300).contains(&status) {
|
||||
anyhow::bail!("kanidm: adding {username} to {group}: http {status}: {text}");
|
||||
|
||||
Reference in New Issue
Block a user