working on backend:

- started FileStore implementation
- implemented placing cookies

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2024-07-18 01:22:43 +02:00
parent 67606a80f4
commit c5352ac73b
18 changed files with 399 additions and 26 deletions

View File

@@ -11,6 +11,7 @@ repositories {
dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
implementation 'org.json:json:20240303'
}
test {

View File

@@ -0,0 +1,42 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import java.util.Map;
public abstract class Cookie implements Map.Entry<String, String> {
private final String key;
private String value = null;
Cookie(String key, String value) {
this.key = key;
setValue(value);
}
public <T extends Cookie> T addTo(Headers headers) {
headers.add("Set-Cookie", "%s=%s".formatted(key, value));
return (T)this;
}
public <T extends Cookie> T addTo(HttpExchange ex) {
return this.addTo(ex.getResponseHeaders());
}
@Override
public String getKey() {
return key;
}
@Override
public String getValue() {
return value;
}
@Override
public String setValue(String s) {
var oldVal = value;
value = s;
return oldVal;
}
}

View File

@@ -0,0 +1,11 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
public interface PasswordHasher<T> {
public String hash(String password, String salt);
public String salt(String hashedPassword);
public default boolean matches(String plaintextPassword, String hashedPassword) {
return hash(plaintextPassword, salt(hashedPassword)).equals(hashedPassword);
}
}

View File

@@ -1,6 +1,8 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
@@ -9,10 +11,14 @@ import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import org.json.JSONObject;
public abstract class PathHandler implements HttpHandler {
private String path;
public static final String CONTENT_TYPE = "Content-Type";
public static final String JSON = "application/json";
public static final String POST = "POST";
private String path;
public class Bond {
Bond(String p) {
@@ -35,15 +41,29 @@ public abstract class PathHandler implements HttpHandler {
return path;
}
public Optional<String> getHeader(HttpExchange ex, String key) {
/******* begin of static methods *************/
public static String body(HttpExchange ex) throws IOException {
return new String(ex.getRequestBody().readAllBytes(), UTF_8);
}
public static Optional<String> getAuthToken(HttpExchange ex) {
return getHeader(ex, "Authorization");
}
public static Optional<String> getHeader(HttpExchange ex, String key) {
return Optional.ofNullable(ex.getRequestHeaders().get(key)).map(List::stream).map(Stream::findFirst).orElse(Optional.empty());
}
public Optional<String> language(HttpExchange ex) {
public static JSONObject json(HttpExchange ex) throws IOException {
return new JSONObject(body(ex));
}
public static Optional<String> language(HttpExchange ex) {
return getHeader(ex, "Accept-Language").map(s -> Arrays.stream(s.split(","))).map(Stream::findFirst).orElse(Optional.empty());
}
public void emptyResponse(int statusCode, HttpExchange ex) throws IOException {
public static void sendEmptyResponse(int statusCode, HttpExchange ex) throws IOException {
ex.sendResponseHeaders(statusCode, 0);
ex.getResponseBody().close();
}

View File

@@ -0,0 +1,9 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
public class SessionToken extends Cookie {
public SessionToken(String value) {
super("sessionToken", value);
}
}

View File

@@ -1,4 +1,90 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
public class User {}
import java.util.Map;
import java.util.Objects;
public final class User {
public static final String EMAIL = "email";
public static final String PASSWORD = "password";
public static final String REALNAME = "realname";
public static final String USERNAME = "username";
private String email, hashedPassword, realName, uuid, username;
public User(String username, String hashedPassword, String realName, String email, String uuid) {
this.username = username;
this.realName = realName;
this.email = email;
this.hashedPassword = hashedPassword;
this.uuid = uuid;
}
public String email() {
return email;
}
public User email(String newVal) {
email = newVal;
return this;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (User)obj;
return Objects.equals(this.uuid, that.uuid);
}
public String hashedPassword() {
return hashedPassword;
}
public User hashedPassword(String newValue) {
hashedPassword = newValue;
return this;
}
@Override
public int hashCode() {
return Objects.hash(username, realName, email, hashedPassword, uuid);
}
public Map<String, String> map(boolean includePassword) {
return includePassword ? Map.of(USERNAME, username, REALNAME, realName, PASSWORD, hashedPassword, EMAIL, email) : Map.of(USERNAME, username, REALNAME, realName, EMAIL, email);
}
public String realName() {
return realName;
}
public User realName(String newValue) {
realName = newValue;
return this;
}
@Override
public String toString() {
return "User["
+ "username=" + username + ", "
+ "realName=" + realName + ", "
+ "email=" + email + ", "
+ "uuid=" + uuid + ']';
}
public String username() {
return username;
}
public User username(String newVal) {
username = newVal;
return this;
}
public String uuid() {
return uuid;
}
}

View File

@@ -0,0 +1,13 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
import java.util.List;
import java.util.Optional;
public interface UserService {
public UserService delete(User user);
public UserService init(User defaultUser);
public List<User> list();
public Optional<User> load(String username, String password);
public UserService save(User user);
}