Fossil SCM
Show the table of public phantoms directly on the security audit page. Dig deeper looking for the source of public phantoms.
Commit
941280ae0aa53d1da49de9d20b6f6b3771039c7a6bf355ca97323c8c262a1aaa
Parent
83db244395090d8…
2 files changed
+105
-53
+4
-7
+105
-53
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -968,10 +968,75 @@ | ||
| 968 | 968 | @ summary TEXT, -- Summary comment for the object |
| 969 | 969 | @ ref TEXT -- hash of an object to link against |
| 970 | 970 | @ ); |
| 971 | 971 | @ CREATE INDEX desctype ON description(summary) WHERE summary='unknown'; |
| 972 | 972 | ; |
| 973 | + | |
| 974 | +/* | |
| 975 | +** Attempt to describe all phantom artifacts. The artifacts are | |
| 976 | +** already loaded into the description table and have summary='unknown'. | |
| 977 | +** This routine attempts to generate a better summary, and possibly | |
| 978 | +** fill in the ref field. | |
| 979 | +*/ | |
| 980 | +static void describe_unknown_artifacts(){ | |
| 981 | + /* Try to figure out the origin of unknown artifacts */ | |
| 982 | + db_multi_exec( | |
| 983 | + "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 984 | + " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 985 | + " CASE WHEN plink.isprim THEN '' ELSE 'merge ' END ||\n" | |
| 986 | + " 'parent of check-in', blob.uuid\n" | |
| 987 | + " FROM description, plink, blob\n" | |
| 988 | + " WHERE description.summary='unknown'\n" | |
| 989 | + " AND plink.pid=description.rid\n" | |
| 990 | + " AND blob.rid=plink.cid;" | |
| 991 | + ); | |
| 992 | + db_multi_exec( | |
| 993 | + "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 994 | + " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 995 | + " 'child of check-in', blob.uuid\n" | |
| 996 | + " FROM description, plink, blob\n" | |
| 997 | + " WHERE description.summary='unknown'\n" | |
| 998 | + " AND plink.cid=description.rid\n" | |
| 999 | + " AND blob.rid=plink.pid;" | |
| 1000 | + ); | |
| 1001 | + db_multi_exec( | |
| 1002 | + "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 1003 | + " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 1004 | + " 'check-in referenced by \"'||tag.tagname ||'\" tag',\n" | |
| 1005 | + " blob.uuid\n" | |
| 1006 | + " FROM description, tagxref, tag, blob\n" | |
| 1007 | + " WHERE description.summary='unknown'\n" | |
| 1008 | + " AND tagxref.origid=description.rid\n" | |
| 1009 | + " AND tag.tagid=tagxref.tagid\n" | |
| 1010 | + " AND blob.rid=tagxref.srcid;" | |
| 1011 | + ); | |
| 1012 | + db_multi_exec( | |
| 1013 | + "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 1014 | + " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 1015 | + " 'file \"'||filename.name||'\"',\n" | |
| 1016 | + " blob.uuid\n" | |
| 1017 | + " FROM description, mlink, filename, blob\n" | |
| 1018 | + " WHERE description.summary='unknown'\n" | |
| 1019 | + " AND mlink.fid=description.rid\n" | |
| 1020 | + " AND blob.rid=mlink.mid\n" | |
| 1021 | + " AND filename.fnid=mlink.fnid;" | |
| 1022 | + ); | |
| 1023 | + if( !db_exists("SELECT 1 FROM description WHERE summary='unknown'") ){ | |
| 1024 | + return; | |
| 1025 | + } | |
| 1026 | + add_content_sql_commands(g.db); | |
| 1027 | + db_multi_exec( | |
| 1028 | + "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 1029 | + " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 1030 | + " 'referenced by cluster', blob.uuid\n" | |
| 1031 | + " FROM description, tagxref, blob\n" | |
| 1032 | + " WHERE description.summary='unknown'\n" | |
| 1033 | + " AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n" | |
| 1034 | + " AND blob.rid=tagxref.rid\n" | |
| 1035 | + " AND content(blob.uuid) GLOB ('*M '||blob.uuid||'*');" | |
| 1036 | + ); | |
| 1037 | +} | |
| 973 | 1038 | |
| 974 | 1039 | /* |
| 975 | 1040 | ** Create the description table if it does not already exists. |
| 976 | 1041 | ** Populate fields of this table with descriptions for all artifacts |
| 977 | 1042 | ** whose RID matches the SQL expression in zWhere. |
| @@ -1120,32 +1185,13 @@ | ||
| 1120 | 1185 | /* Mark private elements */ |
| 1121 | 1186 | db_multi_exec( |
| 1122 | 1187 | "UPDATE description SET isPrivate=1 WHERE rid IN private" |
| 1123 | 1188 | ); |
| 1124 | 1189 | |
| 1125 | - /* Try to figure out the origin of unknown artifacts */ | |
| 1126 | - db_multi_exec( | |
| 1127 | - "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 1128 | - " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 1129 | - " CASE WHEN plink.isprim THEN '' ELSE 'merge ' END ||\n" | |
| 1130 | - " 'parent of check-in', blob.uuid\n" | |
| 1131 | - " FROM description, plink, blob\n" | |
| 1132 | - " WHERE description.summary='unknown'\n" | |
| 1133 | - " AND plink.pid=description.rid\n" | |
| 1134 | - " AND blob.rid=plink.cid;" | |
| 1135 | - ); | |
| 1136 | - db_multi_exec( | |
| 1137 | - "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" | |
| 1138 | - " SELECT description.rid, description.uuid, isPrivate, type,\n" | |
| 1139 | - " 'check-in referenced by \"'||tag.tagname ||'\" tag',\n" | |
| 1140 | - " blob.uuid\n" | |
| 1141 | - " FROM description, tagxref, tag, blob\n" | |
| 1142 | - " WHERE description.summary='unknown'\n" | |
| 1143 | - " AND tagxref.origid=description.rid\n" | |
| 1144 | - " AND tag.tagid=tagxref.tagid\n" | |
| 1145 | - " AND blob.rid=tagxref.srcid;" | |
| 1146 | - ); | |
| 1190 | + if( db_exists("SELECT 1 FROM description WHERE summary='unknown'") ){ | |
| 1191 | + describe_unknown_artifacts(); | |
| 1192 | + } | |
| 1147 | 1193 | } |
| 1148 | 1194 | |
| 1149 | 1195 | /* |
| 1150 | 1196 | ** Print the content of the description table on stdout. |
| 1151 | 1197 | ** |
| @@ -1332,44 +1378,15 @@ | ||
| 1332 | 1378 | db_finalize(&q); |
| 1333 | 1379 | style_footer(); |
| 1334 | 1380 | } |
| 1335 | 1381 | |
| 1336 | 1382 | /* |
| 1337 | -** WEBPAGE: phantoms | |
| 1338 | -** | |
| 1339 | -** Show a list of all "phantom" artifacts that are not marked as "private". | |
| 1340 | -** | |
| 1341 | -** A "phantom" artifact is an artifact whose hash named appears in some | |
| 1342 | -** artifact but whose content is unknown. For example, if a manifest | |
| 1343 | -** references a particular SHA3 hash of a file, but that SHA3 hash is | |
| 1344 | -** not on the shunning list and is not in the database, then the file | |
| 1345 | -** is a phantom. We know it exists, but we do not know its content. | |
| 1346 | -** | |
| 1347 | -** Whenever a sync occurs, both each party looks at its phantom list | |
| 1348 | -** and for every phantom that is not also marked private, it asks the | |
| 1349 | -** other party to send it the content. This mechanism helps keep all | |
| 1350 | -** repositories synced up. | |
| 1351 | -** | |
| 1352 | -** This page is similar to the /bloblist page in that it lists artifacts. | |
| 1353 | -** But this page is a special case in that it only shows phantoms that | |
| 1354 | -** are not private. In other words, this page shows all phantoms that | |
| 1355 | -** generate extra network traffic on every sync request. | |
| 1383 | +** Output HTML that shows a table of all public phantoms. | |
| 1356 | 1384 | */ |
| 1357 | -void phantom_list_page(void){ | |
| 1385 | +void table_of_public_phantoms(void){ | |
| 1358 | 1386 | Stmt q; |
| 1359 | 1387 | char *zRange; |
| 1360 | - | |
| 1361 | - login_check_credentials(); | |
| 1362 | - if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 1363 | - style_header("Public Phantom Artifacts"); | |
| 1364 | - if( g.perm.Admin ){ | |
| 1365 | - style_submenu_element("Artifact Log", "rcvfromlist"); | |
| 1366 | - style_submenu_element("Artifact List", "bloblist"); | |
| 1367 | - } | |
| 1368 | - if( g.perm.Write ){ | |
| 1369 | - style_submenu_element("Artifact Stats", "artifact_stats"); | |
| 1370 | - } | |
| 1371 | 1388 | zRange = mprintf("IN (SELECT rid FROM phantom EXCEPT" |
| 1372 | 1389 | " SELECT rid FROM private)"); |
| 1373 | 1390 | describe_artifacts(zRange); |
| 1374 | 1391 | fossil_free(zRange); |
| 1375 | 1392 | db_prepare(&q, |
| @@ -1392,10 +1409,45 @@ | ||
| 1392 | 1409 | } |
| 1393 | 1410 | @ </tr> |
| 1394 | 1411 | } |
| 1395 | 1412 | @ </table> |
| 1396 | 1413 | db_finalize(&q); |
| 1414 | +} | |
| 1415 | + | |
| 1416 | +/* | |
| 1417 | +** WEBPAGE: phantoms | |
| 1418 | +** | |
| 1419 | +** Show a list of all "phantom" artifacts that are not marked as "private". | |
| 1420 | +** | |
| 1421 | +** A "phantom" artifact is an artifact whose hash named appears in some | |
| 1422 | +** artifact but whose content is unknown. For example, if a manifest | |
| 1423 | +** references a particular SHA3 hash of a file, but that SHA3 hash is | |
| 1424 | +** not on the shunning list and is not in the database, then the file | |
| 1425 | +** is a phantom. We know it exists, but we do not know its content. | |
| 1426 | +** | |
| 1427 | +** Whenever a sync occurs, both each party looks at its phantom list | |
| 1428 | +** and for every phantom that is not also marked private, it asks the | |
| 1429 | +** other party to send it the content. This mechanism helps keep all | |
| 1430 | +** repositories synced up. | |
| 1431 | +** | |
| 1432 | +** This page is similar to the /bloblist page in that it lists artifacts. | |
| 1433 | +** But this page is a special case in that it only shows phantoms that | |
| 1434 | +** are not private. In other words, this page shows all phantoms that | |
| 1435 | +** generate extra network traffic on every sync request. | |
| 1436 | +*/ | |
| 1437 | +void phantom_list_page(void){ | |
| 1438 | + login_check_credentials(); | |
| 1439 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 1440 | + style_header("Public Phantom Artifacts"); | |
| 1441 | + if( g.perm.Admin ){ | |
| 1442 | + style_submenu_element("Artifact Log", "rcvfromlist"); | |
| 1443 | + style_submenu_element("Artifact List", "bloblist"); | |
| 1444 | + } | |
| 1445 | + if( g.perm.Write ){ | |
| 1446 | + style_submenu_element("Artifact Stats", "artifact_stats"); | |
| 1447 | + } | |
| 1448 | + table_of_public_phantoms(); | |
| 1397 | 1449 | style_footer(); |
| 1398 | 1450 | } |
| 1399 | 1451 | |
| 1400 | 1452 | /* |
| 1401 | 1453 | ** WEBPAGE: bigbloblist |
| 1402 | 1454 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -968,10 +968,75 @@ | |
| 968 | @ summary TEXT, -- Summary comment for the object |
| 969 | @ ref TEXT -- hash of an object to link against |
| 970 | @ ); |
| 971 | @ CREATE INDEX desctype ON description(summary) WHERE summary='unknown'; |
| 972 | ; |
| 973 | |
| 974 | /* |
| 975 | ** Create the description table if it does not already exists. |
| 976 | ** Populate fields of this table with descriptions for all artifacts |
| 977 | ** whose RID matches the SQL expression in zWhere. |
| @@ -1120,32 +1185,13 @@ | |
| 1120 | /* Mark private elements */ |
| 1121 | db_multi_exec( |
| 1122 | "UPDATE description SET isPrivate=1 WHERE rid IN private" |
| 1123 | ); |
| 1124 | |
| 1125 | /* Try to figure out the origin of unknown artifacts */ |
| 1126 | db_multi_exec( |
| 1127 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 1128 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 1129 | " CASE WHEN plink.isprim THEN '' ELSE 'merge ' END ||\n" |
| 1130 | " 'parent of check-in', blob.uuid\n" |
| 1131 | " FROM description, plink, blob\n" |
| 1132 | " WHERE description.summary='unknown'\n" |
| 1133 | " AND plink.pid=description.rid\n" |
| 1134 | " AND blob.rid=plink.cid;" |
| 1135 | ); |
| 1136 | db_multi_exec( |
| 1137 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 1138 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 1139 | " 'check-in referenced by \"'||tag.tagname ||'\" tag',\n" |
| 1140 | " blob.uuid\n" |
| 1141 | " FROM description, tagxref, tag, blob\n" |
| 1142 | " WHERE description.summary='unknown'\n" |
| 1143 | " AND tagxref.origid=description.rid\n" |
| 1144 | " AND tag.tagid=tagxref.tagid\n" |
| 1145 | " AND blob.rid=tagxref.srcid;" |
| 1146 | ); |
| 1147 | } |
| 1148 | |
| 1149 | /* |
| 1150 | ** Print the content of the description table on stdout. |
| 1151 | ** |
| @@ -1332,44 +1378,15 @@ | |
| 1332 | db_finalize(&q); |
| 1333 | style_footer(); |
| 1334 | } |
| 1335 | |
| 1336 | /* |
| 1337 | ** WEBPAGE: phantoms |
| 1338 | ** |
| 1339 | ** Show a list of all "phantom" artifacts that are not marked as "private". |
| 1340 | ** |
| 1341 | ** A "phantom" artifact is an artifact whose hash named appears in some |
| 1342 | ** artifact but whose content is unknown. For example, if a manifest |
| 1343 | ** references a particular SHA3 hash of a file, but that SHA3 hash is |
| 1344 | ** not on the shunning list and is not in the database, then the file |
| 1345 | ** is a phantom. We know it exists, but we do not know its content. |
| 1346 | ** |
| 1347 | ** Whenever a sync occurs, both each party looks at its phantom list |
| 1348 | ** and for every phantom that is not also marked private, it asks the |
| 1349 | ** other party to send it the content. This mechanism helps keep all |
| 1350 | ** repositories synced up. |
| 1351 | ** |
| 1352 | ** This page is similar to the /bloblist page in that it lists artifacts. |
| 1353 | ** But this page is a special case in that it only shows phantoms that |
| 1354 | ** are not private. In other words, this page shows all phantoms that |
| 1355 | ** generate extra network traffic on every sync request. |
| 1356 | */ |
| 1357 | void phantom_list_page(void){ |
| 1358 | Stmt q; |
| 1359 | char *zRange; |
| 1360 | |
| 1361 | login_check_credentials(); |
| 1362 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1363 | style_header("Public Phantom Artifacts"); |
| 1364 | if( g.perm.Admin ){ |
| 1365 | style_submenu_element("Artifact Log", "rcvfromlist"); |
| 1366 | style_submenu_element("Artifact List", "bloblist"); |
| 1367 | } |
| 1368 | if( g.perm.Write ){ |
| 1369 | style_submenu_element("Artifact Stats", "artifact_stats"); |
| 1370 | } |
| 1371 | zRange = mprintf("IN (SELECT rid FROM phantom EXCEPT" |
| 1372 | " SELECT rid FROM private)"); |
| 1373 | describe_artifacts(zRange); |
| 1374 | fossil_free(zRange); |
| 1375 | db_prepare(&q, |
| @@ -1392,10 +1409,45 @@ | |
| 1392 | } |
| 1393 | @ </tr> |
| 1394 | } |
| 1395 | @ </table> |
| 1396 | db_finalize(&q); |
| 1397 | style_footer(); |
| 1398 | } |
| 1399 | |
| 1400 | /* |
| 1401 | ** WEBPAGE: bigbloblist |
| 1402 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -968,10 +968,75 @@ | |
| 968 | @ summary TEXT, -- Summary comment for the object |
| 969 | @ ref TEXT -- hash of an object to link against |
| 970 | @ ); |
| 971 | @ CREATE INDEX desctype ON description(summary) WHERE summary='unknown'; |
| 972 | ; |
| 973 | |
| 974 | /* |
| 975 | ** Attempt to describe all phantom artifacts. The artifacts are |
| 976 | ** already loaded into the description table and have summary='unknown'. |
| 977 | ** This routine attempts to generate a better summary, and possibly |
| 978 | ** fill in the ref field. |
| 979 | */ |
| 980 | static void describe_unknown_artifacts(){ |
| 981 | /* Try to figure out the origin of unknown artifacts */ |
| 982 | db_multi_exec( |
| 983 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 984 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 985 | " CASE WHEN plink.isprim THEN '' ELSE 'merge ' END ||\n" |
| 986 | " 'parent of check-in', blob.uuid\n" |
| 987 | " FROM description, plink, blob\n" |
| 988 | " WHERE description.summary='unknown'\n" |
| 989 | " AND plink.pid=description.rid\n" |
| 990 | " AND blob.rid=plink.cid;" |
| 991 | ); |
| 992 | db_multi_exec( |
| 993 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 994 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 995 | " 'child of check-in', blob.uuid\n" |
| 996 | " FROM description, plink, blob\n" |
| 997 | " WHERE description.summary='unknown'\n" |
| 998 | " AND plink.cid=description.rid\n" |
| 999 | " AND blob.rid=plink.pid;" |
| 1000 | ); |
| 1001 | db_multi_exec( |
| 1002 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 1003 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 1004 | " 'check-in referenced by \"'||tag.tagname ||'\" tag',\n" |
| 1005 | " blob.uuid\n" |
| 1006 | " FROM description, tagxref, tag, blob\n" |
| 1007 | " WHERE description.summary='unknown'\n" |
| 1008 | " AND tagxref.origid=description.rid\n" |
| 1009 | " AND tag.tagid=tagxref.tagid\n" |
| 1010 | " AND blob.rid=tagxref.srcid;" |
| 1011 | ); |
| 1012 | db_multi_exec( |
| 1013 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 1014 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 1015 | " 'file \"'||filename.name||'\"',\n" |
| 1016 | " blob.uuid\n" |
| 1017 | " FROM description, mlink, filename, blob\n" |
| 1018 | " WHERE description.summary='unknown'\n" |
| 1019 | " AND mlink.fid=description.rid\n" |
| 1020 | " AND blob.rid=mlink.mid\n" |
| 1021 | " AND filename.fnid=mlink.fnid;" |
| 1022 | ); |
| 1023 | if( !db_exists("SELECT 1 FROM description WHERE summary='unknown'") ){ |
| 1024 | return; |
| 1025 | } |
| 1026 | add_content_sql_commands(g.db); |
| 1027 | db_multi_exec( |
| 1028 | "REPLACE INTO description(rid,uuid,isPrivate,type,summary,ref)\n" |
| 1029 | " SELECT description.rid, description.uuid, isPrivate, type,\n" |
| 1030 | " 'referenced by cluster', blob.uuid\n" |
| 1031 | " FROM description, tagxref, blob\n" |
| 1032 | " WHERE description.summary='unknown'\n" |
| 1033 | " AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n" |
| 1034 | " AND blob.rid=tagxref.rid\n" |
| 1035 | " AND content(blob.uuid) GLOB ('*M '||blob.uuid||'*');" |
| 1036 | ); |
| 1037 | } |
| 1038 | |
| 1039 | /* |
| 1040 | ** Create the description table if it does not already exists. |
| 1041 | ** Populate fields of this table with descriptions for all artifacts |
| 1042 | ** whose RID matches the SQL expression in zWhere. |
| @@ -1120,32 +1185,13 @@ | |
| 1185 | /* Mark private elements */ |
| 1186 | db_multi_exec( |
| 1187 | "UPDATE description SET isPrivate=1 WHERE rid IN private" |
| 1188 | ); |
| 1189 | |
| 1190 | if( db_exists("SELECT 1 FROM description WHERE summary='unknown'") ){ |
| 1191 | describe_unknown_artifacts(); |
| 1192 | } |
| 1193 | } |
| 1194 | |
| 1195 | /* |
| 1196 | ** Print the content of the description table on stdout. |
| 1197 | ** |
| @@ -1332,44 +1378,15 @@ | |
| 1378 | db_finalize(&q); |
| 1379 | style_footer(); |
| 1380 | } |
| 1381 | |
| 1382 | /* |
| 1383 | ** Output HTML that shows a table of all public phantoms. |
| 1384 | */ |
| 1385 | void table_of_public_phantoms(void){ |
| 1386 | Stmt q; |
| 1387 | char *zRange; |
| 1388 | zRange = mprintf("IN (SELECT rid FROM phantom EXCEPT" |
| 1389 | " SELECT rid FROM private)"); |
| 1390 | describe_artifacts(zRange); |
| 1391 | fossil_free(zRange); |
| 1392 | db_prepare(&q, |
| @@ -1392,10 +1409,45 @@ | |
| 1409 | } |
| 1410 | @ </tr> |
| 1411 | } |
| 1412 | @ </table> |
| 1413 | db_finalize(&q); |
| 1414 | } |
| 1415 | |
| 1416 | /* |
| 1417 | ** WEBPAGE: phantoms |
| 1418 | ** |
| 1419 | ** Show a list of all "phantom" artifacts that are not marked as "private". |
| 1420 | ** |
| 1421 | ** A "phantom" artifact is an artifact whose hash named appears in some |
| 1422 | ** artifact but whose content is unknown. For example, if a manifest |
| 1423 | ** references a particular SHA3 hash of a file, but that SHA3 hash is |
| 1424 | ** not on the shunning list and is not in the database, then the file |
| 1425 | ** is a phantom. We know it exists, but we do not know its content. |
| 1426 | ** |
| 1427 | ** Whenever a sync occurs, both each party looks at its phantom list |
| 1428 | ** and for every phantom that is not also marked private, it asks the |
| 1429 | ** other party to send it the content. This mechanism helps keep all |
| 1430 | ** repositories synced up. |
| 1431 | ** |
| 1432 | ** This page is similar to the /bloblist page in that it lists artifacts. |
| 1433 | ** But this page is a special case in that it only shows phantoms that |
| 1434 | ** are not private. In other words, this page shows all phantoms that |
| 1435 | ** generate extra network traffic on every sync request. |
| 1436 | */ |
| 1437 | void phantom_list_page(void){ |
| 1438 | login_check_credentials(); |
| 1439 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1440 | style_header("Public Phantom Artifacts"); |
| 1441 | if( g.perm.Admin ){ |
| 1442 | style_submenu_element("Artifact Log", "rcvfromlist"); |
| 1443 | style_submenu_element("Artifact List", "bloblist"); |
| 1444 | } |
| 1445 | if( g.perm.Write ){ |
| 1446 | style_submenu_element("Artifact Stats", "artifact_stats"); |
| 1447 | } |
| 1448 | table_of_public_phantoms(); |
| 1449 | style_footer(); |
| 1450 | } |
| 1451 | |
| 1452 | /* |
| 1453 | ** WEBPAGE: bigbloblist |
| 1454 |
+4
-7
| --- src/security_audit.c | ||
| +++ src/security_audit.c | ||
| @@ -558,22 +558,19 @@ | ||
| 558 | 558 | |
| 559 | 559 | n = db_int(0,"SELECT count(*) FROM (" |
| 560 | 560 | "SELECT rid FROM phantom EXCEPT SELECT rid FROM private)"); |
| 561 | 561 | if( n>0 ){ |
| 562 | 562 | @ <li><p>\ |
| 563 | - if( n==1 ){ | |
| 564 | - @ There is 1 public phantom artifact | |
| 565 | - }else{ | |
| 566 | - @ There are %d(n) public phantom artifacts | |
| 567 | - } | |
| 568 | - @ (<a href="%R/phantoms">details</a>). | |
| 563 | + @ There exists public phantom artifacts in this repository, shown below. | |
| 569 | 564 | @ Phantom artifacts are artifacts whose hash name is referenced by some |
| 570 | 565 | @ other artifact but whose content is unknown. Some phantoms are marked |
| 571 | 566 | @ private and those are ignored. But public phantoms cause unnecessary |
| 572 | 567 | @ sync traffic and might represent malicious attempts to corrupt the |
| 573 | 568 | @ repository structure. |
| 574 | - @ </p></li> | |
| 569 | + @ </p> | |
| 570 | + table_of_public_phantoms(); | |
| 571 | + @ </li> | |
| 575 | 572 | } |
| 576 | 573 | |
| 577 | 574 | @ </ol> |
| 578 | 575 | style_footer(); |
| 579 | 576 | } |
| 580 | 577 |
| --- src/security_audit.c | |
| +++ src/security_audit.c | |
| @@ -558,22 +558,19 @@ | |
| 558 | |
| 559 | n = db_int(0,"SELECT count(*) FROM (" |
| 560 | "SELECT rid FROM phantom EXCEPT SELECT rid FROM private)"); |
| 561 | if( n>0 ){ |
| 562 | @ <li><p>\ |
| 563 | if( n==1 ){ |
| 564 | @ There is 1 public phantom artifact |
| 565 | }else{ |
| 566 | @ There are %d(n) public phantom artifacts |
| 567 | } |
| 568 | @ (<a href="%R/phantoms">details</a>). |
| 569 | @ Phantom artifacts are artifacts whose hash name is referenced by some |
| 570 | @ other artifact but whose content is unknown. Some phantoms are marked |
| 571 | @ private and those are ignored. But public phantoms cause unnecessary |
| 572 | @ sync traffic and might represent malicious attempts to corrupt the |
| 573 | @ repository structure. |
| 574 | @ </p></li> |
| 575 | } |
| 576 | |
| 577 | @ </ol> |
| 578 | style_footer(); |
| 579 | } |
| 580 |
| --- src/security_audit.c | |
| +++ src/security_audit.c | |
| @@ -558,22 +558,19 @@ | |
| 558 | |
| 559 | n = db_int(0,"SELECT count(*) FROM (" |
| 560 | "SELECT rid FROM phantom EXCEPT SELECT rid FROM private)"); |
| 561 | if( n>0 ){ |
| 562 | @ <li><p>\ |
| 563 | @ There exists public phantom artifacts in this repository, shown below. |
| 564 | @ Phantom artifacts are artifacts whose hash name is referenced by some |
| 565 | @ other artifact but whose content is unknown. Some phantoms are marked |
| 566 | @ private and those are ignored. But public phantoms cause unnecessary |
| 567 | @ sync traffic and might represent malicious attempts to corrupt the |
| 568 | @ repository structure. |
| 569 | @ </p> |
| 570 | table_of_public_phantoms(); |
| 571 | @ </li> |
| 572 | } |
| 573 | |
| 574 | @ </ol> |
| 575 | style_footer(); |
| 576 | } |
| 577 |