mirror of https://github.com/mongodb/mongo
SERVER-108950 Get all commands and agg stages that opted out of authz checks (#42515)
GitOrigin-RevId: feb051350ca4d90e6678ca6af8aff18bdcb216e7
This commit is contained in:
parent
47e7531bcc
commit
8f44848522
|
|
@ -0,0 +1,114 @@
|
|||
import os
|
||||
import re
|
||||
from typing import Optional, Set
|
||||
|
||||
MONGO_DOCUMENT_SOURCE_DIR = "src/mongo/db/pipeline"
|
||||
|
||||
# Regex to find bool requiresAuthzChecks() const override { return false; }
|
||||
AUTHZ_OPT_OUT_PATTERN = re.compile(
|
||||
r"bool\s+requiresAuthzChecks\s*\(\s*\)\s*const\s*override\s*\{\s*return\s+false;\s*\}",
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
# Regex to find the registration macro and capture the stage name
|
||||
STAGE_NAME_PATTERN = re.compile(
|
||||
r"REGISTER(?:_INTERNAL|_TEST)?_DOCUMENT_SOURCE(?:_WITH_FEATURE_FLAG)?\("
|
||||
r"\s*(\w+)", # Capture the stage name (e.g., "listSessions")
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
|
||||
def read_file(filepath: str) -> Optional[str]:
|
||||
try:
|
||||
if os.path.exists(filepath):
|
||||
with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
|
||||
return f.read()
|
||||
except IOError as e:
|
||||
print(f"Could not read {filepath}: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def check_file_pair(base_path: str) -> Optional[str]:
|
||||
"""
|
||||
Check a .h/.cpp file pair for opt-out pattern and stage name.
|
||||
Returns the stage name if found, None otherwise.
|
||||
"""
|
||||
header_path = f"{base_path}.h"
|
||||
cpp_path = f"{base_path}.cpp"
|
||||
|
||||
header_content = read_file(header_path)
|
||||
cpp_content = read_file(cpp_path)
|
||||
|
||||
opt_out_found = False
|
||||
if (header_content and AUTHZ_OPT_OUT_PATTERN.search(header_content)) or (
|
||||
cpp_content and AUTHZ_OPT_OUT_PATTERN.search(cpp_content)
|
||||
):
|
||||
opt_out_found = True
|
||||
|
||||
if not opt_out_found:
|
||||
return None
|
||||
|
||||
for content in [cpp_content, header_content]:
|
||||
if content:
|
||||
match = STAGE_NAME_PATTERN.search(content)
|
||||
if match:
|
||||
return f"${match.group(1)}"
|
||||
|
||||
# Opt-out found but no stage name
|
||||
print(
|
||||
f"Opt-out found in '{os.path.basename(base_path)}' "
|
||||
"but registration macro not found in .h or .cpp file."
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def find_authz_opt_out_stages() -> Set[str]:
|
||||
"""
|
||||
Scans the pipeline directory to find aggregation stages that
|
||||
opted out of authorization checks.
|
||||
|
||||
Returns a set of stage names that opted out.
|
||||
"""
|
||||
if not os.path.isdir(MONGO_DOCUMENT_SOURCE_DIR):
|
||||
print(f"Error: Directory '{MONGO_DOCUMENT_SOURCE_DIR}' does not exist")
|
||||
return set()
|
||||
|
||||
print(f"Scanning for aggregation stages in '{MONGO_DOCUMENT_SOURCE_DIR}'")
|
||||
found_stages: Set[str] = set()
|
||||
processed_bases: Set[str] = set()
|
||||
|
||||
# Walk through directory
|
||||
for root, _, files in os.walk(MONGO_DOCUMENT_SOURCE_DIR):
|
||||
for filename in files:
|
||||
if not filename.endswith((".h", ".cpp")):
|
||||
continue
|
||||
|
||||
filepath = os.path.join(root, filename)
|
||||
base_path = os.path.splitext(filepath)[0]
|
||||
|
||||
# Skip if already processed this file pair
|
||||
if base_path in processed_bases:
|
||||
continue
|
||||
|
||||
processed_bases.add(base_path)
|
||||
|
||||
stage_name = check_file_pair(base_path)
|
||||
if stage_name:
|
||||
found_stages.add(stage_name)
|
||||
|
||||
return found_stages
|
||||
|
||||
|
||||
def main():
|
||||
found_stages = find_authz_opt_out_stages()
|
||||
|
||||
if found_stages:
|
||||
print(f"\nFound {len(found_stages)} stage(s) that opted out of authz checks:")
|
||||
for stage in sorted(found_stages):
|
||||
print(f" - {stage}")
|
||||
else:
|
||||
print("\nNo aggregation stages found that explicitly opted out.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -248,6 +248,7 @@ public:
|
|||
BSONObjBuilder temp(b.subobjStart(command->getName()));
|
||||
temp.append("help", command->help());
|
||||
temp.append("requiresAuth", command->requiresAuth());
|
||||
temp.append("requiresAuthzChecks", command->requiresAuthzChecks());
|
||||
temp.append("secondaryOk",
|
||||
command->secondaryAllowed(opCtx->getServiceContext()) ==
|
||||
Command::AllowedOnSecondary::kAlways);
|
||||
|
|
|
|||
Loading…
Reference in New Issue