Linkding has shipped without any Tools-tab actions since v0.1.0 — the only artifact was scripts/menu/tools/manage_linkding.sh, a dead legacy CLI menu referencing an `appLinkdingSetupUser` function that was never defined. Build the real thing, mirroring bookstack's pattern (manifest + thin tool wrappers + auth_adapter that drives the app's native admin shell): containers/linkding/tools/linkding.tools.json — manifest, 5 tools containers/linkding/tools/linkding_<id>.sh — one wrapper per tool containers/linkding/scripts/linkding_auth.sh — Django shell driver Tools (all category=users, so the WebUI's custom user-list panel and its row-level 🔑 / 👑 / 🗑 buttons light up): reset_password — set_password on an existing user (random if blank) create_account — create_user / create_superuser list_users — emits EZ_USER\t<username>\t<username>\t<role> rows (linkding is username-primary, so username goes into both display slots — keeps the panel click-through identifier consistent with the other tools' fields) delete_user — delete by username (destructive, confirm gated) set_admin — toggle is_superuser + is_staff Implementation runs entirely inside the linkding-service container via `runFileOp docker exec ... python manage.py shell -c "<code>"`, reading inputs through `-e` env vars so quoting stays safe. Django's default get_user_model() User is used directly — passwords hash exactly the way the web UI does, admin flags map to the same fields the UI reads. Also drop the dead legacy stub (scripts/menu/tools/manage_linkding.sh) and regenerate files_menu.sh so the source-scan no longer pulls it in. Nothing referenced linkdingToolsMenu — verified by tree-wide grep. Verified live on dev-ai (Debian 12, linkding installed, Django 5 + sqlite): $ libreportal app tool linkding create_account 'username=alice|password=…|admin=true' ✓ Linkding user created — Username: alice — Password: … $ libreportal app tool linkding list_users '' EZ_USER alice alice admin Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
107 lines
2.9 KiB
JSON
107 lines
2.9 KiB
JSON
{
|
|
"tools": [
|
|
{
|
|
"id": "reset_password",
|
|
"category": "users",
|
|
"label": "Reset User Password",
|
|
"description": "Reset an existing Linkding user's password. Leave the password field blank to generate a random one — it is shown in the task log.",
|
|
"icon": "🔑",
|
|
"fields": [
|
|
{
|
|
"name": "username",
|
|
"label": "Username",
|
|
"type": "text",
|
|
"placeholder": "alice",
|
|
"required": true
|
|
},
|
|
{
|
|
"name": "password",
|
|
"label": "New password (leave blank to generate)",
|
|
"type": "password",
|
|
"placeholder": "Leave blank for random"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "create_account",
|
|
"category": "users",
|
|
"label": "Create User Account",
|
|
"description": "Create a new Linkding user. Tick \"Make admin\" to grant full admin (Django superuser) rights. Leave the password blank to generate a random one.",
|
|
"icon": "👤",
|
|
"fields": [
|
|
{
|
|
"name": "username",
|
|
"label": "Username",
|
|
"type": "text",
|
|
"placeholder": "alice",
|
|
"required": true
|
|
},
|
|
{
|
|
"name": "email",
|
|
"label": "Email (optional)",
|
|
"type": "text",
|
|
"placeholder": "alice@example.com"
|
|
},
|
|
{
|
|
"name": "password",
|
|
"label": "Password (leave blank to generate)",
|
|
"type": "password",
|
|
"placeholder": "Leave blank for random"
|
|
},
|
|
{
|
|
"name": "admin",
|
|
"label": "Make admin",
|
|
"type": "checkbox",
|
|
"default": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "list_users",
|
|
"category": "users",
|
|
"label": "List Users",
|
|
"description": "Show every Linkding user with their admin status.",
|
|
"icon": "📋",
|
|
"fields": []
|
|
},
|
|
{
|
|
"id": "delete_user",
|
|
"category": "users",
|
|
"label": "Delete User Account",
|
|
"description": "Permanently delete a Linkding user account and all of their bookmarks.",
|
|
"icon": "🗑",
|
|
"destructive": true,
|
|
"confirm": "This cannot be undone — the user and all of their bookmarks will be removed.",
|
|
"fields": [
|
|
{
|
|
"name": "username",
|
|
"label": "Username",
|
|
"type": "text",
|
|
"required": true
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "set_admin",
|
|
"category": "users",
|
|
"label": "Set Admin Status",
|
|
"description": "Promote a user to admin (Django is_superuser + is_staff) or demote them to a normal user.",
|
|
"icon": "👑",
|
|
"fields": [
|
|
{
|
|
"name": "username",
|
|
"label": "Username",
|
|
"type": "text",
|
|
"required": true
|
|
},
|
|
{
|
|
"name": "admin",
|
|
"label": "Make admin",
|
|
"type": "checkbox",
|
|
"default": false
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|