Compare commits

...

13 Commits

  1. 30
      Jenkinsfile
  2. 5
      pom.xml
  3. 4
      src/main/java/org/leolo/nrapi/Constants.java
  4. 1
      src/main/java/org/leolo/nrapi/util/MiscUtilAPI.java
  5. 84
      src/main/java/org/leolo/nrapi/web/LoginAPI.java

30
Jenkinsfile vendored

@ -0,0 +1,30 @@
pipeline{
agent any
tools{
maven '3.8.6'
jdk 'JDK 18'
}
stages {
stage ('Initialize') {
steps {
sh '''
echo "PATH = ${PATH}"
echo "M2_HOME = ${M2_HOME}"
'''
}
}
stage('Build'){
steps{
sh 'mvn -Dmaven.test.failure.ignore=true install test'
}
post{
success{
junit 'target/surefire-reports/**/*.xml'
archiveArtifacts artifacts: 'target/*.jar, *.pom', fingerprint: true, followSymlinks: false, onlyIfSuccessful: true
}
}
}
}
}

5
pom.xml

@ -25,6 +25,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>

4
src/main/java/org/leolo/nrapi/Constants.java

@ -2,4 +2,8 @@ package org.leolo.nrapi;
public class Constants {
public static final String REQ_ATTR_USER_ID = "auth-result-user-id";
public static final String SESSION_ATTR_USER_ID = "auth-result-user-id";
public static final int BCRYPT_STRENGTH = 12;
}

1
src/main/java/org/leolo/nrapi/util/MiscUtilAPI.java

@ -153,6 +153,7 @@ public class MiscUtilAPI {
}
}
sb.append("}");
sb.append(",\"api-version\":\"0.1\"");
sb.append("}");
String result = "";
try(

84
src/main/java/org/leolo/nrapi/web/LoginAPI.java

@ -1,28 +1,102 @@
package org.leolo.nrapi.web;
import org.leolo.nrapi.Constants;
import org.leolo.nrapi.manager.DatabaseManager;
import org.leolo.nrapi.util.HttpReqRespUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@RestController
@RequestMapping(value = "web/auth")
public class LoginAPI {
private Logger log = LoggerFactory.getLogger(LoginAPI.class);
@RequestMapping(value = "login", method = RequestMethod.POST)
public Object doLogin(
@RequestParam(name="username", required = true) String userName,
@RequestParam(name="password", required = true) String password,
HttpSession session
){
return new Object(){
public String getStatus(){return "failed";}
public String getMessage() {return "Not implemented";}
};
String reqIP = HttpReqRespUtils.getClientIpAddressIfServletRequestExist();
log.info("Login request from {}, username is {}, password length = {}", reqIP, userName, password.length());
BCryptPasswordEncoder enc = new BCryptPasswordEncoder(Constants.BCRYPT_STRENGTH);
boolean result = false;
try(
Connection conn = DatabaseManager.getInstance().getConnection();
PreparedStatement pstmt = conn.prepareStatement("SELECT user_id, user_name, password FROM user WHERE user_name = ?");
){
pstmt.setString(1, userName);
try(ResultSet rs = pstmt.executeQuery()){
if(rs.next()){
log.debug("User found!");
String passwordHash = rs.getString("password");
if(enc.matches(password, passwordHash)){
//Login OK
result = true;
String tokens [] = passwordHash.split("\\$");
if(enc.upgradeEncoding(passwordHash) ||
(Integer.parseInt(tokens[2])<Constants.BCRYPT_STRENGTH)
){
log.info("User {} have old version of hash. Update required.", userName);
new Thread(()->{
try(
Connection connection = DatabaseManager.getInstance().getConnection();
PreparedStatement psUpd = connection.prepareStatement("UPDATE user SET password = ? WHERE user_name = ?");
){
psUpd.setString(1, enc.encode(password));
psUpd.setString(2, userName);
psUpd.executeUpdate();
connection.commit();
}catch (SQLException e){
log.error(e.getMessage(), e);
}
}).start();
}
session.setAttribute(Constants.SESSION_ATTR_USER_ID, rs.getString("user_id"));
}else{
//Login failed
}
}else{
log.debug("User not found!");
//No such user
//Do a encode to avoid time attack?
enc.encode(password);
}
}
}catch(SQLException e){
log.error(e.getMessage(), e);
return new Object(){
public String getStatus(){return "500";}
public String getMessage() {return "Unable to connection to database";}
};
}
if(result){
return new Object(){
public String getStatus(){return "200";}
public String getMessage() {return "Login Success!";}
};
}else{
return new Object(){
public String getStatus(){return "401";}
public String getMessage() {return "Username or password incorrect";}
};
}
}
@RequestMapping(value = "logout")
public Object doLogin(
public Object doLogout(
HttpSession session
){
session.invalidate();

Loading…
Cancel
Save