Browse Source

altered AuthorizationService to use User and Client references instead of full objects. Added tests.

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
sqlite
Stephan Richter 2 months ago
parent
commit
0b96aeb63d
  1. 6
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/AuthorizationService.java
  2. 73
      de.srsoftware.oidc.api/src/test/java/de/srsoftware/oidc/api/AuthServiceTest.java
  3. 4
      de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java
  4. 29
      de.srsoftware.oidc.datastore.file/src/main/java/de/srsoftware/oidc/datastore/file/FileStore.java
  5. 27
      de.srsoftware.oidc.datastore.file/src/test/java/de/srsoftware/oidc/datastore/file/FileStoreAuthServiceTest.java
  6. 6
      de.srsoftware.oidc.datastore.sqlite/src/main/java/de/srsoftware/oidc/datastore/sqlite/SqliteAuthService.java

6
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/AuthorizationService.java

@ -3,14 +3,12 @@ package de.srsoftware.oidc.api;
import de.srsoftware.oidc.api.data.AuthResult; import de.srsoftware.oidc.api.data.AuthResult;
import de.srsoftware.oidc.api.data.Authorization; 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.time.Instant;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
public interface AuthorizationService { public interface AuthorizationService {
AuthorizationService authorize(User user, Client client, Collection<String> scopes, Instant expiration); AuthorizationService authorize(String userId, String clientId, Collection<String> scopes, Instant expiration);
Optional<Authorization> consumeAuthorization(String authCode); Optional<Authorization> consumeAuthorization(String authCode);
AuthResult getAuthorization(User user, Client client, Collection<String> scopes); AuthResult getAuthorization(String userId, String clientId, Collection<String> scopes);
} }

73
de.srsoftware.oidc.api/src/test/java/de/srsoftware/oidc/api/AuthServiceTest.java

@ -0,0 +1,73 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api;
import static de.srsoftware.oidc.api.Constants.OPENID;
import static de.srsoftware.utils.Strings.uuid;
import static java.time.temporal.ChronoUnit.SECONDS;
import static org.junit.jupiter.api.Assertions.*;
import java.time.Instant;
import java.util.Set;
import org.junit.jupiter.api.Test;
public abstract class AuthServiceTest {
private static final String CLIENT1 = "client1";
private static final Set<String> SCOPES1 = Set.of(OPENID, Constants.EMAIL, "ranzpappe");
private static final String INVALID = "invalid";
private static final String PASS1 = "grunzwanzling";
private static final String USERNAME = "arthurdent";
private static final String REALNAME = "Arthur Dent";
private static final String EMAIL = "arthur@herzaus.gold";
protected abstract AuthorizationService authorizationService();
@Test
public void testAuthorize() {
var authorizationService = authorizationService();
var userId1 = uuid();
var expiration = Instant.now().plusSeconds(3600).truncatedTo(SECONDS);
authorizationService.authorize(userId1, CLIENT1, SCOPES1, expiration);
var authorization = authorizationService.getAuthorization(userId1, CLIENT1, Set.of(OPENID));
assertEquals(1, authorization.authorizedScopes().scopes().size());
assertTrue(authorization.authorizedScopes().scopes().contains(OPENID));
assertEquals(expiration, authorization.authorizedScopes().expiration());
authorization = authorizationService.getAuthorization(userId1, CLIENT1, Set.of(INVALID));
assertNull(authorization.authorizedScopes());
assertNull(authorization.authCode());
assertTrue(authorization.unauthorizedScopes().contains(INVALID));
authorization = authorizationService.getAuthorization(userId1, CLIENT1, Set.of(INVALID, OPENID));
assertEquals(1, authorization.authorizedScopes().scopes().size());
assertTrue(authorization.authorizedScopes().scopes().contains(OPENID));
assertEquals(expiration, authorization.authorizedScopes().expiration());
assertEquals(1, authorization.unauthorizedScopes().size());
assertTrue(authorization.unauthorizedScopes().contains(INVALID));
}
@Test
public void testConsume() {
var authorizationService = authorizationService();
var userId1 = uuid();
var expiration = Instant.now().plusSeconds(3600).truncatedTo(SECONDS);
authorizationService.authorize(userId1, CLIENT1, SCOPES1, expiration);
var authResult = authorizationService.getAuthorization(userId1, CLIENT1, Set.of(OPENID));
var authCode = authResult.authCode();
assertNotNull(authCode);
var optAuth = authorizationService.consumeAuthorization(authCode);
assertTrue(optAuth.isPresent());
var authorization = optAuth.get();
assertEquals(CLIENT1, authorization.clientId());
assertEquals(userId1, authorization.userId());
var scopes = authorization.scopes();
assertEquals(expiration, scopes.expiration());
assertEquals(1, scopes.scopes().size());
assertTrue(scopes.scopes().contains(OPENID));
optAuth = authorizationService.consumeAuthorization(authCode);
assertTrue(optAuth.isEmpty());
}
}

4
de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/ClientController.java

@ -79,10 +79,10 @@ public class ClientController extends Controller {
var days = authorized.getInt("days"); var days = authorized.getInt("days");
var list = new ArrayList<String>(); var list = new ArrayList<String>();
authorized.getJSONArray("scopes").forEach(scope -> list.add(scope.toString())); authorized.getJSONArray("scopes").forEach(scope -> list.add(scope.toString()));
authorizations.authorize(user, client, list, Instant.now().plus(days, ChronoUnit.DAYS)); authorizations.authorize(user.uuid(), client.id(), list, Instant.now().plus(days, ChronoUnit.DAYS));
} }
var authResult = authorizations.getAuthorization(user, client, scopes); var authResult = authorizations.getAuthorization(user.uuid(), client.id(), scopes);
if (!authResult.unauthorizedScopes().isEmpty()) { if (!authResult.unauthorizedScopes().isEmpty()) {
return sendContent(ex, Map.of("unauthorized_scopes", authResult.unauthorizedScopes(), "rp", client.name())); return sendContent(ex, Map.of("unauthorized_scopes", authResult.unauthorizedScopes(), "rp", client.name()));
} }

29
de.srsoftware.oidc.datastore.file/src/main/java/de/srsoftware/oidc/datastore/file/FileStore.java

@ -315,20 +315,20 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
} }
/*** ClaimAuthorizationService methods ***/ /*** ClaimAuthorizationService methods ***/
private String authCode(User user, Client client, Authorization authorization) { private String authCode(Authorization authorization) {
var code = uuid(); var code = uuid();
authCodes.put(code, authorization); authCodes.put(code, authorization);
return code; return code;
} }
@Override @Override
public AuthorizationService authorize(User user, Client client, Collection<String> scopes, Instant expiration) { public AuthorizationService authorize(String userId, String clientId, Collection<String> scopes, Instant expiration) {
if (!json.has(AUTHORIZATIONS)) json.put(AUTHORIZATIONS, new JSONObject()); if (!json.has(AUTHORIZATIONS)) json.put(AUTHORIZATIONS, new JSONObject());
var authorizations = json.getJSONObject(AUTHORIZATIONS); var authorizations = json.getJSONObject(AUTHORIZATIONS);
if (!authorizations.has(user.uuid())) authorizations.put(user.uuid(), new JSONObject()); if (!authorizations.has(userId)) authorizations.put(userId, new JSONObject());
var userAuthorizations = authorizations.getJSONObject(user.uuid()); var userAuthorizations = authorizations.getJSONObject(userId);
if (!userAuthorizations.has(client.id())) userAuthorizations.put(client.id(), new JSONObject()); if (!userAuthorizations.has(clientId)) userAuthorizations.put(clientId, new JSONObject());
var clientScopes = userAuthorizations.getJSONObject(client.id()); var clientScopes = userAuthorizations.getJSONObject(clientId);
for (var scope : scopes) clientScopes.put(scope, expiration.getEpochSecond()); for (var scope : scopes) clientScopes.put(scope, expiration.getEpochSecond());
save(); save();
return this; return this;
@ -341,12 +341,12 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
} }
@Override @Override
public AuthResult getAuthorization(User user, Client client, Collection<String> scopes) { public AuthResult getAuthorization(String userId, String clientId, Collection<String> scopes) {
if (!json.has(AUTHORIZATIONS)) return unauthorized(scopes); if (!json.has(AUTHORIZATIONS)) return unauthorized(scopes);
var authorizations = json.getJSONObject(AUTHORIZATIONS); var authorizations = json.getJSONObject(AUTHORIZATIONS);
var userAuthorizations = authorizations.has(user.uuid()) ? authorizations.getJSONObject(user.uuid()) : null; var userAuthorizations = authorizations.has(userId) ? authorizations.getJSONObject(userId) : null;
if (userAuthorizations == null) return unauthorized(scopes); if (userAuthorizations == null) return unauthorized(scopes);
var clientScopes = userAuthorizations.has(client.id()) ? userAuthorizations.getJSONObject(client.id()) : null; var clientScopes = userAuthorizations.has(clientId) ? userAuthorizations.getJSONObject(clientId) : null;
if (clientScopes == null) return unauthorized(scopes); if (clientScopes == null) return unauthorized(scopes);
var now = Instant.now(); var now = Instant.now();
var authorizedScopes = new HashSet<String>(); var authorizedScopes = new HashSet<String>();
@ -354,18 +354,19 @@ public class FileStore implements AuthorizationService, ClientService, SessionSe
Instant earliestExpiration = null; Instant earliestExpiration = null;
for (var scope : scopes) { for (var scope : scopes) {
if (clientScopes.has(scope)) { if (clientScopes.has(scope)) {
var expiration = Instant.ofEpochSecond(clientScopes.getLong(scope)); var expiration = Instant.ofEpochSecond(clientScopes.getLong(scope)).truncatedTo(SECONDS);
if (expiration.isAfter(now)) { if (expiration.isAfter(now)) {
authorizedScopes.add(scope); authorizedScopes.add(scope);
if (earliestExpiration == null || expiration.isBefore(earliestExpiration)) earliestExpiration = expiration; if (earliestExpiration == null || expiration.isBefore(earliestExpiration)) earliestExpiration = expiration;
} else { continue;
unauthorizedScopes.add(scope);
} }
} }
unauthorizedScopes.add(scope);
} }
if (authorizedScopes.isEmpty()) return unauthorized(scopes);
var authorization = new Authorization(client.id(), user.uuid(), new AuthorizedScopes(authorizedScopes, earliestExpiration)); var authorization = new Authorization(clientId, userId, new AuthorizedScopes(authorizedScopes, earliestExpiration));
return new AuthResult(authorization.scopes(), unauthorizedScopes, authCode(user, client, authorization)); return new AuthResult(authorization.scopes(), unauthorizedScopes, authCode(authorization));
} }
private AuthResult unauthorized(Collection<String> scopes) { private AuthResult unauthorized(Collection<String> scopes) {

27
de.srsoftware.oidc.datastore.file/src/test/java/de/srsoftware/oidc/datastore/file/FileStoreAuthServiceTest.java

@ -0,0 +1,27 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.datastore.file;
import static org.junit.jupiter.api.Assertions.*;
import de.srsoftware.oidc.api.AuthServiceTest;
import de.srsoftware.oidc.api.AuthorizationService;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
public class FileStoreAuthServiceTest extends AuthServiceTest {
private File storage = new File("/tmp/" + UUID.randomUUID());
private AuthorizationService authorizationService;
@Override
protected AuthorizationService authorizationService() {
return authorizationService;
}
@BeforeEach
public void setup() throws IOException {
if (storage.exists()) storage.delete();
authorizationService = new FileStore(storage, null);
}
}

6
de.srsoftware.oidc.datastore.sqlite/src/main/java/de/srsoftware/oidc/datastore/sqlite/SqliteAuthService.java

@ -4,8 +4,6 @@ package de.srsoftware.oidc.datastore.sqlite;
import de.srsoftware.oidc.api.AuthorizationService; import de.srsoftware.oidc.api.AuthorizationService;
import de.srsoftware.oidc.api.data.AuthResult; import de.srsoftware.oidc.api.data.AuthResult;
import de.srsoftware.oidc.api.data.Authorization; import de.srsoftware.oidc.api.data.Authorization;
import de.srsoftware.oidc.api.data.Client;
import de.srsoftware.oidc.api.data.User;
import java.sql.Connection; import java.sql.Connection;
import java.time.Instant; import java.time.Instant;
import java.util.Collection; import java.util.Collection;
@ -16,7 +14,7 @@ public class SqliteAuthService implements AuthorizationService {
} }
@Override @Override
public AuthorizationService authorize(User user, Client client, Collection<String> scopes, Instant expiration) { public AuthorizationService authorize(String userId, String clientId, Collection<String> scopes, Instant expiration) {
return null; return null;
} }
@ -26,7 +24,7 @@ public class SqliteAuthService implements AuthorizationService {
} }
@Override @Override
public AuthResult getAuthorization(User user, Client client, Collection<String> scopes) { public AuthResult getAuthorization(String userId, String clientId, Collection<String> scopes) {
return null; return null;
} }
} }

Loading…
Cancel
Save