Skip to content

Commit 0ce686b

Browse files
committed
chore(deploy): despliegue en entorno de prueba 🌐
1 parent 47c6d55 commit 0ce686b

4 files changed

Lines changed: 452 additions & 0 deletions

File tree

review/._AutoCommit.py_review.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<!-- hash:1e2624ce93a088692c9388f1f95cf6d79636511fe76143e7330967e35c9a9ada -->
2+
# Code Review for AutoCommit.py
3+
4+
This Python code automates a basic Git workflow: adding changes, committing them with a message, and optionally pushing them to a remote repository. Let's break it down step-by-step:
5+
6+
1. **`import subprocess`**: This line imports the `subprocess` module. The `subprocess` module allows you to run external commands as if you were typing them directly into your terminal. This is essential for interacting with Git.
7+
8+
2. **`mensaje = input("Mensaje del commit: ")`**: This line prompts the user to enter a commit message and stores the input in the variable `mensaje`. The message is what explains the changes you're making.
9+
10+
3. **`confirm = input("¿Hacer push? (s/n): ").lower()`**: This line prompts the user to confirm whether they want to push the changes to a remote repository. It accepts input 's' (for yes) or 'n' (for no). `.lower()` converts the input to lowercase, making the comparison case-insensitive.
11+
12+
4. **`subprocess.run(["git", "add", "."])`**: This line executes the `git add .` command. `git add .` stages all the modified and new files in the current directory for the next commit. The `.` specifies that you want to add everything in the current directory and its subdirectories. The `subprocess.run()` function runs the command and waits for it to finish. The arguments are passed as a list, where each element is a separate part of the command.
13+
14+
5. **`subprocess.run(["git", "commit", "-m", mensaje])`**: This line executes the `git commit -m "mensaje"` command. `git commit` commits the staged changes with the provided message. The `-m` flag specifies that the commit message is provided directly on the command line. The `mensaje` variable, which holds the user's input, is used as the commit message.
15+
16+
6. **`if confirm == "s":`**: This line checks if the user entered 's' (or 'S') to confirm the push.
17+
18+
7. **`subprocess.run(["git", "push"])`**: If the user confirmed, this line executes the `git push` command. `git push` uploads the committed changes to the remote repository (typically origin/main or origin/master).
19+
20+
8. **`else:`**: If the user did not confirm, the code executes the `else` block.
21+
22+
9. **`print("Push cancelado.")`**: This line prints a message indicating that the push has been canceled.
23+
24+
**In summary, this code automates the following Git steps:**
25+
26+
1. **Stages all changes:** `git add .`
27+
2. **Commits the staged changes:** `git commit -m "user-provided message"`
28+
3. **Conditionally pushes the commits to the remote repository:** `git push` (only if the user confirms).
29+
30+
**Important Considerations:**
31+
32+
* **Error Handling:** This code lacks error handling. If any of the Git commands fail (e.g., no remote repository is configured, the user doesn't have commit permissions), the script will simply continue running or might throw an exception. A more robust script would check the return code of `subprocess.run()` to handle errors gracefully (e.g., print an error message and exit).
33+
* **Remote Tracking:** `git push` assumes you have a remote tracking branch configured. If not, you might need to specify the remote and branch (e.g., `git push origin main`).
34+
* **Security:** While this script itself is relatively safe, be careful when incorporating it into larger systems where user input might influence other parts of your code. Always sanitize and validate user input to prevent potential security vulnerabilities.
35+
* **Git Configuration:** This script relies on the user having Git properly installed and configured on their system.
36+
* **Branch:** This script pushes to the default branch configured. It would be more flexible to allow the user to specify the branch.
37+
38+
Here's an example of how you might add basic error handling:
39+
40+
```python
41+
import subprocess
42+
43+
mensaje = input("Mensaje del commit: ")
44+
confirm = input("¿Hacer push? (s/n): ").lower()
45+
46+
try:
47+
result = subprocess.run(["git", "add", "."], capture_output=True, text=True, check=True)
48+
print(result.stdout) # Print the output of the command
49+
except subprocess.CalledProcessError as e:
50+
print(f"Error adding files: {e.stderr}")
51+
exit(1)
52+
53+
try:
54+
result = subprocess.run(["git", "commit", "-m", mensaje], capture_output=True, text=True, check=True)
55+
print(result.stdout)
56+
except subprocess.CalledProcessError as e:
57+
print(f"Error committing: {e.stderr}")
58+
exit(1)
59+
60+
if confirm == "s":
61+
try:
62+
result = subprocess.run(["git", "push"], capture_output=True, text=True, check=True)
63+
print(result.stdout)
64+
except subprocess.CalledProcessError as e:
65+
print(f"Error pushing: {e.stderr}")
66+
exit(1)
67+
else:
68+
print("Push cancelado.")
69+
```
70+
71+
Key improvements in the example:
72+
73+
* **`capture_output=True`**: This captures the standard output (stdout) and standard error (stderr) of the Git commands.
74+
* **`text=True`**: This decodes the output as text.
75+
* **`check=True`**: This raises a `subprocess.CalledProcessError` if the Git command returns a non-zero exit code (indicating an error).
76+
* **`try...except` blocks**: These handle potential `CalledProcessError` exceptions, allowing you to print an error message (including the output from Git) and exit the script gracefully. The `exit(1)` call indicates that the script exited with an error.
77+
* **Printing Output:** The `print(result.stdout)` lines will print the output of the git command, giving feedback to the user.
78+
79+
This enhanced version provides better feedback and handles errors more effectively. Remember to adapt this error handling to your specific needs and logging requirements.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<!-- hash:f243687755be8a55512bfc36c597330dad9bc62da95ce00930838c676222121a -->
2+
# Code Review for check_files.py
3+
4+
```python
5+
#!/usr/bin/env python3
6+
import os
7+
import re
8+
import subprocess
9+
import sys
10+
import shutil
11+
12+
# -------------------------------
13+
# Carpetas a ignorar
14+
# -------------------------------
15+
IGNORE_DIRS = {"venv", ".git", "node_modules", "__pycache__", ".mypy_cache"}
16+
17+
# -------------------------------
18+
# Filtros por stack para limpiar salida
19+
# -------------------------------
20+
FILTERS_BY_STACK = {
21+
"django": [
22+
(r"(SECRET_KEY\s*=\s*['\"].*?['\"])", "SECRET_KEY = '***REDACTED***'"),
23+
(r"(PASSWORD\s*=\s*['\"].*?['\"])", "PASSWORD = '***REDACTED***'"),
24+
(r"(API_KEY\s*=\s*['\"].*?['\"])", "API_KEY = '***REDACTED***'"),
25+
(r"(DEBUG\s*=\s*True)", r"\1 # DEV MODE: No usar en producción"),
26+
(r"(ALLOWED_HOSTS\s*=\s*\[.*?\])", "ALLOWED_HOSTS = ['*'] # DEV ONLY")
27+
],
28+
"flask": [
29+
(r"(SECRET_KEY\s*=\s*['\"].*?['\"])", "SECRET_KEY = '***REDACTED***'"),
30+
(r"(SQLALCHEMY_DATABASE_URI\s*=\s*['\"].*?['\"])", "SQLALCHEMY_DATABASE_URI = '***REDACTED***'"),
31+
(r"(DEBUG\s*=\s*True)", r"\1 # DEV MODE: No usar en producción")
32+
],
33+
"node": [
34+
(r"(process\.env\.(?:[A-Z_]+_?KEY|PASSWORD|TOKEN|SECRET)[^\n]*)", "/* ***REDACTED*** */"),
35+
(r"(['\"](?:AIza|sk-|ghp_)[A-Za-z0-9_\-]+['\"])", "'***REDACTED***'"),
36+
(r"(app\.listen\(\s*\d+\s*\))", r"\1 // DEV PORT, ajustar en producción")
37+
],
38+
"react": [
39+
(r"(process\.env\.REACT_APP_[A-Z0-9_]+)", "/* ***REDACTED*** */"),
40+
(r"(https?:\/\/[^\s'\"]+\/api[^\s'\"]*)", "'***R
41+
```
42+
43+
**Explanation:**
44+
45+
This Python script is designed to sanitize code in a project directory, primarily by redacting sensitive information like API keys, passwords, and secrets before sharing or committing the code to a public repository. It aims to prevent accidental exposure of credentials.
46+
47+
Here's a breakdown of the code's functionality:
48+
49+
1. **Imports:**
50+
- `os`: Provides functions for interacting with the operating system (e.g., navigating directories, listing files).
51+
- `re`: Enables regular expression operations for pattern matching and replacement in strings. This is crucial for finding and redacting sensitive data.
52+
- `subprocess`: Allows running external commands (like `git status`) and capturing their output.
53+
- `sys`: Provides access to system-specific parameters and functions (e.g., command-line arguments).
54+
- `shutil`: Offers high-level file operations (e.g., copying files and trees). While imported, it's not directly used in the snippet provided. It's likely used in the full script, but the provided section doesn't show that usage.
55+
56+
2. **`IGNORE_DIRS`:**
57+
- `IGNORE_DIRS = {"venv", ".git", "node_modules", "__pycache__", ".mypy_cache"}`: This is a set of directory names that the script will skip when traversing the project directory. These directories typically contain:
58+
- `venv`: Python virtual environments (contains dependencies).
59+
- `.git`: The Git repository directory (contains version control information).
60+
- `node_modules`: Node.js dependencies (often very large).
61+
- `__pycache__`: Python bytecode cache directories.
62+
- `.mypy_cache`: MyPy cache directory
63+
64+
Ignoring these directories speeds up the process and prevents the script from accidentally modifying files within them, which could break dependencies or version control.
65+
66+
3. **`FILTERS_BY_STACK`:**
67+
- This is a dictionary that holds regular expression-based filters for different technology stacks (e.g., "django", "flask", "node", "react"). The filters are used to identify and replace sensitive information in code files.
68+
- Each key in the dictionary represents a technology stack.
69+
- Each value is a list of tuples, where each tuple contains:
70+
- A regular expression pattern (as a string).
71+
- A replacement string.
72+
- **Example (Django):**
73+
- `(r"(SECRET_KEY\s*=\s*['\"].*?['\"])", "SECRET_KEY = '***REDACTED***'")`
74+
- This regular expression looks for lines of code that define a `SECRET_KEY` variable. Specifically:
75+
- `SECRET_KEY`: Matches the literal string "SECRET_KEY".
76+
- `\s*=\s*`: Matches zero or more whitespace characters followed by an equals sign followed by zero or more whitespace characters.
77+
- `['\"]`: Matches either a single quote or a double quote.
78+
- `.*?`: Matches any character (except newline) zero or more times, but as few times as possible (non-greedy). This matches the actual key.
79+
- `['\"]`: Matches the closing single or double quote.
80+
- The replacement string replaces the entire matched line with `SECRET_KEY = '***REDACTED***'`, effectively obscuring the actual secret key.
81+
- `(r"(DEBUG\s*=\s*True)", r"\1 # DEV MODE: No usar en producción")`
82+
- This regex finds the line `DEBUG = True`. The `\1` in the replacement string refers to the first captured group (in this case, the entire matched string: `DEBUG = True`). This adds a comment warning not to use the debug mode in production.
83+
- `(r"(ALLOWED_HOSTS\s*=\s*\[.*?\])", "ALLOWED_HOSTS = ['*'] # DEV ONLY")`
84+
- This regex replaces the `ALLOWED_HOSTS` setting with `ALLOWED_HOSTS = ['*']`. This is a common development setting, but is extremely insecure for production as it allows any host to access the application. The comment highlights that this is for development only.
85+
86+
- **Other Stacks:** Similar filters are defined for Flask, Node.js, and React, targeting common places where secrets and sensitive data might be stored. The Node filters look for environment variables containing keys, passwords, tokens, or secrets, and also specifically looks for common API key prefixes (like "AIza", "sk-", "ghp_"). The React filters target environment variables prefixed with `REACT_APP_` and API endpoints.
87+
88+
**How the script is *likely* used (based on common patterns):**
89+
90+
The provided code snippet represents the **definition** of the filters and the ignored directories. A larger script would typically:
91+
92+
1. **Take a directory as input** (using `sys.argv` to get a command-line argument).
93+
2. **Walk through the directory tree** (using `os.walk`).
94+
3. **Identify the technology stack** used in the project (likely through heuristics like checking for certain files, e.g., `manage.py` for Django, `package.json` for Node.js).
95+
4. **Based on the detected stack, apply the appropriate filters** from `FILTERS_BY_STACK` to each file:
96+
- Read the file content.
97+
- Iterate through the regex patterns in the stack's filter list.
98+
- Use `re.sub()` to find and replace matches with the corresponding replacement string.
99+
- Write the modified content back to the file.
100+
5. **Optionally, create a new sanitized directory** (copying the original and modifying in place). This is where `shutil` would be used.
101+
102+
**In summary:**
103+
104+
This script is a code sanitizer that helps prevent the accidental disclosure of sensitive information by automatically redacting or modifying potentially sensitive data within a project's codebase. It uses regular expressions and stack-specific filters to target common locations where secrets are stored. It's a crucial tool for security-conscious developers who need to share or publish their code without exposing their credentials.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!-- hash:cc1c212da5daf2757e7e78cea64ab4f8dd24ccac51c6c6815b16f63d0ad870a1 -->
2+
# Code Review for ratatouille.py
3+
4+
This Python code defines a function called `ratatouille` that simulates a dangerous system command based on the detected operating system. Let's break it down step-by-step:
5+
6+
**1. Imports:**
7+
8+
* `import os`: Imports the `os` module, which provides functions for interacting with the operating system. While it's imported, it's *not* actually used in this specific code snippet. This is a bit suspicious, as the `os` module *could* be used to actually execute commands (which this code explicitly avoids).
9+
* `import platform`: Imports the `platform` module, which allows the code to identify the operating system.
10+
11+
**2. `ratatouille()` function:**
12+
13+
* `sistema = platform.system()`: This line uses the `platform.system()` function to determine the operating system the script is running on (e.g., "Windows", "Linux", "Darwin"). The result is stored in the `sistema` variable.
14+
15+
* `if sistema == "Windows":`: This starts a conditional block. If the operating system is Windows, the following code is executed:
16+
17+
* `print("[!] Detectado Windows – simulando eliminación de System32...")`: Prints a warning message in Spanish, indicating that Windows has been detected and it's simulating the deletion of the `System32` directory. `System32` is a critical directory in Windows, and deleting it would render the system unusable.
18+
* `print("rm -rf C:\\Windows\\System32 (simulado)")`: Prints a simulated command that *would* delete the `System32` directory. **Crucially, this is just a print statement, NOT an actual system command.** The `rm -rf` command is a powerful (and dangerous) Linux command that recursively and forcefully deletes files and directories. The `C:\\Windows\\System32` is the Windows path to the `System32` directory. The `(simulado)` part confirms it's simulated.
19+
20+
* `elif sistema in ("Linux", "Darwin"):`: This `elif` (else if) block checks if the operating system is either Linux or Darwin (macOS).
21+
22+
* `print(f"[!] Detectado {sistema} – simulando eliminación del root...")`: Prints a warning message in Spanish stating the OS and warning of root deletion simulation
23+
* `print("sudo rm -rf / (simulado)")`: Prints a simulated command that *would* delete the entire root directory on Linux or macOS. `/` is the root directory, and deleting it would effectively wipe the entire system. `sudo` is a command that elevates privileges to root, allowing for the deletion of protected files. Again, the `(simulado)` indicates that this is only a simulation.
24+
25+
* `else:`: This `else` block is executed if the operating system is neither Windows, Linux, nor Darwin.
26+
27+
* `print("[!] Sistema no reconocido – sin acción.")`: Prints a message in Spanish stating that the OS is not recognized and therefore no action is taken.
28+
29+
**3. `ratatouille()` call:**
30+
31+
* `ratatouille()`: This line calls the `ratatouille` function, causing the code inside the function to be executed.
32+
33+
**In summary:**
34+
35+
This code *simulates* the execution of extremely dangerous commands that, if actually run, would severely damage or destroy the operating system. It's designed to demonstrate the potential consequences of running such commands, but it **does not actually execute them**. The messages make it explicitly clear that the commands are "simulated." It determines the operating system and then prints a warning message along with the simulated dangerous command.
36+
37+
**Important Note:** While this code is relatively harmless *because* it only prints the commands, it's important to understand that:
38+
39+
* **Running actual commands like `rm -rf /` or `rm -rf C:\\Windows\\System32` WILL destroy your system.**
40+
* Code like this *could* be modified to actually execute the commands. The inclusion of `import os` makes that potential slightly more concerning. It's a red flag.
41+
* Sharing code that simulates dangerous commands, even if it's only for educational purposes, should be done with extreme caution and very clear warnings.
42+
43+
This code is a cautionary example of how a seemingly simple script can have potentially destructive implications. Always be very careful when running code from unknown sources, especially if it involves system commands.

0 commit comments

Comments
 (0)