1 # ===================================================================== 2 # deleteAttachment: W-TW file detachment processor. 3 # 4 # Copyright (c) 2007-2010 Carlo Strozzi 5 # 6 # This program is free software; you can redistribute it and/or modify 7 # it under the terms of the GNU General Public License as published by 8 # the Free Software Foundation; version 2 dated June, 1991. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with this program; if not, write to the Free Software 17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 # 19 # ===================================================================== 20 21 # ===================================================================== 22 # Local variables and functions 23 # ===================================================================== 24 25 cgi.group = () 26 cgi.group.literal = () 27 cgi.page = () 28 cgi.page.literal = () 29 cgi.attname = () 30 cgi.attname.literal = () 31 cgi.attname.esc = () 32 cgi.where = web # default location. 33 34 # ===================================================================== 35 # Main program 36 # ===================================================================== 37 38 # I need to accept also POST here, or delete confirmation requests will 39 # not work due to the fact that "DELETE" does not take any content, 40 # hence not even X_CSA_CONFIRMED. For that reason, the confirmation 41 # form needs to use the "?0=deleteAttachment" call format, which does 42 # not allow any ISINDEX of course. This is by no means a flaw or a 43 # limitation in the REST architecture, but rather an intrinsic non- 44 # RESTfulness of the request confirmation process, which is only 45 # meaningful for humans but not for machines. In fact, any confirmation 46 # scheme should rather be implemented on the client side, where it 47 # belongs, with Javascript, AJAX and other similar techniques, and not 48 # on the server side. Since the confirmation action is inherently 49 # non-RESTful, it needs to be handled with the canonical CSA call format 50 # "?0=[application].method" and cannot be mapped into a REST URL scheme. 51 52 csaGetArgs DELETE POST 53 54 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 55 56 . $CSA_ROOT/lib/group-stuff.rc 57 58 ~ $'cgi.page' () || . $CSA_ROOT/lib/page-stuff.rc 59 60 ~ $'cgi.attname' () && csaExit.fault 0038 61 ~ $'cgi.attname.esc' () && csaExit.fault 0041 cgi.attname.esc 62 63 # File names beginning with tw-* are reserved and must be left alone. 64 # They should not even be removed, as their creation/removal is up 65 # to "lib/tpl-stuff.rc" when a new "tb.html" is found in the group 66 # attachment directory. 67 68 ~ $'cgi.attname' tw-* && csaExit.fault --back 1007 69 70 . $CSA_ROOT/lib/group-editor.rc 71 72 ~ ,$TNS_AUTH_GRP, *,editor,* || csaExit.needauth 73 74 # Page name mandatory if private attachment. 75 76 if (~ $'cgi.where' wiki) { 77 78 ~ $'cgi.page' () && csaExit.fault 1001 79 80 tw_stem = $tw_gstem 81 82 keysearch $'cgi.page' $tw_gstem/page+dat | 83 csa-tbl2rc --prefix tbl_page. > $tmp1 84 . $tmp1 85 86 # The specified page MUST exist or it may not have attachments. 87 ~ $'tbl_page.k_page' () && csaExit.fault 1011 $'cgi.page' 88 89 # Set template vars to their final values. 90 tpl.var.tw.page = $'tbl_page.p_name' 91 tpl.var.tw.page.object = $'tpl.var.tw.page' 92 tpl.var.html.title = $'tpl.var.tw.group'/$'tpl.var.tw.page' 93 94 } else { 95 96 cgi.page = () # mandatory if public. 97 98 # If we are being requested to delete a public object the target 99 # public directory must already exist. 100 101 tw_stem = $CSA_DOCROOT/$CSA_LANG/$TNS_ATTACH_PUBDIR/$'cgi.group' 102 test -d $tw_stem || csaExit.fault 0037 1 $CSA_PGM($#CSA_PGM) 103 } 104 105 # Add more forbidden file extensions as needed. 106 ~ $'cgi.attname' *.tmp && csaExit.fault --back 1007 107 108 if (!csaIsConfirmed) { 109 if (csaIsFullPath --exists --quiet \ 110 $CSA_TPL_ROOT/tw-delete-attachment-confirm.txt) { 111 # custom confirmation template. 112 tpl.include.html.body = $CSA_TPL_ROOT/tw-delete-attachment-confirm.txt 113 } else { 114 # default confirmation template. 115 tpl.include.html.body = $tw_dstem/tw-delete-attachment-confirm.txt 116 } 117 118 . $CSA_ROOT/lib/tpl-stuff.rc 119 120 tpl.var.tw.arg3 = $'cgi.attname.literal' 121 tpl.var.tw.arg4 = $'cgi.where' 122 123 # PRG confirmation page must be regarded as a view. 124 tpl.if.tw.ispage = '(::DEL:)' 125 tpl.fi.tw.ispage = '(:DEL::)' 126 tpl.if.tw.printable = '(::DEL:)' 127 tpl.fi.tw.printable = '(:DEL::)' 128 tpl.if.tw.isview = () 129 tpl.fi.tw.isview = () 130 131 csaExit.ok $tpl_file 132 } 133 134 if (~ $'cgi.page' ()) { 135 136 # Neither TPC nor locking really needed here. 137 rm -f $tw_stem/$'cgi.attname' || csaExit.fault 0003 rm 138 139 # Take the client back to the updated group-level attachment list. 140 141 csaExit.location $CSA_RPC_URI/$CSA_LANG/$'tbl_group.g_uri'/tw-webfile 142 } 143 144 # A few more sanity checks won't hurt. 145 csaIsFullPath --exists --quiet $tw_pstem+att || 146 csaExit.fault 0037 2 $CSA_PGM($#CSA_PGM) 147 148 # Load attachment meta-data (only available if old attachment, of course). 149 keysearch wiki/$'cgi.attname' $tw_pstem+att | 150 csa-tbl2rc --prefix tbl_attach. > $tmp1 151 . $tmp1 152 153 # Prepare updated values for the page table. 154 tbl_page.k_page = $'cgi.page' 155 156 # Set Principal Lock Semaphore(s) (PLS). 157 csaLock $tw_gstem/page+dat || csaExit.fault 158 159 if (!~ $'tbl_attach.k_node' ()) { 160 * = `{csa-space $'tbl_attach.k_node'} 161 ~ $1 () && csaExit.fault 0003 csa-space 162 # Schedule the removal of the associated node file, if any. 163 csaIsFullPath --exists --quiet \ 164 $CSA_ROOT/var/nodes/$1/$2/$3/$'tbl_attach.k_node' && 165 csaTrapFile $CSA_ROOT/var/nodes/$1/$2/$3/$'tbl_attach.k_node' 166 } 167 168 # Update the page attachment meta-data table. 169 csaOpen --fast --relaxed $tw_pstem+att || csaExit.fault 170 tmp_attach = $CSA_RESULT 171 172 # If the attachment being deleted is the only record left in table 173 # then 'grep -v' will return non-zero even if the operation was in 174 # fact succesful, hence the additional call to 'istable'. 175 176 filtertable --input $tw_pstem+att -- \ 177 grep -ve '^wiki/'$'cgi.attname.esc'$tab > $tmp_attach || { 178 istable --input $tmp_attach || csaExit.fault 0003 filtertable 179 } 180 181 # Update attachment counters. 182 att_cnt = `{awktable -i $tmp_attach \ 183 '-vre_=^wiki/' -- '$k_attach ~ re_ {i_++}END{print i_/1}'} 184 185 tbl_page.p_npriv = $att_cnt 186 187 # Update the page meta-data table. 188 csaOpen --fast $tw_gstem/page+dat || csaExit.fault 189 tmp_pages = $CSA_RESULT 190 191 envtotable --match '^tbl_page__2e[a-z]' --strip-names '^tbl_page__2e' | 192 updtable --stdin --key-columns k_page $tw_gstem/page+dat | 193 sorttable > $tmp_pages 194 195 csaStatus || csaExit.fault 0003 envtotable/updtable/sorttable 196 197 if (!~ $'cgi.page' ()) { 198 # Update the page-attachments static view. Note that this view may 199 # list attachments which content is not accessible to the viewing 200 # client (based on "attachment:a_allow"), so at least the attachment 201 # URLs and descriptions will be publicly visible if the editor decides 202 # to include this view in any templates. This is in line with the 203 # current TW specs. 204 205 csaOpen --fast --relaxed $tw_pstem-att+xml || csaExit.fault 206 tmp1 = $CSA_RESULT 207 csaAwkCmd pageAttachments.awk 208 getcolumn -i $tmp_attach k_attach a_mtime a_descr | 209 $CSA_RESULT > $tmp1 210 211 csaStatus || csaExit.fault 0003 getcolumn/AWK 212 213 # Hidden pages will have this static view void. 214 ~ $'tbl_page.p_descr' -* || tpl.include.tw.page.att = $tw_pstem-att+xml 215 } 216 217 # Schedule the actual attachment file removal, whether it actually 218 # exists or not, accounting for dummy 'tw-xxx' attachments, which are 219 # not associated with actual files on disk. 220 221 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 222 223 # Take the client back to the updated page-level attachment list. 224 225 csaExit.ok --confirmed \ 226 $CSA_RPC_URI/$CSA_LANG/$'tbl_group.g_uri'/$'tbl_page.p_uri'/wikifile 227 228 #EOF