]> git.plutz.net Git - shellwiki/blobdiff - acl.sh
basic ACLs
[shellwiki] / acl.sh
diff --git a/acl.sh b/acl.sh
new file mode 100755 (executable)
index 0000000..9ec2597
--- /dev/null
+++ b/acl.sh
@@ -0,0 +1,114 @@
+#!/bin/sh
+
+# ACL_OVERRIDE="${ACL_OVERRIDE:-Admin:read,write}"
+ACL_DEFAULT="${ACL_DEFAULT:-All:read${BR}Known:read,write}"
+
+acl_cachepath=''
+acl_collection=''
+
+acl_collect(){
+  local path="${1:-${PATH_INFO}}"
+  # Get directory part of PATH_INFO
+  local path="${path%/*}/./"
+  local pagefile head acl
+
+  if [ "$acl_cachepath" = "$path" ]; then
+    printf '%s\n' "$ACL_OVERRIDE" "$acl_collection" "$ACL_DEFAULT"
+    return 0
+  else
+    acl_cachepath="$path"
+    acl_collection=''
+  fi
+
+  printf '%s\n' "$ACL_OVERRIDE"
+
+  while :; do
+    [ "$path" = / ] && break
+    path="${path%/*/}/"
+
+    if   [ -f "$_DATA/pages/$path/#page.md" ]; then
+      pagefile="$_DATA/pages/$path/#page.md"
+    elif [ -f "$_EXEC/pages/$path/#page.md" ]; then
+      pagefile="$_EXEC/pages/$path/#page.md"
+    else
+      continue
+    fi
+
+    n=20; while read -r head acl; do
+      if [ "$head" = "%acl" ]; then
+        acl_collection="${acl%${CR}}${BR}"
+        printf "%s\n" "${acl%${CR}}"
+        n=$((n+1))
+      fi
+
+      n="$((n - 1))"
+      [ "$n" -eq 0 ] && break
+    done <"$pagefile"
+  done
+
+  printf '%s\n' "$ACL_DEFAULT"
+}
+
+acl_read(){
+  local page="${1:-${PATH_INFO}}"
+  local acl
+
+  while read -r acl; do
+    case ${acl##*:} in
+      read|*,read,*|read,*|*,read)
+         acl="${acl%%:*}:read";;
+      *) acl="${acl%%:*}:";;
+    esac
+    [ "$USER_NAME" ] && case $acl in
+       "Known:read") return 0;;
+       "Known:")     return 1;;
+      "+Known:read") return 0;;
+      "-Known:read") return 1;;
+       "${USER_NAME}:read") return 0;;
+       "${USER_NAME}:")      return 1;;
+      "+{$USER_NAME}:read") return 0;;
+      "-{$USER_NAME}:read") return 1;;
+    esac
+    case $acl in
+       "All:read") return 0;;
+       "All:")     return 1;;
+      "+All:read") return 0;;
+      "-All:read") return 1;;
+    esac
+  done <<-EOF
+       $(acl_collect "$page")
+       EOF
+  return 1
+}
+
+acl_write(){
+  local page="${1:-${PATH_INFO}}"
+  local acl
+
+  while read -r acl; do
+    case ${acl##*:} in
+      write|*,write,*|write,*|*,write)
+         acl="${acl%%:*}:write";;
+      *) acl="${acl%%:*}:";;
+    esac
+    [ "$USER_NAME" ] && case ${acl} in
+       "Known:write") return 0;;
+       "Known:")      return 1;;
+      "+Known:write") return 0;;
+      "-Known:write") return 1;;
+       "${USER_NAME}:write") return 0;;
+       "${USER_NAME}:")      return 1;;
+      "+{$USER_NAME}:write") return 0;;
+      "-{$USER_NAME}:write") return 1;;
+    esac
+    case $acl in
+       "All:write") return 0;;
+       "All:")      return 1;;
+      "+All:write") return 0;;
+      "-All:write") return 1;;
+    esac
+  done <<-EOF
+       $(acl_collect "$page")
+       EOF
+  return 1
+}