1 # ===================================================================== 2 # confirmSubscription: process a self-registration confirmation. 3 # 4 # Copyright (c) 2008,2009,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 28 cgi.reg.userid = () 29 cgi.reg.guid = () 30 cgi.reg.captcha = () 31 cgi.grep.user = () 32 33 captcha_code = () 34 35 tmp1 = /dev/null 36 user_tmp = () 37 openid_tmp = () 38 grep_openid = () 39 group_editor = () 40 41 c_k_group = () 42 c_g_editor = () 43 44 # ===================================================================== 45 # Main program 46 # ===================================================================== 47 48 # Load call arguments. 49 csaGetArgs GET POST 50 51 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 52 53 #~ $REMOTE_ADDR 192.168.1.2 || csaExit.fault 0036 54 55 . $CSA_ROOT/lib/group-stuff.rc 56 57 . $CSA_ROOT/lib/tpl-stuff.rc 58 59 # Prepare the error message "back" button. 60 61 #if (csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-nav-back.txt) { 62 # # custom "back" action template. 63 # tpl.include.nav.next = $CSA_TPL_ROOT/tw-nav-back.txt 64 #} else { 65 # # default "back" action template. 66 # tpl.include.nav.next = $tw_dstem/tw-nav-back.txt 67 #} 68 69 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 70 71 # New registration not allowed if already logged-in 72 # (we should not have landed here in the first place). 73 74 csaTrue $CSA_AUTH_OK && csaExit.fault 403 1028 75 76 # Grant further privileges if appropriate. 77 . $CSA_ROOT/lib/group-editor.rc 78 79 # Is self-registration enabled ? 80 # Again, we should not have got this far in the first place. 81 82 ~ $TNS_SELFREG_AUTH *[a-z]* || csaExit.fault 403 0022 83 84 # If no custom email template exists then use default. 85 if (!csaIsFullPath --exists --quiet \ 86 $CSA_TPL_ROOT/tw-reg-notify-email.txt) { 87 tpl_email = (--file-root $tw_dstem tw-reg-notify-email.txt) 88 } else tpl_email = tw-reg-notify-email.txt 89 90 csaLoadLib csaEmaillib.rc || csaExit.fault 91 tpl.var.tw.reg.userid = $'cgi.reg.userid' 92 93 # Set group template vars as appropriate. 94 tpl.var.tw.group = $'tbl_group.g_name' 95 96 if (~ $'cgi.reg.userid' () || ~ $'cgi.reg.guid' ()) { 97 csaExit.fault 0066 98 } 99 100 # Perform a couple of consistency checks on the supplied arguments. 101 102 csaIsFullPath --exists --quiet $TMPDIR/$'cgi.reg.guid'-reg || 103 csaExit.fault 0066 104 105 # Make sure the atime of this file is updated *before* the one of the 106 # associated main file, to avoid races on the part of cleanup scripts. 107 # Since this file is likely not to have been created, I touch it first 108 # to save space in stderr.log . 109 110 touch $TMPDIR/$'cgi.reg.guid'-editor-reg || csaExit.fault 0003 touch 111 group_editor = `{cat $TMPDIR/$'cgi.reg.guid'-editor-reg} 112 113 # Next grep(1) will also update the GUID file access status and prevent 114 # it from being removed by the housekeeping programs before it is merged 115 # into the user table further down. 116 117 grep -qe '^'$'cgi.grep.user'$tab $TMPDIR/$'cgi.reg.guid'-reg || 118 csaExit.fault 0066 119 120 if (~ $REQUEST_METHOD GET) { 121 122 csaMkTemp tpl.include.tw.page.captcha 123 captcha_code = `{pwgen -1 -A -B 6} 124 ~ $bqstatus 0 || csaExit.fault 0003 pwgen 125 csaSession.set $captcha_code 10 126 echo $captcha_code | figlet -w 80 -k > $'tpl.include.tw.page.captcha' 127 128 # This can be useful to avoid requesting the captcha code if desired, 129 # by turning the relevant form field from type=text to type=hidden 130 # value=$[tpl.var.tw.captcha:x] 131 132 tpl.var.tw.captcha = $captcha_code 133 134 csaSetClear tpl.var.tw.captcha captcha_code 135 csaSetClear tpl.var.tw.reg.userid cgi.reg.userid 136 csaSetClear tpl.var.tw.reg.guid cgi.reg.guid 137 138 if (csaIsFullPath --exists --quiet \ 139 $CSA_TPL_ROOT/tw-reg-final.txt) { 140 # custom registration finalization template. 141 tpl.include.html.body = $CSA_TPL_ROOT/tw-reg-final.txt 142 } else { 143 # default registration finalization template. 144 tpl.include.html.body = $tw_dstem/tw-reg-final.txt 145 } 146 147 csaExit.ok $tpl_file 148 } 149 150 if (~ $'cgi.reg.captcha' () || !~ $'cgi.reg.captcha' $CSA_SESSION(10)) { 151 csaExit.fault 401 1018 152 } 153 154 # Set Principal Lock Semaphore (PLS). 155 csaLock $TNS_USER_TABLE || csaExit.fault 156 157 # In case an equally named user was created in the user table in the 158 # meantime. This should not occur, but better to be safe than sorry. 159 160 grep -qe '^'$'cgi.grep.user'$tab $TNS_USER_TABLE && csaExit.fault 0066 161 162 csaOpen --fast $TNS_USER_TABLE || csaExit.fault 163 user_tmp = $CSA_RESULT 164 165 makeNode auth $'cgi.reg.userid' # create new DB node 166 167 awktable -H -i $TMPDIR/$'cgi.reg.guid'-reg -- '{ 168 $k_node = "'$node_num'" 169 sub(/^,+/,"",$u_group) 170 sub(/,+$/,"",$u_group) 171 print 172 }' | updtable --key-columns k_user $TNS_USER_TABLE | 173 sorttable > $user_tmp 174 csaStatus || csaExit.fault 0003 awktable/updtable/sorttable 175 176 #csaMkTemp debug; viewtable < $user_tmp > $debug; csaExit.pcdata $debug 177 178 # Update also the OpenID table if necessary. If an OpenID URL is found 179 # in the associated temporary registration file it will take over any 180 # value possibly stored in the current session. If a value is found then 181 # I retain only its first $ifs-separated component, just in case. Again, 182 # cat(1) will also update the GUID file access status and prevent it 183 # from being removed by the housekeeping programs before it is no longer 184 # needed. 185 186 if (csaIsFullPath --exists --quiet $TMPDIR/$'cgi.reg.guid'-openid-reg) { 187 * = `{cat $TMPDIR/$'cgi.reg.guid'-openid-reg} 188 if (~ $1 http://* https://*) { 189 190 # escape grep(1) special characters in pattern. 191 grep_openid = `{echo $1 | sed 's[][\\^$.*|()]/\\&/g'} 192 grep -qe '^'$grep_openid$tab CSA_ROOT/var/pages/openid+dat && 193 csaExit.fault 1047 194 195 csaSession.set $1 15 immediate 196 } 197 } 198 199 if (~ $CSA_SESSION(15) http://* https://*) { 200 201 # Create the OpenID table if it does not yet exist. 202 if (!csaIsFullPath --exists --quiet $CSA_ROOT/var/pages/openid+dat) { 203 maketable --input \ 204 $CSA_ROOT/lib/openid.xrf > $CSA_ROOT/var/pages/openid+dat || 205 csaExit.fault 0003 maketable 206 } 207 208 csaOpen --fast --relaxed $CSA_ROOT/var/pages/openid+dat || csaExit.fault 209 openid_tmp = $CSA_RESULT 210 211 # Note: no two users are allowed to have the same OpenID URL. 212 # This should really not occur (as otherwise openidSetup would have 213 # complained in the first place), but if for some strange reasons it 214 # did occur, then I retain only the older entry, on a first come - 215 # first serve basis. 216 217 awktable '-vid_='$CSA_SESSION(15) -H -i \ 218 $CSA_ROOT/var/pages/openid+dat -- ' 219 $openid_url == id_ {dup_ = $openid_url}{print} 220 END {if (dup_=="") print id_, "'$'cgi.reg.userid'"'}' | 221 sorttable > $openid_tmp 222 223 csaStatus || csaExit.fault 0003 awktable/sorttable 224 } 225 226 #csaMkTemp debug; viewtable < $openid_tmp > $debug; csaExit.pcdata $debug 227 228 # Add user to the list of group editors of this group if appropriate. 229 if (!~ $group_editor ()) { 230 231 # This should not occur, but better to double-check. 232 ~ $group_editor $'cgi.group' || csaExit.fault 0066 233 234 # Set Principal Lock Semaphore (PLS). 235 csaLock $CSA_ROOT/var/pages/$CSA_LANG/group+dat || csaExit.fault 236 237 # Since we have set the PLS only at this stage, we need to ensure 238 # that the target group is still there, or races may occur. There is 239 # still a slight possibility that the group record was changed in the 240 # meantime, so that our tbl_group.xxx values are outdated, except for 241 # k_group. To keep on the safe side, I'll therefore ensure that the 242 # group is still there, and I fetch again *only* k_group and g_editor 243 # now that we are under PLS. 244 245 csa-tbl2rc --input $CSA_ROOT/var/pages/$CSA_LANG/group+dat \ 246 --key $'cgi.group' > $tmp1 || csaExit.fault 0003 csa-tbl2rc 247 248 . $tmp1 249 250 # The group must still exist. 251 ~ $c_k_group () && csaExit.fault 0050 $'cgi.group' 252 253 # Really belt an braces here :-) But a DB inconsistency 254 # may always occur, so better put mouse traps everywhere. 255 256 ~ ,$c_g_editor, *,$'cgi.reg.userid',* && 257 csaExit.fault 0037 1 $CSA_PGM($#CSA_PGM) 258 259 # Append this user to group editors. 260 c_g_editor = $c_g_editor,$'cgi.reg.userid' 261 262 csaOpen --fast --relaxed \ 263 $CSA_ROOT/var/pages/$CSA_LANG/group+dat || csaExit.fault 264 265 { 266 printf \001k_group\t\001g_editor\n 267 echo $'cgi.group'$tab$c_g_editor 268 } | updtable --stdin $CSA_ROOT/var/pages/$CSA_LANG/group+dat | 269 sorttable k_group > $CSA_RESULT 270 271 csaStatus || csaExit.fault 0003 updtable/sorttable 272 } 273 274 # Force authentication data for the newly registered user. 275 CSA_AUTH_USER = $'cgi.reg.userid' 276 CSA_AUTH_PW = `{getcolumn --no-header \ 277 --input $TMPDIR/$'cgi.reg.guid'-reg u_passwd} 278 279 ~ $bqstatus 0 || csaExit.fault 0003 getcolumn 280 281 # I still need to call 'authCheck' to set a number of important session 282 # fields, but it must be tricked into using the updated user table, which 283 # has not been committed yet. 284 285 TNS_USER_TABLE = $user_tmp 286 287 if (~ $CSA_SESSION(15) http://* https://*) { 288 authCheck --open-id --return || csaExit.fault 0066 289 } else { 290 authCheck --return || csaExit.fault 0066 291 } 292 293 # Set new auth, after passing the authorization check. 294 HTTP_AUTHORIZATION='Basic '^`{ 295 echo -n $CSA_AUTH_USER:$CSA_AUTH_PW | swu-encdec -e -b 296 } 297 298 csaPrintMsg 0014 # Log the event. 299 300 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 301 302 csaCommit || csaExit.fault 303 304 csaTrapFile $TMPDIR/$'cgi.reg.guid'-reg # housekeeping. 305 csaIsFullPath --exists --quiet $TMPDIR/$'cgi.reg.guid'-openid-reg && 306 csaTrapFile $TMPDIR/$'cgi.reg.guid'-openid-reg 307 308 # Set also the user's editing GUI, if available. 309 u_gui = `{getcolumn --no-header \ 310 --input $TMPDIR/$'cgi.reg.guid'-reg u_gui} 311 312 ~ $u_gui () && u_gui = - 313 314 csaSession.set $u_gui 11 315 316 TNS_EMAIL_TO = $TNS_EMAIL_FROM { csaSendMail $tpl_email } 317 318 # Take the user to either the welcome URL if defined, to the last 319 # failed authentication if applicable, or to the default page for 320 # this group if all else does not apply. 321 322 ~ $TNS_SELFREG_WELCOME http://* https://* /* && 323 csaExit.location $TNS_SELFREG_WELCOME 324 325 if (~ $CSA_SESSION(18) http* /*) { 326 csaSession.set - 18 327 if (csaIsInteractive) { 328 if (~ $CSA_SESSION(18) /$CSA_ID/*) { 329 csaExit.location $CSA_CGI_STEM$CSA_SESSION(18) 330 } else csaExit.location $CSA_SESSION(18) 331 } 332 } 333 334 csaExit.location \ 335 $CSA_RPC_URI/$CSA_LANG/$'cgi.group'/$TNS_GROUP_HOME(2) 336 337 # End of program.