Issue
I'm trying to block an user from my login system if he failed to login after 3 attempts.
I set an "attemp" column to each user with a default int value "3" and I'm trying to decrement it after each try till it goes to 0. The problem here it's that my method isn't updating the value on the table. What could be wrong? Please help.
Here's my sql table:
CREATE TABLE user (
id bigint identity NOT NULL,
username varchar(50) NOT NULL,
password varchar(50) NOT NULL,
attempts int DEFAULT 3,
state varchar(50) DEFAULT 'Active',
PRIMARY KEY (id)
);
This is the login servlet:
public class LoginCheck extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
/**
* verifies is the values are the same on the inputs
* creates session and redirects accordingly to answer
* blocks access after 3 failed attempts
*/
if(CheckUser.Validation(username, password) && !BlockUser.SelectState(username))
{
HttpSession session = request.getSession();
session.setAttribute("username", username);
RequestDispatcher rs = request.getRequestDispatcher("profile.jsp");
rs.forward(request, response);
} else if(CheckUser.Validation(username, password) && BlockUser.SelectState(username)) {
String blocked = "This user is blocked";
request.setAttribute("blocked", blocked);
request.getRequestDispatcher("index.jsp").forward(request, response);
return;
}
else if (!CheckUser.Validation(username, password) && !BlockUser.SelectState(username))
{
//Here is where I call the method and try to decrement the number of attempts accordingly to the user that has been attempting
BlockUser.Attempts(username);
String error = "Wrong user or password. Try again.";
request.setAttribute("error", error);
request.getRequestDispatcher("index.jsp").forward(request, response);
}
else {
String state = "Inactive";
BlockUser.Block(state, username);
String blocked = "Exceeded max attempts. Account is now blocked.";
request.setAttribute("blocked", blocked);
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
}
And here's the class with the method to decrement the value:
public class BlockUser {
private static Connection con = null;
private static PreparedStatement ps = null;
private static ResultSet rs = null;
public static void Attempts(String username) {
try
{con = DBConnectionManager.getConnection();
if (con == null){
System.out.println("Conexão falhada");
}else{
PreparedStatement sel = con.prepareStatement(
"SELECT * FROM user WHERE username = ? AND attempts = ?");
sel.setString(1,username);
if(rs.next()) {
rs.getInt("attempts");
while(rs.getInt("attempts") != 0) {
PreparedStatement ps = con.prepareStatement(
"UPDATE user SET attempts = attempts - 1 WHERE username = ?");
ps.setString(1,username);
ps.executeUpdate();
ps.close();
}}
sel.close();
}
}
catch (Exception e) {
e.printStackTrace(System.out);
}
}
Solution
First of all select
query inside your Attempts(String username)
is wrong you have passed ?
for attempts = ?
but never supplied any value in it .Then you are not getting any value in attempts and directly updating it .Instead your code should look like below :
public static String Attempts(String username) {
//your other codes i.e : connection code here
//..
String message = "";
int value;
PreparedStatement sel = con.prepareStatement(
"SELECT * FROM user WHERE username = ? ");
sel.setString(1, username);
ResultSet rs = sel.executeQuery();
if (rs.next()) {
value = rs.getInt("attempts"); //getting attempt in some varibale i.e : value
}
//checking if value is not equal to 0
if (value != 0) {
//subtract 1
int subtracts = value - 1;
//updatting
PreparedStatement ps = con.prepareStatement(
"UPDATE user SET attempts = ? WHERE username = ?");
ps.setInt(1,subtracts);
ps.setString(2, username);
int count = ps.executeUpdate();
if (count > 0) {
message = "Updated";
}
} else {
message = "Already 0";
//already 0 do something
}
ps.close();
return message; //return back
}
And in servlet do like below :
String message = BlockUser.Attempts(username);
//if the value if updated
if(message.equals("Updated")){
//do something
}else{
//already use all attempts block
}
Answered By - Swati
Answer Checked By - Mildred Charles (JavaFixing Admin)