Fossil SCM

First cut at code to allow anonymous users to self-register.

drh 2010-12-22 23:57 trunk
Commit fedf27e483764c5f7389981ac3a4b1a8266d3c18
1 file changed +124
+124
--- src/login.c
+++ src/login.c
@@ -266,10 +266,13 @@
266266
}
267267
@ your user-id and password at the left and press the
268268
@ "Login" button. Your user name will be stored in a browser cookie.
269269
@ You must configure your web browser to accept cookies in order for
270270
@ the login to take.</p>
271
+ @
272
+ @ <p>If you do not have an account, you can
273
+ @ <a href="%s(g.zTop)/register?g=%T(P("G"))">create one</a>.
271274
if( zAnonPw ){
272275
unsigned int uSeed = captcha_seed();
273276
char const *zDecoded = captcha_decode(uSeed);
274277
int bAutoCaptcha = db_get_boolean("auto-captcha", 1);
275278
char *zCaptcha = captcha_render(zDecoded);
@@ -624,5 +627,126 @@
624627
g.okCsrf = 1;
625628
return;
626629
}
627630
fossil_fatal("Cross-site request forgery attempt");
628631
}
632
+
633
+/*
634
+** WEBPAGE: register
635
+**
636
+** Generate the register page.
637
+**
638
+*/
639
+void register_page(void){
640
+ const char *zUsername, *zPasswd, *zConfirm, *zContact, *zCS, *zPw, *zCap;
641
+
642
+ style_header("Register");
643
+ zUsername = P("u");
644
+ zPasswd = P("p");
645
+ zConfirm = P("cp");
646
+ zContact = P("c");
647
+ zCap = P("cap");
648
+ zCS = P("cs"); /* Captcha Secret */
649
+
650
+ /* Try to make any sense from user input. */
651
+ if( P("new") ){
652
+ if( zCS==0 ) fossil_redirect_home(); /* Forged request */
653
+ zPw = captcha_decode((unsigned int)atoi(zCS));
654
+ if( !(zUsername && zPasswd && zConfirm && zContact) ){
655
+ @ <p><span class="loginError">
656
+ @ All fields are obligatory.
657
+ @ </span></p>
658
+ }else if( strcmp(zPasswd,zConfirm)!=0 ){
659
+ @ <p><span class="loginError">
660
+ @ The two copies of your new passwords do not match.
661
+ @ </span></p>
662
+ }else if( strcasecmp(zPw, zCap)!=0 ){
663
+ @ <p><span class="loginError">
664
+ @ Captcha text invalid.
665
+ @ </span></p>
666
+ }else{
667
+ /* This almost is stupid copy-paste of code from user.c:user_cmd(). */
668
+ Blob passwd, login, contact;
669
+
670
+ blob_init(&login, zUsername, -1);
671
+ blob_init(&contact, zContact, -1);
672
+ blob_init(&passwd, zPasswd, -1);
673
+
674
+ if( db_exists("SELECT 1 FROM user WHERE login=%B", &login) ){
675
+ /* Here lies the reason I don't use zErrMsg - it would not substitute
676
+ * this %s(zUsername), or at least I don't know how to force it to.*/
677
+ @ <p><span class="loginError">
678
+ @ %s(zUsername) already exists.
679
+ @ </span></p>
680
+ }else{
681
+ char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login));
682
+ db_multi_exec(
683
+ "INSERT INTO user(login,pw,cap,info)"
684
+ "VALUES(%B,%Q,'u',%B)", /* u - register as reader, not developer! */
685
+ &login, zPw, &contact
686
+ );
687
+ free(zPw);
688
+
689
+ /* The user is registered, now just log him in. */
690
+ int uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUsername);
691
+ char *zCookie;
692
+ const char *zCookieName = login_cookie_name();
693
+ const char *zExpire = db_get("cookie-expire","8766");
694
+ int expires = atoi(zExpire)*3600;
695
+ const char *zIpAddr = PD("REMOTE_ADDR","nil");
696
+
697
+ zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid);
698
+ cgi_set_cookie(zCookieName, zCookie, 0, expires);
699
+ db_multi_exec(
700
+ "UPDATE user SET cookie=%Q, ipaddr=%Q, "
701
+ " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d",
702
+ zCookie, zIpAddr, expires, uid
703
+ );
704
+ redirect_to_g();
705
+
706
+ }
707
+ }
708
+ }
709
+
710
+ /* Prepare the captcha. */
711
+ unsigned int uSeed = captcha_seed();
712
+ char const *zDecoded = captcha_decode(uSeed);
713
+ char *zCaptcha = captcha_render(zDecoded);
714
+
715
+ /* Print out the registration form. */
716
+ @ <form action="register" method="post">
717
+ if( P("g") ){
718
+ @ <input type="hidden" name="g" value="%h(P("g"))" />
719
+ }
720
+ @ <p><input type="hidden" name="cs" value="%u(uSeed)" />
721
+ @ <table class="login_out">
722
+ @ <tr>
723
+ @ <td class="login_out_label" align="right">User ID:</td>
724
+ @ <td><input type="text" id="u" name="u" value="" size="30" /></td>
725
+ @ </tr>
726
+ @ <tr>
727
+ @ <td class="login_out_label" align="right">Password:</td>
728
+ @ <td><input type="password" id="p" name="p" value="" size="30" /></td>
729
+ @ </tr>
730
+ @ <tr>
731
+ @ <td class="login_out_label" align="right">Confirm password:</td>
732
+ @ <td><input type="password" id="cp" name="cp" value="" size="30" /></td>
733
+ @ </tr>
734
+ @ <tr>
735
+ @ <td class="login_out_label" align="right">Contact info:</td>
736
+ @ <td><input type="text" id="c" name="c" value="" size="30" /></td>
737
+ @ </tr>
738
+ @ <tr>
739
+ @ <td class="login_out_label" align="right">Captcha text (below):</td>
740
+ @ <td><input type="text" id="cap" name="cap" value="" size="30" /></td>
741
+ @ </tr>
742
+ @ <tr><td></td>
743
+ @ <td><input type="submit" name="new" value="Register" /></td></tr>
744
+ @ </table>
745
+ @ <div class="captcha"><table class="captcha"><tr><td><pre>
746
+ @ %s(zCaptcha)
747
+ @ </pre></td></tr></table>
748
+ @ </form>
749
+ style_footer();
750
+
751
+ free(zCaptcha);
752
+}
629753
--- src/login.c
+++ src/login.c
@@ -266,10 +266,13 @@
266 }
267 @ your user-id and password at the left and press the
268 @ "Login" button. Your user name will be stored in a browser cookie.
269 @ You must configure your web browser to accept cookies in order for
270 @ the login to take.</p>
 
 
 
271 if( zAnonPw ){
272 unsigned int uSeed = captcha_seed();
273 char const *zDecoded = captcha_decode(uSeed);
274 int bAutoCaptcha = db_get_boolean("auto-captcha", 1);
275 char *zCaptcha = captcha_render(zDecoded);
@@ -624,5 +627,126 @@
624 g.okCsrf = 1;
625 return;
626 }
627 fossil_fatal("Cross-site request forgery attempt");
628 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
629
--- src/login.c
+++ src/login.c
@@ -266,10 +266,13 @@
266 }
267 @ your user-id and password at the left and press the
268 @ "Login" button. Your user name will be stored in a browser cookie.
269 @ You must configure your web browser to accept cookies in order for
270 @ the login to take.</p>
271 @
272 @ <p>If you do not have an account, you can
273 @ <a href="%s(g.zTop)/register?g=%T(P("G"))">create one</a>.
274 if( zAnonPw ){
275 unsigned int uSeed = captcha_seed();
276 char const *zDecoded = captcha_decode(uSeed);
277 int bAutoCaptcha = db_get_boolean("auto-captcha", 1);
278 char *zCaptcha = captcha_render(zDecoded);
@@ -624,5 +627,126 @@
627 g.okCsrf = 1;
628 return;
629 }
630 fossil_fatal("Cross-site request forgery attempt");
631 }
632
633 /*
634 ** WEBPAGE: register
635 **
636 ** Generate the register page.
637 **
638 */
639 void register_page(void){
640 const char *zUsername, *zPasswd, *zConfirm, *zContact, *zCS, *zPw, *zCap;
641
642 style_header("Register");
643 zUsername = P("u");
644 zPasswd = P("p");
645 zConfirm = P("cp");
646 zContact = P("c");
647 zCap = P("cap");
648 zCS = P("cs"); /* Captcha Secret */
649
650 /* Try to make any sense from user input. */
651 if( P("new") ){
652 if( zCS==0 ) fossil_redirect_home(); /* Forged request */
653 zPw = captcha_decode((unsigned int)atoi(zCS));
654 if( !(zUsername && zPasswd && zConfirm && zContact) ){
655 @ <p><span class="loginError">
656 @ All fields are obligatory.
657 @ </span></p>
658 }else if( strcmp(zPasswd,zConfirm)!=0 ){
659 @ <p><span class="loginError">
660 @ The two copies of your new passwords do not match.
661 @ </span></p>
662 }else if( strcasecmp(zPw, zCap)!=0 ){
663 @ <p><span class="loginError">
664 @ Captcha text invalid.
665 @ </span></p>
666 }else{
667 /* This almost is stupid copy-paste of code from user.c:user_cmd(). */
668 Blob passwd, login, contact;
669
670 blob_init(&login, zUsername, -1);
671 blob_init(&contact, zContact, -1);
672 blob_init(&passwd, zPasswd, -1);
673
674 if( db_exists("SELECT 1 FROM user WHERE login=%B", &login) ){
675 /* Here lies the reason I don't use zErrMsg - it would not substitute
676 * this %s(zUsername), or at least I don't know how to force it to.*/
677 @ <p><span class="loginError">
678 @ %s(zUsername) already exists.
679 @ </span></p>
680 }else{
681 char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login));
682 db_multi_exec(
683 "INSERT INTO user(login,pw,cap,info)"
684 "VALUES(%B,%Q,'u',%B)", /* u - register as reader, not developer! */
685 &login, zPw, &contact
686 );
687 free(zPw);
688
689 /* The user is registered, now just log him in. */
690 int uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUsername);
691 char *zCookie;
692 const char *zCookieName = login_cookie_name();
693 const char *zExpire = db_get("cookie-expire","8766");
694 int expires = atoi(zExpire)*3600;
695 const char *zIpAddr = PD("REMOTE_ADDR","nil");
696
697 zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid);
698 cgi_set_cookie(zCookieName, zCookie, 0, expires);
699 db_multi_exec(
700 "UPDATE user SET cookie=%Q, ipaddr=%Q, "
701 " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d",
702 zCookie, zIpAddr, expires, uid
703 );
704 redirect_to_g();
705
706 }
707 }
708 }
709
710 /* Prepare the captcha. */
711 unsigned int uSeed = captcha_seed();
712 char const *zDecoded = captcha_decode(uSeed);
713 char *zCaptcha = captcha_render(zDecoded);
714
715 /* Print out the registration form. */
716 @ <form action="register" method="post">
717 if( P("g") ){
718 @ <input type="hidden" name="g" value="%h(P("g"))" />
719 }
720 @ <p><input type="hidden" name="cs" value="%u(uSeed)" />
721 @ <table class="login_out">
722 @ <tr>
723 @ <td class="login_out_label" align="right">User ID:</td>
724 @ <td><input type="text" id="u" name="u" value="" size="30" /></td>
725 @ </tr>
726 @ <tr>
727 @ <td class="login_out_label" align="right">Password:</td>
728 @ <td><input type="password" id="p" name="p" value="" size="30" /></td>
729 @ </tr>
730 @ <tr>
731 @ <td class="login_out_label" align="right">Confirm password:</td>
732 @ <td><input type="password" id="cp" name="cp" value="" size="30" /></td>
733 @ </tr>
734 @ <tr>
735 @ <td class="login_out_label" align="right">Contact info:</td>
736 @ <td><input type="text" id="c" name="c" value="" size="30" /></td>
737 @ </tr>
738 @ <tr>
739 @ <td class="login_out_label" align="right">Captcha text (below):</td>
740 @ <td><input type="text" id="cap" name="cap" value="" size="30" /></td>
741 @ </tr>
742 @ <tr><td></td>
743 @ <td><input type="submit" name="new" value="Register" /></td></tr>
744 @ </table>
745 @ <div class="captcha"><table class="captcha"><tr><td><pre>
746 @ %s(zCaptcha)
747 @ </pre></td></tr></table>
748 @ </form>
749 style_footer();
750
751 free(zCaptcha);
752 }
753

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button