preparing to pass error messages to client

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2024-10-18 19:35:40 +02:00
parent a10224a23e
commit 951c65c121
10 changed files with 94 additions and 19 deletions

View File

@@ -20,6 +20,9 @@ public class Constants {
public static final String DAYS = "days";
public static final String ENCRYPTION_KEY = "encryption_key";
public static final String ERROR_DESCRIPTION = "error_description";
public static final String ERROR_LOCKED = "error_locked";
public static final String ERROR_LOGIN_FAILED = "error_login_failed";
public static final String ERROR_NO_USERNAME = "error_no_username";
public static final String EXPIRATION = "expiration";
public static final String EXPIRES_IN = "expires_in";
public static final String GRANT_TYPE = "grant_type";

View File

@@ -0,0 +1,36 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
import java.util.HashMap;
import java.util.Map;
public class Error<T> implements Result<T> {
private final String cause;
private Map<String, Object> metadata;
public Error(String cause) {
this.cause = cause;
}
public String cause() {
return cause;
}
@Override
public boolean isError() {
return true;
}
public static <T> Error<T> message(String text) {
return new Error<T>(text);
}
public Error<T> metadata(Object... tokens) {
metadata = new HashMap<String, Object>();
for (int i = 0; i < tokens.length - 1; i += 2) {
metadata.put(tokens[i].toString(), tokens[i + 1]);
}
return this;
}
}

View File

@@ -0,0 +1,24 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
public class Payload<T> implements Result<T> {
private final T object;
public Payload(T object) {
this.object = object;
}
public static <T> Payload<T> of(T object) {
return new Payload<>(object);
}
@Override
public boolean isError() {
return false;
}
public T get() {
return object;
}
}

View File

@@ -0,0 +1,6 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
public interface Result<T> {
public boolean isError();
}

View File

@@ -26,19 +26,19 @@ 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> forToken(String accessToken);
public UserService init(User defaultUser);
public List<User> list();
public Set<User> find(String idOrEmail);
public default Optional<Lock> getLock(String key) {
var failedLogin = failedLogins.get(key);
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 Lock lock(String key) {
return failedLogins.computeIfAbsent(key,k -> new Lock()).count();
public Optional<User> load(String id);
public Result<User> login(String username, String password);
public default Lock lock(String key) {
return failedLogins.computeIfAbsent(key, k -> new Lock()).count();
}
public boolean passwordMatches(String plaintextPassword, User user);
public UserService save(User user);

View File

@@ -4,8 +4,8 @@ package de.srsoftware.oidc.api.data;
import java.time.Instant;
public class Lock {
private int attempts;
private Instant releaseTime;
private int attempts;
private Instant releaseTime;
public Lock() {
this.attempts = 0;