]> git.plutz.net Git - shellwiki/blob - acl.sh
Merge commit '6bc502434737d7f08379e79b94fc6fda424ef779'
[shellwiki] / acl.sh
1 #!/bin/sh
2
3 [ "$include_acl" ] && return 0
4 include_acl="$0"
5
6 # Copyright 2022 - 2023 Paul Hänsch
7
8 # Permission to use, copy, modify, and/or distribute this software for any
9 # purpose with or without fee is hereby granted, provided that the above
10 # copyright notice and this permission notice appear in all copies.
11
12 # THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
15 # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
18 # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20 # ACL_OVERRIDE="${ACL_OVERRIDE:-Admin:read,write}"
21 ACL_DEFAULT="${ACL_DEFAULT:-Known:read,write${BR}All:read}"
22
23 acl_cachepath=''
24 acl_collection=''
25
26 acl_collect(){
27   local path="$1"
28   # Get directory part of PATH_INFO
29   local path="${path%/*}/./"
30   local pagefile head acl
31
32   printf '%s\n' "$ACL_OVERRIDE"
33
34   while :; do
35     [ "$path" = / ] && break
36     path="${path%/*/}/"
37
38     # Do not use `mdfile` function here because of specialties
39     # in translation handler (`handlers/10_translations.sh`)
40     if   [ -f "$_DATA/pages/$path/#page.md" ]; then
41       pagefile="$_DATA/pages/$path/#page.md"
42     elif [ -f "$_EXEC/pages/$path/#page.md" ]; then
43       pagefile="$_EXEC/pages/$path/#page.md"
44     else
45       continue
46     fi
47
48     acl="$(sed -En '
49       s;\r$;;;
50       /^%acl([\t ]+.*)?$/bACL;
51       20q;
52       b;
53
54       :ACL
55       s;(%(acl)?)?[\t ]*;;
56       p; n; s;\r$;;;
57       /^(%[ \t]+|%acl[ \t]+|[ \t]+)[^ \t\r]+$/bACL;
58       /^(%[ \t]*|%acl[ \t]*)$/bACL;
59     ' <"$pagefile")"
60
61     printf %s\\n "${acl}"
62   done
63
64   printf '%s\n' "$ACL_DEFAULT"
65 }
66
67 acl_read(){
68   local page="${1:-${PATH_INFO}}"
69   local acl group
70
71   if [ "$acl_cachepath" != "$page" ]; then
72     acl_cachepath="$page"
73     acl_collection="$(acl_collect "$page")"
74   fi
75
76   while read -r acl; do
77     case ${acl##*:} in
78       read|*,read,*|read,*|*,read)
79          acl="${acl%%:*}:read";;
80       *) acl="${acl%%:*}:";;
81     esac
82     [ "$USER_NAME" ] && case ${acl%:*} in
83       \&*|+\&*|-\&*)
84         group="${acl%%:*}" group="${group#[+-]}"
85         printf '%s\n' "$USER_GROUPS" |grep -qxF "$group" \
86         || continue
87         ;;
88     esac
89     [ "$USER_NAME" ] && case $acl in
90        "@${USER_NAME}:"|"Known:"|"@@:"|"&"*":")
91         return 1;;
92        "@${USER_NAME}:read"|"Known:read"|"@@:read"|"&"*":read")
93         return 0;;
94       "-@{$USER_NAME}:read"|"-Known:read"|"-@@:read"|"-&"*":read")
95         return 1;;
96       "+@{$USER_NAME}:read"|"+Known:read"|"+@@:read"|"+&"*":read")
97         return 0;;
98     esac
99     case $acl in
100        "All:"|"*:")          return 1;;
101        "All:read"|"*:read")  return 0;;
102       "-All:read"|"-*:read") return 1;;
103       "+All:read"|"+*:read") return 0;;
104     esac
105    done <<-EOF
106         ${acl_collection}
107         EOF
108   return 1
109 }
110
111 acl_write(){
112   local page="${1:-${PATH_INFO}}"
113   local acl group
114
115   if [ "$acl_cachepath" != "$page" ]; then
116     acl_cachepath="$page"
117     acl_collection="$(acl_collect "$page")"
118   fi
119
120   while read -r acl; do
121     case ${acl##*:} in
122       write|*,write,*|write,*|*,write)
123          acl="${acl%%:*}:write";;
124       *) acl="${acl%%:*}:";;
125     esac
126     [ "$USER_NAME" ] && case ${acl%:*} in
127       \&*|+\&*|-\&*)
128         group="${acl%%:*}" group="${group#[+-]}"
129         printf '%s\n' "$USER_GROUPS" |grep -qxF "$group" \
130         || continue
131         ;;
132     esac
133     [ "$USER_NAME" ] && case ${acl} in
134        "@${USER_NAME}:"|"Known:"|"@@:"|"&"*":")
135         return 1;;
136        "@${USER_NAME}:write"|"Known:write"|"@@:write"|"&"*":write")
137         return 0;;
138       "-@{$USER_NAME}:write"|"-Known:write"|"-@@:write"|"-&"*":write")
139         return 1;;
140       "+@{$USER_NAME}:write"|"+Known:write"|"+@@:write"|"+&"*":write")
141         return 0;;
142     esac
143     case $acl in
144        "All:"|"*:")             return 1;;
145        "All:write"|"*:write")   return 0;;
146       "-All:write"|"-*:write")  return 1;;
147       "+All:write"|"+*:write")  return 0;;
148     esac
149   done <<-EOF
150         ${acl_collection}
151         EOF
152   return 1
153 }