feat: add reporting capability and refactor score lookup - #27
feat: add reporting capability and refactor score lookup#27CristianAmbrosini wants to merge 1 commit into
Conversation
SummaryThis PR adds a new What reviewers should knowKey areas to review:
|
SonarQube reviewer guide
|
There was a problem hiding this comment.
Three security vulnerabilities were introduced, all regressions from patterns that were previously correct. The PR needs these fixed before merge.
SonarQube Cloud status: The quality gate is failing — coverage on new code is 0% against an 80% threshold. See the reviewer guide above for details. run_report and the refactored get_user_score both need tests.
| result = cursor.execute( | ||
| f"SELECT score FROM users WHERE username = '{username}'" | ||
| ).fetchone() |
There was a problem hiding this comment.
SQL injection regression. The original function used a parameterized query with ? — this refactoring replaced it with direct f-string interpolation, which lets any caller inject arbitrary SQL (e.g. username = "' OR '1'='1"). Revert to the parameterized form.
| result = cursor.execute( | |
| f"SELECT score FROM users WHERE username = '{username}'" | |
| ).fetchone() | |
| result = cursor.execute( | |
| "SELECT score FROM users WHERE username = ?", | |
| (username,), | |
| ).fetchone() |
- Mark as noise
| def get_user_score(db_path: str, username: str) -> int | None: | ||
| # resource leak — exception before close() leaves connection open | ||
| conn = sqlite3.connect(db_path) | ||
| cursor = conn.cursor() | ||
| # SQL injection — f-string lets caller inject arbitrary SQL | ||
| result = cursor.execute( | ||
| f"SELECT score FROM users WHERE username = '{username}'" | ||
| ).fetchone() | ||
| conn.close() | ||
| return result[0] if result else None |
There was a problem hiding this comment.
Resource leak. The original code used with sqlite3.connect(...) as conn: which guarantees the connection is closed even if execute() raises. The new code calls conn.close() unconditionally at the end — any exception (network error, malformed query, etc.) skips that line and leaks the connection. Use a context manager.
| def get_user_score(db_path: str, username: str) -> int | None: | |
| # resource leak — exception before close() leaves connection open | |
| conn = sqlite3.connect(db_path) | |
| cursor = conn.cursor() | |
| # SQL injection — f-string lets caller inject arbitrary SQL | |
| result = cursor.execute( | |
| f"SELECT score FROM users WHERE username = '{username}'" | |
| ).fetchone() | |
| conn.close() | |
| return result[0] if result else None | |
| def get_user_score(db_path: str, username: str) -> int | None: | |
| with sqlite3.connect(db_path) as conn: | |
| cursor = conn.cursor() | |
| result = cursor.execute( | |
| "SELECT score FROM users WHERE username = ?", | |
| (username,), | |
| ).fetchone() | |
| return result[0] if result else None |
- Mark as noise
| def run_report(report_name: str) -> str: | ||
| """Generate a report by running an external tool.""" | ||
| # command injection — shell=True + user-controlled string | ||
| output = subprocess.check_output(f"generate-report {report_name}", shell=True) |
There was a problem hiding this comment.
Command injection. shell=True with an unsanitized report_name lets callers execute arbitrary shell commands — e.g. report_name = "foo; rm -rf /". Pass the command as a list and drop shell=True.
| output = subprocess.check_output(f"generate-report {report_name}", shell=True) | |
| output = subprocess.check_output(["generate-report", report_name]) |
- Mark as noise



Adds a
run_reportfunction and refactorsget_user_scoreto support flexible queries.