Fossil SCM

Add the ability to deny capabilities to self-registered accounts until the email verification comes through.

drh 2020-04-24 00:49 restricted-self-registration
Commit 3b7970e032b39c6bab92a635d2c49430f0f833b01690df13e123403bd13ceb1f
+15 -2
--- src/alerts.c
+++ src/alerts.c
@@ -1733,13 +1733,26 @@
17331733
smip = db_column_text(&q, 5);
17341734
mtime = db_column_text(&q, 7);
17351735
sctime = db_column_text(&q, 8);
17361736
if( !g.perm.Admin && !sverified ){
17371737
if( nName==64 ){
1738
- db_multi_exec(
1739
- "UPDATE subscriber SET sverified=1 WHERE subscriberCode=hextoblob(%Q)",
1738
+ db_multi_exec(
1739
+ "UPDATE subscriber SET sverified=1"
1740
+ " WHERE subscriberCode=hextoblob(%Q)",
17401741
zName);
1742
+ if( db_get_boolean("selfreg-verify",0) ){
1743
+ char *zNewCap = db_get("default-perms","u");
1744
+ db_multi_exec(
1745
+ "UPDATE user"
1746
+ " SET cap=%Q"
1747
+ " WHERE cap='7' AND login=("
1748
+ " SELECT suname FROM subscriber"
1749
+ " WHERE subscriberCode=hextoblob(%Q))",
1750
+ zNewCap, zName
1751
+ );
1752
+ login_set_capabilities(zNewCap, 0);
1753
+ }
17411754
@ <h1>Your email alert subscription has been verified!</h1>
17421755
@ <p>Use the form below to update your subscription information.</p>
17431756
@ <p>Hint: Bookmark this page so that you can more easily update
17441757
@ your subscription information in the future</p>
17451758
}else{
17461759
--- src/alerts.c
+++ src/alerts.c
@@ -1733,13 +1733,26 @@
1733 smip = db_column_text(&q, 5);
1734 mtime = db_column_text(&q, 7);
1735 sctime = db_column_text(&q, 8);
1736 if( !g.perm.Admin && !sverified ){
1737 if( nName==64 ){
1738 db_multi_exec(
1739 "UPDATE subscriber SET sverified=1 WHERE subscriberCode=hextoblob(%Q)",
 
1740 zName);
 
 
 
 
 
 
 
 
 
 
 
 
1741 @ <h1>Your email alert subscription has been verified!</h1>
1742 @ <p>Use the form below to update your subscription information.</p>
1743 @ <p>Hint: Bookmark this page so that you can more easily update
1744 @ your subscription information in the future</p>
1745 }else{
1746
--- src/alerts.c
+++ src/alerts.c
@@ -1733,13 +1733,26 @@
1733 smip = db_column_text(&q, 5);
1734 mtime = db_column_text(&q, 7);
1735 sctime = db_column_text(&q, 8);
1736 if( !g.perm.Admin && !sverified ){
1737 if( nName==64 ){
1738 db_multi_exec(
1739 "UPDATE subscriber SET sverified=1"
1740 " WHERE subscriberCode=hextoblob(%Q)",
1741 zName);
1742 if( db_get_boolean("selfreg-verify",0) ){
1743 char *zNewCap = db_get("default-perms","u");
1744 db_multi_exec(
1745 "UPDATE user"
1746 " SET cap=%Q"
1747 " WHERE cap='7' AND login=("
1748 " SELECT suname FROM subscriber"
1749 " WHERE subscriberCode=hextoblob(%Q))",
1750 zNewCap, zName
1751 );
1752 login_set_capabilities(zNewCap, 0);
1753 }
1754 @ <h1>Your email alert subscription has been verified!</h1>
1755 @ <p>Use the form below to update your subscription information.</p>
1756 @ <p>Hint: Bookmark this page so that you can more easily update
1757 @ your subscription information in the future</p>
1758 }else{
1759
--- src/capabilities.c
+++ src/capabilities.c
@@ -366,11 +366,11 @@
366366
CapabilityString *pCap;
367367
char *zSelfCap;
368368
char *zPubPages = db_get("public-pages",0);
369369
int hasPubPages = zPubPages && zPubPages[0];
370370
371
- pCap = capability_add(0, db_get("default-perms",0));
371
+ pCap = capability_add(0, db_get("default-perms","u"));
372372
capability_expand(pCap);
373373
zSelfCap = capability_string(pCap);
374374
capability_free(pCap);
375375
376376
db_prepare(&q,
377377
--- src/capabilities.c
+++ src/capabilities.c
@@ -366,11 +366,11 @@
366 CapabilityString *pCap;
367 char *zSelfCap;
368 char *zPubPages = db_get("public-pages",0);
369 int hasPubPages = zPubPages && zPubPages[0];
370
371 pCap = capability_add(0, db_get("default-perms",0));
372 capability_expand(pCap);
373 zSelfCap = capability_string(pCap);
374 capability_free(pCap);
375
376 db_prepare(&q,
377
--- src/capabilities.c
+++ src/capabilities.c
@@ -366,11 +366,11 @@
366 CapabilityString *pCap;
367 char *zSelfCap;
368 char *zPubPages = db_get("public-pages",0);
369 int hasPubPages = zPubPages && zPubPages[0];
370
371 pCap = capability_add(0, db_get("default-perms","u"));
372 capability_expand(pCap);
373 zSelfCap = capability_string(pCap);
374 capability_free(pCap);
375
376 db_prepare(&q,
377
+12 -4
--- src/login.c
+++ src/login.c
@@ -481,11 +481,11 @@
481481
int login_self_register_available(const char *zNeeded){
482482
CapabilityString *pCap;
483483
int rc;
484484
if( !db_get_boolean("self-register",0) ) return 0;
485485
if( zNeeded==0 ) return 1;
486
- pCap = capability_add(0, db_get("default-perms", 0));
486
+ pCap = capability_add(0, db_get("default-perms", "u"));
487487
capability_expand(pCap);
488488
rc = capability_has_any(pCap, zNeeded);
489489
capability_free(pCap);
490490
return rc;
491491
}
@@ -1128,11 +1128,11 @@
11281128
if( zPublicPages!=0 ){
11291129
Glob *pGlob = glob_create(zPublicPages);
11301130
const char *zUri = PD("REQUEST_URI","");
11311131
zUri += (int)strlen(g.zTop);
11321132
if( glob_match(pGlob, zUri) ){
1133
- login_set_capabilities(db_get("default-perms", 0), 0);
1133
+ login_set_capabilities(db_get("default-perms", "u"), 0);
11341134
}
11351135
glob_free(pGlob);
11361136
}
11371137
}
11381138
@@ -1511,11 +1511,11 @@
15111511
@ <p>This project does not allow user self-registration. Please contact the
15121512
@ project administrator to obtain an account.</p>
15131513
style_footer();
15141514
return;
15151515
}
1516
- zPerms = db_get("default-perms", 0);
1516
+ zPerms = db_get("default-perms", "u");
15171517
15181518
/* Prompt the user for email alerts if this repository is configured for
15191519
** email alerts and if the default permissions include "7" */
15201520
canDoAlerts = alert_tables_exist() && db_int(0,
15211521
"SELECT fullcap(%Q) GLOB '*7*'", zPerms
@@ -1578,16 +1578,24 @@
15781578
/* If all of the tests above have passed, that means that the submitted
15791579
** form contains valid data and we can proceed to create the new login */
15801580
Blob sql;
15811581
int uid;
15821582
char *zPass = sha1_shared_secret(zPasswd, zUserID, 0);
1583
+ const char *zStartPerms = zPerms;
1584
+ if( db_get_boolean("selfreg-verify",0) ){
1585
+ /* If email verification is required for self-registration, initalize
1586
+ ** the new user capabilities to just "7" (Sign up for email). The
1587
+ ** full "default-perms" permissions will be added when they click
1588
+ ** the verification link on the email they are sent. */
1589
+ zStartPerms = "7";
1590
+ }
15831591
blob_init(&sql, 0, 0);
15841592
blob_append_sql(&sql,
15851593
"INSERT INTO user(login,pw,cap,info,mtime)\n"
15861594
"VALUES(%Q,%Q,%Q,"
15871595
"'%q <%q>\nself-register from ip %q on '||datetime('now'),now())",
1588
- zUserID, zPass, zPerms, zDName, zEAddr, g.zIpAddr);
1596
+ zUserID, zPass, zStartPerms, zDName, zEAddr, g.zIpAddr);
15891597
fossil_free(zPass);
15901598
db_multi_exec("%s", blob_sql_text(&sql));
15911599
uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUserID);
15921600
login_set_user_cookie(zUserID, uid, NULL);
15931601
if( doAlerts ){
15941602
--- src/login.c
+++ src/login.c
@@ -481,11 +481,11 @@
481 int login_self_register_available(const char *zNeeded){
482 CapabilityString *pCap;
483 int rc;
484 if( !db_get_boolean("self-register",0) ) return 0;
485 if( zNeeded==0 ) return 1;
486 pCap = capability_add(0, db_get("default-perms", 0));
487 capability_expand(pCap);
488 rc = capability_has_any(pCap, zNeeded);
489 capability_free(pCap);
490 return rc;
491 }
@@ -1128,11 +1128,11 @@
1128 if( zPublicPages!=0 ){
1129 Glob *pGlob = glob_create(zPublicPages);
1130 const char *zUri = PD("REQUEST_URI","");
1131 zUri += (int)strlen(g.zTop);
1132 if( glob_match(pGlob, zUri) ){
1133 login_set_capabilities(db_get("default-perms", 0), 0);
1134 }
1135 glob_free(pGlob);
1136 }
1137 }
1138
@@ -1511,11 +1511,11 @@
1511 @ <p>This project does not allow user self-registration. Please contact the
1512 @ project administrator to obtain an account.</p>
1513 style_footer();
1514 return;
1515 }
1516 zPerms = db_get("default-perms", 0);
1517
1518 /* Prompt the user for email alerts if this repository is configured for
1519 ** email alerts and if the default permissions include "7" */
1520 canDoAlerts = alert_tables_exist() && db_int(0,
1521 "SELECT fullcap(%Q) GLOB '*7*'", zPerms
@@ -1578,16 +1578,24 @@
1578 /* If all of the tests above have passed, that means that the submitted
1579 ** form contains valid data and we can proceed to create the new login */
1580 Blob sql;
1581 int uid;
1582 char *zPass = sha1_shared_secret(zPasswd, zUserID, 0);
 
 
 
 
 
 
 
 
1583 blob_init(&sql, 0, 0);
1584 blob_append_sql(&sql,
1585 "INSERT INTO user(login,pw,cap,info,mtime)\n"
1586 "VALUES(%Q,%Q,%Q,"
1587 "'%q <%q>\nself-register from ip %q on '||datetime('now'),now())",
1588 zUserID, zPass, zPerms, zDName, zEAddr, g.zIpAddr);
1589 fossil_free(zPass);
1590 db_multi_exec("%s", blob_sql_text(&sql));
1591 uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUserID);
1592 login_set_user_cookie(zUserID, uid, NULL);
1593 if( doAlerts ){
1594
--- src/login.c
+++ src/login.c
@@ -481,11 +481,11 @@
481 int login_self_register_available(const char *zNeeded){
482 CapabilityString *pCap;
483 int rc;
484 if( !db_get_boolean("self-register",0) ) return 0;
485 if( zNeeded==0 ) return 1;
486 pCap = capability_add(0, db_get("default-perms", "u"));
487 capability_expand(pCap);
488 rc = capability_has_any(pCap, zNeeded);
489 capability_free(pCap);
490 return rc;
491 }
@@ -1128,11 +1128,11 @@
1128 if( zPublicPages!=0 ){
1129 Glob *pGlob = glob_create(zPublicPages);
1130 const char *zUri = PD("REQUEST_URI","");
1131 zUri += (int)strlen(g.zTop);
1132 if( glob_match(pGlob, zUri) ){
1133 login_set_capabilities(db_get("default-perms", "u"), 0);
1134 }
1135 glob_free(pGlob);
1136 }
1137 }
1138
@@ -1511,11 +1511,11 @@
1511 @ <p>This project does not allow user self-registration. Please contact the
1512 @ project administrator to obtain an account.</p>
1513 style_footer();
1514 return;
1515 }
1516 zPerms = db_get("default-perms", "u");
1517
1518 /* Prompt the user for email alerts if this repository is configured for
1519 ** email alerts and if the default permissions include "7" */
1520 canDoAlerts = alert_tables_exist() && db_int(0,
1521 "SELECT fullcap(%Q) GLOB '*7*'", zPerms
@@ -1578,16 +1578,24 @@
1578 /* If all of the tests above have passed, that means that the submitted
1579 ** form contains valid data and we can proceed to create the new login */
1580 Blob sql;
1581 int uid;
1582 char *zPass = sha1_shared_secret(zPasswd, zUserID, 0);
1583 const char *zStartPerms = zPerms;
1584 if( db_get_boolean("selfreg-verify",0) ){
1585 /* If email verification is required for self-registration, initalize
1586 ** the new user capabilities to just "7" (Sign up for email). The
1587 ** full "default-perms" permissions will be added when they click
1588 ** the verification link on the email they are sent. */
1589 zStartPerms = "7";
1590 }
1591 blob_init(&sql, 0, 0);
1592 blob_append_sql(&sql,
1593 "INSERT INTO user(login,pw,cap,info,mtime)\n"
1594 "VALUES(%Q,%Q,%Q,"
1595 "'%q <%q>\nself-register from ip %q on '||datetime('now'),now())",
1596 zUserID, zPass, zStartPerms, zDName, zEAddr, g.zIpAddr);
1597 fossil_free(zPass);
1598 db_multi_exec("%s", blob_sql_text(&sql));
1599 uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUserID);
1600 login_set_user_cookie(zUserID, uid, NULL);
1601 if( doAlerts ){
1602
--- src/security_audit.c
+++ src/security_audit.c
@@ -122,11 +122,11 @@
122122
zAnonCap = db_text("", "SELECT fullcap(NULL)");
123123
zDevCap = db_text("", "SELECT fullcap('v')");
124124
zReadCap = db_text("", "SELECT fullcap('u')");
125125
zPubPages = db_get("public-pages",0);
126126
hasSelfReg = db_get_boolean("self-register",0);
127
- pCap = capability_add(0, db_get("default-perms",0));
127
+ pCap = capability_add(0, db_get("default-perms","u"));
128128
capability_expand(pCap);
129129
zSelfCap = capability_string(pCap);
130130
capability_free(pCap);
131131
if( hasAnyCap(zAnonCap,"as") ){
132132
@ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
133133
--- src/security_audit.c
+++ src/security_audit.c
@@ -122,11 +122,11 @@
122 zAnonCap = db_text("", "SELECT fullcap(NULL)");
123 zDevCap = db_text("", "SELECT fullcap('v')");
124 zReadCap = db_text("", "SELECT fullcap('u')");
125 zPubPages = db_get("public-pages",0);
126 hasSelfReg = db_get_boolean("self-register",0);
127 pCap = capability_add(0, db_get("default-perms",0));
128 capability_expand(pCap);
129 zSelfCap = capability_string(pCap);
130 capability_free(pCap);
131 if( hasAnyCap(zAnonCap,"as") ){
132 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
133
--- src/security_audit.c
+++ src/security_audit.c
@@ -122,11 +122,11 @@
122 zAnonCap = db_text("", "SELECT fullcap(NULL)");
123 zDevCap = db_text("", "SELECT fullcap('v')");
124 zReadCap = db_text("", "SELECT fullcap('u')");
125 zPubPages = db_get("public-pages",0);
126 hasSelfReg = db_get_boolean("self-register",0);
127 pCap = capability_add(0, db_get("default-perms","u"));
128 capability_expand(pCap);
129 zSelfCap = capability_string(pCap);
130 capability_free(pCap);
131 if( hasAnyCap(zAnonCap,"as") ){
132 @ <li><p>This repository is <big><b>Wildly INSECURE</b></big> because
133
--- src/setup.c
+++ src/setup.c
@@ -508,10 +508,18 @@
508508
@ (<em>auto-captcha</em> setting is ignored). Keep in mind that anyone
509509
@ can register under any user name. This option is useful for public projects
510510
@ where you do not want everyone in any ticket discussion to be named
511511
@ "Anonymous". (Property: "self-register")</p>
512512
513
+ @ <hr />
514
+ onoff_attribute("Email verification required for self-registration",
515
+ "selfreg-verify", "selfregver", 0, 0);
516
+ @ <p>If enabled, self-registration creates a new entry in the USER table
517
+ @ but with provide any new capabilities until the email address provided
518
+ @ with registration has been verified.
519
+ @ (Property: "selfreg-verify")</p>
520
+
513521
@ <hr />
514522
entry_attribute("Authorized self-registration email addresses", 35,
515523
"self-reg-email", "selfregemail", "", 0);
516524
@ <p>This is a comma-separated list of GLOB patterns that specify
517525
@ email addresses that are authorized to self-register. If blank
518526
--- src/setup.c
+++ src/setup.c
@@ -508,10 +508,18 @@
508 @ (<em>auto-captcha</em> setting is ignored). Keep in mind that anyone
509 @ can register under any user name. This option is useful for public projects
510 @ where you do not want everyone in any ticket discussion to be named
511 @ "Anonymous". (Property: "self-register")</p>
512
 
 
 
 
 
 
 
 
513 @ <hr />
514 entry_attribute("Authorized self-registration email addresses", 35,
515 "self-reg-email", "selfregemail", "", 0);
516 @ <p>This is a comma-separated list of GLOB patterns that specify
517 @ email addresses that are authorized to self-register. If blank
518
--- src/setup.c
+++ src/setup.c
@@ -508,10 +508,18 @@
508 @ (<em>auto-captcha</em> setting is ignored). Keep in mind that anyone
509 @ can register under any user name. This option is useful for public projects
510 @ where you do not want everyone in any ticket discussion to be named
511 @ "Anonymous". (Property: "self-register")</p>
512
513 @ <hr />
514 onoff_attribute("Email verification required for self-registration",
515 "selfreg-verify", "selfregver", 0, 0);
516 @ <p>If enabled, self-registration creates a new entry in the USER table
517 @ but with provide any new capabilities until the email address provided
518 @ with registration has been verified.
519 @ (Property: "selfreg-verify")</p>
520
521 @ <hr />
522 entry_attribute("Authorized self-registration email addresses", 35,
523 "self-reg-email", "selfregemail", "", 0);
524 @ <p>This is a comma-separated list of GLOB patterns that specify
525 @ email addresses that are authorized to self-register. If blank
526
+1 -1
--- src/setupuser.c
+++ src/setupuser.c
@@ -553,11 +553,11 @@
553553
if( alert_tables_exist() ){
554554
int sid;
555555
sid = db_int(0, "SELECT subscriberId FROM subscriber"
556556
" WHERE suname=%Q", zLogin);
557557
if( sid>0 ){
558
- @ &nbsp;&nbsp;<a href="%R/alerts?sid=%d(sid)>\
558
+ @ &nbsp;&nbsp;<a href="%R/alerts?sid=%d(sid)">\
559559
@ (subscription info for %h(zLogin))</a>\
560560
}
561561
}
562562
@ </td></tr>
563563
@ <tr>
564564
--- src/setupuser.c
+++ src/setupuser.c
@@ -553,11 +553,11 @@
553 if( alert_tables_exist() ){
554 int sid;
555 sid = db_int(0, "SELECT subscriberId FROM subscriber"
556 " WHERE suname=%Q", zLogin);
557 if( sid>0 ){
558 @ &nbsp;&nbsp;<a href="%R/alerts?sid=%d(sid)>\
559 @ (subscription info for %h(zLogin))</a>\
560 }
561 }
562 @ </td></tr>
563 @ <tr>
564
--- src/setupuser.c
+++ src/setupuser.c
@@ -553,11 +553,11 @@
553 if( alert_tables_exist() ){
554 int sid;
555 sid = db_int(0, "SELECT subscriberId FROM subscriber"
556 " WHERE suname=%Q", zLogin);
557 if( sid>0 ){
558 @ &nbsp;&nbsp;<a href="%R/alerts?sid=%d(sid)">\
559 @ (subscription info for %h(zLogin))</a>\
560 }
561 }
562 @ </td></tr>
563 @ <tr>
564

Keyboard Shortcuts

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