Fossil SCM

Initial alerts infrastructure for user-elevation notifications. Alerts are not yet sent.

stephan 2025-03-08 12:48 useredit-note-elevation
Commit 54db7c07a7e7d78a24c876eca72604db1fd4de8744e9463befdb9b8e4b999c93
2 files changed +15 -2 +12 -20
+15 -2
--- src/alerts.c
+++ src/alerts.c
@@ -51,10 +51,11 @@
5151
@ -- f - Forum posts
5252
@ -- k - ** Special: Unsubscribed using /oneclickunsub
5353
@ -- n - New forum threads
5454
@ -- r - Replies to my own forum posts
5555
@ -- t - Ticket changes
56
+@ -- u - Elevation of users' permissions (admins only)
5657
@ -- w - Wiki changes
5758
@ -- x - Edits to forum posts
5859
@ -- Probably different codes will be added in the future. In the future
5960
@ -- we might also add a separate table that allows subscribing to email
6061
@ -- notifications for specific branches or tags or tickets.
@@ -1563,10 +1564,11 @@
15631564
if( g.perm.Read && PB("sc") ) ssub[nsub++] = 'c';
15641565
if( g.perm.RdForum && PB("sf") ) ssub[nsub++] = 'f';
15651566
if( g.perm.RdForum && PB("sn") ) ssub[nsub++] = 'n';
15661567
if( g.perm.RdForum && PB("sr") ) ssub[nsub++] = 'r';
15671568
if( g.perm.RdTkt && PB("st") ) ssub[nsub++] = 't';
1569
+ if( g.perm.Admin && PB("su") ) ssub[nsub++] = 'u';
15681570
if( g.perm.RdWiki && PB("sw") ) ssub[nsub++] = 'w';
15691571
if( g.perm.RdForum && PB("sx") ) ssub[nsub++] = 'x';
15701572
ssub[nsub] = 0;
15711573
zCode = db_text(0,
15721574
"INSERT INTO subscriber(semail,suname,"
@@ -1627,10 +1629,11 @@
16271629
if( g.perm.Read ) cgi_set_parameter_nocopy("sc","1",1);
16281630
if( g.perm.RdForum ) cgi_set_parameter_nocopy("sf","1",1);
16291631
if( g.perm.RdForum ) cgi_set_parameter_nocopy("sn","1",1);
16301632
if( g.perm.RdForum ) cgi_set_parameter_nocopy("sr","1",1);
16311633
if( g.perm.RdTkt ) cgi_set_parameter_nocopy("st","1",1);
1634
+ if( g.perm.Admin ) cgi_set_parameter_nocopy("su","1",1);
16321635
if( g.perm.RdWiki ) cgi_set_parameter_nocopy("sw","1",1);
16331636
}
16341637
@ <p>To receive email notifications for changes to this
16351638
@ repository, fill out the form below and press the "Submit" button.</p>
16361639
form_begin(0, "%R/subscribe");
@@ -1699,10 +1702,14 @@
16991702
}
17001703
if( g.perm.RdWiki ){
17011704
@ <label><input type="checkbox" name="sw" %s(PCK("sw"))> \
17021705
@ Wiki</label><br>
17031706
}
1707
+ if( g.perm.Admin ){
1708
+ @ <label><input type="checkbox" name="su" %s(PCK("su"))> \
1709
+ @ User permission elevation</label>
1710
+ }
17041711
di = PB("di");
17051712
@ </td></tr>
17061713
@ <tr>
17071714
@ <td class="form_label">Delivery:</td>
17081715
@ <td><select size="1" name="di">
@@ -1820,11 +1827,11 @@
18201827
** verifying the email address.
18211828
*/
18221829
void alert_page(void){
18231830
const char *zName = 0; /* Value of the name= query parameter */
18241831
Stmt q; /* For querying the database */
1825
- int sa, sc, sf, st, sw, sx; /* Types of notifications requested */
1832
+ int sa, sc, sf, st, su, sw, sx; /* Types of notifications requested */
18261833
int sn, sr;
18271834
int sdigest = 0, sdonotcall = 0, sverified = 0; /* Other fields */
18281835
int isLogin; /* True if logged in as an individual */
18291836
const char *ssub = 0; /* Subscription flags */
18301837
const char *semail = 0; /* Email address */
@@ -1881,10 +1888,11 @@
18811888
if( g.perm.Read && PB("sc") ) newSsub[nsub++] = 'c';
18821889
if( g.perm.RdForum && PB("sf") ) newSsub[nsub++] = 'f';
18831890
if( g.perm.RdForum && PB("sn") ) newSsub[nsub++] = 'n';
18841891
if( g.perm.RdForum && PB("sr") ) newSsub[nsub++] = 'r';
18851892
if( g.perm.RdTkt && PB("st") ) newSsub[nsub++] = 't';
1893
+ if( g.perm.Admin && PB("su") ) newSsub[nsub++] = 'u';
18861894
if( g.perm.RdWiki && PB("sw") ) newSsub[nsub++] = 'w';
18871895
if( g.perm.RdForum && PB("sx") ) newSsub[nsub++] = 'x';
18881896
newSsub[nsub] = 0;
18891897
ssub = newSsub;
18901898
blob_init(&update, "UPDATE subscriber SET", -1);
@@ -1979,10 +1987,11 @@
19791987
sc = strchr(ssub,'c')!=0;
19801988
sf = strchr(ssub,'f')!=0;
19811989
sn = strchr(ssub,'n')!=0;
19821990
sr = strchr(ssub,'r')!=0;
19831991
st = strchr(ssub,'t')!=0;
1992
+ su = g.perm.Admin && strchr(ssub,'u')!=0;
19841993
sw = strchr(ssub,'w')!=0;
19851994
sx = strchr(ssub,'x')!=0;
19861995
smip = db_column_text(&q, 5);
19871996
mtime = db_column_text(&q, 7);
19881997
sctime = db_column_text(&q, 8);
@@ -2097,11 +2106,15 @@
20972106
@ <label><input type="checkbox" name="st" %s(st?"checked":"")>\
20982107
@ Ticket changes</label><br>
20992108
}
21002109
if( g.perm.RdWiki ){
21012110
@ <label><input type="checkbox" name="sw" %s(sw?"checked":"")>\
2102
- @ Wiki</label>
2111
+ @ Wiki</label><br>
2112
+ }
2113
+ if( g.perm.Admin ){
2114
+ @ <label><input type="checkbox" name="su" %s(su?"checked":"")>\
2115
+ @ User permission elevation</label>
21032116
}
21042117
@ </td></tr>
21052118
if( strchr(ssub,'k')!=0 ){
21062119
@ <tr><td></td><td>&nbsp;&uarr;&nbsp;
21072120
@ Note: User did a one-click unsubscribe</td></tr>
21082121
--- src/alerts.c
+++ src/alerts.c
@@ -51,10 +51,11 @@
51 @ -- f - Forum posts
52 @ -- k - ** Special: Unsubscribed using /oneclickunsub
53 @ -- n - New forum threads
54 @ -- r - Replies to my own forum posts
55 @ -- t - Ticket changes
 
56 @ -- w - Wiki changes
57 @ -- x - Edits to forum posts
58 @ -- Probably different codes will be added in the future. In the future
59 @ -- we might also add a separate table that allows subscribing to email
60 @ -- notifications for specific branches or tags or tickets.
@@ -1563,10 +1564,11 @@
1563 if( g.perm.Read && PB("sc") ) ssub[nsub++] = 'c';
1564 if( g.perm.RdForum && PB("sf") ) ssub[nsub++] = 'f';
1565 if( g.perm.RdForum && PB("sn") ) ssub[nsub++] = 'n';
1566 if( g.perm.RdForum && PB("sr") ) ssub[nsub++] = 'r';
1567 if( g.perm.RdTkt && PB("st") ) ssub[nsub++] = 't';
 
1568 if( g.perm.RdWiki && PB("sw") ) ssub[nsub++] = 'w';
1569 if( g.perm.RdForum && PB("sx") ) ssub[nsub++] = 'x';
1570 ssub[nsub] = 0;
1571 zCode = db_text(0,
1572 "INSERT INTO subscriber(semail,suname,"
@@ -1627,10 +1629,11 @@
1627 if( g.perm.Read ) cgi_set_parameter_nocopy("sc","1",1);
1628 if( g.perm.RdForum ) cgi_set_parameter_nocopy("sf","1",1);
1629 if( g.perm.RdForum ) cgi_set_parameter_nocopy("sn","1",1);
1630 if( g.perm.RdForum ) cgi_set_parameter_nocopy("sr","1",1);
1631 if( g.perm.RdTkt ) cgi_set_parameter_nocopy("st","1",1);
 
1632 if( g.perm.RdWiki ) cgi_set_parameter_nocopy("sw","1",1);
1633 }
1634 @ <p>To receive email notifications for changes to this
1635 @ repository, fill out the form below and press the "Submit" button.</p>
1636 form_begin(0, "%R/subscribe");
@@ -1699,10 +1702,14 @@
1699 }
1700 if( g.perm.RdWiki ){
1701 @ <label><input type="checkbox" name="sw" %s(PCK("sw"))> \
1702 @ Wiki</label><br>
1703 }
 
 
 
 
1704 di = PB("di");
1705 @ </td></tr>
1706 @ <tr>
1707 @ <td class="form_label">Delivery:</td>
1708 @ <td><select size="1" name="di">
@@ -1820,11 +1827,11 @@
1820 ** verifying the email address.
1821 */
1822 void alert_page(void){
1823 const char *zName = 0; /* Value of the name= query parameter */
1824 Stmt q; /* For querying the database */
1825 int sa, sc, sf, st, sw, sx; /* Types of notifications requested */
1826 int sn, sr;
1827 int sdigest = 0, sdonotcall = 0, sverified = 0; /* Other fields */
1828 int isLogin; /* True if logged in as an individual */
1829 const char *ssub = 0; /* Subscription flags */
1830 const char *semail = 0; /* Email address */
@@ -1881,10 +1888,11 @@
1881 if( g.perm.Read && PB("sc") ) newSsub[nsub++] = 'c';
1882 if( g.perm.RdForum && PB("sf") ) newSsub[nsub++] = 'f';
1883 if( g.perm.RdForum && PB("sn") ) newSsub[nsub++] = 'n';
1884 if( g.perm.RdForum && PB("sr") ) newSsub[nsub++] = 'r';
1885 if( g.perm.RdTkt && PB("st") ) newSsub[nsub++] = 't';
 
1886 if( g.perm.RdWiki && PB("sw") ) newSsub[nsub++] = 'w';
1887 if( g.perm.RdForum && PB("sx") ) newSsub[nsub++] = 'x';
1888 newSsub[nsub] = 0;
1889 ssub = newSsub;
1890 blob_init(&update, "UPDATE subscriber SET", -1);
@@ -1979,10 +1987,11 @@
1979 sc = strchr(ssub,'c')!=0;
1980 sf = strchr(ssub,'f')!=0;
1981 sn = strchr(ssub,'n')!=0;
1982 sr = strchr(ssub,'r')!=0;
1983 st = strchr(ssub,'t')!=0;
 
1984 sw = strchr(ssub,'w')!=0;
1985 sx = strchr(ssub,'x')!=0;
1986 smip = db_column_text(&q, 5);
1987 mtime = db_column_text(&q, 7);
1988 sctime = db_column_text(&q, 8);
@@ -2097,11 +2106,15 @@
2097 @ <label><input type="checkbox" name="st" %s(st?"checked":"")>\
2098 @ Ticket changes</label><br>
2099 }
2100 if( g.perm.RdWiki ){
2101 @ <label><input type="checkbox" name="sw" %s(sw?"checked":"")>\
2102 @ Wiki</label>
 
 
 
 
2103 }
2104 @ </td></tr>
2105 if( strchr(ssub,'k')!=0 ){
2106 @ <tr><td></td><td>&nbsp;&uarr;&nbsp;
2107 @ Note: User did a one-click unsubscribe</td></tr>
2108
--- src/alerts.c
+++ src/alerts.c
@@ -51,10 +51,11 @@
51 @ -- f - Forum posts
52 @ -- k - ** Special: Unsubscribed using /oneclickunsub
53 @ -- n - New forum threads
54 @ -- r - Replies to my own forum posts
55 @ -- t - Ticket changes
56 @ -- u - Elevation of users' permissions (admins only)
57 @ -- w - Wiki changes
58 @ -- x - Edits to forum posts
59 @ -- Probably different codes will be added in the future. In the future
60 @ -- we might also add a separate table that allows subscribing to email
61 @ -- notifications for specific branches or tags or tickets.
@@ -1563,10 +1564,11 @@
1564 if( g.perm.Read && PB("sc") ) ssub[nsub++] = 'c';
1565 if( g.perm.RdForum && PB("sf") ) ssub[nsub++] = 'f';
1566 if( g.perm.RdForum && PB("sn") ) ssub[nsub++] = 'n';
1567 if( g.perm.RdForum && PB("sr") ) ssub[nsub++] = 'r';
1568 if( g.perm.RdTkt && PB("st") ) ssub[nsub++] = 't';
1569 if( g.perm.Admin && PB("su") ) ssub[nsub++] = 'u';
1570 if( g.perm.RdWiki && PB("sw") ) ssub[nsub++] = 'w';
1571 if( g.perm.RdForum && PB("sx") ) ssub[nsub++] = 'x';
1572 ssub[nsub] = 0;
1573 zCode = db_text(0,
1574 "INSERT INTO subscriber(semail,suname,"
@@ -1627,10 +1629,11 @@
1629 if( g.perm.Read ) cgi_set_parameter_nocopy("sc","1",1);
1630 if( g.perm.RdForum ) cgi_set_parameter_nocopy("sf","1",1);
1631 if( g.perm.RdForum ) cgi_set_parameter_nocopy("sn","1",1);
1632 if( g.perm.RdForum ) cgi_set_parameter_nocopy("sr","1",1);
1633 if( g.perm.RdTkt ) cgi_set_parameter_nocopy("st","1",1);
1634 if( g.perm.Admin ) cgi_set_parameter_nocopy("su","1",1);
1635 if( g.perm.RdWiki ) cgi_set_parameter_nocopy("sw","1",1);
1636 }
1637 @ <p>To receive email notifications for changes to this
1638 @ repository, fill out the form below and press the "Submit" button.</p>
1639 form_begin(0, "%R/subscribe");
@@ -1699,10 +1702,14 @@
1702 }
1703 if( g.perm.RdWiki ){
1704 @ <label><input type="checkbox" name="sw" %s(PCK("sw"))> \
1705 @ Wiki</label><br>
1706 }
1707 if( g.perm.Admin ){
1708 @ <label><input type="checkbox" name="su" %s(PCK("su"))> \
1709 @ User permission elevation</label>
1710 }
1711 di = PB("di");
1712 @ </td></tr>
1713 @ <tr>
1714 @ <td class="form_label">Delivery:</td>
1715 @ <td><select size="1" name="di">
@@ -1820,11 +1827,11 @@
1827 ** verifying the email address.
1828 */
1829 void alert_page(void){
1830 const char *zName = 0; /* Value of the name= query parameter */
1831 Stmt q; /* For querying the database */
1832 int sa, sc, sf, st, su, sw, sx; /* Types of notifications requested */
1833 int sn, sr;
1834 int sdigest = 0, sdonotcall = 0, sverified = 0; /* Other fields */
1835 int isLogin; /* True if logged in as an individual */
1836 const char *ssub = 0; /* Subscription flags */
1837 const char *semail = 0; /* Email address */
@@ -1881,10 +1888,11 @@
1888 if( g.perm.Read && PB("sc") ) newSsub[nsub++] = 'c';
1889 if( g.perm.RdForum && PB("sf") ) newSsub[nsub++] = 'f';
1890 if( g.perm.RdForum && PB("sn") ) newSsub[nsub++] = 'n';
1891 if( g.perm.RdForum && PB("sr") ) newSsub[nsub++] = 'r';
1892 if( g.perm.RdTkt && PB("st") ) newSsub[nsub++] = 't';
1893 if( g.perm.Admin && PB("su") ) newSsub[nsub++] = 'u';
1894 if( g.perm.RdWiki && PB("sw") ) newSsub[nsub++] = 'w';
1895 if( g.perm.RdForum && PB("sx") ) newSsub[nsub++] = 'x';
1896 newSsub[nsub] = 0;
1897 ssub = newSsub;
1898 blob_init(&update, "UPDATE subscriber SET", -1);
@@ -1979,10 +1987,11 @@
1987 sc = strchr(ssub,'c')!=0;
1988 sf = strchr(ssub,'f')!=0;
1989 sn = strchr(ssub,'n')!=0;
1990 sr = strchr(ssub,'r')!=0;
1991 st = strchr(ssub,'t')!=0;
1992 su = g.perm.Admin && strchr(ssub,'u')!=0;
1993 sw = strchr(ssub,'w')!=0;
1994 sx = strchr(ssub,'x')!=0;
1995 smip = db_column_text(&q, 5);
1996 mtime = db_column_text(&q, 7);
1997 sctime = db_column_text(&q, 8);
@@ -2097,11 +2106,15 @@
2106 @ <label><input type="checkbox" name="st" %s(st?"checked":"")>\
2107 @ Ticket changes</label><br>
2108 }
2109 if( g.perm.RdWiki ){
2110 @ <label><input type="checkbox" name="sw" %s(sw?"checked":"")>\
2111 @ Wiki</label><br>
2112 }
2113 if( g.perm.Admin ){
2114 @ <label><input type="checkbox" name="su" %s(su?"checked":"")>\
2115 @ User permission elevation</label>
2116 }
2117 @ </td></tr>
2118 if( strchr(ssub,'k')!=0 ){
2119 @ <tr><td></td><td>&nbsp;&uarr;&nbsp;
2120 @ Note: User did a one-click unsubscribe</td></tr>
2121
+12 -20
--- src/setupuser.c
+++ src/setupuser.c
@@ -304,28 +304,19 @@
304304
while( zPw[0]=='*' ){ zPw++; }
305305
return zPw[0]!=0;
306306
}
307307
308308
/*
309
-** Return 1 if user capability string zCaps contains the given
310
-** capability letter, else 0.
311
-*/
312
-static int userCapsContain(const char *zCaps, const char letter){
313
- for( ; zCaps && *zCaps; ++zCaps ){
314
- if( letter==*zCaps ) return 1;
315
- }
316
- return 0;
317
-}
318
-
319
-/*
320
-** Return 1 if user capability string zNew contains any capability
321
-** letter which is not in user capability string zOrig, else 0.
322
-*/
323
-static int userCapsAreElevated(const char *zOrig, const char *zNew){
324
- for( ; zNew && *zNew; ++zNew ){
325
- if( !userCapsContain(zOrig, *zNew) ){
326
- return 1;
309
+** Return true if user capability string zNew contains any capability
310
+** letter which is not in user capability string zOrig, else 0. This
311
+** does not take inherited permissions into account. Either argument
312
+** may be NULL.
313
+*/
314
+static int userHasNewCaps(const char *zOrig, const char *zNew){
315
+ for( ; zNew && *zNew; ++zNew ){
316
+ if( !zOrig || strchr(zOrig,*zNew)==0 ){
317
+ return *zNew;
327318
}
328319
}
329320
return 0;
330321
}
331322
@@ -486,14 +477,15 @@
486477
}
487478
admin_log( "Renamed user [%q] to [%q].", zOldLogin, zLogin );
488479
}
489480
db_protect_pop();
490481
setup_incr_cfgcnt();
482
+ @ zOldCaps=%s(zOldCaps) aCap=%s(&aCap[0])<br>
491483
admin_log( "Updated user [%q] with%s capabilities [%q].",
492484
zLogin,
493
- userCapsAreElevated(zOldCaps, &aCap[0])
494
- ? " elevated" : "",
485
+ userHasNewCaps(zOldCaps, &aCap[0])
486
+ ? " new" : "",
495487
&aCap[0] );
496488
if( atoi(PD("all","0"))>0 ){
497489
Blob sql;
498490
char *zErr = 0;
499491
blob_zero(&sql);
500492
--- src/setupuser.c
+++ src/setupuser.c
@@ -304,28 +304,19 @@
304 while( zPw[0]=='*' ){ zPw++; }
305 return zPw[0]!=0;
306 }
307
308 /*
309 ** Return 1 if user capability string zCaps contains the given
310 ** capability letter, else 0.
311 */
312 static int userCapsContain(const char *zCaps, const char letter){
313 for( ; zCaps && *zCaps; ++zCaps ){
314 if( letter==*zCaps ) return 1;
315 }
316 return 0;
317 }
318
319 /*
320 ** Return 1 if user capability string zNew contains any capability
321 ** letter which is not in user capability string zOrig, else 0.
322 */
323 static int userCapsAreElevated(const char *zOrig, const char *zNew){
324 for( ; zNew && *zNew; ++zNew ){
325 if( !userCapsContain(zOrig, *zNew) ){
326 return 1;
327 }
328 }
329 return 0;
330 }
331
@@ -486,14 +477,15 @@
486 }
487 admin_log( "Renamed user [%q] to [%q].", zOldLogin, zLogin );
488 }
489 db_protect_pop();
490 setup_incr_cfgcnt();
 
491 admin_log( "Updated user [%q] with%s capabilities [%q].",
492 zLogin,
493 userCapsAreElevated(zOldCaps, &aCap[0])
494 ? " elevated" : "",
495 &aCap[0] );
496 if( atoi(PD("all","0"))>0 ){
497 Blob sql;
498 char *zErr = 0;
499 blob_zero(&sql);
500
--- src/setupuser.c
+++ src/setupuser.c
@@ -304,28 +304,19 @@
304 while( zPw[0]=='*' ){ zPw++; }
305 return zPw[0]!=0;
306 }
307
308 /*
309 ** Return true if user capability string zNew contains any capability
310 ** letter which is not in user capability string zOrig, else 0. This
311 ** does not take inherited permissions into account. Either argument
312 ** may be NULL.
313 */
314 static int userHasNewCaps(const char *zOrig, const char *zNew){
315 for( ; zNew && *zNew; ++zNew ){
316 if( !zOrig || strchr(zOrig,*zNew)==0 ){
317 return *zNew;
 
 
 
 
 
 
 
 
 
318 }
319 }
320 return 0;
321 }
322
@@ -486,14 +477,15 @@
477 }
478 admin_log( "Renamed user [%q] to [%q].", zOldLogin, zLogin );
479 }
480 db_protect_pop();
481 setup_incr_cfgcnt();
482 @ zOldCaps=%s(zOldCaps) aCap=%s(&aCap[0])<br>
483 admin_log( "Updated user [%q] with%s capabilities [%q].",
484 zLogin,
485 userHasNewCaps(zOldCaps, &aCap[0])
486 ? " new" : "",
487 &aCap[0] );
488 if( atoi(PD("all","0"))>0 ){
489 Blob sql;
490 char *zErr = 0;
491 blob_zero(&sql);
492

Keyboard Shortcuts

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