-
Notifications
You must be signed in to change notification settings - Fork 59
Dev #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Dev #15
Changes from all commits
d8dd081
d1b1ba6
6b62a97
7fbf621
f1f07d7
595fb35
28d8d43
68302ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,9 +1,8 @@ | ||||||||||||||||||
| package com.example; | ||||||||||||||||||
|
|
||||||||||||||||||
| import java.sql.Connection; | ||||||||||||||||||
| import java.sql.DriverManager; | ||||||||||||||||||
| import java.sql.SQLException; | ||||||||||||||||||
| import java.sql.*; | ||||||||||||||||||
| import java.util.Arrays; | ||||||||||||||||||
| import java.util.Scanner; | ||||||||||||||||||
|
|
||||||||||||||||||
| public class Main { | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -27,12 +26,183 @@ public void run() { | |||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| try (Connection connection = DriverManager.getConnection(jdbcUrl, dbUser, dbPass)) { | ||||||||||||||||||
| Scanner scanner = new Scanner(System.in); | ||||||||||||||||||
| boolean loggedIn = false; | ||||||||||||||||||
| while (!loggedIn) { | ||||||||||||||||||
| System.out.print("Username: "); | ||||||||||||||||||
| String username = scanner.nextLine(); | ||||||||||||||||||
| System.out.print("Password: "); | ||||||||||||||||||
| String password = scanner.nextLine(); | ||||||||||||||||||
|
|
||||||||||||||||||
| if (isValidLogin(connection,username,password)) { | ||||||||||||||||||
| loggedIn = true; | ||||||||||||||||||
| System.out.println("Logged in as " + username); | ||||||||||||||||||
| } else { | ||||||||||||||||||
| System.out.println("Invalid username or password"); | ||||||||||||||||||
| System.out.println("0) Exit"); | ||||||||||||||||||
| System.out.println("Press any other key to try again"); | ||||||||||||||||||
|
|
||||||||||||||||||
| String choice = scanner.nextLine(); | ||||||||||||||||||
| if (choice.equals("0")) { | ||||||||||||||||||
| return; | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| while (true) { | ||||||||||||||||||
| printMenu(); | ||||||||||||||||||
| String option = scanner.nextLine(); | ||||||||||||||||||
|
|
||||||||||||||||||
| switch (option) { | ||||||||||||||||||
| case "1": | ||||||||||||||||||
| listMoonMissions(connection); | ||||||||||||||||||
| break; | ||||||||||||||||||
| case "2": | ||||||||||||||||||
| System.out.print("Enter mission_id: "); | ||||||||||||||||||
| String idStr = scanner.nextLine(); | ||||||||||||||||||
| getMoonMissionById(connection, idStr); | ||||||||||||||||||
| break; | ||||||||||||||||||
| case "3": | ||||||||||||||||||
| System.out.print("Enter year: "); | ||||||||||||||||||
| String yearStr = scanner.nextLine(); | ||||||||||||||||||
| countMissionsByYear(connection, yearStr); | ||||||||||||||||||
| break; | ||||||||||||||||||
| case "4": | ||||||||||||||||||
| createAccount(connection, scanner); | ||||||||||||||||||
| break; | ||||||||||||||||||
| case "5": | ||||||||||||||||||
| updateAccountPassword(connection, scanner); | ||||||||||||||||||
| break; | ||||||||||||||||||
| case "6": | ||||||||||||||||||
| deleteAccount(connection, scanner); | ||||||||||||||||||
| break; | ||||||||||||||||||
| case "0": | ||||||||||||||||||
| return; | ||||||||||||||||||
| default: | ||||||||||||||||||
| System.out.println("Invalid option, try again."); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| } | ||||||||||||||||||
| } catch (SQLException e) { | ||||||||||||||||||
| throw new RuntimeException(e); | ||||||||||||||||||
| } | ||||||||||||||||||
| //Todo: Starting point for your code | ||||||||||||||||||
|
|
||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void printMenu() { | ||||||||||||||||||
| System.out.println("\n--- Moon Mission Menu ---"); | ||||||||||||||||||
| System.out.println("1. List moon missions"); | ||||||||||||||||||
| System.out.println("2. Get moon mission by id"); | ||||||||||||||||||
| System.out.println("3. Count missions by year"); | ||||||||||||||||||
| System.out.println("4. Create an account"); | ||||||||||||||||||
| System.out.println("5. Update an account password"); | ||||||||||||||||||
| System.out.println("6. Delete an account"); | ||||||||||||||||||
| System.out.println("0. Exit"); | ||||||||||||||||||
| System.out.print("Choice: "); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void listMoonMissions(Connection conn) throws SQLException { | ||||||||||||||||||
| String query = "SELECT * FROM moon_mission"; | ||||||||||||||||||
| try (PreparedStatement stmt = conn.prepareStatement(query); | ||||||||||||||||||
| ResultSet rs = stmt.executeQuery()) { | ||||||||||||||||||
|
|
||||||||||||||||||
| while (rs.next()) { | ||||||||||||||||||
| System.out.println(rs.getString("spacecraft")); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void getMoonMissionById(Connection conn, String id) throws SQLException { | ||||||||||||||||||
| String query = "SELECT * FROM moon_mission WHERE mission_id = ?"; | ||||||||||||||||||
| try (PreparedStatement stmt = conn.prepareStatement(query)) { | ||||||||||||||||||
| stmt.setString(1, id); | ||||||||||||||||||
| try (ResultSet rs = stmt.executeQuery()) { | ||||||||||||||||||
| if (rs.next()) { | ||||||||||||||||||
| String dateStr = rs.getString("launch_date"); | ||||||||||||||||||
| String year = (dateStr != null && dateStr.length() >= 4) ? dateStr.substring(0, 4) : "N/A"; | ||||||||||||||||||
|
|
||||||||||||||||||
| System.out.println("Mission: " + rs.getString("spacecraft") + | ||||||||||||||||||
| ", Year: " + year); | ||||||||||||||||||
| } else { | ||||||||||||||||||
| System.out.println("Mission not found."); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void countMissionsByYear(Connection conn, String year) throws SQLException { | ||||||||||||||||||
| String query = "SELECT COUNT(*) FROM moon_mission WHERE YEAR(launch_date) = ?"; | ||||||||||||||||||
| try (PreparedStatement stmt = conn.prepareStatement(query)) { | ||||||||||||||||||
| stmt.setString(1, year); | ||||||||||||||||||
| try (ResultSet rs = stmt.executeQuery()) { | ||||||||||||||||||
| if (rs.next()) { | ||||||||||||||||||
| int count = rs.getInt(1); | ||||||||||||||||||
| System.out.println("Missions in " + year + ": " + count); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void createAccount(Connection conn, Scanner sc) throws SQLException { | ||||||||||||||||||
| System.out.print("First name: "); | ||||||||||||||||||
| String first = sc.nextLine(); | ||||||||||||||||||
| System.out.print("Last name: "); | ||||||||||||||||||
| String last = sc.nextLine(); | ||||||||||||||||||
| System.out.print("SSN: "); | ||||||||||||||||||
| String ssn = sc.nextLine(); | ||||||||||||||||||
| System.out.print("Password: "); | ||||||||||||||||||
| String pass = sc.nextLine(); | ||||||||||||||||||
|
|
||||||||||||||||||
| String generatedName = ""; | ||||||||||||||||||
| if (first.length() >= 3 && last.length() >= 3) { | ||||||||||||||||||
| generatedName = first.substring(0, 3) + last.substring(0, 3); | ||||||||||||||||||
| } else { | ||||||||||||||||||
| generatedName = first + last; | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+155
to
+160
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Simplify name generation to match The conditional logic creates inconsistent usernames for short names. When either name is shorter than 3 characters, it concatenates the full names, which differs from the Apply this diff to ensure consistent behavior: - String generatedName = "";
- if (first.length() >= 3 && last.length() >= 3) {
- generatedName = first.substring(0, 3) + last.substring(0, 3);
- } else {
- generatedName = first + last;
- }
+ String generatedName = first.substring(0, Math.min(3, first.length())) +
+ last.substring(0, Math.min(3, last.length()));This ensures names like "Al Smith" generate "AlSmi" instead of "AlSmith". 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| String query = "INSERT INTO account (name, first_name, last_name, ssn, password) VALUES (?, ?, ?, ?, ?)"; | ||||||||||||||||||
|
|
||||||||||||||||||
| try (PreparedStatement stmt = conn.prepareStatement(query)) { | ||||||||||||||||||
| stmt.setString(1, generatedName); // Sätter det genererade namnet | ||||||||||||||||||
| stmt.setString(2, first); | ||||||||||||||||||
| stmt.setString(3, last); | ||||||||||||||||||
| stmt.setString(4, ssn); | ||||||||||||||||||
| stmt.setString(5, pass); | ||||||||||||||||||
| stmt.executeUpdate(); | ||||||||||||||||||
| System.out.println("Account created. Your username is: " + generatedName); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private void updateAccountPassword(Connection conn, Scanner sc) throws SQLException { | ||||||||||||||||||
| System.out.print("Enter user_id: "); | ||||||||||||||||||
| String id = sc.nextLine(); | ||||||||||||||||||
| System.out.print("Enter new password: "); | ||||||||||||||||||
| String pass = sc.nextLine(); | ||||||||||||||||||
|
|
||||||||||||||||||
| String query = "UPDATE account SET password = ? WHERE user_id = ?"; | ||||||||||||||||||
| try (PreparedStatement stmt = conn.prepareStatement(query)) { | ||||||||||||||||||
| stmt.setString(1, pass); | ||||||||||||||||||
| stmt.setString(2, id); | ||||||||||||||||||
| int rows = stmt.executeUpdate(); | ||||||||||||||||||
| if (rows > 0) System.out.println("Password updated."); | ||||||||||||||||||
| else System.out.println("User not found."); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+175
to
+189
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Missing authorization check allows privilege escalation. Any authenticated user can change anyone's password by providing any At minimum, verify the logged-in user is modifying their own account: private void updateAccountPassword(Connection conn, Scanner sc) throws SQLException {
System.out.print("Enter user_id: ");
String id = sc.nextLine();
System.out.print("Enter new password: ");
String pass = sc.nextLine();
- String query = "UPDATE account SET password = ? WHERE user_id = ?";
+ // TODO: Pass the authenticated username to this method and verify user_id matches
+ String query = "UPDATE account SET password = ? WHERE user_id = ? AND name = ?";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
stmt.setString(1, pass);
stmt.setString(2, id);
+ stmt.setString(3, authenticatedUsername); // Verify ownership
int rows = stmt.executeUpdate();Alternatively, remove the Additionally,
🤖 Prompt for AI Agents |
||||||||||||||||||
| private void deleteAccount(Connection conn, Scanner sc) throws SQLException { | ||||||||||||||||||
| System.out.print("Enter user_id: "); | ||||||||||||||||||
| String id = sc.nextLine(); | ||||||||||||||||||
|
|
||||||||||||||||||
| String query = "DELETE FROM account WHERE user_id = ?"; | ||||||||||||||||||
| try (PreparedStatement stmt = conn.prepareStatement(query)) { | ||||||||||||||||||
| stmt.setString(1, id); | ||||||||||||||||||
| int rows = stmt.executeUpdate(); | ||||||||||||||||||
| if (rows > 0) System.out.println("Account deleted."); | ||||||||||||||||||
| else System.out.println("User not found."); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+190
to
+201
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Missing authorization check and confirmation for destructive operation. This method has two critical issues:
Add authorization and confirmation: private void deleteAccount(Connection conn, Scanner sc) throws SQLException {
System.out.print("Enter user_id: ");
String id = sc.nextLine();
+
+ System.out.print("Are you sure you want to delete this account? (yes/no): ");
+ String confirm = sc.nextLine();
+ if (!confirm.equalsIgnoreCase("yes")) {
+ System.out.println("Delete cancelled.");
+ return;
+ }
- String query = "DELETE FROM account WHERE user_id = ?";
+ // TODO: Pass authenticated username and verify ownership
+ String query = "DELETE FROM account WHERE user_id = ? AND name = ?";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
- stmt.setString(1, id);
+ stmt.setInt(1, Integer.parseInt(id));
+ stmt.setString(2, authenticatedUsername); // Verify ownership
int rows = stmt.executeUpdate();Consider whether account deletion should even be self-service, or if it should require admin privileges.
|
||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| /** | ||||||||||||||||||
| * Determines if the application is running in development mode based on system properties, | ||||||||||||||||||
| * environment variables, or command-line arguments. | ||||||||||||||||||
|
|
@@ -59,4 +229,16 @@ private static String resolveConfig(String propertyKey, String envKey) { | |||||||||||||||||
| } | ||||||||||||||||||
| return (v == null || v.trim().isEmpty()) ? null : v.trim(); | ||||||||||||||||||
| } | ||||||||||||||||||
| private boolean isValidLogin(Connection conn, String user, String pass) throws SQLException { | ||||||||||||||||||
| String query = "SELECT * FROM account WHERE name = ? AND password = ?"; | ||||||||||||||||||
|
|
||||||||||||||||||
| try (PreparedStatement stmt = conn.prepareStatement(query)) { | ||||||||||||||||||
| stmt.setString(1, user); | ||||||||||||||||||
| stmt.setString(2, pass); | ||||||||||||||||||
|
|
||||||||||||||||||
| try (ResultSet rs = stmt.executeQuery()) { | ||||||||||||||||||
| return rs.next(); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make mission queries deterministic + avoid
SELECT *.SELECT *and missingORDER BYcan make outputs flaky (and unnecessarily reads columns).(If the tests feed non-numeric years, wrap the
parseIntwith a friendly error message instead of throwing.)📝 Committable suggestion
🤖 Prompt for AI Agents