Fossil SCM
Initial alerts infrastructure for user-elevation notifications. Alerts are not yet sent.
Commit
54db7c07a7e7d78a24c876eca72604db1fd4de8744e9463befdb9b8e4b999c93
Parent
4332ba5d37de55d…
2 files changed
+15
-2
+12
-20
+15
-2
| --- src/alerts.c | ||
| +++ src/alerts.c | ||
| @@ -51,10 +51,11 @@ | ||
| 51 | 51 | @ -- f - Forum posts |
| 52 | 52 | @ -- k - ** Special: Unsubscribed using /oneclickunsub |
| 53 | 53 | @ -- n - New forum threads |
| 54 | 54 | @ -- r - Replies to my own forum posts |
| 55 | 55 | @ -- t - Ticket changes |
| 56 | +@ -- u - Elevation of users' permissions (admins only) | |
| 56 | 57 | @ -- w - Wiki changes |
| 57 | 58 | @ -- x - Edits to forum posts |
| 58 | 59 | @ -- Probably different codes will be added in the future. In the future |
| 59 | 60 | @ -- we might also add a separate table that allows subscribing to email |
| 60 | 61 | @ -- notifications for specific branches or tags or tickets. |
| @@ -1563,10 +1564,11 @@ | ||
| 1563 | 1564 | if( g.perm.Read && PB("sc") ) ssub[nsub++] = 'c'; |
| 1564 | 1565 | if( g.perm.RdForum && PB("sf") ) ssub[nsub++] = 'f'; |
| 1565 | 1566 | if( g.perm.RdForum && PB("sn") ) ssub[nsub++] = 'n'; |
| 1566 | 1567 | if( g.perm.RdForum && PB("sr") ) ssub[nsub++] = 'r'; |
| 1567 | 1568 | if( g.perm.RdTkt && PB("st") ) ssub[nsub++] = 't'; |
| 1569 | + if( g.perm.Admin && PB("su") ) ssub[nsub++] = 'u'; | |
| 1568 | 1570 | if( g.perm.RdWiki && PB("sw") ) ssub[nsub++] = 'w'; |
| 1569 | 1571 | if( g.perm.RdForum && PB("sx") ) ssub[nsub++] = 'x'; |
| 1570 | 1572 | ssub[nsub] = 0; |
| 1571 | 1573 | zCode = db_text(0, |
| 1572 | 1574 | "INSERT INTO subscriber(semail,suname," |
| @@ -1627,10 +1629,11 @@ | ||
| 1627 | 1629 | if( g.perm.Read ) cgi_set_parameter_nocopy("sc","1",1); |
| 1628 | 1630 | if( g.perm.RdForum ) cgi_set_parameter_nocopy("sf","1",1); |
| 1629 | 1631 | if( g.perm.RdForum ) cgi_set_parameter_nocopy("sn","1",1); |
| 1630 | 1632 | if( g.perm.RdForum ) cgi_set_parameter_nocopy("sr","1",1); |
| 1631 | 1633 | if( g.perm.RdTkt ) cgi_set_parameter_nocopy("st","1",1); |
| 1634 | + if( g.perm.Admin ) cgi_set_parameter_nocopy("su","1",1); | |
| 1632 | 1635 | if( g.perm.RdWiki ) cgi_set_parameter_nocopy("sw","1",1); |
| 1633 | 1636 | } |
| 1634 | 1637 | @ <p>To receive email notifications for changes to this |
| 1635 | 1638 | @ repository, fill out the form below and press the "Submit" button.</p> |
| 1636 | 1639 | form_begin(0, "%R/subscribe"); |
| @@ -1699,10 +1702,14 @@ | ||
| 1699 | 1702 | } |
| 1700 | 1703 | if( g.perm.RdWiki ){ |
| 1701 | 1704 | @ <label><input type="checkbox" name="sw" %s(PCK("sw"))> \ |
| 1702 | 1705 | @ Wiki</label><br> |
| 1703 | 1706 | } |
| 1707 | + if( g.perm.Admin ){ | |
| 1708 | + @ <label><input type="checkbox" name="su" %s(PCK("su"))> \ | |
| 1709 | + @ User permission elevation</label> | |
| 1710 | + } | |
| 1704 | 1711 | di = PB("di"); |
| 1705 | 1712 | @ </td></tr> |
| 1706 | 1713 | @ <tr> |
| 1707 | 1714 | @ <td class="form_label">Delivery:</td> |
| 1708 | 1715 | @ <td><select size="1" name="di"> |
| @@ -1820,11 +1827,11 @@ | ||
| 1820 | 1827 | ** verifying the email address. |
| 1821 | 1828 | */ |
| 1822 | 1829 | void alert_page(void){ |
| 1823 | 1830 | const char *zName = 0; /* Value of the name= query parameter */ |
| 1824 | 1831 | 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 */ | |
| 1826 | 1833 | int sn, sr; |
| 1827 | 1834 | int sdigest = 0, sdonotcall = 0, sverified = 0; /* Other fields */ |
| 1828 | 1835 | int isLogin; /* True if logged in as an individual */ |
| 1829 | 1836 | const char *ssub = 0; /* Subscription flags */ |
| 1830 | 1837 | const char *semail = 0; /* Email address */ |
| @@ -1881,10 +1888,11 @@ | ||
| 1881 | 1888 | if( g.perm.Read && PB("sc") ) newSsub[nsub++] = 'c'; |
| 1882 | 1889 | if( g.perm.RdForum && PB("sf") ) newSsub[nsub++] = 'f'; |
| 1883 | 1890 | if( g.perm.RdForum && PB("sn") ) newSsub[nsub++] = 'n'; |
| 1884 | 1891 | if( g.perm.RdForum && PB("sr") ) newSsub[nsub++] = 'r'; |
| 1885 | 1892 | if( g.perm.RdTkt && PB("st") ) newSsub[nsub++] = 't'; |
| 1893 | + if( g.perm.Admin && PB("su") ) newSsub[nsub++] = 'u'; | |
| 1886 | 1894 | if( g.perm.RdWiki && PB("sw") ) newSsub[nsub++] = 'w'; |
| 1887 | 1895 | if( g.perm.RdForum && PB("sx") ) newSsub[nsub++] = 'x'; |
| 1888 | 1896 | newSsub[nsub] = 0; |
| 1889 | 1897 | ssub = newSsub; |
| 1890 | 1898 | blob_init(&update, "UPDATE subscriber SET", -1); |
| @@ -1979,10 +1987,11 @@ | ||
| 1979 | 1987 | sc = strchr(ssub,'c')!=0; |
| 1980 | 1988 | sf = strchr(ssub,'f')!=0; |
| 1981 | 1989 | sn = strchr(ssub,'n')!=0; |
| 1982 | 1990 | sr = strchr(ssub,'r')!=0; |
| 1983 | 1991 | st = strchr(ssub,'t')!=0; |
| 1992 | + su = g.perm.Admin && strchr(ssub,'u')!=0; | |
| 1984 | 1993 | sw = strchr(ssub,'w')!=0; |
| 1985 | 1994 | sx = strchr(ssub,'x')!=0; |
| 1986 | 1995 | smip = db_column_text(&q, 5); |
| 1987 | 1996 | mtime = db_column_text(&q, 7); |
| 1988 | 1997 | sctime = db_column_text(&q, 8); |
| @@ -2097,11 +2106,15 @@ | ||
| 2097 | 2106 | @ <label><input type="checkbox" name="st" %s(st?"checked":"")>\ |
| 2098 | 2107 | @ Ticket changes</label><br> |
| 2099 | 2108 | } |
| 2100 | 2109 | if( g.perm.RdWiki ){ |
| 2101 | 2110 | @ <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> | |
| 2103 | 2116 | } |
| 2104 | 2117 | @ </td></tr> |
| 2105 | 2118 | if( strchr(ssub,'k')!=0 ){ |
| 2106 | 2119 | @ <tr><td></td><td> ↑ |
| 2107 | 2120 | @ Note: User did a one-click unsubscribe</td></tr> |
| 2108 | 2121 |
| --- 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> ↑ |
| 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> ↑ |
| 2120 | @ Note: User did a one-click unsubscribe</td></tr> |
| 2121 |
+12
-20
| --- src/setupuser.c | ||
| +++ src/setupuser.c | ||
| @@ -304,28 +304,19 @@ | ||
| 304 | 304 | while( zPw[0]=='*' ){ zPw++; } |
| 305 | 305 | return zPw[0]!=0; |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | 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; | |
| 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; | |
| 327 | 318 | } |
| 328 | 319 | } |
| 329 | 320 | return 0; |
| 330 | 321 | } |
| 331 | 322 | |
| @@ -486,14 +477,15 @@ | ||
| 486 | 477 | } |
| 487 | 478 | admin_log( "Renamed user [%q] to [%q].", zOldLogin, zLogin ); |
| 488 | 479 | } |
| 489 | 480 | db_protect_pop(); |
| 490 | 481 | setup_incr_cfgcnt(); |
| 482 | + @ zOldCaps=%s(zOldCaps) aCap=%s(&aCap[0])<br> | |
| 491 | 483 | admin_log( "Updated user [%q] with%s capabilities [%q].", |
| 492 | 484 | zLogin, |
| 493 | - userCapsAreElevated(zOldCaps, &aCap[0]) | |
| 494 | - ? " elevated" : "", | |
| 485 | + userHasNewCaps(zOldCaps, &aCap[0]) | |
| 486 | + ? " new" : "", | |
| 495 | 487 | &aCap[0] ); |
| 496 | 488 | if( atoi(PD("all","0"))>0 ){ |
| 497 | 489 | Blob sql; |
| 498 | 490 | char *zErr = 0; |
| 499 | 491 | blob_zero(&sql); |
| 500 | 492 |
| --- 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 |