Skip to content

Commit

Permalink
Added quiet flag for commands #10
Browse files Browse the repository at this point in the history
  • Loading branch information
Veinar committed Dec 9, 2024
1 parent 402d74f commit 662e656
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 32 deletions.
7 changes: 5 additions & 2 deletions envcloak/commands/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
import click
from click import style
from envcloak.comparator import compare_files_or_directories
from envcloak.utils import debug_log
from envcloak.decorators.common_decorators import debug_option, no_sha_validation_option
from envcloak.utils import debug_log, conditional_echo, conditional_secho
from envcloak.decorators.common_decorators import (
debug_option,
no_sha_validation_option,
)


@click.command()
Expand Down
9 changes: 6 additions & 3 deletions envcloak/commands/decrypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
debug_log,
calculate_required_space,
list_files_to_encrypt,
read_key_file,
read_key_file, conditional_echo, conditional_secho
)
from envcloak.handlers import (
handle_directory_preview,
Expand All @@ -23,6 +23,7 @@
no_sha_validation_option,
recursion_option,
preview_option,
quiet_option,
)
from envcloak.validation import (
check_file_exists,
Expand All @@ -39,6 +40,7 @@

@click.command()
@debug_option
@quiet_option
@dry_run_option
@force_option
@no_sha_validation_option
Expand Down Expand Up @@ -76,6 +78,7 @@ def decrypt(
skip_sha_validation,
recursion,
preview,
quiet,
):
"""
Decrypt environment variables from a file or all files in a directory.
Expand Down Expand Up @@ -129,7 +132,7 @@ def decrypt(
debug,
)
decrypt_file(input, output, key, validate_integrity=not skip_sha_validation)
click.echo(f"File {input} decrypted -> {output} using key {key_file}")
conditional_echo(f"File {input} decrypted -> {output} using key {key_file}", quiet)
elif directory:
debug_log(f"Debug: Decrypting files in directory {directory}.", debug)
traverse_and_process_files(
Expand All @@ -146,7 +149,7 @@ def decrypt(
),
recursion=recursion,
)
click.echo(f"All files in directory {directory} decrypted -> {output}")
conditional_echo(f"All files in directory {directory} decrypted -> {output}", quiet)
except FileDecryptionException as e:
click.echo(
f"Error during decryption: Error: Failed to decrypt the file.\nDetails: {e.details}",
Expand Down
10 changes: 6 additions & 4 deletions envcloak/commands/encrypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
calculate_required_space,
list_files_to_encrypt,
validate_paths,
read_key_file,
read_key_file, conditional_echo, conditional_secho
)
from envcloak.handlers import (
handle_directory_preview,
Expand All @@ -23,6 +23,7 @@
dry_run_option,
recursion_option,
preview_option,
quiet_option,
)
from envcloak.validation import (
check_disk_space,
Expand All @@ -34,6 +35,7 @@


@click.command()
@quiet_option
@debug_option
@dry_run_option
@force_option
Expand All @@ -58,7 +60,7 @@
"--key-file", "-k", required=True, help="Path to the encryption key file."
)
def encrypt(
input, directory, output, key_file, dry_run, force, debug, recursion, preview
input, directory, output, key_file, dry_run, force, debug, recursion, preview, quiet
):
"""
Encrypt environment variables from a file or all files in a directory.
Expand Down Expand Up @@ -106,7 +108,7 @@ def encrypt(
debug,
)
encrypt_file(input, output, key)
click.echo(f"File {input} encrypted -> {output} using key {key_file}")
conditional_echo(f"File {input} encrypted -> {output} using key {key_file}", quiet)
elif directory:
debug_log(f"Debug: Encrypting files in directory {directory}.", debug)
traverse_and_process_files(
Expand All @@ -120,7 +122,7 @@ def encrypt(
),
recursion=recursion,
)
click.echo(f"All files in directory {directory} encrypted -> {output}")
conditional_echo(f"All files in directory {directory} encrypted -> {output}", quiet)
except FileEncryptionException as e:
click.echo(
f"Error: An error occurred during file encryption.\nDetails: {e}",
Expand Down
15 changes: 10 additions & 5 deletions envcloak/commands/generate_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,26 @@
import click
from envcloak.validation import check_output_not_exists, check_disk_space
from envcloak.generator import generate_key_file
from envcloak.utils import add_to_gitignore, debug_log
from envcloak.decorators.common_decorators import debug_option, dry_run_option
from envcloak.utils import add_to_gitignore, debug_log, conditional_echo, conditional_secho
from envcloak.decorators.common_decorators import (
debug_option,
dry_run_option,
quiet_option,
)
from envcloak.exceptions import OutputFileExistsException, DiskSpaceException


@click.command()
@debug_option
@quiet_option
@dry_run_option
@click.option(
"--output", "-o", required=True, help="Path to save the generated encryption key."
)
@click.option(
"--no-gitignore", is_flag=True, help="Skip adding the key file to .gitignore."
)
def generate_key(output, no_gitignore, dry_run, debug):
def generate_key(output, no_gitignore, dry_run, debug, quiet):
"""
Generate a new encryption key.
"""
Expand All @@ -47,12 +52,12 @@ def generate_key(output, no_gitignore, dry_run, debug):
# Actual key generation logic
debug_log(f"Debug: Generating key file at {output}.", debug)
output_path = Path(output)
generate_key_file(output_path)
generate_key_file(output_path, quiet)
if not no_gitignore:
debug_log(
f"Debug: Adding {output_path.name} to .gitignore in parent directory {output_path.parent}.",
debug,
)
add_to_gitignore(output_path.parent, output_path.name)
add_to_gitignore(output_path.parent, output_path.name, quiet)
except (OutputFileExistsException, DiskSpaceException) as e:
click.echo(f"Error during key generation: {str(e)}")
17 changes: 12 additions & 5 deletions envcloak/commands/generate_key_from_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
import click
from envcloak.validation import check_output_not_exists, check_disk_space, validate_salt
from envcloak.generator import generate_key_from_password_file
from envcloak.utils import debug_log, add_to_gitignore
from envcloak.decorators.common_decorators import debug_option, dry_run_option
from envcloak.utils import debug_log, add_to_gitignore, conditional_echo, conditional_secho
from envcloak.decorators.common_decorators import (
debug_option,
dry_run_option,
quiet_option,
)
from envcloak.exceptions import (
OutputFileExistsException,
DiskSpaceException,
Expand All @@ -19,6 +23,7 @@

@click.command()
@debug_option
@quiet_option
@dry_run_option
@click.option(
"--password", "-p", required=True, help="Password to derive the encryption key."
Expand All @@ -32,7 +37,9 @@
@click.option(
"--no-gitignore", is_flag=True, help="Skip adding the key file to .gitignore."
)
def generate_key_from_password(password, salt, output, no_gitignore, dry_run, debug):
def generate_key_from_password(
password, salt, output, no_gitignore, dry_run, debug, quiet
):
"""
Derive an encryption key from a password and salt.
"""
Expand All @@ -58,12 +65,12 @@ def generate_key_from_password(password, salt, output, no_gitignore, dry_run, de
# Actual key derivation logic
debug_log(f"Debug: Deriving key from password for output file {output}.", debug)
output_path = Path(output)
generate_key_from_password_file(password, output_path, salt)
generate_key_from_password_file(password, output_path, quiet, salt)
if not no_gitignore:
debug_log(
f"Debug: Adding {output_path.name} to .gitignore in parent directory {output_path.parent}.",
debug,
)
add_to_gitignore(output_path.parent, output_path.name)
add_to_gitignore(output_path.parent, output_path.name, quiet)
except (OutputFileExistsException, DiskSpaceException, InvalidSaltException) as e:
click.echo(f"Error during key derivation: {str(e)}")
19 changes: 13 additions & 6 deletions envcloak/commands/rotate_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@

import os
import click
from envcloak.utils import debug_log
from envcloak.decorators.common_decorators import debug_option, dry_run_option
from envcloak.utils import debug_log, conditional_echo, conditional_secho
from envcloak.decorators.common_decorators import (
debug_option,
dry_run_option,
quiet_option,
)
from envcloak.validation import (
check_file_exists,
check_permissions,
Expand All @@ -25,6 +29,7 @@

@click.command()
@debug_option
@quiet_option
@dry_run_option
@click.option(
"--input", "-i", required=True, help="Path to the encrypted file to re-encrypt."
Expand All @@ -41,7 +46,9 @@
is_flag=True,
help="Preview the key rotation process without making changes.",
)
def rotate_keys(input, old_key_file, new_key_file, output, dry_run, debug, preview):
def rotate_keys(
input, old_key_file, new_key_file, output, dry_run, debug, preview, quiet
):
"""
Rotate encryption keys by re-encrypting a file with a new key.
"""
Expand All @@ -59,14 +66,14 @@ def rotate_keys(input, old_key_file, new_key_file, output, dry_run, debug, previ

# Handle Preview or Dry-run modes
if preview:
click.secho(
conditional_secho(
f"""
Preview of Key Rotation:
- Old key: {old_key_file} will no longer be valid for this encrypted file.
- New key: {new_key_file} will be used to decrypt the encrypted file.
- Encrypted file: {input} will be re-encrypted to {output}.
""",
fg="cyan",
fg="cyan", quiet=quiet
)
return
if dry_run:
Expand Down Expand Up @@ -95,7 +102,7 @@ def rotate_keys(input, old_key_file, new_key_file, output, dry_run, debug, previ

debug_log(f"Debug: Removing temporary decrypted file {temp_decrypted}.", debug)
os.remove(temp_decrypted) # Clean up temporary file
click.echo(f"Keys rotated for {input} -> {output}")
conditional_echo(f"Keys rotated for {input} -> {output}", quiet)
except (
OutputFileExistsException,
DiskSpaceException,
Expand Down
11 changes: 11 additions & 0 deletions envcloak/decorators/common_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,14 @@ def preview_option(func):
is_flag=True,
help="List files that will be decrypted (only applicable for directories).",
)(func)


def quiet_option(func):
"""
Add a `--quiet` flag to a Click command.
"""
return click.option(
"--quiet",
is_flag=True,
help="Suppress all output except errors.",
)(func)
8 changes: 4 additions & 4 deletions envcloak/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@
import secrets


def generate_key_file(output_path: Path):
def generate_key_file(output_path: Path, quiet: bool):
"""
Generate a secure random encryption key, save it to a file.
"""
key = secrets.token_bytes(32) # Generate a 256-bit random key
output_path.parent.mkdir(parents=True, exist_ok=True) # Ensure directory exists
with open(output_path, "wb") as key_file:
key_file.write(key)
print(f"Encryption key generated and saved to {output_path}")
if not quiet: print(f"Encryption key generated and saved to {output_path}")


def generate_key_from_password_file(password: str, output_path: Path, salt: str = None):
def generate_key_from_password_file(password: str, output_path: Path, quiet: bool, salt: str = None):
"""
Derive an encryption key from a password and save it to a file.
If no salt is provided, a random one is generated.
Expand All @@ -49,4 +49,4 @@ def generate_key_from_password_file(password: str, output_path: Path, salt: str
with open(output_path, "wb") as key_file:
key_file.write(key)

print(f"Derived encryption key saved to {output_path}")
if not quiet: print(f"Derived encryption key saved to {output_path}")
20 changes: 17 additions & 3 deletions envcloak/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
)


def add_to_gitignore(directory: str, filename: str):
def add_to_gitignore(directory: str, filename: str, quiet: bool):
"""
Add a filename to the .gitignore file in the specified directory.
Expand All @@ -32,12 +32,12 @@ def add_to_gitignore(directory: str, filename: str):
content = gitignore_file.read()
if filename not in content:
gitignore_file.write(f"\n{filename}")
print(f"Added '{filename}' to {gitignore_path}")
if not quiet: print(f"Added '{filename}' to {gitignore_path}")
else:
# Create a new .gitignore file and add the filename
with open(gitignore_path, "w", encoding="utf-8") as gitignore_file:
gitignore_file.write(f"{filename}\n")
print(f"Created {gitignore_path} and added '{filename}'")
if not quiet: print(f"Created {gitignore_path} and added '{filename}'")


def calculate_required_space(input=None, directory=None):
Expand Down Expand Up @@ -143,3 +143,17 @@ def read_key_file(key_file, debug):
key = kf.read()
debug_log(f"Debug: Key file {key_file} read successfully.", debug)
return key

def conditional_echo(message, quiet, **kwargs):
"""
Echo a message only if `quiet` is False.
"""
if not quiet:
click.echo(message, **kwargs)

def conditional_secho(message, quiet, **kwargs):
"""
Styled echo a message only if `quiet` is False.
"""
if not quiet:
click.secho(message, **kwargs)

0 comments on commit 662e656

Please sign in to comment.