Fossil SCM
Send notifications to subscribers with a 'u' subscription when setup_uedit adds new permissions to a user.
Commit
a69c933e0cddf1f9274e1ef8b170b3c59d34924c3bab98a9764912ecc18ce07d
Parent
54db7c07a7e7d78…
1 file changed
+60
-4
+60
-4
| --- src/setupuser.c | ||
| +++ src/setupuser.c | ||
| @@ -317,10 +317,61 @@ | ||
| 317 | 317 | return *zNew; |
| 318 | 318 | } |
| 319 | 319 | } |
| 320 | 320 | return 0; |
| 321 | 321 | } |
| 322 | + | |
| 323 | +/* | |
| 324 | +** Sends notification of user permission elevation changes to all | |
| 325 | +** subscribers with a "u" subscription. | |
| 326 | +*/ | |
| 327 | +static void alert_user_elevation(const char *zLogin, /*Affected user*/ | |
| 328 | + int uid, /*[user].uid*/ | |
| 329 | + const char *zOrigCaps,/*Old caps*/ | |
| 330 | + const char *zNewCaps /*New caps*/){ | |
| 331 | + Blob hdr, body; | |
| 332 | + Stmt q; | |
| 333 | + int nUsed; | |
| 334 | + AlertSender *pSender; | |
| 335 | + char *zSubname = db_get("email-subname", "[Fossil Repo]"); | |
| 336 | + char *zURL = db_get("email-url",0); | |
| 337 | + char * zSubject = mprintf("User [%q] permissions elevated", zLogin); | |
| 338 | + blob_init(&body, 0, 0); | |
| 339 | + blob_init(&hdr, 0, 0); | |
| 340 | + blob_appendf(&body, "Permissions for user [%q] where elevated " | |
| 341 | + "from [%q] to [%q] by user [%q].\n", | |
| 342 | + zLogin, zOrigCaps, zNewCaps, g.zLogin); | |
| 343 | + if( zURL ){ | |
| 344 | + blob_appendf(&body, "User editor: %s/setup_uedit?uid=%d\n", zURL, uid); | |
| 345 | + } | |
| 346 | + nUsed = blob_size(&body); | |
| 347 | + pSender = alert_sender_new(0, 0); | |
| 348 | + db_prepare(&q, | |
| 349 | + "SELECT semail, hex(subscriberCode)" | |
| 350 | + " FROM subscriber, user " | |
| 351 | + " WHERE sverified AND NOT sdonotcall" | |
| 352 | + " AND suname=login" | |
| 353 | + " AND fullcap(cap) GLOB '*a*'" | |
| 354 | + " AND ssub GLOB '*u*'"); | |
| 355 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 356 | + const char *zTo = db_column_text(&q, 0); | |
| 357 | + blob_truncate(&hdr, 0); | |
| 358 | + blob_appendf(&hdr, "To: <%s>\r\nSubject: %s %s\r\n", | |
| 359 | + zTo, zSubname, zSubject); | |
| 360 | + if( zURL ){ | |
| 361 | + const char *zCode = db_column_text(&q, 1); | |
| 362 | + blob_appendf(&body,"\n-- \nSubscription info: %s/alerts/%s\n", | |
| 363 | + zURL, zCode); | |
| 364 | + } | |
| 365 | + alert_send(pSender, &hdr, &body, 0); | |
| 366 | + } | |
| 367 | + db_finalize(&q); | |
| 368 | + alert_sender_free(pSender); | |
| 369 | + fossil_free(zURL); | |
| 370 | + fossil_free(zSubname); | |
| 371 | + fossil_free(zSubject); | |
| 372 | +} | |
| 322 | 373 | |
| 323 | 374 | /* |
| 324 | 375 | ** WEBPAGE: setup_uedit |
| 325 | 376 | ** |
| 326 | 377 | ** Edit information about a user or create a new user. |
| @@ -410,10 +461,11 @@ | ||
| 410 | 461 | }else if( !cgi_csrf_safe(2) ){ |
| 411 | 462 | /* This might be a cross-site request forgery, so ignore it */ |
| 412 | 463 | }else{ |
| 413 | 464 | /* We have all the information we need to make the change to the user */ |
| 414 | 465 | char c; |
| 466 | + int bHasNewCaps = 0 /* 1 if user's permissions are increased */; | |
| 415 | 467 | char aCap[70], zNm[4]; |
| 416 | 468 | zNm[0] = 'a'; |
| 417 | 469 | zNm[2] = 0; |
| 418 | 470 | for(i=0, c='a'; c<='z'; c++){ |
| 419 | 471 | zNm[1] = c; |
| @@ -430,10 +482,11 @@ | ||
| 430 | 482 | a[c&0x7f] = P(zNm)!=0; |
| 431 | 483 | if( a[c&0x7f] ) aCap[i++] = c; |
| 432 | 484 | } |
| 433 | 485 | |
| 434 | 486 | aCap[i] = 0; |
| 487 | + bHasNewCaps = userHasNewCaps(zOldCaps, &aCap[0]); | |
| 435 | 488 | zPw = P("pw"); |
| 436 | 489 | zLogin = P("login"); |
| 437 | 490 | if( strlen(zLogin)==0 ){ |
| 438 | 491 | const char *zRef = cgi_referer("setup_ulist"); |
| 439 | 492 | style_header("User Creation Error"); |
| @@ -477,15 +530,12 @@ | ||
| 477 | 530 | } |
| 478 | 531 | admin_log( "Renamed user [%q] to [%q].", zOldLogin, zLogin ); |
| 479 | 532 | } |
| 480 | 533 | db_protect_pop(); |
| 481 | 534 | setup_incr_cfgcnt(); |
| 482 | - @ zOldCaps=%s(zOldCaps) aCap=%s(&aCap[0])<br> | |
| 483 | 535 | admin_log( "Updated user [%q] with%s capabilities [%q].", |
| 484 | - zLogin, | |
| 485 | - userHasNewCaps(zOldCaps, &aCap[0]) | |
| 486 | - ? " new" : "", | |
| 536 | + zLogin, bHasNewCaps ? " new" : "", | |
| 487 | 537 | &aCap[0] ); |
| 488 | 538 | if( atoi(PD("all","0"))>0 ){ |
| 489 | 539 | Blob sql; |
| 490 | 540 | char *zErr = 0; |
| 491 | 541 | blob_zero(&sql); |
| @@ -536,13 +586,19 @@ | ||
| 536 | 586 | @ <span class="loginError">%h(zErr)</span> |
| 537 | 587 | @ |
| 538 | 588 | @ <p><a href="setup_uedit?id=%d(uid)&referer=%T(zRef)"> |
| 539 | 589 | @ [Bummer]</a></p> |
| 540 | 590 | style_finish_page(); |
| 591 | + if( bHasNewCaps ){ | |
| 592 | + alert_user_elevation(zLogin, uid, zOldCaps, &aCap[0]); | |
| 593 | + } | |
| 541 | 594 | return; |
| 542 | 595 | } |
| 543 | 596 | } |
| 597 | + if( bHasNewCaps ){ | |
| 598 | + alert_user_elevation(zLogin, uid, zOldCaps, &aCap[0]); | |
| 599 | + } | |
| 544 | 600 | cgi_redirect(cgi_referer("setup_ulist")); |
| 545 | 601 | return; |
| 546 | 602 | } |
| 547 | 603 | |
| 548 | 604 | /* Load the existing information about the user, if any |
| 549 | 605 |
| --- src/setupuser.c | |
| +++ src/setupuser.c | |
| @@ -317,10 +317,61 @@ | |
| 317 | return *zNew; |
| 318 | } |
| 319 | } |
| 320 | return 0; |
| 321 | } |
| 322 | |
| 323 | /* |
| 324 | ** WEBPAGE: setup_uedit |
| 325 | ** |
| 326 | ** Edit information about a user or create a new user. |
| @@ -410,10 +461,11 @@ | |
| 410 | }else if( !cgi_csrf_safe(2) ){ |
| 411 | /* This might be a cross-site request forgery, so ignore it */ |
| 412 | }else{ |
| 413 | /* We have all the information we need to make the change to the user */ |
| 414 | char c; |
| 415 | char aCap[70], zNm[4]; |
| 416 | zNm[0] = 'a'; |
| 417 | zNm[2] = 0; |
| 418 | for(i=0, c='a'; c<='z'; c++){ |
| 419 | zNm[1] = c; |
| @@ -430,10 +482,11 @@ | |
| 430 | a[c&0x7f] = P(zNm)!=0; |
| 431 | if( a[c&0x7f] ) aCap[i++] = c; |
| 432 | } |
| 433 | |
| 434 | aCap[i] = 0; |
| 435 | zPw = P("pw"); |
| 436 | zLogin = P("login"); |
| 437 | if( strlen(zLogin)==0 ){ |
| 438 | const char *zRef = cgi_referer("setup_ulist"); |
| 439 | style_header("User Creation Error"); |
| @@ -477,15 +530,12 @@ | |
| 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); |
| @@ -536,13 +586,19 @@ | |
| 536 | @ <span class="loginError">%h(zErr)</span> |
| 537 | @ |
| 538 | @ <p><a href="setup_uedit?id=%d(uid)&referer=%T(zRef)"> |
| 539 | @ [Bummer]</a></p> |
| 540 | style_finish_page(); |
| 541 | return; |
| 542 | } |
| 543 | } |
| 544 | cgi_redirect(cgi_referer("setup_ulist")); |
| 545 | return; |
| 546 | } |
| 547 | |
| 548 | /* Load the existing information about the user, if any |
| 549 |
| --- src/setupuser.c | |
| +++ src/setupuser.c | |
| @@ -317,10 +317,61 @@ | |
| 317 | return *zNew; |
| 318 | } |
| 319 | } |
| 320 | return 0; |
| 321 | } |
| 322 | |
| 323 | /* |
| 324 | ** Sends notification of user permission elevation changes to all |
| 325 | ** subscribers with a "u" subscription. |
| 326 | */ |
| 327 | static void alert_user_elevation(const char *zLogin, /*Affected user*/ |
| 328 | int uid, /*[user].uid*/ |
| 329 | const char *zOrigCaps,/*Old caps*/ |
| 330 | const char *zNewCaps /*New caps*/){ |
| 331 | Blob hdr, body; |
| 332 | Stmt q; |
| 333 | int nUsed; |
| 334 | AlertSender *pSender; |
| 335 | char *zSubname = db_get("email-subname", "[Fossil Repo]"); |
| 336 | char *zURL = db_get("email-url",0); |
| 337 | char * zSubject = mprintf("User [%q] permissions elevated", zLogin); |
| 338 | blob_init(&body, 0, 0); |
| 339 | blob_init(&hdr, 0, 0); |
| 340 | blob_appendf(&body, "Permissions for user [%q] where elevated " |
| 341 | "from [%q] to [%q] by user [%q].\n", |
| 342 | zLogin, zOrigCaps, zNewCaps, g.zLogin); |
| 343 | if( zURL ){ |
| 344 | blob_appendf(&body, "User editor: %s/setup_uedit?uid=%d\n", zURL, uid); |
| 345 | } |
| 346 | nUsed = blob_size(&body); |
| 347 | pSender = alert_sender_new(0, 0); |
| 348 | db_prepare(&q, |
| 349 | "SELECT semail, hex(subscriberCode)" |
| 350 | " FROM subscriber, user " |
| 351 | " WHERE sverified AND NOT sdonotcall" |
| 352 | " AND suname=login" |
| 353 | " AND fullcap(cap) GLOB '*a*'" |
| 354 | " AND ssub GLOB '*u*'"); |
| 355 | while( db_step(&q)==SQLITE_ROW ){ |
| 356 | const char *zTo = db_column_text(&q, 0); |
| 357 | blob_truncate(&hdr, 0); |
| 358 | blob_appendf(&hdr, "To: <%s>\r\nSubject: %s %s\r\n", |
| 359 | zTo, zSubname, zSubject); |
| 360 | if( zURL ){ |
| 361 | const char *zCode = db_column_text(&q, 1); |
| 362 | blob_appendf(&body,"\n-- \nSubscription info: %s/alerts/%s\n", |
| 363 | zURL, zCode); |
| 364 | } |
| 365 | alert_send(pSender, &hdr, &body, 0); |
| 366 | } |
| 367 | db_finalize(&q); |
| 368 | alert_sender_free(pSender); |
| 369 | fossil_free(zURL); |
| 370 | fossil_free(zSubname); |
| 371 | fossil_free(zSubject); |
| 372 | } |
| 373 | |
| 374 | /* |
| 375 | ** WEBPAGE: setup_uedit |
| 376 | ** |
| 377 | ** Edit information about a user or create a new user. |
| @@ -410,10 +461,11 @@ | |
| 461 | }else if( !cgi_csrf_safe(2) ){ |
| 462 | /* This might be a cross-site request forgery, so ignore it */ |
| 463 | }else{ |
| 464 | /* We have all the information we need to make the change to the user */ |
| 465 | char c; |
| 466 | int bHasNewCaps = 0 /* 1 if user's permissions are increased */; |
| 467 | char aCap[70], zNm[4]; |
| 468 | zNm[0] = 'a'; |
| 469 | zNm[2] = 0; |
| 470 | for(i=0, c='a'; c<='z'; c++){ |
| 471 | zNm[1] = c; |
| @@ -430,10 +482,11 @@ | |
| 482 | a[c&0x7f] = P(zNm)!=0; |
| 483 | if( a[c&0x7f] ) aCap[i++] = c; |
| 484 | } |
| 485 | |
| 486 | aCap[i] = 0; |
| 487 | bHasNewCaps = userHasNewCaps(zOldCaps, &aCap[0]); |
| 488 | zPw = P("pw"); |
| 489 | zLogin = P("login"); |
| 490 | if( strlen(zLogin)==0 ){ |
| 491 | const char *zRef = cgi_referer("setup_ulist"); |
| 492 | style_header("User Creation Error"); |
| @@ -477,15 +530,12 @@ | |
| 530 | } |
| 531 | admin_log( "Renamed user [%q] to [%q].", zOldLogin, zLogin ); |
| 532 | } |
| 533 | db_protect_pop(); |
| 534 | setup_incr_cfgcnt(); |
| 535 | admin_log( "Updated user [%q] with%s capabilities [%q].", |
| 536 | zLogin, bHasNewCaps ? " new" : "", |
| 537 | &aCap[0] ); |
| 538 | if( atoi(PD("all","0"))>0 ){ |
| 539 | Blob sql; |
| 540 | char *zErr = 0; |
| 541 | blob_zero(&sql); |
| @@ -536,13 +586,19 @@ | |
| 586 | @ <span class="loginError">%h(zErr)</span> |
| 587 | @ |
| 588 | @ <p><a href="setup_uedit?id=%d(uid)&referer=%T(zRef)"> |
| 589 | @ [Bummer]</a></p> |
| 590 | style_finish_page(); |
| 591 | if( bHasNewCaps ){ |
| 592 | alert_user_elevation(zLogin, uid, zOldCaps, &aCap[0]); |
| 593 | } |
| 594 | return; |
| 595 | } |
| 596 | } |
| 597 | if( bHasNewCaps ){ |
| 598 | alert_user_elevation(zLogin, uid, zOldCaps, &aCap[0]); |
| 599 | } |
| 600 | cgi_redirect(cgi_referer("setup_ulist")); |
| 601 | return; |
| 602 | } |
| 603 | |
| 604 | /* Load the existing information about the user, if any |
| 605 |