diff --git a/src/main/java/org/ccalm/jwt/MainController.java b/src/main/java/org/ccalm/jwt/MainController.java index 66e8d7a..b9cfe30 100644 --- a/src/main/java/org/ccalm/jwt/MainController.java +++ b/src/main/java/org/ccalm/jwt/MainController.java @@ -66,9 +66,9 @@ public class MainController implements ServletContextAware { private static final Logger logger = LogManager.getLogger(MainController.class); @Value("${spring.application.name}") - String application_name=""; + String application_name = ""; @Value("${issuer.name}") - String issuer_name=""; + String issuer_name = ""; @Value("${public.key}") String public_key; @Value("${private.key}") @@ -76,9 +76,9 @@ public class MainController implements ServletContextAware { @Value("${captcha.key}") String captchaKey; @Value("${access.time}") - int access_time=0; //На сколько секунд продлевать время Access токена + int access_time = 0; //На сколько секунд продлевать время Access токена @Value("${refresh.time}") - int refresh_time=0; //На сколько секунд продлевать время Refresh токена + int refresh_time = 0; //На сколько секунд продлевать время Refresh токена @Value("${mail.host}") String mail_host = ""; @Value("${mail.port}") @@ -103,11 +103,11 @@ public class MainController implements ServletContextAware { private ServletContext context; private final NamedParameterJdbcTemplate jdbcTemplate; private HikariDataSource dataSource; - public Storage storage=new Storage(); + public Storage storage = new Storage(); @Override public void setServletContext(ServletContext servletContext) { - this.context=servletContext; + this.context = servletContext; } @Autowired @@ -120,32 +120,35 @@ public class MainController implements ServletContextAware { this.jdbcTemplate = jdbcTemplate; } - public String createStrJSONError(int code, String message,String marker) { + public String createStrJSONError(int code, String message, String marker) { JSONObject json = new JSONObject(); - json.put("error_code",code); - json.put("error_message",message); - json.put("error_marker",marker); + json.put("error_code", code); + json.put("error_message", message); + json.put("error_marker", marker); return json.toString(); } - public JSONObject createJSONError(int code, String message,String marker){ + + public JSONObject createJSONError(int code, String message, String marker) { JSONObject json = new JSONObject(); - json.put("error_code",code); - json.put("error_message",message); - json.put("error_marker",marker); + json.put("error_code", code); + json.put("error_message", message); + json.put("error_marker", marker); return json; } - public String createHTMLError(int code,String message) - { - return ""; + + public String createHTMLError(int code, String message) { + return ""; } public static int countOccurrences(String str, char symbol) { int count = 0; - for (int i = 0; i < str.length(); i++) { + + for(int i = 0; i < str.length(); i++) { if (str.charAt(i) == symbol) { count++; } } + return count; } @@ -157,8 +160,7 @@ public class MainController implements ServletContextAware { return str.substring(pos + sub.length()); } - public static String beforeFirst(String str, String ch) - { + public static String beforeFirst(String str, String ch) { int i=str.indexOf(ch); if(i!=-1) { @@ -167,9 +169,9 @@ public class MainController implements ServletContextAware { return ""; } - private PrivateKey getPrivateKey(){ + private PrivateKey getPrivateKey() { try { - byte[] keyBytes = Base64.getDecoder().decode(private_key); + byte[] keyBytes = Base64.getDecoder().decode(this.private_key); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePrivate(spec); @@ -179,9 +181,9 @@ public class MainController implements ServletContextAware { return null; } - private PublicKey getPublicKey(){ + private PublicKey getPublicKey() { try { - byte[] keyBytes = Base64.getDecoder().decode(public_key); + byte[] keyBytes = Base64.getDecoder().decode(this.public_key); X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey key = keyFactory.generatePublic(spec); @@ -749,7 +751,7 @@ public class MainController implements ServletContextAware { } } if(json.has("count") && json.has("limit_count") && json.has("limit_duration")) { - attempt_count = json.getInt("count"); + attempt_count = json.getInt("count") + 1; attempt_limit = json.getInt("limit_count"); //attempt_duration = json.getInt("limit_duration"); } @@ -763,13 +765,15 @@ public class MainController implements ServletContextAware { //I'm trying to log in json = null; try { - sql="select * from main.p__login_v4(:user_id,:login,:password,:ip,:fingerprint);"; + sql="select * from main.p__login_v4(:user_id,:login,:password,:totp_code,:ip,:fingerprint);"; parameters = new MapSqlParameterSource(); parameters.addValue("user_id", 1); parameters.addValue("login", loginModel.getLogin()); parameters.addValue("password", loginModel.getPassword()); + parameters.addValue("totp_code", loginModel.getTotp()); parameters.addValue("ip", ipAddress); parameters.addValue("fingerprint", null); + ret = jdbcTemplate.query(sql, parameters, new DBTools.JsonRowMapper()); for (int i = 0; i < ret.size(); i++) { json = new JSONObject(ret.get(i)); @@ -787,32 +791,63 @@ public class MainController implements ServletContextAware { throw new CustomException(10000, msg, null); } - if(json.has("block")) { - if(json.getBoolean("block")) - throw new CustomException(10006,trt.trt("The_user_account_is_blocked"),null); + if (json.has("block")) { + if (json.getBoolean("block")) { + throw new CustomException(10006, trt.trt("The_user_account_is_blocked"), (String)null); + } + json.remove("block"); } - //Если для пользователя настроено то что он обязательно должен авторизоваться используя TOTP а он не задан то генерю его ему - if(json.has("key_required") && !json.isNull("key_required") && json.getBoolean("key_required") && json.has("secret") && json.isNull("secret")) { - throw new CustomException(10010, trt.trt("You_need_to_get_a_new_TOTP_key"), null); + long currentTime = System.currentTimeMillis() / 1000L; + if (json.has("expiration") && json.getLong("expiration") < currentTime) { + throw new CustomException(10009, trt.trt("Password_expired_and_must_be_changed"), (String)null); } - if(json.has("secret")) { - if(!json.isNull("secret")) { - if(!Tools.isInteger(loginModel.getTotp())) { - throw new CustomException(10000, trt.trt("The_TOTP_field_is_empty"), null); - } - //Проверяю на соответствие TOTP ключа TODO потом написать поверку в функции p__Login плагином - GoogleAuthenticator gAuth = new GoogleAuthenticator(); - boolean isCodeValid = gAuth.authorize(json.getString("secret"), Integer.parseInt(loginModel.getTotp())); - if(!isCodeValid){ - throw new CustomException(10000, trt.trt("TOTP_key_does_not_match"), null); - } + + if (json.has("totp_required") && !json.isNull("totp_required") && json.getBoolean("totp_required") && json.has("totp_key") && json.isNull("totp_key")) { + throw new CustomException(10010, trt.trt("You_need_to_get_a_new_TOTP_key"), (String)null); + } + + ArrayList errorMessages; + ArrayList errorSettings; + if (json.has("totp_required") && !json.isNull("totp_required") && json.getBoolean("totp_required") && !Tools.isInteger(loginModel.getTotp())) { + errorMessages = new ArrayList(); + errorSettings = new ArrayList(); + errorMessages.add(trt.trt("The_TOTP_field_is_empty")); + errorSettings.add(""); + if (attempt_count > 1) { + errorMessages.add(trt.trt("Authorization_attempts_s_out_of_s")); + String str = String.valueOf(attempt_count); + errorSettings.add(str + ";" + String.valueOf(attempt_limit) + ";"); } - json.remove("secret"); + + throw new CustomException(10012, errorMessages, errorSettings, (String)null); } - if(json.has("key_required")) { - json.remove("key_required"); + + if (json.has("totp_success") && !json.getBoolean("totp_success")) { + errorMessages = new ArrayList(); + errorSettings = new ArrayList(); + errorMessages.add(trt.trt("Please_send_the_correct_TOTP_code")); + errorSettings.add(""); + if (attempt_count > 1) { + errorMessages.add(trt.trt("Authorization_attempts_s_out_of_s")); + String str = String.valueOf(attempt_count); + errorSettings.add(str + ";" + String.valueOf(attempt_limit) + ";"); + } + + throw new CustomException(10000, errorMessages, errorSettings, (String)null); + } + + if (json.has("totp_required")) { + json.remove("totp_required"); + } + + if (json.has("totp_success")) { + json.remove("totp_success"); + } + + if (json.has("totp_key")) { + json.remove("totp_key"); } //В каком ARM был в последний раз пользователь @@ -996,11 +1031,12 @@ public class MainController implements ServletContextAware { //I'm trying to log in json = null; try { - sql="select * from main.p__login_v4(:user_id,:login,:password,:ip,:fingerprint);"; + sql="select * from main.p__login_v4(:user_id,:login,:password,:totp,:ip,:fingerprint);"; parameters = new MapSqlParameterSource(); parameters.addValue("user_id", 1); parameters.addValue("login", loginModel.getLogin()); parameters.addValue("password", loginModel.getPassword()); + parameters.addValue("totp", loginModel.getTotp()); parameters.addValue("ip", ipAddress); parameters.addValue("fingerprint", null); ret = jdbcTemplate.query(sql, parameters, new DBTools.JsonRowMapper()); @@ -1475,4 +1511,4 @@ public class MainController implements ServletContextAware { } return createStrJSONError(0,"",null); } -} +} \ No newline at end of file diff --git a/src/main/java/org/ccalm/jwt/Translation.java b/src/main/java/org/ccalm/jwt/Translation.java index ec4aa4d..028790a 100644 --- a/src/main/java/org/ccalm/jwt/Translation.java +++ b/src/main/java/org/ccalm/jwt/Translation.java @@ -33,7 +33,7 @@ public class Translation { } String trt(String text){ - String sql = """ + /*String sql = """ select translation from @@ -54,7 +54,7 @@ public class Translation { } if(i==0){ text = text.replace("_", " "); - } + }*/ return text; } } diff --git a/src/main/java/org/ccalm/jwt/tools/CustomException.java b/src/main/java/org/ccalm/jwt/tools/CustomException.java index 3ac21b0..5c7612c 100644 --- a/src/main/java/org/ccalm/jwt/tools/CustomException.java +++ b/src/main/java/org/ccalm/jwt/tools/CustomException.java @@ -2,29 +2,67 @@ package org.ccalm.jwt.tools; import org.json.JSONObject; +import java.util.Arrays; +import java.util.List; + public class CustomException extends Exception { private int errorCode; private String marker; + private List errorMessages; + private List errorSettings; - public CustomException(int errorCode,String message,String marker) { - super(message); + public CustomException(int errorCode, String errorMessage, String marker) { + super(errorMessage); + this.errorMessages = Arrays.asList(errorMessage); + this.errorCode = errorCode; + this.marker = marker; + } + + public CustomException(int errorCode, String errorMessage, String errorSetting, String marker) { + super(errorMessage); + this.errorMessages = Arrays.asList(errorMessage); + this.errorSettings = Arrays.asList(errorSetting); + this.errorCode = errorCode; + this.marker = marker; + } + + public CustomException(int errorCode, List errorMessages, String marker) { + super(String.join(" ", errorMessages)); + this.errorMessages = errorMessages; + this.errorCode = errorCode; + this.marker = marker; + } + + public CustomException(int errorCode, List errorMessages, List errorSettings, String marker) { + super(String.join(" ", errorMessages)); + this.errorMessages = errorMessages; + this.errorSettings = errorSettings; this.errorCode = errorCode; this.marker = marker; } public int getErrorCode() { - return errorCode; + return this.errorCode; } public String getErrorMarker() { - return marker; + return this.marker; + } + + public List getErrorMessages() { + return this.errorMessages; + } + + public List getErrorSettings() { + return this.errorSettings; } public JSONObject getJson() { JSONObject json = new JSONObject(); - json.put("error_code", getErrorCode()); - json.put("error_message", getMessage()); - json.put("error_marker", getErrorMarker()); + json.put("error_code", this.getErrorCode()); + json.put("error_message", this.getErrorMessages()); + json.put("error_setting", this.getErrorSettings()); + json.put("error_marker", this.getErrorMarker()); return json; } }