refactored classes and modules, fixed decoding bug

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2024-08-05 00:27:09 +02:00
parent 49929adaa3
commit d01289c068
31 changed files with 82 additions and 56 deletions

View File

@@ -12,6 +12,7 @@ repositories {
dependencies { dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0') testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.junit.jupiter:junit-jupiter'
implementation 'org.json:json:20240303'
implementation project(':de.srsoftware.utils') implementation project(':de.srsoftware.utils')
} }

View File

@@ -1,5 +1,5 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.cookies; package de.srsoftware.http;
import static de.srsoftware.utils.Optionals.nullable; import static de.srsoftware.utils.Optionals.nullable;
import static java.lang.System.Logger.Level.*; import static java.lang.System.Logger.Level.*;

View File

@@ -1,7 +1,7 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.http;
import static de.srsoftware.oidc.api.Constants.AUTHORIZATION;
import static de.srsoftware.utils.Optionals.nullable; import static de.srsoftware.utils.Optionals.nullable;
import static java.lang.System.Logger.Level.*; import static java.lang.System.Logger.Level.*;
import static java.net.HttpURLConnection.*; import static java.net.HttpURLConnection.*;
@@ -16,6 +16,7 @@ import java.util.stream.Stream;
import org.json.JSONObject; import org.json.JSONObject;
public abstract class PathHandler implements HttpHandler { public abstract class PathHandler implements HttpHandler {
public static final String AUTHORIZATION = "Authorization";
public static final String CONTENT_TYPE = "Content-Type"; public static final String CONTENT_TYPE = "Content-Type";
public static final String DELETE = "DELETE"; public static final String DELETE = "DELETE";
private static final String FORWARDED_HOST = "x-forwarded-host"; private static final String FORWARDED_HOST = "x-forwarded-host";

View File

@@ -1,5 +1,5 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.cookies; package de.srsoftware.http;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;

View File

@@ -0,0 +1,16 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
import de.srsoftware.oidc.api.data.AuthResult;
import de.srsoftware.oidc.api.data.Authorization;
import de.srsoftware.oidc.api.data.Client;
import de.srsoftware.oidc.api.data.User;
import java.time.Instant;
import java.util.Collection;
import java.util.Optional;
public interface AuthorizationService {
AuthorizationService authorize(User user, Client client, Collection<String> scopes, Instant expiration);
Optional<Authorization> consumeAuthorization(String authCode);
AuthResult getAuthorization(User user, Client client, Collection<String> scopes);
}

View File

@@ -1,12 +0,0 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
import java.time.Instant;
import java.util.Collection;
import java.util.Optional;
public interface ClaimAuthorizationService {
ClaimAuthorizationService authorize(User user, Client client, Collection<String> scopes, Instant expiration);
Optional<Authorization> consumeAuthorization(String authCode);
AuthResult getAuthorization(User user, Client client, Collection<String> scopes);
}

View File

@@ -1,6 +1,7 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api;
import de.srsoftware.oidc.api.data.Client;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;

View File

@@ -6,7 +6,6 @@ public class Constants {
public static final String ACCESS_TOKEN = "access_token"; public static final String ACCESS_TOKEN = "access_token";
public static final String APP_NAME = "LightOIDC"; public static final String APP_NAME = "LightOIDC";
public static final String AUTH_CODE = "authorization_code"; public static final String AUTH_CODE = "authorization_code";
public static final String AUTHORIZATION = "Authorization";
public static final String AUTHORZED = "authorized"; public static final String AUTHORZED = "authorized";
public static final String BEARER = "Bearer"; public static final String BEARER = "Bearer";
public static final String CAUSE = "cause"; public static final String CAUSE = "cause";

View File

@@ -1,6 +1,8 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api;
import de.srsoftware.oidc.api.data.Session;
import de.srsoftware.oidc.api.data.User;
import java.time.Duration; import java.time.Duration;
import java.util.Optional; import java.util.Optional;

View File

@@ -1,6 +1,7 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api;
import de.srsoftware.oidc.api.data.User;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;

View File

@@ -1,5 +1,5 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api.data;
import java.util.Set; import java.util.Set;

View File

@@ -1,5 +1,5 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api.data;
public record Authorization(String clientId, String userId, AuthorizedScopes scopes) { public record Authorization(String clientId, String userId, AuthorizedScopes scopes) {
} }

View File

@@ -1,5 +1,5 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api.data;
import java.time.Instant; import java.time.Instant;
import java.util.Set; import java.util.Set;

View File

@@ -1,5 +1,5 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api.data;
import static de.srsoftware.oidc.api.Constants.*; import static de.srsoftware.oidc.api.Constants.*;

View File

@@ -1,4 +1,4 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api.data;
public enum Permission { MANAGE_CLIENTS } public enum Permission { MANAGE_CLIENTS }

View File

@@ -1,5 +1,5 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api.data;
import java.time.Instant; import java.time.Instant;

View File

@@ -1,5 +1,5 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api.data;
import java.util.*; import java.util.*;

View File

@@ -12,6 +12,7 @@ repositories {
dependencies { dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0') testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.junit.jupiter:junit-jupiter'
implementation project(':de.srsoftware.http')
implementation project(':de.srsoftware.logging') implementation project(':de.srsoftware.logging')
implementation project(':de.srsoftware.oidc.api') implementation project(':de.srsoftware.oidc.api')
implementation project(':de.srsoftware.oidc.backend') implementation project(':de.srsoftware.oidc.backend')

View File

@@ -3,7 +3,7 @@ package de.srsoftware.oidc.app;
import static de.srsoftware.oidc.api.Constants.*; import static de.srsoftware.oidc.api.Constants.*;
import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS; import static de.srsoftware.oidc.api.data.Permission.MANAGE_CLIENTS;
import static de.srsoftware.utils.Optionals.emptyIfBlank; import static de.srsoftware.utils.Optionals.emptyIfBlank;
import static de.srsoftware.utils.Paths.configDir; import static de.srsoftware.utils.Paths.configDir;
import static de.srsoftware.utils.Strings.uuid; import static de.srsoftware.utils.Strings.uuid;
@@ -16,7 +16,7 @@ import com.sun.net.httpserver.HttpServer;
import de.srsoftware.logging.ColorLogger; import de.srsoftware.logging.ColorLogger;
import de.srsoftware.oidc.api.KeyManager; import de.srsoftware.oidc.api.KeyManager;
import de.srsoftware.oidc.api.KeyStorage; import de.srsoftware.oidc.api.KeyStorage;
import de.srsoftware.oidc.api.User; import de.srsoftware.oidc.api.data.User;
import de.srsoftware.oidc.backend.*; import de.srsoftware.oidc.backend.*;
import de.srsoftware.oidc.datastore.file.FileStore; import de.srsoftware.oidc.datastore.file.FileStore;
import de.srsoftware.oidc.datastore.file.PlaintextKeyStore; import de.srsoftware.oidc.datastore.file.PlaintextKeyStore;

View File

@@ -12,9 +12,9 @@ repositories {
dependencies { dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0') testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.junit.jupiter:junit-jupiter'
implementation project(':de.srsoftware.cookies') implementation project(':de.srsoftware.http')
implementation project(':de.srsoftware.oidc.api')
implementation project(':de.srsoftware.logging') implementation project(':de.srsoftware.logging')
implementation project(':de.srsoftware.oidc.api')
implementation project(':de.srsoftware.utils') implementation project(':de.srsoftware.utils')
implementation 'org.json:json:20240303' implementation 'org.json:json:20240303'
implementation 'org.bitbucket.b_c:jose4j:0.9.6' implementation 'org.bitbucket.b_c:jose4j:0.9.6'

View File

@@ -2,12 +2,15 @@
package de.srsoftware.oidc.backend; package de.srsoftware.oidc.backend;
import static de.srsoftware.oidc.api.Constants.*; import static de.srsoftware.oidc.api.Constants.*;
import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS; import static de.srsoftware.oidc.api.data.Permission.MANAGE_CLIENTS;
import static de.srsoftware.utils.Optionals.emptyIfBlank; import static de.srsoftware.utils.Optionals.emptyIfBlank;
import static java.net.HttpURLConnection.*; import static java.net.HttpURLConnection.*;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.oidc.api.*; import de.srsoftware.oidc.api.*;
import de.srsoftware.oidc.api.data.AuthorizedScopes;
import de.srsoftware.oidc.api.data.Client;
import de.srsoftware.oidc.api.data.Session;
import de.srsoftware.utils.Optionals; import de.srsoftware.utils.Optionals;
import java.io.IOException; import java.io.IOException;
import java.time.Instant; import java.time.Instant;
@@ -16,11 +19,11 @@ import java.util.*;
import org.json.JSONObject; import org.json.JSONObject;
public class ClientController extends Controller { public class ClientController extends Controller {
private static final System.Logger LOG = System.getLogger(ClientController.class.getSimpleName()); private static final System.Logger LOG = System.getLogger(ClientController.class.getSimpleName());
private final ClaimAuthorizationService authorizations; private final AuthorizationService authorizations;
private final ClientService clients; private final ClientService clients;
public ClientController(ClaimAuthorizationService authorizationService, ClientService clientService, SessionService sessionService) { public ClientController(AuthorizationService authorizationService, ClientService clientService, SessionService sessionService) {
super(sessionService); super(sessionService);
authorizations = authorizationService; authorizations = authorizationService;
clients = clientService; clients = clientService;

View File

@@ -2,10 +2,10 @@
package de.srsoftware.oidc.backend; package de.srsoftware.oidc.backend;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.cookies.SessionToken; import de.srsoftware.http.PathHandler;
import de.srsoftware.oidc.api.PathHandler; import de.srsoftware.http.SessionToken;
import de.srsoftware.oidc.api.Session;
import de.srsoftware.oidc.api.SessionService; import de.srsoftware.oidc.api.SessionService;
import de.srsoftware.oidc.api.data.Session;
import java.util.Optional; import java.util.Optional;
public abstract class Controller extends PathHandler { public abstract class Controller extends PathHandler {

View File

@@ -2,9 +2,9 @@
package de.srsoftware.oidc.backend; package de.srsoftware.oidc.backend;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.http.PathHandler;
import de.srsoftware.oidc.api.KeyManager; import de.srsoftware.oidc.api.KeyManager;
import de.srsoftware.oidc.api.KeyStorage; import de.srsoftware.oidc.api.KeyStorage;
import de.srsoftware.oidc.api.PathHandler;
import java.io.IOException; import java.io.IOException;
import org.jose4j.jwk.JsonWebKey; import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.PublicJsonWebKey; import org.jose4j.jwk.PublicJsonWebKey;

View File

@@ -4,11 +4,13 @@ package de.srsoftware.oidc.backend;
import static de.srsoftware.oidc.api.Constants.*; import static de.srsoftware.oidc.api.Constants.*;
import static de.srsoftware.oidc.api.Constants.ERROR; import static de.srsoftware.oidc.api.Constants.ERROR;
import static de.srsoftware.utils.Optionals.emptyIfBlank; import static de.srsoftware.utils.Optionals.emptyIfBlank;
import static java.lang.System.Logger.Level.*;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.http.PathHandler;
import de.srsoftware.oidc.api.*; import de.srsoftware.oidc.api.*;
import de.srsoftware.oidc.api.data.Client;
import de.srsoftware.oidc.api.data.User;
import java.io.IOException; import java.io.IOException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@@ -23,13 +25,13 @@ import org.json.JSONObject;
public class TokenController extends PathHandler { public class TokenController extends PathHandler {
public record Configuration(String issuer, int tokenExpirationMinutes) { public record Configuration(String issuer, int tokenExpirationMinutes) {
} }
private final ClientService clients; private final ClientService clients;
private final ClaimAuthorizationService authorizations; private final AuthorizationService authorizations;
private final UserService users; private final UserService users;
private final KeyManager keyManager; private final KeyManager keyManager;
private Configuration config; private Configuration config;
public TokenController(ClaimAuthorizationService authorizationService, ClientService clientService, KeyManager keyManager, UserService userService, Configuration configuration) { public TokenController(AuthorizationService authorizationService, ClientService clientService, KeyManager keyManager, UserService userService, Configuration configuration) {
authorizations = authorizationService; authorizations = authorizationService;
clients = clientService; clients = clientService;
this.keyManager = keyManager; this.keyManager = keyManager;
@@ -37,8 +39,15 @@ public class TokenController extends PathHandler {
config = configuration; config = configuration;
} }
private String decode(String urlencoded) {
return URLDecoder.decode(urlencoded, StandardCharsets.UTF_8);
}
private Map<String, String> deserialize(String body) { private Map<String, String> deserialize(String body) {
return Arrays.stream(body.split("&")).map(s -> s.split("=")).collect(Collectors.toMap(arr -> arr[0], arr -> arr[1])); return Arrays
.stream(body.split("&")) //
.map(s -> s.split("="))
.collect(Collectors.toMap(arr -> decode(arr[0]), arr -> decode(arr[1])));
} }
@Override @Override

View File

@@ -1,12 +1,14 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.backend; package de.srsoftware.oidc.backend;
import static de.srsoftware.oidc.api.User.*; import static de.srsoftware.oidc.api.data.User.*;
import static java.net.HttpURLConnection.*; import static java.net.HttpURLConnection.*;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.cookies.SessionToken; import de.srsoftware.http.SessionToken;
import de.srsoftware.oidc.api.*; import de.srsoftware.oidc.api.*;
import de.srsoftware.oidc.api.data.Session;
import de.srsoftware.oidc.api.data.User;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;

View File

@@ -3,7 +3,7 @@ package de.srsoftware.oidc.backend;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.oidc.api.PathHandler; import de.srsoftware.http.PathHandler;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;

View File

@@ -1,13 +1,14 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.datastore.file; /* © SRSoftware 2024 */ package de.srsoftware.oidc.datastore.file; /* © SRSoftware 2024 */
import static de.srsoftware.oidc.api.Constants.EXPIRATION; import static de.srsoftware.oidc.api.Constants.EXPIRATION;
import static de.srsoftware.oidc.api.User.*; import static de.srsoftware.oidc.api.data.User.*;
import static de.srsoftware.utils.Optionals.nullable; import static de.srsoftware.utils.Optionals.nullable;
import static de.srsoftware.utils.Strings.uuid; import static de.srsoftware.utils.Strings.uuid;
import static java.lang.System.Logger.Level.WARNING; import static java.lang.System.Logger.Level.WARNING;
import static java.util.Optional.empty; import static java.util.Optional.empty;
import de.srsoftware.oidc.api.*; import de.srsoftware.oidc.api.*;
import de.srsoftware.oidc.api.data.*;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@@ -19,7 +20,7 @@ import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import org.json.JSONObject; import org.json.JSONObject;
public class FileStore implements ClaimAuthorizationService, ClientService, SessionService, UserService { public class FileStore implements AuthorizationService, ClientService, SessionService, UserService {
private static final String AUTHORIZATIONS = "authorizations"; private static final String AUTHORIZATIONS = "authorizations";
private static final String CLIENTS = "clients"; private static final String CLIENTS = "clients";
private static final String CODES = "codes"; private static final String CODES = "codes";
@@ -273,7 +274,7 @@ public class FileStore implements ClaimAuthorizationService, ClientService, Sess
} }
@Override @Override
public ClaimAuthorizationService authorize(User user, Client client, Collection<String> scopes, Instant expiration) { public AuthorizationService authorize(User user, Client client, Collection<String> scopes, Instant expiration) {
LOG.log(WARNING, "{0}.authorize({1}, {2}, {3}, {4}) not implemented", getClass().getSimpleName(), user.realName(), client.name(), scopes, expiration); LOG.log(WARNING, "{0}.authorize({1}, {2}, {3}, {4}) not implemented", getClass().getSimpleName(), user.realName(), client.name(), scopes, expiration);
var authorizations = json.getJSONObject(AUTHORIZATIONS); var authorizations = json.getJSONObject(AUTHORIZATIONS);
if (!authorizations.has(user.uuid())) authorizations.put(user.uuid(), new JSONObject()); if (!authorizations.has(user.uuid())) authorizations.put(user.uuid(), new JSONObject());

View File

@@ -13,6 +13,7 @@ dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0') testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.junit.jupiter:junit-jupiter'
implementation project(':de.srsoftware.oidc.api') implementation project(':de.srsoftware.oidc.api')
implementation project(':de.srsoftware.http')
} }
test { test {

View File

@@ -4,7 +4,7 @@ package de.srsoftware.oidc.web;
import static java.lang.System.Logger.Level.INFO; import static java.lang.System.Logger.Level.INFO;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.oidc.api.PathHandler; import de.srsoftware.http.PathHandler;
import java.io.IOException; import java.io.IOException;
public class Forward extends PathHandler { public class Forward extends PathHandler {

View File

@@ -5,7 +5,7 @@ import static java.lang.System.Logger.Level.*;
import static java.util.Optional.empty; import static java.util.Optional.empty;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.oidc.api.PathHandler; import de.srsoftware.http.PathHandler;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;

View File

@@ -1,10 +1,10 @@
rootProject.name = 'LightOIDC' rootProject.name = 'LightOIDC'
include 'de.srsoftware.http'
include 'de.srsoftware.logging'
include 'de.srsoftware.oidc.api' include 'de.srsoftware.oidc.api'
include 'de.srsoftware.oidc.app' include 'de.srsoftware.oidc.app'
include 'de.srsoftware.oidc.web'
include 'de.srsoftware.oidc.backend' include 'de.srsoftware.oidc.backend'
include 'de.srsoftware.oidc.datastore.file' include 'de.srsoftware.oidc.datastore.file'
include 'de.srsoftware.cookies' include 'de.srsoftware.oidc.web'
include 'de.srsoftware.logging'
include 'de.srsoftware.utils' include 'de.srsoftware.utils'