package LoginSystem;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
//data base consists of columns [ID, username, password, numOfPasswordChanges, passwordChangeTimer]
public class DataBaseController {
private static final int MAX_USERNAME_LENGTH = 20;
private static final int MIN_USERNAME_LENGTH = 5;
private static final int MAX_PASSWORD_LENGTH = 30;
private static final int MIN_PASSWORD_LENGTH = 7;
public static final int CORRECT_PASSWORD_RETURN_VAL = 1;
public static final int INCORRECT_PASSWORD_RETURN_VAL = 2;
public static final int MAX_PASSWORD_RESETS_REACHED_RETURN_VAL = 3;
public static final int WEAK_PASSWORD_RETURN_VAL = 4;
public static final int WEAK_USERNAME_RETURN_VAL = 5;
public static final int USER_ALREADY_EXISTS_RETURN_VAL = 6;
public static final int USER_NOT_EXISTS_RETURN_VAL = 7;
private static final int ID_INDEX = 1;
private static final int USERNAME_INDEX = 2;
private static final int PASSWORD_INDEX = 3;
private static final int PASSWORD_RESET_INDEX = 4;
private static final int RESET_TIMER_INDEX = 5;
private static final int MAX_PASSWORD_RESETS = 3;
private static final long RESET_TIME_TO_ADD = 20000L;
private static final String ROOT_NAME = "root";
private static final String DB_PASSWORD = "root";
private static final String DB_NAME = "mydb";
public DataBaseController() throws SQLException {
}
public static boolean authorizeUser(String username, String password) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + DB_NAME, ROOT_NAME,DB_PASSWORD);
Statement stmt = con.createStatement();
String query = "SELECT * FROM users WHERE username = " + "'" + username + "'" + " AND password = " + "'" + password + "'";
ResultSet rs = stmt.executeQuery(query);
boolean userExists = rs.next();
if(rs.next()) {
throw new Exception("Duplicate username in database!");
}
rs.previous();
boolean correctLogin = false;
if(userExists) {
correctLogin = rs.getString(USERNAME_INDEX).equals(username) && rs.getString(PASSWORD_INDEX).equals(password);
}
return correctLogin;
}
public static int register(String username, String password) throws ClassNotFoundException, SQLException {
if(!checkIfUsernameValid(username)) {
return WEAK_USERNAME_RETURN_VAL;
}
if(!checkIfPasswordValid(password)) {
return WEAK_PASSWORD_RETURN_VAL;
}
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + DB_NAME + "?verifyServerCertificate=false&useSSL=true", ROOT_NAME, DB_PASSWORD);
Statement stmt = con.createStatement();
String query = "SELECT * FROM users WHERE username = " + "'" + username + "'";
ResultSet rs = stmt.executeQuery(query);
boolean doesUserExists = rs.next();
if(!doesUserExists) {
String numberOfUsersQuery = "SELECT COUNT(*) FROM users";
ResultSet userIDRs = stmt.executeQuery(numberOfUsersQuery);
String addUserSql = "";
userIDRs.next();
int newID = 1 + userIDRs.getInt(1);
addUserSql = "INSERT INTO users(ID, username, password) VALUES(" + newID +", " + "'" + username + "'" + ", " + "'" + password + "');";
stmt.executeUpdate(addUserSql);
}
if(doesUserExists) {
return USER_ALREADY_EXISTS_RETURN_VAL;
}
return USER_NOT_EXISTS_RETURN_VAL;
}
public static int resetPassword(String username, String oldPassword, String newPassword) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + DB_NAME + "?verifyServerCertificate=false&useSSL=true", ROOT_NAME, DB_PASSWORD);
Statement stmt = con.createStatement();
String checkUserQuery = "SELECT * FROM users WHERE username = " + "'" + username + "'" + " AND " + "password = " + "'" + oldPassword + "'";
ResultSet rs = stmt.executeQuery(checkUserQuery);
if(!rs.next()) {
return INCORRECT_PASSWORD_RETURN_VAL;
}
if(!checkIfPasswordValid(newPassword)) {
return WEAK_PASSWORD_RETURN_VAL;
}
int numOfChanges = rs.getInt(PASSWORD_RESET_INDEX);
Timestamp usersResetTimer = rs.getTimestamp(RESET_TIMER_INDEX);
System.out.println(usersResetTimer + " **** " + new Timestamp(System.currentTimeMillis()) + " **** " + usersResetTimer.after(new Timestamp(System.currentTimeMillis())));
if(!usersResetTimer.after(new Timestamp(System.currentTimeMillis()))) {
numOfChanges = 0;
}
if(numOfChanges >= MAX_PASSWORD_RESETS) {
return MAX_PASSWORD_RESETS_REACHED_RETURN_VAL;
}
String query = "UPDATE users SET password = " + "'" + newPassword + "'" + " WHERE username = " + "'" + username + "'";
try {
stmt.executeUpdate(query);
numOfChanges += 1;
query = "UPDATE users SET numOfPasswordChanges = " + numOfChanges + " WHERE username = " + "'" + username + "'";
stmt.executeUpdate(query);
Timestamp newUserResetTimer = new Timestamp(System.currentTimeMillis() + RESET_TIME_TO_ADD);
System.out.println(newUserResetTimer);
String timeWithoutMillis = newUserResetTimer.toString().split("\\.")[0];
System.out.println(newUserResetTimer.toString());
query = "UPDATE users SET passwordChangeTimer = " + "'" + timeWithoutMillis + "'" + " WHERE username = " + "'" + username + "'";
stmt.executeUpdate(query);
} catch (Exception e) {
e.printStackTrace();
}
return CORRECT_PASSWORD_RETURN_VAL;
}
private static boolean checkIfUsernameValid(String username) {
if( username == null || username.length() > MAX_USERNAME_LENGTH || username.length() < MIN_USERNAME_LENGTH)
{
return false;
}
for(int i = 0; i < username.length(); i++) {
if(!Character.isLetter(username.charAt(i)) && !Character.isDigit(username.charAt(i))) {
return false;
}
}
return true;
}
private static boolean checkIfPasswordValid(String password) {
if(password == null || password.length() > MAX_PASSWORD_LENGTH || password.length() < MIN_PASSWORD_LENGTH) {
return false;
}
boolean symbolFlag = false;
boolean digitFlag = false;
boolean letterFlag = false;
for(int i = 0; i < password.length(); i++) {
if(!Character.isLetter(password.charAt(i)) && !Character.isDigit(password.charAt(i))) {
symbolFlag = true;
}
if(Character.isLetter(password.charAt(i))) {
letterFlag = true;
}
if(Character.isDigit(password.charAt(i))) {
digitFlag = true;
}
if(symbolFlag && digitFlag && letterFlag) {
return true;
}
}
return false;
}
}
I have a bunch of classes that uses this to register/change password etc... and this is basically all of my backend in one class almost all of it static aside from a simple checks if username and passwords aren't weak (although nothing will change if it were static), so is it good practice? I can add here the rest of the files but all of them are just simple front end swing GUI pages with no server running in this project.