nextcloud: per-user mail sync + portal RBAC
This commit is contained in:
parent
51b0a88a62
commit
91106ee298
@ -6,6 +6,7 @@ KC_REALM="${KC_REALM:?}"
|
||||
KC_ADMIN_USER="${KC_ADMIN_USER:?}"
|
||||
KC_ADMIN_PASS="${KC_ADMIN_PASS:?}"
|
||||
MAILU_DOMAIN="${MAILU_DOMAIN:?}"
|
||||
ONLY_USERNAME="${ONLY_USERNAME:-}"
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
apt-get update && apt-get install -y jq curl >/dev/null
|
||||
@ -57,11 +58,52 @@ fi
|
||||
|
||||
cd /var/www/html
|
||||
|
||||
users=$(curl -s -H "Authorization: Bearer ${token}" \
|
||||
"${KC_BASE}/admin/realms/${KC_REALM}/users?max=2000")
|
||||
kc_users_url="${KC_BASE}/admin/realms/${KC_REALM}/users?max=2000"
|
||||
if [[ -n "${ONLY_USERNAME}" ]]; then
|
||||
username_q=$(jq -nr --arg v "${ONLY_USERNAME}" '$v|@uri')
|
||||
kc_users_url="${KC_BASE}/admin/realms/${KC_REALM}/users?username=${username_q}&exact=true&max=1"
|
||||
fi
|
||||
|
||||
echo "${users}" | jq -c '.[]' | while read -r user; do
|
||||
username=$(echo "${user}" | jq -r '.username')
|
||||
users=$(curl -s -H "Authorization: Bearer ${token}" "${kc_users_url}")
|
||||
|
||||
kc_set_user_mail_meta() {
|
||||
local user_id="${1}"
|
||||
local primary_email="${2}"
|
||||
local mailu_account_count="${3}"
|
||||
local synced_at="${4}"
|
||||
|
||||
# Fetch the full user representation so we don't accidentally clobber attributes.
|
||||
local user_json updated_json
|
||||
if ! user_json=$(curl -fsS -H "Authorization: Bearer ${token}" \
|
||||
"${KC_BASE}/admin/realms/${KC_REALM}/users/${user_id}"); then
|
||||
echo "WARN: unable to fetch Keycloak user ${user_id} for metadata writeback" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
updated_json=$(
|
||||
jq -c \
|
||||
--arg primary_email "${primary_email}" \
|
||||
--arg mailu_account_count "${mailu_account_count}" \
|
||||
--arg synced_at "${synced_at}" \
|
||||
'
|
||||
.attributes = (.attributes // {}) |
|
||||
.attributes.nextcloud_mail_primary_email = [$primary_email] |
|
||||
.attributes.nextcloud_mail_account_count = [$mailu_account_count] |
|
||||
.attributes.nextcloud_mail_synced_at = [$synced_at] |
|
||||
del(.access)
|
||||
' <<<"${user_json}"
|
||||
)
|
||||
|
||||
curl -fsS -X PUT \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "${updated_json}" \
|
||||
"${KC_BASE}/admin/realms/${KC_REALM}/users/${user_id}" >/dev/null
|
||||
}
|
||||
|
||||
while read -r user; do
|
||||
user_id=$(jq -r '.id' <<<"${user}")
|
||||
username=$(jq -r '.username' <<<"${user}")
|
||||
keycloak_email=$(echo "${user}" | jq -r '.email // empty')
|
||||
mailu_email=$(echo "${user}" | jq -r '(.attributes.mailu_email[0] // .attributes.mailu_email // empty)')
|
||||
app_pw=$(echo "${user}" | jq -r '(.attributes.mailu_app_password[0] // .attributes.mailu_app_password // empty)')
|
||||
@ -131,4 +173,32 @@ echo "${users}" | jq -c '.[]' | while read -r user; do
|
||||
mail.bstein.dev 993 ssl "${desired_email}" "${app_pw}" \
|
||||
mail.bstein.dev 587 tls "${desired_email}" "${app_pw}" password >/dev/null 2>&1 || true
|
||||
fi
|
||||
done
|
||||
|
||||
# Write non-secret metadata back to Keycloak for UI introspection and onboarding gating.
|
||||
synced_at=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
if accounts_after=$(list_mail_accounts "${username}"); then
|
||||
mailu_accounts_after=$(awk -v d="${MAILU_DOMAIN,,}" 'tolower($2) ~ ("@" d "$") {print}' <<<"${accounts_after}" || true)
|
||||
if [[ -n "${mailu_accounts_after}" ]]; then
|
||||
mailu_account_count=$(printf '%s\n' "${mailu_accounts_after}" | wc -l | tr -d ' ')
|
||||
else
|
||||
mailu_account_count="0"
|
||||
fi
|
||||
primary_email_after=""
|
||||
if [[ -n "${mailu_accounts_after}" ]]; then
|
||||
while IFS=$'\t' read -r _account_id account_email; do
|
||||
if [[ "${account_email,,}" == "${desired_email,,}" ]]; then
|
||||
primary_email_after="${account_email}"
|
||||
break
|
||||
fi
|
||||
if [[ -z "${primary_email_after}" ]]; then
|
||||
primary_email_after="${account_email}"
|
||||
fi
|
||||
done <<<"${mailu_accounts_after}"
|
||||
fi
|
||||
else
|
||||
mailu_account_count="0"
|
||||
primary_email_after=""
|
||||
fi
|
||||
|
||||
kc_set_user_mail_meta "${user_id}" "${primary_email_after}" "${mailu_account_count}" "${synced_at}" || true
|
||||
done < <(jq -c '.[]' <<<"${users}")
|
||||
|
||||
@ -75,3 +75,34 @@ subjects:
|
||||
- kind: ServiceAccount
|
||||
name: bstein-dev-home
|
||||
namespace: bstein-dev-home
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: bstein-dev-home-nextcloud-mail-sync
|
||||
namespace: nextcloud
|
||||
rules:
|
||||
- apiGroups: ["batch"]
|
||||
resources: ["cronjobs"]
|
||||
verbs: ["get"]
|
||||
resourceNames: ["nextcloud-mail-sync"]
|
||||
- apiGroups: ["batch"]
|
||||
resources: ["jobs"]
|
||||
verbs: ["create", "get", "list", "watch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: bstein-dev-home-nextcloud-mail-sync
|
||||
namespace: nextcloud
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: bstein-dev-home-nextcloud-mail-sync
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: bstein-dev-home
|
||||
namespace: bstein-dev-home
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user