#!/bin/bash # install.sh -- the .org XWiki's three pages (Captain Bob, 2026-11-07): a landing page anyone can # read, an admin dashboard for the administrator alone, and a contributors' dashboard for the # group XWiki.StarshipContributors (and the administrator). Through XWiki's REST API: # # Main.WebHome Main.WebHome.xwiki rights untouched: the wiki's own (guests view) # Admin.WebHome Admin.WebHome.xwiki Admin.WebPreferences: view, edit, comment, # delete -- $ADMIN_USER alone # Contributors.WebHome Contributors.WebHome.xwiki Contributors.WebPreferences: view, comment -- # XWiki.StarshipContributors and $ADMIN_USER; # edit, delete -- $ADMIN_USER # XWiki.StarshipContributors the group, created empty; members are added in the wiki's # administration (Users and Groups) # # An allow on a space denies that right there to everyone not named -- guests included. # # XWIKI_USER=rajames XWIKI_PASSWORD=... site/org/install.sh [https://starshipos-f18.org] # # Run it again after editing a page: pages are replaced, rights and the group are added once. # It ends by checking, without logging in, that the landing page is readable and the dashboards # are not. set -euo pipefail cd "$(dirname "$0")" base=${1:-https://starshipos-f18.org} rest="$base/rest/wikis/xwiki" user=${XWIKI_USER:?set XWIKI_USER} pass=${XWIKI_PASSWORD:?set XWIKI_PASSWORD} admin=${ADMIN_USER:-XWiki.$user} group=XWiki.StarshipContributors auth=(-u "$user:$pass") page() { # page [file]: create or replace local body body=$(python3 -c ' import sys from xml.sax.saxutils import escape title, path = sys.argv[1], sys.argv[2] content = open(path).read() if path else "" print("<page xmlns=\"http://www.xwiki.org\"><title>%sxwiki/2.1" "%s" % (escape(title), escape(content)))' "$3" "${4:-}") curl -fsS -o /dev/null -w " page $1.$2: %{http_code}\n" "${auth[@]}" -X PUT \ -H 'Content-Type: application/xml' --data-binary "$body" "$rest/spaces/$1/pages/$2" } objects() { # objects : how many the page has curl -fsS "${auth[@]}" -H 'Accept: application/json' "$rest/spaces/$1/pages/$2/objects/$3" | python3 -c 'import json,sys; print(len(json.load(sys.stdin).get("objectSummaries") or []))' } object() { # object ...: add one # as XML: XWiki refuses a form-encoded POST without its form token (CSRF), not an XML one local s=$1 p=$2 c=$3; shift 3 local body body=$(python3 -c ' import sys from xml.sax.saxutils import escape props = "".join("%s" % (escape(k), escape(v)) for k, v in (a.split("=", 1) for a in sys.argv[2:])) print("%s%s" % (escape(sys.argv[1]), props))' "$c" "$@") curl -fsS -o /dev/null -w " $s.$p: $c added (%{http_code})\n" "${auth[@]}" -X POST \ -H 'Content-Type: application/xml' --data-binary "$body" "$rest/spaces/$s/pages/$p/objects" } echo "=== $base, as $user" echo "=== the group $group" page XWiki StarshipContributors "Starship Contributors" if [ "$(objects XWiki StarshipContributors XWiki.XWikiGroups)" = 0 ]; then object XWiki StarshipContributors XWiki.XWikiGroups "member=" else echo " already a group" fi echo "=== rights" page Admin WebPreferences "Admin rights" if [ "$(objects Admin WebPreferences XWiki.XWikiGlobalRights)" = 0 ]; then object Admin WebPreferences XWiki.XWikiGlobalRights \ "levels=view,edit,comment,delete" "users=$admin" "groups=" "allow=1" else echo " Admin: rights there already, left as they are" fi page Contributors WebPreferences "Contributors rights" if [ "$(objects Contributors WebPreferences XWiki.XWikiGlobalRights)" = 0 ]; then object Contributors WebPreferences XWiki.XWikiGlobalRights \ "levels=view,comment" "users=$admin" "groups=$group" "allow=1" object Contributors WebPreferences XWiki.XWikiGlobalRights \ "levels=edit,delete" "users=$admin" "groups=" "allow=1" else echo " Contributors: rights there already, left as they are" fi echo "=== the pages -- after their spaces' rights, so a dashboard is never readable without them" page Main WebHome "StarshipOS" Main.WebHome.xwiki page Admin WebHome "Admin Dashboard" Admin.WebHome.xwiki page Contributors WebHome "Contributors' Dashboard" Contributors.WebHome.xwiki echo "=== as a guest" bad= for p in Main Admin Contributors; do code=$(curl -s -o /dev/null -w '%{http_code}' -H 'Accept: application/json' "$rest/spaces/$p/pages/WebHome") case "$p:$code" in Main:200|Admin:401|Admin:403|Contributors:401|Contributors:403) echo " $p.WebHome: $code -- as it should be";; *) echo " $p.WebHome: $code -- NOT as it should be"; bad=1;; esac done [ -z "$bad" ] || { echo "install: a guest's view is wrong; see above" >&2; exit 1; } echo "=== done: $base/bin/view/Main/"