]> git.plutz.net Git - shellwiki/commitdiff
basic locking and editing
authorPaul Hänsch <paul@plutz.net>
Tue, 15 Mar 2022 14:52:00 +0000 (15:52 +0100)
committerPaul Hänsch <paul@plutz.net>
Tue, 15 Mar 2022 14:52:00 +0000 (15:52 +0100)
index.cgi
page_edit.sh [new file with mode: 0755]
session_lock.sh [new file with mode: 0755]
themes/default.sh

index 76f1bef6a0062b6e71e6191a3feeb74bd990a7c2..2d4954f0c4cc55a1b3778fbebac4f00579afd965 100755 (executable)
--- a/index.cgi
+++ b/index.cgi
@@ -79,6 +79,8 @@ attachment() {
   fi
 }
 
+. "$_EXEC/page_edit.sh"
+
 case "${PATH_INFO}" in
   /"[.]"/*)
     FILE "${_EXEC}/${PATH_INFO#/\[.\]}"
@@ -91,9 +93,6 @@ case "${PATH_INFO}" in
       theme_404
     fi
     ;;
-  */"[edit]")
-    theme_editor "${PATH_INFO%\[edit\]}"
-    ;;
   */"[login]")
     [ "$USER_NAME" ] \
     && REDIRECT "./" \
diff --git a/page_edit.sh b/page_edit.sh
new file mode 100755 (executable)
index 0000000..9bb9f5f
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+. "${_EXEC}/themes/default.sh"
+. "${_EXEC}/session_lock.sh"
+
+wiki_text() {
+  # Print source text of a wiki page
+  # Get page from data or underlay dir
+  local page="$(PATH "$1")"
+
+  if [ -f "$_DATA/pages/$page/#page.md" ]; then
+    cat -- "$_DATA/pages/$page/#page.md"
+  elif [ -f "$_EXEC/pages/$page/#page.md" ]; then
+    cat -- "$_EXEC/pages/$page/#page.md"
+  else
+    return 1
+  fi
+}
+
+edit_page="${PATH_INFO%\[edit\]}"
+edit_file="$_DATA/pages/$edit_page/#page.md"
+[ "$REQUEST_METHOD" = POST ] && edit_action="$(POST action)"
+
+debug "RM: $REQUEST_METHOD ea: $edit_action"
+
+if [ "$edit_page" = "$PATH_INFO" ]; then
+  unset edit_page edit_action edit_file
+  # END EDIT SCRIPT, continue in index.cgi
+
+elif [ "$edit_action" = update ]; then
+  mkdir -p -- "${edit_file%/#page.md}"
+
+  if S_LOCK "$edit_file"; then
+    POST pagetext >"$edit_file"
+    S_RELEASE "$edit_file"
+    REDIRECT "${_BASE}${PATH_INFO%\[edit\]}" |debug
+  else
+    export ERRMSG="ERR_NOLOCK"
+    REDIRECT "${_BASE}${PATH_INFO%\[edit\]}/[edit]" |debug
+  fi
+
+elif [ "$edit_action" = cancel ]; then
+  S_RELEASE "$edit_file"
+  REDIRECT "${_BASE}${PATH_INFO%\[edit\]}" |debug
+
+elif mkdir -p -- "${edit_file%/#page.md}" && S_LOCK "$edit_file"; then
+  # Display editor page
+  SESSION_COOKIE
+  theme_editor "$edit_page"
+
+else
+  export ERRMSG="ERR_NOLOCK"
+  theme_page "$edit_page"
+
+fi
diff --git a/session_lock.sh b/session_lock.sh
new file mode 100755 (executable)
index 0000000..f55c9cd
--- /dev/null
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+. "$_EXEC/cgilite/storage.sh"
+. "$_EXEC/cgilite/session.sh"
+
+LOCK_TIMEOUT="${LOCK_TIMEOUT:-1200}"
+
+S_LOCK(){
+  local file="$1" timeout="${2:-$LOCK_TIMEOUT}"
+  local date sid
+
+  printf "%i %s\n" "$_DATE" "$SESSION_ID" >>"${file}.lock"
+
+  if ! read date sid <"${file}.lock"; then
+    debug "Unable to access lock: ${file}.lock"
+
+  elif [ $((date + timeout)) -lt $_DATE ]; then
+    # Override stale lock
+    if LOCK "${file}.lock" 1; then
+      debug "Overriding stale lock: ${file}.lock"
+      printf "%i %s\n" "$_DATE" "$SESSION_ID" >"${file}.lock"
+      RELEASE "${file}.lock"
+      return 0
+    else
+      return 1
+    fi
+
+  elif [ "$sid" = "$SESSION_ID" -a "$date" -ne "$_DATE" ]; then
+    # Refresh aged lock
+    printf "%i %s\n" "$_DATE" "$SESSION_ID" >"${file}.lock"
+    return 0
+
+  elif [ "$sid" = "$SESSION_ID" ]; then
+    # Simple success
+    return 0
+
+  else
+    return 1
+  fi
+}
+
+S_RELEASE(){
+  local file="$1" timeout="${2:-$LOCK_TIMEOUT}"
+  local date sid
+
+  if ! read date sid <"${file}.lock"; then
+    # File was not locked
+    return 0
+
+  elif [ "$sid" = "$SESSION_ID" -a  $((date + timeout)) -lt $_DATE ]; then
+    # if lock is stale, protect against stale override before release
+    if LOCK "${file}.lock" 1; then
+      rm -- "${file}.lock"
+      RELEASE "${file}.lock"
+      return 0
+    else
+      return 1
+    fi
+
+  elif [ "$sid" = "$SESSION_ID" ]; then
+    # Simple success
+    rm -- "${file}.lock"
+    return 0
+
+  else
+    return 1
+  fi
+}
index 56b57aed24eb505669d742cca13fde2f9660ae3f..c096f8218a03639d6b24352c4ed4228df515993d 100755 (executable)
@@ -39,7 +39,7 @@ theme_editor(){
   local page="$1" title
   title="${page%/}"; title="${title##*/}"
 
-  # Important! Web Server response including newline newline
+  # Important! Web Server response including newline
   printf "%s\r\n" "Content-Type: text/html; charset=utf-8" ""
 
   cat <<-EOF
@@ -50,9 +50,10 @@ theme_editor(){
        </head><body id="$(HTML "$page")" class="editor">
          $(theme_header)
          <main><form method=POST>
-            <textarea name=page>$(wiki_text "$page" |HTML)</textarea>
-            <button type=submit name=update value="$(HTML "$page")">Update</button>
-            <button type=submit name=cancel value="$(HTML "$page")">Cancel</button>
+           <input type=hidden name=session_key value="${SESSION_KEY}"/>
+            <textarea name=pagetext>$(wiki_text "$page" |HTML)</textarea>
+            <button type=submit name=action value=update>Update</button>
+            <button type=submit name=action value=cancel>Cancel</button>
           </form></main>
          $(theme_footer)
        </body></html>