librelad 875a60f90f LibrePortal v0.1.0 — initial release
A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys,
Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun
VPN routing, and a web dashboard to manage it all.

Free & open forever to self-host; optional paid hosted services fund it.
See PROMISE.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-21 20:37:54 +01:00

114 lines
4.3 KiB
Bash

#!/bin/bash
# Nextcloud exposes all admin operations through its `occ` CLI inside the
# container. We `docker exec` as www-data so file permissions stay sane, and
# pipe passwords via the OC_PASS env var (occ supports --password-from-env).
_nextcloudOcc() {
sudo docker exec -u www-data nextcloud-service php occ "$@" 2>&1
}
_nextcloudOccWithPass() {
local pass="$1"; shift
sudo docker exec -e OC_PASS="$pass" -u www-data nextcloud-service php occ "$@" 2>&1
}
authAdapter_nextcloud_setPassword() {
local username="$1" password="$2"
[[ -z "$username" ]] && { isError "Username is required."; return 1; }
[[ -z "$password" ]] && password=$(generateRandomPassword)
local out
out=$(_nextcloudOccWithPass "$password" user:resetpassword --password-from-env "$username")
if echo "$out" | grep -qi "user.* does not exist\|user not found"; then
isError "No Nextcloud user '$username'."; return 1
fi
if ! echo "$out" | grep -qi "successfully"; then
isError "Nextcloud reset failed: $out"; return 1
fi
if [[ "$username" == "${CFG_NEXTCLOUD_ADMIN_USER:-}" ]]; then
authPersistCfg nextcloud ADMIN_PASSWORD "$password"
fi
isSuccessful "Nextcloud password set for $username — New password: $password"
}
authAdapter_nextcloud_createUser() {
local username="$1" password="$2" displayName="$3" isAdmin="$4"
[[ -z "$username" ]] && { isError "Username is required."; return 1; }
[[ -z "$displayName" ]] && displayName="$username"
[[ -z "$password" ]] && password=$(generateRandomPassword)
local out args=(--password-from-env --display-name="$displayName")
[[ "$isAdmin" == "true" ]] && args+=(--group=admin)
out=$(_nextcloudOccWithPass "$password" user:add "${args[@]}" "$username")
if echo "$out" | grep -qi "user.* already exists\|user already exists"; then
isError "User '$username' already exists."; return 1
fi
if ! echo "$out" | grep -qi "user .* was created\|user.* added"; then
isError "Nextcloud create failed: $out"; return 1
fi
if [[ "$isAdmin" == "true" && -z "${CFG_NEXTCLOUD_ADMIN_USER:-}" ]]; then
authPersistCfg nextcloud ADMIN_USER "$username"
authPersistCfg nextcloud ADMIN_PASSWORD "$password"
fi
isSuccessful "Nextcloud user created — Username: $username — Password: $password"
}
authAdapter_nextcloud_listUsers() {
local users_json admin_json
users_json=$(_nextcloudOcc user:list --output=json)
admin_json=$(_nextcloudOcc group:list --output=json)
# users_json: {"alice":"Alice","bob":"Bob"} ; admin members come from group:list.
# Format each line as EZ_USER<tab>username<tab>display<tab>roles to match the
# tab-separated shape the dispatcher prints back to the UI.
python3 - "$users_json" "$admin_json" <<'PY'
import json, sys
try:
users = json.loads(sys.argv[1] or "{}")
except Exception:
users = {}
try:
groups = json.loads(sys.argv[2] or "{}")
except Exception:
groups = {}
admins = set(groups.get("admin", []))
for username, display in users.items():
role = "admin" if username in admins else "user"
print(f"EZ_USER\t{username}\t{display or username}\t{role}")
PY
}
authAdapter_nextcloud_deleteUser() {
local username="$1"
[[ -z "$username" ]] && { isError "Username is required."; return 1; }
local out
out=$(_nextcloudOcc user:delete "$username")
if echo "$out" | grep -qi "user.* does not exist\|user not found"; then
isError "No Nextcloud user '$username'."; return 1
fi
if ! echo "$out" | grep -qi "the specified user was deleted\|user .* deleted"; then
isError "Nextcloud delete failed: $out"; return 1
fi
isSuccessful "Nextcloud user '$username' deleted."
}
authAdapter_nextcloud_setAdmin() {
local username="$1" isAdmin="$2"
[[ -z "$username" ]] && { isError "Username is required."; return 1; }
local target="${isAdmin}"; [[ "$target" != "true" ]] && target="false"
local out
if [[ "$target" == "true" ]]; then
out=$(_nextcloudOcc group:adduser admin "$username")
else
out=$(_nextcloudOcc group:removeuser admin "$username")
fi
if echo "$out" | grep -qi "user.* does not exist\|user not found"; then
isError "No Nextcloud user '$username'."; return 1
fi
isSuccessful "Nextcloud user '$username' admin → $target."
}