Fossil SCM
Add the --private option to the "scrub" command. Add any manifest that includes the "private" tag to the list of private artifacts if it is not there already.
Commit
ef1c65a4287c0ad3b3f42c7c14dd9ffaeb90ffe4
Parent
1aae2b582e9afc7…
2 files changed
+23
-14
+6
+23
-14
| --- src/rebuild.c | ||
| +++ src/rebuild.c | ||
| @@ -540,19 +540,20 @@ | ||
| 540 | 540 | } |
| 541 | 541 | } |
| 542 | 542 | |
| 543 | 543 | /* |
| 544 | 544 | ** COMMAND: scrub |
| 545 | -** %fossil scrub [--verily] [--force] [REPOSITORY] | |
| 545 | +** %fossil scrub [--verily] [--force] [--private] [REPOSITORY] | |
| 546 | 546 | ** |
| 547 | 547 | ** The command removes sensitive information (such as passwords) from a |
| 548 | 548 | ** repository so that the respository can be sent to an untrusted reader. |
| 549 | 549 | ** |
| 550 | 550 | ** By default, only passwords are removed. However, if the --verily option |
| 551 | 551 | ** is added, then private branches, concealed email addresses, IP |
| 552 | 552 | ** addresses of correspondents, and similar privacy-sensitive fields |
| 553 | -** are also purged. | |
| 553 | +** are also purged. If the --private option is used, then only private | |
| 554 | +** branches are removed and all other information is left intact. | |
| 554 | 555 | ** |
| 555 | 556 | ** This command permanently deletes the scrubbed information. The effects |
| 556 | 557 | ** of this command are irreversible. Use with caution. |
| 557 | 558 | ** |
| 558 | 559 | ** The user is prompted to confirm the scrub unless the --force option |
| @@ -559,10 +560,11 @@ | ||
| 559 | 560 | ** is used. |
| 560 | 561 | */ |
| 561 | 562 | void scrub_cmd(void){ |
| 562 | 563 | int bVerily = find_option("verily",0,0)!=0; |
| 563 | 564 | int bForce = find_option("force", "f", 0)!=0; |
| 565 | + int privateOnly = find_option("private",0,0)!=0; | |
| 564 | 566 | int bNeedRebuild = 0; |
| 565 | 567 | if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); |
| 566 | 568 | if( g.argc==2 ){ |
| 567 | 569 | db_must_be_within_tree(); |
| 568 | 570 | }else{ |
| @@ -569,30 +571,37 @@ | ||
| 569 | 571 | db_open_repository(g.argv[2]); |
| 570 | 572 | } |
| 571 | 573 | if( !bForce ){ |
| 572 | 574 | Blob ans; |
| 573 | 575 | blob_zero(&ans); |
| 574 | - prompt_user("Scrubbing the repository will permanently remove user\n" | |
| 575 | - "passwords and other information. Changes cannot be undone.\n" | |
| 576 | - "Continue (y/N)? ", &ans); | |
| 576 | + prompt_user("Scrubbing the repository will permanently information.\n" | |
| 577 | + "Changes cannot be undone. Continue (y/N)? ", &ans); | |
| 577 | 578 | if( blob_str(&ans)[0]!='y' ){ |
| 578 | 579 | fossil_exit(1); |
| 579 | 580 | } |
| 580 | 581 | } |
| 581 | 582 | db_begin_transaction(); |
| 582 | - db_multi_exec( | |
| 583 | - "UPDATE user SET pw='';" | |
| 584 | - "DELETE FROM config WHERE name GLOB 'last-sync-*';" | |
| 585 | - ); | |
| 586 | - if( bVerily ){ | |
| 583 | + if( privateOnly || bVerily ){ | |
| 587 | 584 | bNeedRebuild = db_exists("SELECT 1 FROM private"); |
| 588 | 585 | db_multi_exec( |
| 589 | - "DELETE FROM concealed;" | |
| 590 | - "UPDATE rcvfrom SET ipaddr='unknown';" | |
| 591 | - "UPDATE user SET photo=NULL, info='';" | |
| 592 | - "INSERT INTO shun SELECT uuid FROM blob WHERE rid IN private;" | |
| 586 | + "DELETE FROM blob WHERE rid IN private;" | |
| 587 | + "DELETE FROM delta WHERE rid IN private;" | |
| 588 | + "DELETE FROM private;" | |
| 589 | + ); | |
| 590 | + } | |
| 591 | + if( !privateOnly ){ | |
| 592 | + db_multi_exec( | |
| 593 | + "UPDATE user SET pw='';" | |
| 594 | + "DELETE FROM config WHERE name GLOB 'last-sync-*';" | |
| 593 | 595 | ); |
| 596 | + if( bVerily ){ | |
| 597 | + db_multi_exec( | |
| 598 | + "DELETE FROM concealed;" | |
| 599 | + "UPDATE rcvfrom SET ipaddr='unknown';" | |
| 600 | + "UPDATE user SET photo=NULL, info='';" | |
| 601 | + ); | |
| 602 | + } | |
| 594 | 603 | } |
| 595 | 604 | if( !bNeedRebuild ){ |
| 596 | 605 | db_end_transaction(0); |
| 597 | 606 | db_multi_exec("VACUUM;"); |
| 598 | 607 | }else{ |
| 599 | 608 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -540,19 +540,20 @@ | |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | /* |
| 544 | ** COMMAND: scrub |
| 545 | ** %fossil scrub [--verily] [--force] [REPOSITORY] |
| 546 | ** |
| 547 | ** The command removes sensitive information (such as passwords) from a |
| 548 | ** repository so that the respository can be sent to an untrusted reader. |
| 549 | ** |
| 550 | ** By default, only passwords are removed. However, if the --verily option |
| 551 | ** is added, then private branches, concealed email addresses, IP |
| 552 | ** addresses of correspondents, and similar privacy-sensitive fields |
| 553 | ** are also purged. |
| 554 | ** |
| 555 | ** This command permanently deletes the scrubbed information. The effects |
| 556 | ** of this command are irreversible. Use with caution. |
| 557 | ** |
| 558 | ** The user is prompted to confirm the scrub unless the --force option |
| @@ -559,10 +560,11 @@ | |
| 559 | ** is used. |
| 560 | */ |
| 561 | void scrub_cmd(void){ |
| 562 | int bVerily = find_option("verily",0,0)!=0; |
| 563 | int bForce = find_option("force", "f", 0)!=0; |
| 564 | int bNeedRebuild = 0; |
| 565 | if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); |
| 566 | if( g.argc==2 ){ |
| 567 | db_must_be_within_tree(); |
| 568 | }else{ |
| @@ -569,30 +571,37 @@ | |
| 569 | db_open_repository(g.argv[2]); |
| 570 | } |
| 571 | if( !bForce ){ |
| 572 | Blob ans; |
| 573 | blob_zero(&ans); |
| 574 | prompt_user("Scrubbing the repository will permanently remove user\n" |
| 575 | "passwords and other information. Changes cannot be undone.\n" |
| 576 | "Continue (y/N)? ", &ans); |
| 577 | if( blob_str(&ans)[0]!='y' ){ |
| 578 | fossil_exit(1); |
| 579 | } |
| 580 | } |
| 581 | db_begin_transaction(); |
| 582 | db_multi_exec( |
| 583 | "UPDATE user SET pw='';" |
| 584 | "DELETE FROM config WHERE name GLOB 'last-sync-*';" |
| 585 | ); |
| 586 | if( bVerily ){ |
| 587 | bNeedRebuild = db_exists("SELECT 1 FROM private"); |
| 588 | db_multi_exec( |
| 589 | "DELETE FROM concealed;" |
| 590 | "UPDATE rcvfrom SET ipaddr='unknown';" |
| 591 | "UPDATE user SET photo=NULL, info='';" |
| 592 | "INSERT INTO shun SELECT uuid FROM blob WHERE rid IN private;" |
| 593 | ); |
| 594 | } |
| 595 | if( !bNeedRebuild ){ |
| 596 | db_end_transaction(0); |
| 597 | db_multi_exec("VACUUM;"); |
| 598 | }else{ |
| 599 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -540,19 +540,20 @@ | |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | /* |
| 544 | ** COMMAND: scrub |
| 545 | ** %fossil scrub [--verily] [--force] [--private] [REPOSITORY] |
| 546 | ** |
| 547 | ** The command removes sensitive information (such as passwords) from a |
| 548 | ** repository so that the respository can be sent to an untrusted reader. |
| 549 | ** |
| 550 | ** By default, only passwords are removed. However, if the --verily option |
| 551 | ** is added, then private branches, concealed email addresses, IP |
| 552 | ** addresses of correspondents, and similar privacy-sensitive fields |
| 553 | ** are also purged. If the --private option is used, then only private |
| 554 | ** branches are removed and all other information is left intact. |
| 555 | ** |
| 556 | ** This command permanently deletes the scrubbed information. The effects |
| 557 | ** of this command are irreversible. Use with caution. |
| 558 | ** |
| 559 | ** The user is prompted to confirm the scrub unless the --force option |
| @@ -559,10 +560,11 @@ | |
| 560 | ** is used. |
| 561 | */ |
| 562 | void scrub_cmd(void){ |
| 563 | int bVerily = find_option("verily",0,0)!=0; |
| 564 | int bForce = find_option("force", "f", 0)!=0; |
| 565 | int privateOnly = find_option("private",0,0)!=0; |
| 566 | int bNeedRebuild = 0; |
| 567 | if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?"); |
| 568 | if( g.argc==2 ){ |
| 569 | db_must_be_within_tree(); |
| 570 | }else{ |
| @@ -569,30 +571,37 @@ | |
| 571 | db_open_repository(g.argv[2]); |
| 572 | } |
| 573 | if( !bForce ){ |
| 574 | Blob ans; |
| 575 | blob_zero(&ans); |
| 576 | prompt_user("Scrubbing the repository will permanently information.\n" |
| 577 | "Changes cannot be undone. Continue (y/N)? ", &ans); |
| 578 | if( blob_str(&ans)[0]!='y' ){ |
| 579 | fossil_exit(1); |
| 580 | } |
| 581 | } |
| 582 | db_begin_transaction(); |
| 583 | if( privateOnly || bVerily ){ |
| 584 | bNeedRebuild = db_exists("SELECT 1 FROM private"); |
| 585 | db_multi_exec( |
| 586 | "DELETE FROM blob WHERE rid IN private;" |
| 587 | "DELETE FROM delta WHERE rid IN private;" |
| 588 | "DELETE FROM private;" |
| 589 | ); |
| 590 | } |
| 591 | if( !privateOnly ){ |
| 592 | db_multi_exec( |
| 593 | "UPDATE user SET pw='';" |
| 594 | "DELETE FROM config WHERE name GLOB 'last-sync-*';" |
| 595 | ); |
| 596 | if( bVerily ){ |
| 597 | db_multi_exec( |
| 598 | "DELETE FROM concealed;" |
| 599 | "UPDATE rcvfrom SET ipaddr='unknown';" |
| 600 | "UPDATE user SET photo=NULL, info='';" |
| 601 | ); |
| 602 | } |
| 603 | } |
| 604 | if( !bNeedRebuild ){ |
| 605 | db_end_transaction(0); |
| 606 | db_multi_exec("VACUUM;"); |
| 607 | }else{ |
| 608 |
+6
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -204,10 +204,16 @@ | ||
| 204 | 204 | break; |
| 205 | 205 | } |
| 206 | 206 | case TAG_USER: { |
| 207 | 207 | zCol = "euser"; |
| 208 | 208 | break; |
| 209 | + } | |
| 210 | + case TAG_PRIVATE: { | |
| 211 | + db_multi_exec( | |
| 212 | + "INSERT OR IGNORE INTO private(rid) VALUES(%d);", | |
| 213 | + rid | |
| 214 | + ); | |
| 209 | 215 | } |
| 210 | 216 | } |
| 211 | 217 | if( zCol ){ |
| 212 | 218 | db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid); |
| 213 | 219 | if( tagid==TAG_COMMENT ){ |
| 214 | 220 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -204,10 +204,16 @@ | |
| 204 | break; |
| 205 | } |
| 206 | case TAG_USER: { |
| 207 | zCol = "euser"; |
| 208 | break; |
| 209 | } |
| 210 | } |
| 211 | if( zCol ){ |
| 212 | db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid); |
| 213 | if( tagid==TAG_COMMENT ){ |
| 214 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -204,10 +204,16 @@ | |
| 204 | break; |
| 205 | } |
| 206 | case TAG_USER: { |
| 207 | zCol = "euser"; |
| 208 | break; |
| 209 | } |
| 210 | case TAG_PRIVATE: { |
| 211 | db_multi_exec( |
| 212 | "INSERT OR IGNORE INTO private(rid) VALUES(%d);", |
| 213 | rid |
| 214 | ); |
| 215 | } |
| 216 | } |
| 217 | if( zCol ){ |
| 218 | db_multi_exec("UPDATE event SET %s=%Q WHERE objid=%d", zCol, zValue, rid); |
| 219 | if( tagid==TAG_COMMENT ){ |
| 220 |