diff --git a/app/env_pro/commands/encrypt_cmds.py b/app/env_pro/commands/encrypt_cmds.py new file mode 100644 index 0000000..037998c --- /dev/null +++ b/app/env_pro/commands/encrypt_cmds.py @@ -0,0 +1,65 @@ +"""Encryption commands for env-pro.""" + +import click + + +@click.command() +def generate(): + """Generate a new encryption key.""" + from env_pro.core.encryption import generate_key, store_key_in_keyring + + key = generate_key() + store_key_in_keyring(key) + click.echo("Generated new encryption key and stored in keyring") + click.echo("Keep this key safe - it's stored in your system keyring") + + +@click.command() +def rotate(): + """Rotate (regenerate) the encryption key.""" + from env_pro.core.encryption import ( + generate_key, store_key_in_keyring, + get_key_from_keyring, encrypt_value + ) + from env_pro.core.profile import get_active_profile, get_profile_vars, set_profile_var + + old_key = get_key_from_keyring() + if old_key is None: + click.echo("No existing key found. Generating new key.") + generate() + return + + new_key = generate_key() + store_key_in_keyring(new_key) + + profile = get_active_profile() or "default" + vars = get_profile_vars(profile) + + reencrypted = 0 + for key_name, value in vars.items(): + try: + decrypted = decrypt_value(value, old_key) + encrypted = encrypt_value(decrypted, new_key) + set_profile_var(profile, key_name, encrypted) + reencrypted += 1 + except Exception: + pass + + click.echo(f"Generated new key and re-encrypted {reencrypted} values") + + +@click.command() +def show(): + """Show key status.""" + from env_pro.core.encryption import get_key_from_keyring + + key = get_key_from_keyring() + if key: + click.echo("Encryption key is set and stored in keyring") + else: + click.echo("No encryption key found. Run 'env-pro key generate' to create one.") + + +def decrypt_value(value, key): + from env_pro.core.encryption import decrypt_value as _decrypt + return _decrypt(value, key)