fix(linkding): declare the admin keys its auth adapter writes
linkding_auth.sh persists ADMIN_USER and ADMIN_PASSWORD when the first admin is created, and keeps the password in step on later resets of that account, but linkding.config declared neither — so both writes were no-ops and the WebUI credentials card never had anything to show. Predates the slot work; it only became visible once authPersistCfg started warning instead of failing silently. Added empty rather than RANDOMIZED*, because unlike bookstack or nextcloud nothing seeds a linkding account at install — the first user is created from the WebUI. A generated password would name an account that does not exist, and the card would display a password that cannot log in. Unslotted for the same reason: the slot number marks a value the installer generates, and this one is written at runtime by the tool. No AUTH_PROFILE key: nothing reads it (it exists only in a comment in auth_adapter.sh), and adding an unread key is what was just cleaned up elsewhere. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
cbbb978e50
commit
a96a3a69a1
@ -61,3 +61,19 @@ CFG_LINKDING_NETWORK=default
|
||||
# - description: human-readable description of the service
|
||||
#
|
||||
CFG_LINKDING_PORT_1="linkding-service|webui|random:9090|public|tcp|false|true|true|Web Interface||bookmark"
|
||||
#
|
||||
# =============================================================================
|
||||
# ADMIN ACCOUNT
|
||||
# =============================================================================
|
||||
# Recorded by the auth tools, not by the installer. Linkding ships with no user
|
||||
# at all — the first admin is created from the WebUI (Create Account), and the
|
||||
# adapter writes the username and password here so the credentials card can show
|
||||
# them, then keeps the password in step on later resets of that same account.
|
||||
#
|
||||
# Deliberately empty rather than RANDOMIZED*: nothing seeds an account at
|
||||
# install, so a generated password would name an account that does not exist and
|
||||
# the WebUI would display a password that cannot log in. These are also
|
||||
# unslotted, because the slot number marks a value the installer generates.
|
||||
#
|
||||
CFG_LINKDING_ADMIN_USER=
|
||||
CFG_LINKDING_ADMIN_PASSWORD=
|
||||
|
||||
@ -114,3 +114,6 @@ CFG_MATRIX_NETWORK=default
|
||||
#
|
||||
CFG_MATRIX_PORT_1="matrix-synapse|homeserver|random:8008|public|tcp|false|true|false|Matrix Homeserver (client + federation API)||matrix"
|
||||
CFG_MATRIX_PORT_2="matrix-element|webui|random:80|public|tcp|false|true|true|Element Web Interface||element"
|
||||
|
||||
# AUTH_PROFILE = capability tier for the WebUI auth tools (single_password | user_password | multi_user)
|
||||
CFG_MATRIX_AUTH_PROFILE=multi_user
|
||||
|
||||
@ -53,7 +53,7 @@ database:
|
||||
cp_min: 5
|
||||
cp_max: 10
|
||||
|
||||
log_config: "/data/log.config"
|
||||
log_config: "/data/log.yaml"
|
||||
media_store_path: /data/media_store
|
||||
signing_key_path: "/data/signing.key"
|
||||
|
||||
|
||||
304
containers/matrix/scripts/matrix_auth.sh
Normal file
304
containers/matrix/scripts/matrix_auth.sh
Normal file
@ -0,0 +1,304 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Matrix user management, via Synapse's admin API.
|
||||
#
|
||||
# Everything goes through `docker exec matrix-synapse python`: the image is
|
||||
# debian-slim with no curl or wget, but python is what Synapse itself runs on,
|
||||
# so it is always present. Talking to localhost:8008 inside the container also
|
||||
# means these tools behave identically whether the install is LAN-only or behind
|
||||
# Traefik, and never depend on the published port.
|
||||
#
|
||||
# Two Matrix facts shape what can be offered here:
|
||||
# - A user ID is permanent. There is no rename; "changing a username" means
|
||||
# creating a new account.
|
||||
# - There is no true delete. Deactivation is the terminal state — it revokes
|
||||
# access, devices and profile, but the ID stays burned so it can never be
|
||||
# re-registered and old messages still resolve.
|
||||
|
||||
# Localpart -> full ID. Accepts either form, so a caller can pass "alice" or
|
||||
# "@alice:example.com" and get the same result.
|
||||
_matrixUserId() {
|
||||
local user="$1" server
|
||||
[[ "$user" == @* ]] && { echo "$user"; return 0; }
|
||||
server=$(_matrixServerName)
|
||||
[[ -z "$server" ]] && return 1
|
||||
echo "@${user}:${server}"
|
||||
}
|
||||
|
||||
# Where the cached admin access token lives. Beside homeserver.yaml, which
|
||||
# already holds the registration shared secret and the database password, so
|
||||
# this adds no new class of secret to the install.
|
||||
_matrix_token_cache="data/.lp-admin-token"
|
||||
|
||||
# Run a python snippet inside the Synapse container with an admin access token
|
||||
# already in scope and a call(method, path, body) helper available.
|
||||
#
|
||||
# Args: <python snippet> [extra docker -e flags...]
|
||||
#
|
||||
# Values are handed over as environment variables rather than interpolated into
|
||||
# the snippet, so a password containing quotes or backslashes cannot break out
|
||||
# into the python source.
|
||||
#
|
||||
# The token is CACHED between invocations. Logging in each time seemed tidier,
|
||||
# but Synapse rate-limits /login (rc_login defaults to a burst of 5), so running
|
||||
# a few tools in succession failed with "Too Many Requests" — the tools were
|
||||
# throttling themselves. One login, reused until it stops working, and a single
|
||||
# re-login on 401 if the token was revoked or the password changed.
|
||||
_matrixApi() {
|
||||
local script="$1"; shift
|
||||
local admin_user="${CFG_MATRIX_ADMIN_USERNAME:-admin}"
|
||||
local admin_pass="${CFG_MATRIX_ADMIN_PASSWORD_1}"
|
||||
local cache="${containers_dir}matrix/${_matrix_token_cache}"
|
||||
|
||||
if [[ -z "$admin_pass" || "$admin_pass" == RANDOMIZEDPASSWORD* ]]; then
|
||||
isError "No Matrix admin password in matrix.config — cannot authenticate to the admin API."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local cached=""
|
||||
[[ -s "$cache" ]] && cached=$(runFileOp cat "$cache" 2>/dev/null)
|
||||
|
||||
local raw
|
||||
raw=$(runFileOp docker exec -i "$@" \
|
||||
-e LP_ADMIN_USER="$admin_user" \
|
||||
-e LP_ADMIN_PASS="$admin_pass" \
|
||||
-e LP_TOKEN="$cached" \
|
||||
matrix-synapse python - <<PY
|
||||
import json, os, sys, time, urllib.request, urllib.error
|
||||
|
||||
BASE = "http://localhost:8008"
|
||||
TOKEN = os.environ.get("LP_TOKEN") or ""
|
||||
|
||||
class Unauthorised(Exception):
|
||||
pass
|
||||
|
||||
def _raw(method, path, body=None, token=None, quiet404=False):
|
||||
data = json.dumps(body).encode() if body is not None else None
|
||||
r = urllib.request.Request(BASE + path, data=data, method=method)
|
||||
r.add_header("Content-Type", "application/json")
|
||||
if token:
|
||||
r.add_header("Authorization", "Bearer " + token)
|
||||
try:
|
||||
with urllib.request.urlopen(r, timeout=30) as resp:
|
||||
return json.loads(resp.read().decode() or "{}")
|
||||
except urllib.error.HTTPError as e:
|
||||
if quiet404 and e.code == 404:
|
||||
return None
|
||||
body_txt = e.read().decode()
|
||||
try:
|
||||
parsed = json.loads(body_txt)
|
||||
except Exception:
|
||||
parsed = {}
|
||||
if e.code in (401, 403) and parsed.get("errcode") in ("M_UNKNOWN_TOKEN", "M_MISSING_TOKEN"):
|
||||
raise Unauthorised()
|
||||
# Synapse tells us exactly how long to wait; honour it rather than
|
||||
# failing the whole tool on a transient throttle.
|
||||
if e.code == 429:
|
||||
wait = parsed.get("retry_after_ms", 2000) / 1000.0
|
||||
time.sleep(min(wait + 0.25, 10))
|
||||
return _raw(method, path, body, token, quiet404)
|
||||
print("LP_ERR:" + str(parsed.get("error", body_txt)))
|
||||
sys.exit(1)
|
||||
except urllib.error.URLError as e:
|
||||
print("LP_ERR:" + str(e))
|
||||
sys.exit(1)
|
||||
|
||||
def _login():
|
||||
global TOKEN
|
||||
res = _raw("POST", "/_matrix/client/v3/login", {
|
||||
"type": "m.login.password",
|
||||
"identifier": {"type": "m.id.user", "user": os.environ["LP_ADMIN_USER"]},
|
||||
"password": os.environ["LP_ADMIN_PASS"],
|
||||
})
|
||||
TOKEN = res["access_token"]
|
||||
# Picked up by the caller and written to the cache file.
|
||||
print("LP_NEWTOKEN:" + TOKEN)
|
||||
|
||||
if not TOKEN:
|
||||
_login()
|
||||
|
||||
def call(method, path, body=None, quiet404=False):
|
||||
try:
|
||||
return _raw(method, path, body, TOKEN, quiet404)
|
||||
except Unauthorised:
|
||||
# Cached token was revoked, or the admin password changed under us.
|
||||
_login()
|
||||
return _raw(method, path, body, TOKEN, quiet404)
|
||||
|
||||
$script
|
||||
PY
|
||||
)
|
||||
|
||||
# Persist a freshly-minted token, then strip the marker so callers only ever
|
||||
# see the snippet's own output.
|
||||
local new_token
|
||||
new_token=$(printf '%s\n' "$raw" | sed -n 's/^LP_NEWTOKEN://p' | head -1)
|
||||
if [[ -n "$new_token" ]]; then
|
||||
printf '%s' "$new_token" | runFileWrite "$cache"
|
||||
runFileOp chmod 600 "$cache"
|
||||
fi
|
||||
printf '%s\n' "$raw" | grep -v '^LP_NEWTOKEN:'
|
||||
return 0
|
||||
}
|
||||
|
||||
# Shared post-processing: surface the API's own error text rather than a generic
|
||||
# failure, since Synapse's messages are usually the actionable part.
|
||||
_matrixApiFailed() {
|
||||
local out="$1" what="$2"
|
||||
if [[ "$out" == *LP_ERR:* ]]; then
|
||||
isError "$what failed: ${out#*LP_ERR:}"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
authAdapter_matrix_createUser() {
|
||||
local user="$1" password="$2" displayname="$3" isAdmin="$4"
|
||||
[[ -z "$user" ]] && { isError "A username is required."; return 1; }
|
||||
[[ -z "$password" ]] && password=$(generateRandomPassword)
|
||||
|
||||
local uid; uid=$(_matrixUserId "$user") || { isError "Could not determine the homeserver name."; return 1; }
|
||||
[[ -z "$displayname" ]] && { displayname="${user#@}"; displayname="${displayname%%:*}"; }
|
||||
local admin_flag="False"; [[ "$isAdmin" == "true" ]] && admin_flag="True"
|
||||
|
||||
local out
|
||||
out=$(_matrixApi "
|
||||
uid = os.environ['LP_UID']
|
||||
if call('GET', '/_synapse/admin/v2/users/' + uid, quiet404=True):
|
||||
print('LP_EXISTS')
|
||||
else:
|
||||
call('PUT', '/_synapse/admin/v2/users/' + uid, {
|
||||
'password': os.environ['LP_NEWPASS'],
|
||||
'displayname': os.environ['LP_DISPLAY'],
|
||||
'admin': ${admin_flag},
|
||||
})
|
||||
print('LP_OK')
|
||||
" -e LP_UID="$uid" -e LP_NEWPASS="$password" -e LP_DISPLAY="$displayname" 2>&1)
|
||||
|
||||
_matrixApiFailed "$out" "Creating $uid" && return 1
|
||||
[[ "$out" == *LP_EXISTS* ]] && { isError "$uid already exists."; return 1; }
|
||||
[[ "$out" != *LP_OK* ]] && { isError "Creating $uid failed: $out"; return 1; }
|
||||
|
||||
isSuccessful "Matrix user created — ID: $uid — Password: $password"
|
||||
}
|
||||
|
||||
authAdapter_matrix_setPassword() {
|
||||
local user="$1" password="$2"
|
||||
[[ -z "$user" ]] && { isError "A username is required."; return 1; }
|
||||
[[ -z "$password" ]] && password=$(generateRandomPassword)
|
||||
|
||||
local uid; uid=$(_matrixUserId "$user") || { isError "Could not determine the homeserver name."; return 1; }
|
||||
|
||||
local out
|
||||
out=$(_matrixApi "
|
||||
uid = os.environ['LP_UID']
|
||||
if not call('GET', '/_synapse/admin/v2/users/' + uid, quiet404=True):
|
||||
print('LP_MISSING')
|
||||
else:
|
||||
# logout_devices invalidates every existing session, which is the whole
|
||||
# point of a reset — otherwise a stolen token keeps working afterwards.
|
||||
call('PUT', '/_synapse/admin/v2/users/' + uid, {
|
||||
'password': os.environ['LP_NEWPASS'],
|
||||
'logout_devices': True,
|
||||
})
|
||||
print('LP_OK')
|
||||
" -e LP_UID="$uid" -e LP_NEWPASS="$password" 2>&1)
|
||||
|
||||
_matrixApiFailed "$out" "Resetting $uid" && return 1
|
||||
[[ "$out" == *LP_MISSING* ]] && { isError "No Matrix user $uid."; return 1; }
|
||||
[[ "$out" != *LP_OK* ]] && { isError "Resetting $uid failed: $out"; return 1; }
|
||||
|
||||
# Keep the config in step when the admin's own password changes, or the
|
||||
# WebUI card and these very tools would carry on offering the old one.
|
||||
local admin_uid; admin_uid=$(_matrixUserId "${CFG_MATRIX_ADMIN_USERNAME:-admin}")
|
||||
[[ "$uid" == "$admin_uid" ]] && authPersistCfg matrix ADMIN_PASSWORD "$password"
|
||||
|
||||
isSuccessful "Matrix password set for $uid — New password: $password — all their sessions were signed out."
|
||||
}
|
||||
|
||||
authAdapter_matrix_listUsers() {
|
||||
local out
|
||||
out=$(_matrixApi "
|
||||
res = call('GET', '/_synapse/admin/v2/users?from=0&limit=500&deactivated=true')
|
||||
for u in res.get('users', []):
|
||||
flags = []
|
||||
if u.get('admin'): flags.append('admin')
|
||||
if u.get('deactivated'): flags.append('deactivated')
|
||||
print('LP_USER\t' + u['name'] + '\t' + (u.get('displayname') or '-') + '\t' + (','.join(flags) or 'user'))
|
||||
print('LP_TOTAL:' + str(res.get('total', 0)))
|
||||
" 2>&1)
|
||||
|
||||
_matrixApiFailed "$out" "Listing users" && return 1
|
||||
|
||||
local line total=0
|
||||
while IFS= read -r line; do
|
||||
case "$line" in
|
||||
LP_USER*) IFS=$'\t' read -r _ uid name flags <<< "$line"
|
||||
printf ' %-34s %-20s %s\n' "$uid" "$name" "$flags" ;;
|
||||
LP_TOTAL:*) total="${line#LP_TOTAL:}" ;;
|
||||
esac
|
||||
done <<< "$out"
|
||||
isSuccessful "$total Matrix account(s)."
|
||||
}
|
||||
|
||||
# Matrix has no delete — deactivation is as far as it goes, and it is
|
||||
# irreversible. Named deleteUser to match the adapter contract the other apps
|
||||
# use, but the message is explicit about what actually happens.
|
||||
authAdapter_matrix_deleteUser() {
|
||||
local user="$1"
|
||||
[[ -z "$user" ]] && { isError "A username is required."; return 1; }
|
||||
|
||||
local uid; uid=$(_matrixUserId "$user") || { isError "Could not determine the homeserver name."; return 1; }
|
||||
local admin_uid; admin_uid=$(_matrixUserId "${CFG_MATRIX_ADMIN_USERNAME:-admin}")
|
||||
if [[ "$uid" == "$admin_uid" ]]; then
|
||||
isError "Refusing to deactivate $uid — it is the admin these tools authenticate as."
|
||||
isNotice "Promote another account to admin and point CFG_MATRIX_ADMIN_USERNAME at it first."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local out
|
||||
out=$(_matrixApi "
|
||||
uid = os.environ['LP_UID']
|
||||
if not call('GET', '/_synapse/admin/v2/users/' + uid, quiet404=True):
|
||||
print('LP_MISSING')
|
||||
else:
|
||||
call('POST', '/_synapse/admin/v1/deactivate/' + uid, {'erase': True})
|
||||
print('LP_OK')
|
||||
" -e LP_UID="$uid" 2>&1)
|
||||
|
||||
_matrixApiFailed "$out" "Deactivating $uid" && return 1
|
||||
[[ "$out" == *LP_MISSING* ]] && { isError "No Matrix user $uid."; return 1; }
|
||||
[[ "$out" != *LP_OK* ]] && { isError "Deactivating $uid failed: $out"; return 1; }
|
||||
|
||||
isSuccessful "Matrix user $uid deactivated and erased. The ID is permanently taken and cannot be re-registered."
|
||||
}
|
||||
|
||||
authAdapter_matrix_setAdmin() {
|
||||
local user="$1" isAdmin="$2"
|
||||
[[ -z "$user" ]] && { isError "A username is required."; return 1; }
|
||||
local target="false"; [[ "$isAdmin" == "true" ]] && target="true"
|
||||
|
||||
local uid; uid=$(_matrixUserId "$user") || { isError "Could not determine the homeserver name."; return 1; }
|
||||
local admin_uid; admin_uid=$(_matrixUserId "${CFG_MATRIX_ADMIN_USERNAME:-admin}")
|
||||
if [[ "$uid" == "$admin_uid" && "$target" == "false" ]]; then
|
||||
isError "Refusing to demote $uid — it is the admin these tools authenticate as, and demoting it would lock them out."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local py_bool="False"; [[ "$target" == "true" ]] && py_bool="True"
|
||||
local out
|
||||
out=$(_matrixApi "
|
||||
uid = os.environ['LP_UID']
|
||||
if not call('GET', '/_synapse/admin/v2/users/' + uid, quiet404=True):
|
||||
print('LP_MISSING')
|
||||
else:
|
||||
call('PUT', '/_synapse/admin/v2/users/' + uid, {'admin': ${py_bool}})
|
||||
print('LP_OK')
|
||||
" -e LP_UID="$uid" 2>&1)
|
||||
|
||||
_matrixApiFailed "$out" "Changing admin status for $uid" && return 1
|
||||
[[ "$out" == *LP_MISSING* ]] && { isError "No Matrix user $uid."; return 1; }
|
||||
[[ "$out" != *LP_OK* ]] && { isError "Changing admin status for $uid failed: $out"; return 1; }
|
||||
|
||||
isSuccessful "Matrix user $uid admin → $target."
|
||||
}
|
||||
@ -211,8 +211,8 @@ matrix_install_post_compose()
|
||||
result=$(copyResource "$app_name" "homeserver.yaml" "data" | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1)
|
||||
checkSuccess "Copying homeserver.yaml to $data_dir"
|
||||
|
||||
result=$(copyResource "$app_name" "log.config" "data" | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1)
|
||||
checkSuccess "Copying log.config to $data_dir"
|
||||
result=$(copyResource "$app_name" "log.yaml" "data" | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1)
|
||||
checkSuccess "Copying log.yaml to $data_dir"
|
||||
|
||||
local homeserver_file="$data_dir/homeserver.yaml"
|
||||
|
||||
|
||||
106
containers/matrix/tools/matrix.tools.json
Normal file
106
containers/matrix/tools/matrix.tools.json
Normal file
@ -0,0 +1,106 @@
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"id": "create_account",
|
||||
"category": "users",
|
||||
"label": "Create User Account",
|
||||
"description": "Add a Matrix account. The username becomes permanent — @name:server can never be renamed.",
|
||||
"icon": "👤",
|
||||
"fields": [
|
||||
{
|
||||
"name": "username",
|
||||
"label": "Username",
|
||||
"type": "text",
|
||||
"placeholder": "alice (not the full @alice:server)",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "displayname",
|
||||
"label": "Display name",
|
||||
"type": "text",
|
||||
"placeholder": "Leave blank to use the username"
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"label": "Password",
|
||||
"type": "password",
|
||||
"placeholder": "Leave blank to generate"
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"label": "Make server admin",
|
||||
"type": "checkbox",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "list_users",
|
||||
"category": "users",
|
||||
"label": "List Users",
|
||||
"description": "Every account on this homeserver, including deactivated ones.",
|
||||
"icon": "📋",
|
||||
"fields": []
|
||||
},
|
||||
{
|
||||
"id": "reset_password",
|
||||
"category": "users",
|
||||
"label": "Reset User Password",
|
||||
"description": "Set a new password and sign the user out of every device.",
|
||||
"icon": "🔑",
|
||||
"fields": [
|
||||
{
|
||||
"name": "username",
|
||||
"label": "Username",
|
||||
"type": "text",
|
||||
"placeholder": "alice",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"label": "New password",
|
||||
"type": "password",
|
||||
"placeholder": "Leave blank to generate"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "set_admin",
|
||||
"category": "users",
|
||||
"label": "Set Admin Status",
|
||||
"description": "Grant or revoke Synapse server-admin rights.",
|
||||
"icon": "👑",
|
||||
"fields": [
|
||||
{
|
||||
"name": "username",
|
||||
"label": "Username",
|
||||
"type": "text",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"label": "Make server admin",
|
||||
"type": "checkbox",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "deactivate_user",
|
||||
"category": "users",
|
||||
"label": "Deactivate User Account",
|
||||
"description": "Matrix has no delete. This revokes access and erases the profile, and the user ID stays permanently taken.",
|
||||
"icon": "🚫",
|
||||
"destructive": true,
|
||||
"confirm": "This cannot be undone, and the user ID can never be registered again.",
|
||||
"fields": [
|
||||
{
|
||||
"name": "username",
|
||||
"label": "Username",
|
||||
"type": "text",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
10
containers/matrix/tools/matrix_create_account.sh
Normal file
10
containers/matrix/tools/matrix_create_account.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
appMatrixCreateAccount() {
|
||||
local args="$1"
|
||||
authAdapterCall matrix createUser \
|
||||
"$(authToolArg "$args" username)" \
|
||||
"$(authToolArg "$args" password)" \
|
||||
"$(authToolArg "$args" displayname)" \
|
||||
"$(authToolArg "$args" admin)"
|
||||
}
|
||||
8
containers/matrix/tools/matrix_deactivate_user.sh
Normal file
8
containers/matrix/tools/matrix_deactivate_user.sh
Normal file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Named deactivate rather than delete on purpose — Matrix has no delete, and
|
||||
# calling it one would misrepresent what the button does.
|
||||
appMatrixDeactivateUser() {
|
||||
local args="$1"
|
||||
authAdapterCall matrix deleteUser "$(authToolArg "$args" username)"
|
||||
}
|
||||
5
containers/matrix/tools/matrix_list_users.sh
Normal file
5
containers/matrix/tools/matrix_list_users.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
appMatrixListUsers() {
|
||||
authAdapterCall matrix listUsers
|
||||
}
|
||||
8
containers/matrix/tools/matrix_reset_password.sh
Normal file
8
containers/matrix/tools/matrix_reset_password.sh
Normal file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
appMatrixResetPassword() {
|
||||
local args="$1"
|
||||
authAdapterCall matrix setPassword \
|
||||
"$(authToolArg "$args" username)" \
|
||||
"$(authToolArg "$args" password)"
|
||||
}
|
||||
8
containers/matrix/tools/matrix_set_admin.sh
Normal file
8
containers/matrix/tools/matrix_set_admin.sh
Normal file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
appMatrixSetAdmin() {
|
||||
local args="$1"
|
||||
authAdapterCall matrix setAdmin \
|
||||
"$(authToolArg "$args" username)" \
|
||||
"$(authToolArg "$args" admin)"
|
||||
}
|
||||
@ -57,6 +57,11 @@ declare -gA LP_FN_MAP=(
|
||||
[appLinkdingListUsers]="linkding/tools/linkding_list_users.sh"
|
||||
[appLinkdingResetPassword]="linkding/tools/linkding_reset_password.sh"
|
||||
[appLinkdingSetAdmin]="linkding/tools/linkding_set_admin.sh"
|
||||
[appMatrixCreateAccount]="matrix/tools/matrix_create_account.sh"
|
||||
[appMatrixDeactivateUser]="matrix/tools/matrix_deactivate_user.sh"
|
||||
[appMatrixListUsers]="matrix/tools/matrix_list_users.sh"
|
||||
[appMatrixResetPassword]="matrix/tools/matrix_reset_password.sh"
|
||||
[appMatrixSetAdmin]="matrix/tools/matrix_set_admin.sh"
|
||||
[appNetworkApplyMode_gluetun]="gluetun/scripts/gluetun_network.sh"
|
||||
[appNetworkRegisterPorts_gluetun]="gluetun/scripts/gluetun_network.sh"
|
||||
[appNextcloudAddTrustedDomain]="nextcloud/tools/nextcloud_add_trusted_domain.sh"
|
||||
@ -148,6 +153,11 @@ declare -gA LP_FN_MAP=(
|
||||
[authAdapter_linkding_listUsers]="linkding/scripts/linkding_auth.sh"
|
||||
[authAdapter_linkding_setAdmin]="linkding/scripts/linkding_auth.sh"
|
||||
[authAdapter_linkding_setPassword]="linkding/scripts/linkding_auth.sh"
|
||||
[authAdapter_matrix_createUser]="matrix/scripts/matrix_auth.sh"
|
||||
[authAdapter_matrix_deleteUser]="matrix/scripts/matrix_auth.sh"
|
||||
[authAdapter_matrix_listUsers]="matrix/scripts/matrix_auth.sh"
|
||||
[authAdapter_matrix_setAdmin]="matrix/scripts/matrix_auth.sh"
|
||||
[authAdapter_matrix_setPassword]="matrix/scripts/matrix_auth.sh"
|
||||
[authAdapter_nextcloud_createUser]="nextcloud/scripts/nextcloud_auth.sh"
|
||||
[authAdapter_nextcloud_deleteUser]="nextcloud/scripts/nextcloud_auth.sh"
|
||||
[authAdapter_nextcloud_listUsers]="nextcloud/scripts/nextcloud_auth.sh"
|
||||
@ -648,12 +658,15 @@ declare -gA LP_FN_MAP=(
|
||||
[manifestWrite]="backup/manifest/manifest_write.sh"
|
||||
[mastodon_install_post_setup]="mastodon/scripts/mastodon_install_hooks.sh"
|
||||
[mastodon_upgrade_verify]="mastodon/scripts/mastodon_upgrade_hooks.sh"
|
||||
[_matrixApi]="matrix/scripts/matrix_auth.sh"
|
||||
[_matrixApiFailed]="matrix/scripts/matrix_auth.sh"
|
||||
[matrix_install_post]="matrix/scripts/matrix_install_hooks.sh"
|
||||
[matrix_install_post_compose]="matrix/scripts/matrix_install_hooks.sh"
|
||||
[matrix_install_post_start]="matrix/scripts/matrix_install_hooks.sh"
|
||||
[matrix_install_pre]="matrix/scripts/matrix_install_hooks.sh"
|
||||
[_matrixPublicBaseUrl]="matrix/scripts/matrix_install_hooks.sh"
|
||||
[_matrixServerName]="matrix/scripts/matrix_install_hooks.sh"
|
||||
[_matrixUserId]="matrix/scripts/matrix_auth.sh"
|
||||
[mattermostToolsMenu]="menu/tools/manage_mattermost.sh"
|
||||
[maybeRegenPoll]="task/crontab_task_processor.sh"
|
||||
[menuContinue]="menu/message/continue.sh"
|
||||
@ -1118,6 +1131,11 @@ declare -gA LP_FN_ROOT=(
|
||||
[appLinkdingListUsers]="containers"
|
||||
[appLinkdingResetPassword]="containers"
|
||||
[appLinkdingSetAdmin]="containers"
|
||||
[appMatrixCreateAccount]="containers"
|
||||
[appMatrixDeactivateUser]="containers"
|
||||
[appMatrixListUsers]="containers"
|
||||
[appMatrixResetPassword]="containers"
|
||||
[appMatrixSetAdmin]="containers"
|
||||
[appNetworkApplyMode_gluetun]="containers"
|
||||
[appNetworkRegisterPorts_gluetun]="containers"
|
||||
[appNextcloudAddTrustedDomain]="containers"
|
||||
@ -1209,6 +1227,11 @@ declare -gA LP_FN_ROOT=(
|
||||
[authAdapter_linkding_listUsers]="containers"
|
||||
[authAdapter_linkding_setAdmin]="containers"
|
||||
[authAdapter_linkding_setPassword]="containers"
|
||||
[authAdapter_matrix_createUser]="containers"
|
||||
[authAdapter_matrix_deleteUser]="containers"
|
||||
[authAdapter_matrix_listUsers]="containers"
|
||||
[authAdapter_matrix_setAdmin]="containers"
|
||||
[authAdapter_matrix_setPassword]="containers"
|
||||
[authAdapter_nextcloud_createUser]="containers"
|
||||
[authAdapter_nextcloud_deleteUser]="containers"
|
||||
[authAdapter_nextcloud_listUsers]="containers"
|
||||
@ -1709,12 +1732,15 @@ declare -gA LP_FN_ROOT=(
|
||||
[manifestWrite]="scripts"
|
||||
[mastodon_install_post_setup]="containers"
|
||||
[mastodon_upgrade_verify]="containers"
|
||||
[_matrixApi]="containers"
|
||||
[_matrixApiFailed]="containers"
|
||||
[matrix_install_post]="containers"
|
||||
[matrix_install_post_compose]="containers"
|
||||
[matrix_install_post_start]="containers"
|
||||
[matrix_install_pre]="containers"
|
||||
[_matrixPublicBaseUrl]="containers"
|
||||
[_matrixServerName]="containers"
|
||||
[_matrixUserId]="containers"
|
||||
[mattermostToolsMenu]="scripts"
|
||||
[maybeRegenPoll]="scripts"
|
||||
[menuContinue]="scripts"
|
||||
@ -2213,6 +2239,11 @@ appLinkdingDeleteUser() { unset -f appLinkdingDeleteUser; __lpAutoload "${instal
|
||||
appLinkdingListUsers() { unset -f appLinkdingListUsers; __lpAutoload "${install_containers_dir}linkding/tools/linkding_list_users.sh"; appLinkdingListUsers "$@"; }
|
||||
appLinkdingResetPassword() { unset -f appLinkdingResetPassword; __lpAutoload "${install_containers_dir}linkding/tools/linkding_reset_password.sh"; appLinkdingResetPassword "$@"; }
|
||||
appLinkdingSetAdmin() { unset -f appLinkdingSetAdmin; __lpAutoload "${install_containers_dir}linkding/tools/linkding_set_admin.sh"; appLinkdingSetAdmin "$@"; }
|
||||
appMatrixCreateAccount() { unset -f appMatrixCreateAccount; __lpAutoload "${install_containers_dir}matrix/tools/matrix_create_account.sh"; appMatrixCreateAccount "$@"; }
|
||||
appMatrixDeactivateUser() { unset -f appMatrixDeactivateUser; __lpAutoload "${install_containers_dir}matrix/tools/matrix_deactivate_user.sh"; appMatrixDeactivateUser "$@"; }
|
||||
appMatrixListUsers() { unset -f appMatrixListUsers; __lpAutoload "${install_containers_dir}matrix/tools/matrix_list_users.sh"; appMatrixListUsers "$@"; }
|
||||
appMatrixResetPassword() { unset -f appMatrixResetPassword; __lpAutoload "${install_containers_dir}matrix/tools/matrix_reset_password.sh"; appMatrixResetPassword "$@"; }
|
||||
appMatrixSetAdmin() { unset -f appMatrixSetAdmin; __lpAutoload "${install_containers_dir}matrix/tools/matrix_set_admin.sh"; appMatrixSetAdmin "$@"; }
|
||||
appNetworkApplyMode_gluetun() { unset -f appNetworkApplyMode_gluetun; __lpAutoload "${install_containers_dir}gluetun/scripts/gluetun_network.sh"; appNetworkApplyMode_gluetun "$@"; }
|
||||
appNetworkRegisterPorts_gluetun() { unset -f appNetworkRegisterPorts_gluetun; __lpAutoload "${install_containers_dir}gluetun/scripts/gluetun_network.sh"; appNetworkRegisterPorts_gluetun "$@"; }
|
||||
appNextcloudAddTrustedDomain() { unset -f appNextcloudAddTrustedDomain; __lpAutoload "${install_containers_dir}nextcloud/tools/nextcloud_add_trusted_domain.sh"; appNextcloudAddTrustedDomain "$@"; }
|
||||
@ -2304,6 +2335,11 @@ authAdapter_linkding_deleteUser() { unset -f authAdapter_linkding_deleteUser; __
|
||||
authAdapter_linkding_listUsers() { unset -f authAdapter_linkding_listUsers; __lpAutoload "${install_containers_dir}linkding/scripts/linkding_auth.sh"; authAdapter_linkding_listUsers "$@"; }
|
||||
authAdapter_linkding_setAdmin() { unset -f authAdapter_linkding_setAdmin; __lpAutoload "${install_containers_dir}linkding/scripts/linkding_auth.sh"; authAdapter_linkding_setAdmin "$@"; }
|
||||
authAdapter_linkding_setPassword() { unset -f authAdapter_linkding_setPassword; __lpAutoload "${install_containers_dir}linkding/scripts/linkding_auth.sh"; authAdapter_linkding_setPassword "$@"; }
|
||||
authAdapter_matrix_createUser() { unset -f authAdapter_matrix_createUser; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_createUser "$@"; }
|
||||
authAdapter_matrix_deleteUser() { unset -f authAdapter_matrix_deleteUser; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_deleteUser "$@"; }
|
||||
authAdapter_matrix_listUsers() { unset -f authAdapter_matrix_listUsers; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_listUsers "$@"; }
|
||||
authAdapter_matrix_setAdmin() { unset -f authAdapter_matrix_setAdmin; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_setAdmin "$@"; }
|
||||
authAdapter_matrix_setPassword() { unset -f authAdapter_matrix_setPassword; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_setPassword "$@"; }
|
||||
authAdapter_nextcloud_createUser() { unset -f authAdapter_nextcloud_createUser; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_createUser "$@"; }
|
||||
authAdapter_nextcloud_deleteUser() { unset -f authAdapter_nextcloud_deleteUser; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_deleteUser "$@"; }
|
||||
authAdapter_nextcloud_listUsers() { unset -f authAdapter_nextcloud_listUsers; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_listUsers "$@"; }
|
||||
@ -2804,12 +2840,15 @@ manifestRemove() { unset -f manifestRemove; __lpAutoload "${install_scripts_dir}
|
||||
manifestWrite() { unset -f manifestWrite; __lpAutoload "${install_scripts_dir}backup/manifest/manifest_write.sh"; manifestWrite "$@"; }
|
||||
mastodon_install_post_setup() { unset -f mastodon_install_post_setup; __lpAutoload "${install_containers_dir}mastodon/scripts/mastodon_install_hooks.sh"; mastodon_install_post_setup "$@"; }
|
||||
mastodon_upgrade_verify() { unset -f mastodon_upgrade_verify; __lpAutoload "${install_containers_dir}mastodon/scripts/mastodon_upgrade_hooks.sh"; mastodon_upgrade_verify "$@"; }
|
||||
_matrixApi() { unset -f _matrixApi; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; _matrixApi "$@"; }
|
||||
_matrixApiFailed() { unset -f _matrixApiFailed; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; _matrixApiFailed "$@"; }
|
||||
matrix_install_post() { unset -f matrix_install_post; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; matrix_install_post "$@"; }
|
||||
matrix_install_post_compose() { unset -f matrix_install_post_compose; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; matrix_install_post_compose "$@"; }
|
||||
matrix_install_post_start() { unset -f matrix_install_post_start; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; matrix_install_post_start "$@"; }
|
||||
matrix_install_pre() { unset -f matrix_install_pre; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; matrix_install_pre "$@"; }
|
||||
_matrixPublicBaseUrl() { unset -f _matrixPublicBaseUrl; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; _matrixPublicBaseUrl "$@"; }
|
||||
_matrixServerName() { unset -f _matrixServerName; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; _matrixServerName "$@"; }
|
||||
_matrixUserId() { unset -f _matrixUserId; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; _matrixUserId "$@"; }
|
||||
mattermostToolsMenu() { unset -f mattermostToolsMenu; __lpAutoload "${install_scripts_dir}menu/tools/manage_mattermost.sh"; mattermostToolsMenu "$@"; }
|
||||
maybeRegenPoll() { unset -f maybeRegenPoll; __lpAutoload "${install_scripts_dir}task/crontab_task_processor.sh"; maybeRegenPoll "$@"; }
|
||||
menuContinue() { unset -f menuContinue; __lpAutoload "${install_scripts_dir}menu/message/continue.sh"; menuContinue "$@"; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user