Batch-audit passwords from a file. Exports metrics only (no plaintext).
(
file: str = typer.Argument(..., help="File with one password per line"),
policy: str = typer.Option("enterprise", "--policy", "-p"),
output: Optional[str] = typer.Option(None, "--output", "-o", help="Export path (JSON or CSV)"),
fmt: str = typer.Option("json", "--format", help="json | csv"),
)
| 2056 | console.print(f" Chars: {' '.join(char_flags) or 'none'}") |
| 2057 | |
| 2058 | if result.is_common: |
| 2059 | console.print(" [bold red]⚠ Matches a common password list[/bold red]") |
| 2060 | if result.patterns_found: |
| 2061 | console.print(f" Patterns: {', '.join(result.patterns_found)}") |
| 2062 | |
| 2063 | console.print("\n[bold]Recommendations:[/bold]") |
| 2064 | for rec in result.recommendations: |
| 2065 | icon = "✓" if "meets" in rec.lower() else "→" |
| 2066 | color2 = "green" if "meets" in rec.lower() else "yellow" |
| 2067 | console.print(f" [{color2}]{icon} {rec}[/{color2}]") |
| 2068 | |
| 2069 | |
| 2070 | @password_app.command("generate") |
| 2071 | def password_generate( |
| 2072 | length: int = typer.Option(20, "--length", "-l"), |
| 2073 | count: int = typer.Option(1, "--count", "-n", help="Number of passwords to generate"), |
| 2074 | passphrase: bool = typer.Option(False, "--passphrase", help="Generate passphrase instead"), |
| 2075 | words: int = typer.Option(5, "--words", help="Words in passphrase"), |
| 2076 | no_special: bool = typer.Option(False, "--no-special"), |
| 2077 | no_digits: bool = typer.Option(False, "--no-digits"), |
| 2078 | no_ambiguous: bool = typer.Option(False, "--no-ambiguous", help="Exclude lookalike chars (O,0,I,l,1)"), |
| 2079 | ): |
| 2080 | """Generate secure random passwords or passphrases.""" |
| 2081 | from modules.password import PasswordGenerator |
| 2082 | |
| 2083 | console.print() |
| 2084 | if passphrase: |
| 2085 | for _ in range(count): |
| 2086 | p = PasswordGenerator.generate_passphrase(word_count=words) |
| 2087 | console.print(f" [green]{p}[/green]") |
| 2088 | else: |
| 2089 | for _ in range(count): |
| 2090 | p = PasswordGenerator.generate( |
| 2091 | length=length, |
| 2092 | use_special=not no_special, |
| 2093 | use_digits=not no_digits, |
| 2094 | exclude_ambiguous=no_ambiguous, |
nothing calls this directly
no test coverage detected