implemented locking-user-on-login-fail, needs to be tested

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2024-10-18 00:11:40 +02:00
parent f5976a7dc3
commit a4200f43aa
8 changed files with 127 additions and 27 deletions

View File

@@ -1,13 +1,17 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
import static java.util.Optional.empty;
import de.srsoftware.oidc.api.data.AccessToken;
import de.srsoftware.oidc.api.data.FailedLogin;
import de.srsoftware.oidc.api.data.User;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.time.Instant;
import java.util.*;
public interface UserService {
Map<String, FailedLogin> failedLogins = new HashMap<>();
/**
* create a new access token for a given user
* @param user
@@ -22,13 +26,30 @@ public interface UserService {
* @param accessToken
* @return
*/
public Optional<User> forToken(String accessToken);
public UserService init(User defaultUser);
public List<User> list();
public Set<User> find(String idOrEmail);
public Optional<User> load(String id);
public Optional<User> load(String username, String password);
public boolean passwordMatches(String plaintextPassword, User user);
public UserService save(User user);
public UserService updatePassword(User user, String plaintextPassword);
public Optional<User> forToken(String accessToken);
public UserService init(User defaultUser);
public List<User> list();
public Set<User> find(String idOrEmail);
public default Optional<FailedLogin> getLock(String id) {
var failedLogin = failedLogins.get(id);
if (failedLogin == null || failedLogin.releaseTime().isBefore(Instant.now())) return empty();
return Optional.of(failedLogin);
}
public Optional<User> load(String id);
public Optional<User> login(String username, String password);
public default UserService lock(String id) {
var failedLogin = failedLogins.get(id);
if (failedLogin == null) {
failedLogins.put(id, failedLogin = new FailedLogin(id));
}
return this;
}
public boolean passwordMatches(String plaintextPassword, User user);
public UserService save(User user);
public default UserService unlock(String id) {
failedLogins.remove(id);
return this;
}
public UserService updatePassword(User user, String plaintextPassword);
}

View File

@@ -0,0 +1,32 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api.data;
import java.time.Instant;
public class FailedLogin {
private final String userId;
private int attempts;
private Instant releaseTime;
public FailedLogin(String userId) {
this.userId = userId;
this.attempts = 0;
count();
}
public void count() {
attempts++;
if (attempts > 13) attempts = 13;
var seconds = 1;
for (long i = 0; i < attempts; i++) seconds *= 2;
releaseTime = Instant.now().plusSeconds(seconds);
}
public int attempts() {
return attempts;
}
public Instant releaseTime() {
return releaseTime;
}
}