feat: Implement console session management with tenant and profile handling
- Add ConsoleSessionStore for managing console session state including tenants, profile, and token information. - Create OperatorContextService to manage operator context for orchestrator actions. - Implement OperatorMetadataInterceptor to enrich HTTP requests with operator context metadata. - Develop ConsoleProfileComponent to display user profile and session details, including tenant information and access tokens. - Add corresponding HTML and SCSS for ConsoleProfileComponent to enhance UI presentation. - Write unit tests for ConsoleProfileComponent to ensure correct rendering and functionality.
This commit is contained in:
		
							
								
								
									
										86
									
								
								scripts/verify-policy-scopes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								scripts/verify-policy-scopes.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| #!/usr/bin/env python3 | ||||
| """Ensure Authority policy client configs use the fine-grained scope set.""" | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| import sys | ||||
| from pathlib import Path | ||||
|  | ||||
| EXPECTED_SCOPES = ( | ||||
|     "policy:read", | ||||
|     "policy:author", | ||||
|     "policy:review", | ||||
|     "policy:simulate", | ||||
|     "findings:read", | ||||
| ) | ||||
|  | ||||
|  | ||||
| def extract_scopes(lines: list[str], start_index: int) -> tuple[str, ...] | None: | ||||
|     for offset in range(1, 12): | ||||
|         if start_index + offset >= len(lines): | ||||
|             break | ||||
|         line = lines[start_index + offset].strip() | ||||
|         if not line: | ||||
|             continue | ||||
|         if line.startswith("scopes:"): | ||||
|             try: | ||||
|                 raw = line.split("[", 1)[1].rsplit("]", 1)[0] | ||||
|             except IndexError: | ||||
|                 return None | ||||
|             scopes = tuple(scope.strip().strip('"') for scope in raw.split(",")) | ||||
|             scopes = tuple(scope for scope in scopes if scope) | ||||
|             return scopes | ||||
|     return None | ||||
|  | ||||
|  | ||||
| def validate(path: Path) -> list[str]: | ||||
|     errors: list[str] = [] | ||||
|     try: | ||||
|         text = path.read_text(encoding="utf-8") | ||||
|     except FileNotFoundError: | ||||
|         return [f"{path}: missing file"] | ||||
|  | ||||
|     if "policy:write" in text or "policy:submit" in text: | ||||
|         errors.append(f"{path}: contains legacy policy scope names (policy:write/policy:submit)") | ||||
|  | ||||
|     lines = text.splitlines() | ||||
|     client_indices = [idx for idx, line in enumerate(lines) if 'clientId: "policy-cli"' in line] | ||||
|     if not client_indices: | ||||
|         errors.append(f"{path}: policy-cli client registration not found") | ||||
|         return errors | ||||
|  | ||||
|     for idx in client_indices: | ||||
|         scopes = extract_scopes(lines, idx) | ||||
|         if scopes is None: | ||||
|             errors.append(f"{path}: unable to parse scopes for policy-cli client") | ||||
|             continue | ||||
|         if tuple(sorted(scopes)) != tuple(sorted(EXPECTED_SCOPES)): | ||||
|             errors.append( | ||||
|                 f"{path}: unexpected policy-cli scopes {scopes}; expected {EXPECTED_SCOPES}" | ||||
|             ) | ||||
|  | ||||
|     return errors | ||||
|  | ||||
|  | ||||
| def main(argv: list[str]) -> int: | ||||
|     repo_root = Path(__file__).resolve().parents[1] | ||||
|     targets = [ | ||||
|         repo_root / "etc" / "authority.yaml", | ||||
|         repo_root / "etc" / "authority.yaml.sample", | ||||
|     ] | ||||
|  | ||||
|     failures: list[str] = [] | ||||
|     for target in targets: | ||||
|         failures.extend(validate(target)) | ||||
|  | ||||
|     if failures: | ||||
|         for message in failures: | ||||
|             print(f"error: {message}", file=sys.stderr) | ||||
|         return 1 | ||||
|  | ||||
|     print("policy scope verification passed") | ||||
|     return 0 | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     raise SystemExit(main(sys.argv)) | ||||
		Reference in New Issue
	
	Block a user