package art.servers.transactionsserver.model.access.login; import art.library.interop.InteropParameters; import art.library.interop.InteropResponse; import art.library.interop.serialization.SerializationException; import art.library.model.devices.user.UserIdentification; import art.library.model.transactions.useraccess.AddressLogin; import art.library.utils.licence.Licence; import art.servers.transactionsserver.Shared; import art.servers.transactionsserver.configuration.ConfigurationLoginBlockedManager; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; public class LoginBlockedManager { private int MINUTES_UNLOCK_USER = 15; private int MINUTES_UNLOCK_ADDRESS = 720; private int MAXIMUM_USER_LOGIN_ATTEMPS = 3; private int MAXIMUM_ADDRESS_LOGIN_ATTEMPS = 20; private boolean managerActivated = false; private BlockingNotificationEmailSender mailSender; public LoginBlockedManager(ConfigurationLoginBlockedManager configuration, BlockingNotificationEmailSender mailSender) { this.mailSender = mailSender; if (configuration != null) { managerActivated = configuration.activated; MINUTES_UNLOCK_USER = configuration.MINUTES_UNLOCK_USER; MINUTES_UNLOCK_ADDRESS = configuration.MINUTES_UNLOCK_ADDRESS; MAXIMUM_USER_LOGIN_ATTEMPS = configuration.MAXIMUM_USER_LOGIN_ATTEMPS; MAXIMUM_ADDRESS_LOGIN_ATTEMPS = configuration.MAXIMUM_ADDRESS_LOGIN_ATTEMPS; managerActivated = configuration.activated; } } public InteropResponse getBlockedUsers(InteropParameters parameters) throws SerializationException { try { List lblockedUsers = LoginBlockedRepository.getUserIdentifications().stream() .filter(user -> user.attempts >= MAXIMUM_USER_LOGIN_ATTEMPS) .map(user -> new UserIdentification(user.group, user.username, user.name, user.attempts)) .collect(Collectors.toList()); return new InteropResponse(lblockedUsers.toArray(new UserIdentification[0])); } catch (Exception e) { throw new SerializationException(Shared.getMessage("error getting the list of blocked users")); } } public InteropResponse getBlockedIPAddresses(InteropParameters parameters) throws SerializationException { try { List lblockedAddressLogin = LoginBlockedRepository.getAddressLogins().stream() .filter(address -> address.attempts >= MAXIMUM_ADDRESS_LOGIN_ATTEMPS) .map(address -> new AddressLogin(address.loginAddress,address.attempts, address.timestamp)) .collect(Collectors.toList()); return new InteropResponse(lblockedAddressLogin.toArray(new AddressLogin[0])); } catch (Exception e) { throw new SerializationException(Shared.getMessage("error getting the list of blocked IP addresses")); } } public InteropResponse unlockUsers(String[] lusernames) throws SerializationException { try { Arrays.stream(lusernames).forEach(name -> { try { LoginBlockedRepository.removeUserIdentification(Licence.encrypt(name)); } catch (Exception ex) { throw new RuntimeException("error when enabling " + name + " username"); } }); return new InteropResponse(new Boolean(true)); } catch (Exception e) { throw new SerializationException(Shared.getMessage("error when enabling users")); } } public InteropResponse unlockIPAddress(String[] lipAddress) throws SerializationException { try { Arrays.stream(lipAddress).forEach(ipAddress -> { try { LoginBlockedRepository.removeAddress(ipAddress); } catch (Exception ex) { throw new RuntimeException("error when enabling " + ipAddress + " address"); } }); return new InteropResponse(new Boolean(true)); } catch (Exception e) { throw new SerializationException(Shared.getMessage("error when enabling IP addresses")); } } public void addFailedLoginAttempt(UserIdentification[] lusersIdentification, String loginAddress, long timestamp) throws Exception { if(!managerActivated) return; if ((lusersIdentification == null) || lusersIdentification[0] == null) throw new Exception("error empty users list"); Arrays.stream(lusersIdentification).forEach(u -> { try { UserIdentification userIdentification = LoginBlockedRepository.getUserIdentification(u.username); if (userIdentification == null) userIdentification = u; userIdentification.name = Licence.decrypt(userIdentification.username); userIdentification.timestampEnd = timestamp; if (userIdentification.attempts < Integer.MAX_VALUE) userIdentification.attempts++; userIdentification.console = loginAddress; LoginBlockedRepository.setUserIdentification(userIdentification); if ((userIdentification.attempts >= MAXIMUM_USER_LOGIN_ATTEMPS) || (isAddressLoginBlocked(loginAddress))) addFailedLoginAddressAttempt(loginAddress, timestamp, userIdentification.name); if (isUserBlocked(u.username) && userIdentification.attempts == MAXIMUM_USER_LOGIN_ATTEMPS) mailSender.sendMailToAll(BlockingNotificationGenerator.generateUserBlockedMessage(userIdentification)); } catch (Exception ex) { Logger.getLogger(LoginBlockedManager.class.getName()).log(Level.SEVERE, null, ex); } }); } public void addCorrectLoginAttempt(UserIdentification[] lusersIdentification, String loginAddress, long timestamp) throws Exception { if(!managerActivated) return; if ((lusersIdentification == null) || lusersIdentification[0] == null) throw new Exception("error empty users list"); Arrays.stream(lusersIdentification).forEach(u -> { try { UserIdentification userIdentification = LoginBlockedRepository.getUserIdentification(u.username); if (userIdentification == null) userIdentification = u; userIdentification.name = Licence.decrypt(userIdentification.username); userIdentification.timestampEnd = timestamp; userIdentification.attempts = 0; userIdentification.console = loginAddress; LoginBlockedRepository.removeUserIdentification(userIdentification.username); addCorrectLoginAddressAttempt(loginAddress, timestamp, userIdentification.name); } catch (Exception ex) { Logger.getLogger(LoginBlockedManager.class.getName()).log(Level.SEVERE, null, ex); } }); } private void addFailedLoginAddressAttempt(String loginAddress, long timestamp, String notEncryptedUsername) { try { AddressLogin addresssLogin = LoginBlockedRepository.getAddressLogin(loginAddress); if (addresssLogin == null) addresssLogin = new AddressLogin(); addresssLogin.loginAddress = loginAddress; addresssLogin.timestamp = timestamp; if (addresssLogin.attempts < Integer.MAX_VALUE) addresssLogin.attempts++; LoginBlockedRepository.setAddressLogin(addresssLogin); if (isAddressLoginBlocked(loginAddress) && addresssLogin.attempts == MAXIMUM_ADDRESS_LOGIN_ATTEMPS) mailSender.sendMailToAll(BlockingNotificationGenerator.generateAddressBlockedMessage(addresssLogin, notEncryptedUsername)); } catch (Exception e) { e.printStackTrace(); } } private void addCorrectLoginAddressAttempt(String loginAddress, long timestamp, String notEncryptedUsername) { try { AddressLogin addresssLogin = LoginBlockedRepository.getAddressLogin(loginAddress); if (addresssLogin == null) addresssLogin = new AddressLogin(); addresssLogin.loginAddress = loginAddress; addresssLogin.timestamp = timestamp; addresssLogin.attempts = 0; LoginBlockedRepository.removeAddress(addresssLogin.loginAddress); } catch (Exception e) { e.printStackTrace(); } } public boolean isAddressLoginBlocked(String loginAddress) throws Exception { if (!managerActivated) return false; AddressLogin addressLogin = LoginBlockedRepository.getAddressLogin(loginAddress); if ((addressLogin == null) || (addressLogin.attempts < MAXIMUM_ADDRESS_LOGIN_ATTEMPS)) { return false; } return true; } public boolean isUserBlocked(String username) throws Exception { if (!managerActivated) return false; UserIdentification userIdentification = LoginBlockedRepository.getUserIdentification(username); if (userIdentification == null) return false; if (userIdentification.attempts < MAXIMUM_USER_LOGIN_ATTEMPS) return false; long dif = System.currentTimeMillis() - userIdentification.timestampEnd; if (dif > (MINUTES_UNLOCK_USER*60000L)) { try { LoginBlockedRepository.removeUserIdentification(userIdentification.username); } catch (Exception ex) { } return(false); } return true; } /** * checkTimestampAttempts check if after the n minutes the counters have to be set to 0 */ public void checkTimestampAttempts() { long currentTimestamp = System.currentTimeMillis(); checkTimestampAttempsUserIdentificaton(currentTimestamp); checkTimestampAttempsAddress(currentTimestamp); } private void checkTimestampAttempsUserIdentificaton(long currentTimestamp) { LoginBlockedRepository.getUserIdentifications().stream().forEach(user -> { if (user.attempts < MAXIMUM_USER_LOGIN_ATTEMPS) { long minutes = TimeUnit.MILLISECONDS.toMinutes(currentTimestamp - user.timestampEnd); if (minutes > MINUTES_UNLOCK_USER) { try { LoginBlockedRepository.removeUserIdentification(user.username); } catch (Exception ex) { Logger.getLogger(LoginBlockedManager.class.getName()).log(Level.SEVERE, null, ex); } } } }); } private void checkTimestampAttempsAddress(long currentTimestamp) { LoginBlockedRepository.getAddressLogins().stream().forEach(address -> { if (address.attempts < MAXIMUM_ADDRESS_LOGIN_ATTEMPS) { long minutes = TimeUnit.MILLISECONDS.toMinutes(currentTimestamp - address.timestamp); if (minutes > MINUTES_UNLOCK_ADDRESS) { try { LoginBlockedRepository.removeAddress(address.loginAddress); } catch (Exception ex) { Logger.getLogger(LoginBlockedManager.class.getName()).log(Level.SEVERE, null, ex); } } } }); } }