]> git.plutz.net Git - shellwiki/blob - handlers/20_edit_attachment.sh
Separate file for attachment edit functions. Functions to move attached files.
[shellwiki] / handlers / 20_edit_attachment.sh
1 #!/bin/sh
2
3 REV_ATTACHMENTS="${REV_ATTACHMENTS:-false}"
4
5 if [ "${PATH_INFO##*/\[attachment\]}" ]; then
6   # Skip any action not happening on attachment page
7   return 1
8 fi
9
10 page="${PATH_INFO%\[attachment\]}"
11 action="$(POST action)"
12
13 tsid="$(POST session_key)"; tsid="${tsid%% *}"
14
15
16 if ! acl_write "${PATH_INFO%\[attachment\]}"; then
17   # Deny access to write protected pages
18   printf 'Refresh: %i\r\n' 4
19   theme_error 403
20   [ "${CONTENT_TYPE%%;*}" = "multipart/form-data" ] \
21   && head -c $((CONTENT_LENGTH)) >/dev/null
22   return 0
23
24 elif [ "${CONTENT_TYPE%%;*}" = "multipart/form-data" ]; then
25   . "$_EXEC/multipart.sh"
26   multipart_cache
27
28   # Use positional parameters for filename collection
29   # The positional array is the only array available
30   # in plain posix shells, see the documentation for
31   # your shells "set" builtin for a hint to this
32   # obscure use mode
33   set --
34
35   # Validate session id from form to prevent CSRF
36   # Only validate if username is present, because no username means
37   # anonymous uploads are allowed via acl and cgilite/session.sh does not
38   # validate anonymous sessions from a multipart/formdata
39   if [ "$USER_NAME" -a "$(multipart session_id)" != "$SESSION_ID" ]; then
40     rm -- "$multipart_cachefile"
41     printf 'Refresh: %i\r\n' 4
42     theme_error 403
43     return 0
44   fi
45
46   mkdir -p "$_DATA/pages${page}#attachments/"
47   n=1; while filename=$(multipart_filename "file" "$n"); do
48     filename="$(printf %s "$filename" |tr /\\0 __)"
49     set -- "$@" "pages${page}#attachments/$filename"
50     multipart "file" "$n" >"$_DATA/pages${page}#attachments/$filename"
51     n=$((n + 1))
52   done
53   rm -- "$multipart_cachefile"
54   if [ "$REV_ATTACHMENTS" = true ]; then
55     git -C "$_DATA" add -- "$@"
56     git -C "$_DATA" commit -qm "Attachments to # $page # uploaded by @ $USER_NAME @" -- "$@"
57   fi
58   REDIRECT "${_BASE}${PATH_INFO}"
59
60 elif [ "$SESSION_ID" != "$tsid" ]; then
61   # Match session key from POST-Data to prevent CSRF:
62   # For authenticated users the POST session_key must match
63   # the session key used for authentication (usually from a
64   # cookie). This should ensure that POST requests were not
65   # triggered by malicious 3rd party sites freeriding on an
66   # existing user authentication.
67   # For pages that are writable by anonymous users, this is
68   # not reliable.
69
70   printf 'Refresh: %i\r\n' 4
71   theme_error 403
72   return 0
73 fi
74
75 if [ "$action" = delete -o "$action" = move ]; then
76   set --
77   n="$(POST_COUNT select)"; while [ $n -gt 0 ]; do
78     select="$(POST select $n |PATH)"
79     set -- "$@" "pages${page}#attachments/${select##*/}"
80     n=$((n - 1))
81   done
82 fi
83
84 if [ "$action" = delete ]; then
85   if [ "$REV_ATTACHMENTS" = true ]; then
86     git -C "$_DATA" rm -- "$@"
87     git -C "$_DATA" commit -qm \
88         "Attachment to # $page # deleted by @ $USER_NAME @" -- "$@"
89   else
90     ( cd "$_DATA" && rm -- "$@"; )
91   fi
92   REDIRECT "${_BASE}${PATH_INFO}"
93
94 elif [ "$action" = move ]; then
95   moveto="$(POST moveto |PATH)"
96
97   if ! acl_write "$moveto"; then
98     printf 'Refresh: %i\r\n' 4
99     theme_error 403
100     return 0
101
102   elif [ ! -d "${_DATA}/pages${moveto}" ]; then
103     printf 'Refresh: %i\r\n' 4
104     theme_error 404
105     return 0
106
107   elif [ "$REV_ATTACHMENTS" = true ]; then
108     mkdir -p -- "${_DATA}/pages${moveto}/#attachments"
109     git -C "$_DATA" mv -f -- "$@" "pages${moveto}/#attachments/"
110
111     cnt=$#; while [ $cnt -gt 0 ]; do
112       set -- "$@" "$1" "pages/${moveto}/#attachments/${1##*/}"
113       cnt=$((cnt - 1)); shift 1
114     done
115
116     git -C "$_DATA" commit -qm \
117         "Attachment moved from # $page # to # $moveto # by @ $USER_NAME @" -- "$@"
118   else
119     mkdir -p -- "${_DATA}/pages${moveto}/#attachments"
120     ( cd "$_DATA" && mv -- "$@" "pages${moveto}/#attachments/"; )
121   fi
122   REDIRECT "${_BASE}${PATH_INFO}"
123
124 fi
125
126 return 1