Fossil SCM
Improved login screen with a "Create A New Account" button.
Commit
14335899ef335f78aec72ad5160c5f454364e393bcb8fadfa599603ca587cb4a
Parent
45591e211154bc5…
2 files changed
+14
+37
-8
+14
| --- src/capabilities.c | ||
| +++ src/capabilities.c | ||
| @@ -68,10 +68,24 @@ | ||
| 68 | 68 | if( c>='0' && c<='z' ) pIn->x[c] = 0; |
| 69 | 69 | } |
| 70 | 70 | } |
| 71 | 71 | return pIn; |
| 72 | 72 | } |
| 73 | + | |
| 74 | +/* | |
| 75 | +** Return true if any of the capabilities in zNeeded are found in pCap | |
| 76 | +*/ | |
| 77 | +int capability_has_any(CapabilityString *p, const char *zNeeded){ | |
| 78 | + if( p==0 ) return 0; | |
| 79 | + if( zNeeded==0 ) return 0; | |
| 80 | + while( zNeeded[0] ){ | |
| 81 | + int c = zNeeded[0]; | |
| 82 | + if( fossil_isalnum(c) && p->x[c] ) return 1; | |
| 83 | + zNeeded++; | |
| 84 | + } | |
| 85 | + return 0; | |
| 86 | +} | |
| 73 | 87 | |
| 74 | 88 | /* |
| 75 | 89 | ** Delete a CapabilityString object. |
| 76 | 90 | */ |
| 77 | 91 | void capability_free(CapabilityString *p){ |
| 78 | 92 |
| --- src/capabilities.c | |
| +++ src/capabilities.c | |
| @@ -68,10 +68,24 @@ | |
| 68 | if( c>='0' && c<='z' ) pIn->x[c] = 0; |
| 69 | } |
| 70 | } |
| 71 | return pIn; |
| 72 | } |
| 73 | |
| 74 | /* |
| 75 | ** Delete a CapabilityString object. |
| 76 | */ |
| 77 | void capability_free(CapabilityString *p){ |
| 78 |
| --- src/capabilities.c | |
| +++ src/capabilities.c | |
| @@ -68,10 +68,24 @@ | |
| 68 | if( c>='0' && c<='z' ) pIn->x[c] = 0; |
| 69 | } |
| 70 | } |
| 71 | return pIn; |
| 72 | } |
| 73 | |
| 74 | /* |
| 75 | ** Return true if any of the capabilities in zNeeded are found in pCap |
| 76 | */ |
| 77 | int capability_has_any(CapabilityString *p, const char *zNeeded){ |
| 78 | if( p==0 ) return 0; |
| 79 | if( zNeeded==0 ) return 0; |
| 80 | while( zNeeded[0] ){ |
| 81 | int c = zNeeded[0]; |
| 82 | if( fossil_isalnum(c) && p->x[c] ) return 1; |
| 83 | zNeeded++; |
| 84 | } |
| 85 | return 0; |
| 86 | } |
| 87 | |
| 88 | /* |
| 89 | ** Delete a CapabilityString object. |
| 90 | */ |
| 91 | void capability_free(CapabilityString *p){ |
| 92 |
+37
-8
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -470,10 +470,28 @@ | ||
| 470 | 470 | zPattern = mprintf("%s/login*", g.zBaseURL); |
| 471 | 471 | rc = sqlite3_strglob(zPattern, zReferer)==0; |
| 472 | 472 | fossil_free(zPattern); |
| 473 | 473 | return rc; |
| 474 | 474 | } |
| 475 | + | |
| 476 | +/* | |
| 477 | +** Return TRUE if self-registration is available. If the zNeeded | |
| 478 | +** argument is not NULL, then only return true if self-registration is | |
| 479 | +** available and any of the capabilities named in zNeeded are available | |
| 480 | +** to self-registered users. | |
| 481 | +*/ | |
| 482 | +int login_self_register_available(const char *zNeeded){ | |
| 483 | + CapabilityString *pCap; | |
| 484 | + int rc; | |
| 485 | + if( !db_get_boolean("self-register",0) ) return 0; | |
| 486 | + if( zNeeded==0 ) return 1; | |
| 487 | + pCap = capability_add(0, db_get("default-perms","")); | |
| 488 | + capability_expand(pCap); | |
| 489 | + rc = capability_has_any(pCap, zNeeded); | |
| 490 | + capability_free(pCap); | |
| 491 | + return rc; | |
| 492 | +} | |
| 475 | 493 | |
| 476 | 494 | /* |
| 477 | 495 | ** There used to be a page named "my" that was designed to show information |
| 478 | 496 | ** about a specific user. The "my" page was linked from the "Logged in as USER" |
| 479 | 497 | ** line on the title bar. The "my" page was never completed so it is now |
| @@ -536,10 +554,16 @@ | ||
| 536 | 554 | if( P("out") ){ |
| 537 | 555 | login_clear_login_data(); |
| 538 | 556 | redirect_to_g(); |
| 539 | 557 | return; |
| 540 | 558 | } |
| 559 | + | |
| 560 | + /* Redirect for create-new-account requests */ | |
| 561 | + if( P("self") ){ | |
| 562 | + cgi_redirectf("%R/register"); | |
| 563 | + return; | |
| 564 | + } | |
| 541 | 565 | |
| 542 | 566 | /* Deal with password-change requests */ |
| 543 | 567 | if( g.perm.Password && zPasswd |
| 544 | 568 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 545 | 569 | ){ |
| @@ -675,11 +699,11 @@ | ||
| 675 | 699 | @ <td><input type="text" id="u" name="u" value="anonymous" size="30"></td> |
| 676 | 700 | }else{ |
| 677 | 701 | @ <td><input type="text" id="u" name="u" value="" size="30" /></td> |
| 678 | 702 | } |
| 679 | 703 | if( P("HTTPS")==0 ){ |
| 680 | - @ <td width="15"><td rowspan="3"> | |
| 704 | + @ <td width="15"><td rowspan="2"> | |
| 681 | 705 | @ <p class='securityWarning'> |
| 682 | 706 | @ Warning: Your password will be sent in the clear over an |
| 683 | 707 | @ unencrypted connection. |
| 684 | 708 | if( g.sslNotAvailable ){ |
| 685 | 709 | @ No encrypted connection is available on this server. |
| @@ -690,27 +714,32 @@ | ||
| 690 | 714 | @ </p> |
| 691 | 715 | } |
| 692 | 716 | @ </tr> |
| 693 | 717 | @ <tr> |
| 694 | 718 | @ <td class="form_label">Password:</td> |
| 695 | - @ <td><input type="password" id="p" name="p" value="" size="30" /></td> | |
| 719 | + @ <td><input type="password" id="p" name="p" value="" size="30" /></td> | |
| 696 | 720 | @ </tr> |
| 697 | 721 | if( g.zLogin==0 && (anonFlag || zGoto==0) ){ |
| 698 | 722 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 699 | 723 | " WHERE login='anonymous'" |
| 700 | 724 | " AND cap!=''"); |
| 701 | 725 | } |
| 702 | 726 | @ <tr> |
| 703 | 727 | @ <td></td> |
| 704 | - @ <td><input type="submit" name="in" value="Login"> | |
| 728 | + @ <td><input type="submit" name="in" value="Login"></td> | |
| 729 | + @ <td colspan="2">← Pressing this button grants\ | |
| 730 | + @ permission to store a cookie | |
| 705 | 731 | @ </tr> |
| 706 | - @ </table> | |
| 707 | - @ <p>Pressing the Login button grants permission to store a cookie.</p> | |
| 708 | - if( db_get_boolean("self-register", 0) ){ | |
| 709 | - @ <p>If you do not have an account, you can | |
| 710 | - @ <a href="%R/register?g=%T(P("G"))">create one</a>. | |
| 732 | + if( login_self_register_available(0) ){ | |
| 733 | + @ <tr> | |
| 734 | + @ <td></td> | |
| 735 | + @ <td><input type="submit" name="self" value="Create A New Account"> | |
| 736 | + @ <td colspan="2"> \ | |
| 737 | + @ ← Don't have a login? Click this button to create one. | |
| 738 | + @ </tr> | |
| 711 | 739 | } |
| 740 | + @ </table> | |
| 712 | 741 | if( zAnonPw ){ |
| 713 | 742 | unsigned int uSeed = captcha_seed(); |
| 714 | 743 | const char *zDecoded = captcha_decode(uSeed); |
| 715 | 744 | int bAutoCaptcha = db_get_boolean("auto-captcha", 0); |
| 716 | 745 | char *zCaptcha = captcha_render(zDecoded); |
| 717 | 746 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -470,10 +470,28 @@ | |
| 470 | zPattern = mprintf("%s/login*", g.zBaseURL); |
| 471 | rc = sqlite3_strglob(zPattern, zReferer)==0; |
| 472 | fossil_free(zPattern); |
| 473 | return rc; |
| 474 | } |
| 475 | |
| 476 | /* |
| 477 | ** There used to be a page named "my" that was designed to show information |
| 478 | ** about a specific user. The "my" page was linked from the "Logged in as USER" |
| 479 | ** line on the title bar. The "my" page was never completed so it is now |
| @@ -536,10 +554,16 @@ | |
| 536 | if( P("out") ){ |
| 537 | login_clear_login_data(); |
| 538 | redirect_to_g(); |
| 539 | return; |
| 540 | } |
| 541 | |
| 542 | /* Deal with password-change requests */ |
| 543 | if( g.perm.Password && zPasswd |
| 544 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 545 | ){ |
| @@ -675,11 +699,11 @@ | |
| 675 | @ <td><input type="text" id="u" name="u" value="anonymous" size="30"></td> |
| 676 | }else{ |
| 677 | @ <td><input type="text" id="u" name="u" value="" size="30" /></td> |
| 678 | } |
| 679 | if( P("HTTPS")==0 ){ |
| 680 | @ <td width="15"><td rowspan="3"> |
| 681 | @ <p class='securityWarning'> |
| 682 | @ Warning: Your password will be sent in the clear over an |
| 683 | @ unencrypted connection. |
| 684 | if( g.sslNotAvailable ){ |
| 685 | @ No encrypted connection is available on this server. |
| @@ -690,27 +714,32 @@ | |
| 690 | @ </p> |
| 691 | } |
| 692 | @ </tr> |
| 693 | @ <tr> |
| 694 | @ <td class="form_label">Password:</td> |
| 695 | @ <td><input type="password" id="p" name="p" value="" size="30" /></td> |
| 696 | @ </tr> |
| 697 | if( g.zLogin==0 && (anonFlag || zGoto==0) ){ |
| 698 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 699 | " WHERE login='anonymous'" |
| 700 | " AND cap!=''"); |
| 701 | } |
| 702 | @ <tr> |
| 703 | @ <td></td> |
| 704 | @ <td><input type="submit" name="in" value="Login"> |
| 705 | @ </tr> |
| 706 | @ </table> |
| 707 | @ <p>Pressing the Login button grants permission to store a cookie.</p> |
| 708 | if( db_get_boolean("self-register", 0) ){ |
| 709 | @ <p>If you do not have an account, you can |
| 710 | @ <a href="%R/register?g=%T(P("G"))">create one</a>. |
| 711 | } |
| 712 | if( zAnonPw ){ |
| 713 | unsigned int uSeed = captcha_seed(); |
| 714 | const char *zDecoded = captcha_decode(uSeed); |
| 715 | int bAutoCaptcha = db_get_boolean("auto-captcha", 0); |
| 716 | char *zCaptcha = captcha_render(zDecoded); |
| 717 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -470,10 +470,28 @@ | |
| 470 | zPattern = mprintf("%s/login*", g.zBaseURL); |
| 471 | rc = sqlite3_strglob(zPattern, zReferer)==0; |
| 472 | fossil_free(zPattern); |
| 473 | return rc; |
| 474 | } |
| 475 | |
| 476 | /* |
| 477 | ** Return TRUE if self-registration is available. If the zNeeded |
| 478 | ** argument is not NULL, then only return true if self-registration is |
| 479 | ** available and any of the capabilities named in zNeeded are available |
| 480 | ** to self-registered users. |
| 481 | */ |
| 482 | int login_self_register_available(const char *zNeeded){ |
| 483 | CapabilityString *pCap; |
| 484 | int rc; |
| 485 | if( !db_get_boolean("self-register",0) ) return 0; |
| 486 | if( zNeeded==0 ) return 1; |
| 487 | pCap = capability_add(0, db_get("default-perms","")); |
| 488 | capability_expand(pCap); |
| 489 | rc = capability_has_any(pCap, zNeeded); |
| 490 | capability_free(pCap); |
| 491 | return rc; |
| 492 | } |
| 493 | |
| 494 | /* |
| 495 | ** There used to be a page named "my" that was designed to show information |
| 496 | ** about a specific user. The "my" page was linked from the "Logged in as USER" |
| 497 | ** line on the title bar. The "my" page was never completed so it is now |
| @@ -536,10 +554,16 @@ | |
| 554 | if( P("out") ){ |
| 555 | login_clear_login_data(); |
| 556 | redirect_to_g(); |
| 557 | return; |
| 558 | } |
| 559 | |
| 560 | /* Redirect for create-new-account requests */ |
| 561 | if( P("self") ){ |
| 562 | cgi_redirectf("%R/register"); |
| 563 | return; |
| 564 | } |
| 565 | |
| 566 | /* Deal with password-change requests */ |
| 567 | if( g.perm.Password && zPasswd |
| 568 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 569 | ){ |
| @@ -675,11 +699,11 @@ | |
| 699 | @ <td><input type="text" id="u" name="u" value="anonymous" size="30"></td> |
| 700 | }else{ |
| 701 | @ <td><input type="text" id="u" name="u" value="" size="30" /></td> |
| 702 | } |
| 703 | if( P("HTTPS")==0 ){ |
| 704 | @ <td width="15"><td rowspan="2"> |
| 705 | @ <p class='securityWarning'> |
| 706 | @ Warning: Your password will be sent in the clear over an |
| 707 | @ unencrypted connection. |
| 708 | if( g.sslNotAvailable ){ |
| 709 | @ No encrypted connection is available on this server. |
| @@ -690,27 +714,32 @@ | |
| 714 | @ </p> |
| 715 | } |
| 716 | @ </tr> |
| 717 | @ <tr> |
| 718 | @ <td class="form_label">Password:</td> |
| 719 | @ <td><input type="password" id="p" name="p" value="" size="30" /></td> |
| 720 | @ </tr> |
| 721 | if( g.zLogin==0 && (anonFlag || zGoto==0) ){ |
| 722 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 723 | " WHERE login='anonymous'" |
| 724 | " AND cap!=''"); |
| 725 | } |
| 726 | @ <tr> |
| 727 | @ <td></td> |
| 728 | @ <td><input type="submit" name="in" value="Login"></td> |
| 729 | @ <td colspan="2">← Pressing this button grants\ |
| 730 | @ permission to store a cookie |
| 731 | @ </tr> |
| 732 | if( login_self_register_available(0) ){ |
| 733 | @ <tr> |
| 734 | @ <td></td> |
| 735 | @ <td><input type="submit" name="self" value="Create A New Account"> |
| 736 | @ <td colspan="2"> \ |
| 737 | @ ← Don't have a login? Click this button to create one. |
| 738 | @ </tr> |
| 739 | } |
| 740 | @ </table> |
| 741 | if( zAnonPw ){ |
| 742 | unsigned int uSeed = captcha_seed(); |
| 743 | const char *zDecoded = captcha_decode(uSeed); |
| 744 | int bAutoCaptcha = db_get_boolean("auto-captcha", 0); |
| 745 | char *zCaptcha = captcha_render(zDecoded); |
| 746 |