roster/example_sensitive_vars.py

159 lines
5.6 KiB
Python

#!/usr/bin/env python3
"""
Example script demonstrating sensitive variable usage.
This script shows how to:
1. Create a project with variables
2. Mark some variables as sensitive
3. Set values for both regular and sensitive variables
4. Retrieve values from both storages
5. Use variables in request substitution
Run this from the project root after building the app.
"""
import sys
import os
# Add src to path for testing
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
from roster.project_manager import ProjectManager
from roster.models import HttpRequest
from roster.variable_substitution import VariableSubstitution
def main():
print("=" * 60)
print("Sensitive Variables Example")
print("=" * 60)
pm = ProjectManager()
# Create a test project
print("\n1. Creating test project...")
project = pm.add_project("API Test Project")
project_id = project.id
print(f" Created project: {project.name} (ID: {project_id})")
# Add environments
print("\n2. Adding environments...")
env_prod = pm.add_environment(project_id, "Production")
env_dev = pm.add_environment(project_id, "Development")
print(f" - Production (ID: {env_prod.id})")
print(f" - Development (ID: {env_dev.id})")
# Add variables
print("\n3. Adding variables...")
pm.add_variable(project_id, "base_url")
pm.add_variable(project_id, "api_key")
pm.add_variable(project_id, "timeout")
print(" - base_url (regular)")
print(" - api_key (regular for now)")
print(" - timeout (regular)")
# Set values for regular variables
print("\n4. Setting values for regular variables...")
pm.set_variable_value(project_id, env_prod.id, "base_url", "https://api.example.com")
pm.set_variable_value(project_id, env_dev.id, "base_url", "https://dev.api.example.com")
pm.set_variable_value(project_id, env_prod.id, "timeout", "30")
pm.set_variable_value(project_id, env_dev.id, "timeout", "60")
print(" ✓ Set base_url for both environments")
print(" ✓ Set timeout for both environments")
# Set API key values (still regular)
print("\n5. Setting API key values (in JSON - NOT SECURE YET)...")
pm.set_variable_value(project_id, env_prod.id, "api_key", "prod-secret-key-12345")
pm.set_variable_value(project_id, env_dev.id, "api_key", "dev-secret-key-67890")
print(" ⚠ API keys stored in plain JSON file!")
# Mark API key as sensitive
print("\n6. Marking api_key as SENSITIVE...")
success = pm.mark_variable_as_sensitive(project_id, "api_key")
if success:
print(" ✓ api_key is now stored in GNOME Keyring (encrypted)")
print(" ✓ Values moved from JSON to keyring")
print(" ✓ JSON now contains empty placeholders")
else:
print(" ✗ Failed to mark as sensitive")
return
# Verify storage
print("\n7. Verifying storage...")
is_sensitive = pm.is_variable_sensitive(project_id, "api_key")
print(f" - api_key is sensitive: {is_sensitive}")
# Retrieve values
print("\n8. Retrieving values...")
base_url_prod = pm.get_variable_value(project_id, env_prod.id, "base_url")
api_key_prod = pm.get_variable_value(project_id, env_prod.id, "api_key")
api_key_dev = pm.get_variable_value(project_id, env_dev.id, "api_key")
print(f" - Production base_url: {base_url_prod}")
print(f" - Production api_key: {api_key_prod} (from keyring)")
print(f" - Development api_key: {api_key_dev} (from keyring)")
# Use in request substitution
print("\n9. Using in request substitution...")
request = HttpRequest(
method="GET",
url="{{base_url}}/users",
headers={
"Authorization": "Bearer {{api_key}}",
"X-Timeout": "{{timeout}}"
},
body=""
)
print(f" Original request URL: {request.url}")
print(f" Original request headers: {request.headers}")
# Get environment with secrets
env_with_secrets = pm.get_environment_with_secrets(project_id, env_prod.id)
# Substitute variables
vs = VariableSubstitution()
substituted_request, undefined = vs.substitute_request(request, env_with_secrets)
print(f"\n Substituted request URL: {substituted_request.url}")
print(f" Substituted headers: {substituted_request.headers}")
print(f" Undefined variables: {undefined}")
# Demonstrate file storage
print("\n10. Checking file storage...")
projects = pm.load_projects()
for p in projects:
if p.id == project_id:
print(f" Variables: {p.variable_names}")
print(f" Sensitive variables: {p.sensitive_variables}")
for env in p.environments:
if env.id == env_prod.id:
print(f" Production variables in JSON: {env.variables}")
print(f" Notice: api_key is empty (value in keyring)")
# Cleanup
print("\n11. Cleanup...")
response = input(" Delete test project? (y/n): ")
if response.lower() == 'y':
pm.delete_project(project_id)
print(" ✓ Project deleted (secrets also removed from keyring)")
else:
print(f" Project kept. ID: {project_id}")
print(" You can view secrets in 'Passwords and Keys' app")
print("\n" + "=" * 60)
print("Example completed!")
print("=" * 60)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\nInterrupted by user")
sys.exit(1)
except Exception as e:
print(f"\n\nError: {e}")
import traceback
traceback.print_exc()
sys.exit(1)