1 # ===================================================================== 2 # registerUser: process a self-registration form. 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.passwd = () 30 cgi.reg.name_last = () 31 cgi.reg.name_first = () 32 cgi.reg.email = () 33 cgi.reg.watch = () 34 cgi.reg.openid = () 35 cgi.reg.auth = () 36 cgi.reg.gui = default 37 cgi.captcha = () 38 39 cgi.privacy = () 40 cgi.grep.user = () 41 cgi.grep.openid = () 42 43 reg_auth = () 44 45 # ===================================================================== 46 # Main program 47 # ===================================================================== 48 49 # Load call arguments. 50 csaGetArgs POST 51 52 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 53 54 . $CSA_ROOT/lib/group-stuff.rc 55 56 . $CSA_ROOT/lib/tpl-stuff.rc 57 58 # Prepare the error message "back" button. 59 # 60 #if (csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-nav-back.txt) { 61 # # custom "back" action template. 62 # tpl.include.nav.next = $CSA_TPL_ROOT/tw-nav-back.txt 63 #} else { 64 # # default "back" action template. 65 # tpl.include.nav.next = $tw_dstem/tw-nav-back.txt 66 #} 67 68 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 69 70 # New registration not allowed if already logged-in 71 # (we should not have landed here in the first place). 72 73 csaTrue $CSA_AUTH_OK && csaExit.fault 403 1028 74 75 # Grant further privileges if appropriate. 76 . $CSA_ROOT/lib/group-editor.rc 77 78 # Is self-registration enabled ? 79 # Again, we should not have got this far in the first place. 80 81 ~ $TNS_SELFREG_AUTH *[a-z]* || csaExit.fault 403 0022 82 83 # Set group template vars as appropriate. 84 tpl.var.tw.group = $'tbl_group.g_name' 85 tpl.var.tw.descr = $'tbl_group.g_descr' 86 87 ~ $'cgi.reg.userid' . && csaExit.fault --back 1030 88 ~ $'cgi.reg.passwd' . && csaExit.fault --back 1031 89 ~ $'cgi.reg.openid' . && csaExit.fault --back 1046 90 ~ $'cgi.reg.passwd' - && csaExit.fault --back 1033 91 ~ $'cgi.reg.email' () && csaExit.fault --back 1015 92 ~ $'cgi.reg.name_first' . && csaExit.fault --back 1035 93 94 ~ $'cgi.privacy' y || csaExit.fault --back 1043 95 96 if (~ $'cgi.captcha' () || !~ $'cgi.captcha' $CSA_SESSION(10)) { 97 csaExit.fault --back 401 1018 98 } 99 100 # Restore old value if none of the above errors occurred. 101 #csaChop $CSA_EXIT_SCRIPT; CSA_EXIT_SCRIPT = $CSA_RESULT 102 103 makeFullName --sreg $'cgi.reg.name_first' $'cgi.reg.name_last' 104 105 tpl.var.tw.reg.fullname = $CSA_RESULT 106 107 # Accept empty name/surname only if allowed. This test is currently 108 # disabled as this field cannot be verified and therefore it tells us 109 # nothing useful regarding the real identity of the requestor. The 110 # e-mail address is the sole piece of information that can be verified, 111 # to some extent. 112 113 #if (!csaTrue $TNS_SELFREG_ANONYMOUS) { 114 # ~ $'tpl.var.tw.reg.fullname' () && csaExit.fault 1032 115 #} 116 117 # Set default in templates if anonymous. 118 ~ $'tpl.var.tw.reg.fullname' () && 119 tpl.var.tw.reg.fullname = $'nls.reg.fullname.empty' 120 121 csaSetClear tpl.var.tw.reg.name_first cgi.reg.name_first 122 csaSetClear tpl.var.tw.reg.name_last cgi.reg.name_last 123 124 # Use an internally-generated userid if not specified. 125 if (~ $'cgi.reg.userid' ()) { 126 cgi.reg.userid = `{pwgen -1 -A -B 6} 127 ~ $bqstatus 0 || csaExit.fault 0003 pwgen 128 cgi.grep.user = $'cgi.reg.userid' 129 } else { 130 ~ $'cgi.grep.user' () && csaExit.fault 0066 # should not occur. 131 } 132 133 # Set Principal Lock Semaphore (PLS). 134 csaLock $TNS_USER_TABLE || csaExit.fault 135 136 if (!csaIsFullPath --exists --quiet $CSA_ROOT/var/pages/openid+dat) { 137 maketable --input \ 138 $CSA_ROOT/lib/openid.xrf > $CSA_ROOT/var/pages/openid+dat || 139 csaExit.fault 0003 maketable 140 } 141 142 # Check for duplicated userid (even if internally generated, just in case). 143 144 grep -qe '^'$'cgi.grep.user'$tab $TNS_USER_TABLE && 145 csaExit.fault --back 1030 146 147 grep -qe '^'$'cgi.grep.user'$tab $TMPDIR/*-reg && 148 csaExit.fault --back 1030 149 150 # Check also for invalid/duplicated OpenID URL, if entered by the 151 # client. No two accounts are allowed to refer to the same OpenID URL in 152 # 'openid+dat'. If a user wants to be able to log-in through multiple 153 # OpenID URLs then she will have to register with us multiple times, 154 # with different accounts. This should not be a problem though, as one 155 # who wants to authenticate via OpenID will not even really need to know 156 # the local account she is logged-in with. 157 158 if (~ $'cgi.reg.openid' http://* https://*) { 159 grep -qe '^'$'cgi.grep.openid'$tab CSA_ROOT/var/pages/openid+dat && 160 csaExit.fault --back 1047 161 162 # This is needed to recover the OpenID URL in case subscription 163 # requests are subject to approval by an administration, who could 164 # approve them with some lag, so I cannot rely on a session cookie 165 # to reliably store this URL. 166 167 echo $'cgi.reg.openid' > $TMPDIR/$CSA_GUID-openid-reg 168 } 169 170 # Release the PLS ASAP. 171 csaUnlock $TNS_USER_TABLE 172 173 # Use an internally-generated password if not specified. 174 ~ $'cgi.reg.passwd' () && cgi.reg.passwd = `{pwgen -1 -A -B 8} 175 ~ $bqstatus 0 || csaExit.fault 0003 pwgen 176 177 # Make sure that any group(s) specified by the user fall within the list 178 # of allowed ones. Any forbidden groups will be silently ignored. 179 # Note that this check must be done here because TNS_SELFREG_AUTH is 180 # still unset when _userproc() is executed, unless we set it in csa.rc 181 # but then we would have to remember to turn it off on a per-group 182 # basis and leakages may occur, so better define it at group level. 183 184 * = $'cgi.reg.auth' 185 while (!~ $#* 0) { 186 # Skip "editor" if this is going to end up in auth+dat !!! 187 if (!csaIsConfirmed || !~ $1 editor) { 188 if (~ $1 $TNS_SELFREG_AUTH) { 189 if (~ $reg_auth *[a-z]*) { 190 ~ $reg_auth *, || reg_auth = $reg_auth, 191 } 192 reg_auth = $reg_auth$1 193 } 194 } 195 shift 196 } 197 198 # Set default registration auth if still unset. If the user did not pick 199 # any of the allowed groups the most sensible choice would seem to grant 200 # her the most generic auth level. 201 202 ~ $reg_auth () && reg_auth = user 203 204 # Normalize as usual, it won't hurt. 205 #~ $reg_auth ,* || reg_auth = ,$reg_auth 206 #~ $reg_auth *, || reg_auth = $reg_auth, 207 208 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 209 210 if (!csaIsConfirmed) { 211 212 csaSetClear tpl.var.tw.reg.userid cgi.reg.userid 213 csaSetClear tpl.var.tw.reg.passwd cgi.reg.passwd 214 csaSetClear tpl.var.tw.reg.email cgi.reg.email 215 csaSetClear tpl.var.tw.reg.openid cgi.reg.openid 216 csaSetClear tpl.var.tw.reg.auth reg_auth 217 csaSetClear tpl.var.tw.reg.gui cgi.reg.gui 218 219 tpl.var.tw.captcha = $'cgi.captcha' 220 221 if (csaIsFullPath --exists --quiet \ 222 $CSA_TPL_ROOT/tw-reg-form-confirm.txt) { 223 # custom registration confirmation template. 224 tpl.include.html.body = $CSA_TPL_ROOT/tw-reg-form-confirm.txt 225 } else { 226 # default registration confirmation template. 227 tpl.include.html.body = $tw_dstem/tw-reg-form-confirm.txt 228 } 229 230 # PRG confirmation page must be regarded as a view. 231 tpl.if.tw.ispage = '(::DEL:)' 232 tpl.fi.tw.ispage = '(:DEL::)' 233 tpl.if.tw.printable = '(::DEL:)' 234 tpl.fi.tw.printable = '(:DEL::)' 235 tpl.if.tw.isview = () 236 tpl.fi.tw.isview = () 237 238 csaExit.ok $tpl_file 239 } 240 241 if (~ $'cgi.reg.auth' editor && ~ editor $TNS_SELFREG_AUTH) { 242 echo $'cgi.group' > $TMPDIR/$CSA_GUID-editor-reg || 243 csaExit.fault 0009 $TMPDIR/$CSA_GUID-editor-reg 244 } 245 246 # reg_auth here is expected NOT to contain "editor" !!! 247 tbl_reg.u_group = $reg_auth 248 tbl_reg.u_name = $'tpl.var.tw.reg.name_first' 249 tbl_reg.u_sname = $'tpl.var.tw.reg.name_last' 250 tbl_reg.u_gui = $'cgi.reg.gui' 251 252 csaSetClear tbl_reg.k_user cgi.reg.userid 253 csaSetClear tbl_reg.u_passwd cgi.reg.passwd 254 csaSetClear tbl_reg.u_email cgi.reg.email 255 csaSetClear tbl_reg.u_other cgi.reg.watch 256 257 #~ $REMOTE_ADDR 192.168.1.2 && csaExit.env 258 259 maketable --input $CSA_ROOT/lib/auth.xrf > $tmp1 || 260 csaExit.fault 0003 maketable 261 262 envtotable --match '^tbl_reg__2e[a-z]' \ 263 --strip-names '^tbl_reg__2e' | updtable --stdin \ 264 --key-columns k_user $tmp1 > $TMPDIR/$CSA_GUID-reg 265 266 csaStatus || csaExit.fault 0003 envtotable/updtable 267 268 #~ $REMOTE_ADDR 192.168.1.2 || csaExit.fault 0036 269 270 # If no custom email template exists then use default. 271 if (!csaIsFullPath --exists --quiet $CSA_TPL_ROOT/tw-reg-email.txt) { 272 tpl_email = (--file-root $tw_dstem tw-reg-email.txt) 273 } else tpl_email = tw-reg-email.txt 274 275 csaLoadLib csaEmaillib.rc || csaExit.fault 276 tpl.var.tw.reg.userid = $'tbl_reg.k_user' 277 tpl.var.tw.reg.passwd = $'tbl_reg.u_passwd' 278 tpl.var.tw.reg.email = $'tbl_reg.u_email' 279 tpl.var.tw.reg.gui = $'tbl_reg.u_gui' 280 281 # If subscription requests require approval, then send the message to 282 # the designated administrator as opposed to the requesting user. The 283 # administrator, in turn, will forward the message to the applicant 284 # if the request is approved. This procedure discloses the account 285 # password to the administrator, but I do not currently see this as 286 # a real problem. To approve a registration request, the administrator 287 # will simply need to reply to it, including a copy of the message body. 288 289 if (csaTrue $TNS_SELFREG_APPROVE) { 290 TNS_EMAIL_TO = $TNS_EMAIL_FROM 291 TNS_EMAIL_REPLY_TO = $'tbl_reg.u_email' 292 # Not all clients handle the Reply-To header correctly. 293 TNS_EMAIL_FROM = $'tbl_reg.u_email' 294 } else TNS_EMAIL_TO = $'tbl_reg.u_email' 295 296 csaSendMail $tpl_email 297 298 if (csaIsFullPath --exists --quiet \ 299 $CSA_TPL_ROOT/tw-reg-sent.txt) { 300 # custom registration confirmation message template. 301 tpl.include.html.body = $CSA_TPL_ROOT/tw-reg-sent.txt 302 } else { 303 # default registration confirmation message template. 304 tpl.include.html.body = $tw_dstem/tw-reg-sent.txt 305 } 306 307 csaExit.ok $tpl_file 308 309 # End of program.