-
Notifications
You must be signed in to change notification settings - Fork 1
Moon mission db #3
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?
Changes from all commits
8ba1148
f572162
e55a38f
739e517
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 |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.example; | ||
|
|
||
| import java.sql.SQLException; | ||
|
|
||
| public interface AccountRepository { | ||
| boolean findByNameAndPassword(String username, String password) throws SQLException; | ||
| int create(String firstName, String lastName, String ssn, String password, String username) throws SQLException; | ||
| int updatePassword(long userId, String newPassword) throws SQLException; | ||
| int delete(long userId) throws SQLException; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.example; | ||
|
|
||
| import java.sql.Connection; | ||
| import java.sql.SQLException; | ||
|
|
||
| public interface DataSource { | ||
| Connection getConnection() throws SQLException; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| package com.example; | ||
|
|
||
| import java.sql.Connection; | ||
| import java.sql.PreparedStatement; | ||
| import java.sql.ResultSet; | ||
| import java.sql.SQLException; | ||
|
|
||
| public class JdbcAccountRepository implements AccountRepository { | ||
|
|
||
| private final DataSource dataSource; | ||
|
|
||
| public JdbcAccountRepository(DataSource dataSource) { | ||
| this.dataSource = dataSource; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean findByNameAndPassword(String username, String password) throws SQLException { | ||
| String sql = "SELECT user_id FROM account WHERE name = ? AND password = ?"; | ||
| // Använder try-with-resources för att säkerställa att Connection stängs | ||
| try (Connection connection = dataSource.getConnection(); | ||
| PreparedStatement stmt = connection.prepareStatement(sql)) { | ||
| stmt.setString(1, username); | ||
| stmt.setString(2, password); | ||
| try (ResultSet rs = stmt.executeQuery()) { | ||
| return rs.next(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public int create(String firstName, String lastName, String ssn, String password, String username) throws SQLException { | ||
| String sql = "INSERT INTO account (first_name, last_name, ssn, password, name) VALUES (?, ?, ?, ?, ?)"; | ||
| try (Connection connection = dataSource.getConnection(); | ||
| PreparedStatement stmt = connection.prepareStatement(sql)) { | ||
| stmt.setString(1, firstName); | ||
| stmt.setString(2, lastName); | ||
| stmt.setString(3, ssn); | ||
| stmt.setString(4, password); | ||
| stmt.setString(5, username); | ||
|
|
||
| return stmt.executeUpdate(); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public int updatePassword(long userId, String newPassword) throws SQLException { | ||
| String sql = "UPDATE account SET password = ? WHERE user_id = ?"; | ||
| try (Connection connection = dataSource.getConnection(); | ||
| PreparedStatement stmt = connection.prepareStatement(sql)) { | ||
| stmt.setString(1, newPassword); | ||
| stmt.setLong(2, userId); | ||
|
|
||
| return stmt.executeUpdate(); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public int delete(long userId) throws SQLException { | ||
| String sql = "DELETE FROM account WHERE user_id = ?"; | ||
| try (Connection connection = dataSource.getConnection(); | ||
| PreparedStatement stmt = connection.prepareStatement(sql)) { | ||
| stmt.setLong(1, userId); | ||
|
|
||
| return stmt.executeUpdate(); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| package com.example; | ||
|
|
||
| import java.sql.Connection; | ||
| import java.sql.PreparedStatement; | ||
| import java.sql.ResultSet; | ||
| import java.sql.SQLException; | ||
| import java.sql.Statement; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class JdbcMoonMissionRepository implements MoonMissionRepository { | ||
|
|
||
| private final DataSource dataSource; | ||
|
|
||
| public JdbcMoonMissionRepository(DataSource dataSource) { | ||
| this.dataSource = dataSource; | ||
| } | ||
|
|
||
| @Override | ||
| public List<String> findAllSpacecraftNames() throws SQLException { | ||
| List<String> names = new ArrayList<>(); | ||
| String sql = "SELECT spacecraft FROM moon_mission"; | ||
| try (Connection connection = dataSource.getConnection(); | ||
| Statement stmt = connection.createStatement(); | ||
| ResultSet rs = stmt.executeQuery(sql)) { | ||
| while (rs.next()) { | ||
| names.add(rs.getString("spacecraft")); | ||
| } | ||
| } | ||
| return names; | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public ResultSet findMissionById(long missionId, Connection connection) throws SQLException { | ||
| String sql = "SELECT * FROM moon_mission WHERE mission_id = ?"; | ||
| PreparedStatement stmt = connection.prepareStatement(sql); | ||
| stmt.setLong(1, missionId); | ||
| return stmt.executeQuery(); | ||
| } | ||
|
Comment on lines
+34
to
+40
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. Resource leak: The This is another reason to avoid returning - @Override
- public ResultSet findMissionById(long missionId, Connection connection) throws SQLException {
- String sql = "SELECT * FROM moon_mission WHERE mission_id = ?";
- PreparedStatement stmt = connection.prepareStatement(sql);
- stmt.setLong(1, missionId);
- return stmt.executeQuery();
- }
+ @Override
+ public Optional<MoonMission> findMissionById(long missionId) throws SQLException {
+ String sql = "SELECT * FROM moon_mission WHERE mission_id = ?";
+ try (Connection connection = dataSource.getConnection();
+ PreparedStatement stmt = connection.prepareStatement(sql)) {
+ stmt.setLong(1, missionId);
+ try (ResultSet rs = stmt.executeQuery()) {
+ if (rs.next()) {
+ return Optional.of(new MoonMission(
+ rs.getLong("mission_id"),
+ rs.getString("spacecraft"),
+ rs.getDate("launch_date").toLocalDate(),
+ rs.getString("outcome")
+ ));
+ }
+ return Optional.empty();
+ }
+ }
+ }
🤖 Prompt for AI Agents |
||
|
|
||
| @Override | ||
| public int countMissionsByYear(int year) throws SQLException { | ||
| String sql = "SELECT COUNT(*) FROM moon_mission WHERE YEAR(launch_date) = ?"; | ||
| try (Connection connection = dataSource.getConnection(); | ||
| PreparedStatement stmt = connection.prepareStatement(sql)) { | ||
| stmt.setInt(1, year); | ||
| try (ResultSet rs = stmt.executeQuery()) { | ||
| if (rs.next()) { | ||
| return rs.getInt(1); | ||
| } | ||
| return 0; | ||
| } | ||
| } | ||
| } | ||
| } | ||
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.
🧩 Analysis chain
🏁 Script executed:
Repository: ithsjava25/databas-jdbc-johanbriger
Length of output: 106
🏁 Script executed:
Repository: ithsjava25/databas-jdbc-johanbriger
Length of output: 108
🏁 Script executed:
Repository: ithsjava25/databas-jdbc-johanbriger
Length of output: 7764
🏁 Script executed:
Repository: ithsjava25/databas-jdbc-johanbriger
Length of output: 167
🏁 Script executed:
Repository: ithsjava25/databas-jdbc-johanbriger
Length of output: 1967
🏁 Script executed:
# Read the schema file to check for UNIQUE constraints on name column cat src/main/resources/init.sqlRepository: ithsjava25/databas-jdbc-johanbriger
Length of output: 4833
🏁 Script executed:
# Check the Main.java file for complete authentication flow cat src/main/java/com/example/Main.javaRepository: ithsjava25/databas-jdbc-johanbriger
Length of output: 10100
🏁 Script executed:
Repository: ithsjava25/databas-jdbc-johanbriger
Length of output: 61
🏁 Script executed:
Repository: ithsjava25/databas-jdbc-johanbriger
Length of output: 195
🏁 Script executed:
Repository: ithsjava25/databas-jdbc-johanbriger
Length of output: 2940
🏁 Script executed:
# Read the complete JdbcAccountRepository implementation cat src/main/java/com/example/JdbcAccountRepository.javaRepository: ithsjava25/databas-jdbc-johanbriger
Length of output: 2521
Store and compare password hashes, not plaintext values; enforce unique constraint on name column
Password hashing: The codebase stores and compares passwords as plaintext (no bcrypt, argon2, or similar in dependencies). Passwords are inserted directly in
create()and compared directly infindByNameAndPassword(). This is a critical security vulnerability. Before any password reaches the repository, hash and salt it (e.g., using Spring Security'sBCryptPasswordEncoderor similar), and store only the hash. UpdatefindByNameAndPassword()to accept a hashed password or implement a separate verification method that hashes the input before comparison. At minimum, rename thepasswordparameter and column topasswordHashto signal that hashed values are expected.Name column uniqueness: The schema (
init.sql) definesnameasVARCHAR(255)with noUNIQUEconstraint. Multiple users can have identical names, and login would succeed for any matching account without indication of duplicates. Add aUNIQUEconstraint to thenamecolumn at the database level:ALTER TABLE account ADD UNIQUE (name);