diff --git a/postgres.docker-compose.yml b/postgres.docker-compose.yml
index 61337cff..c6ffcec0 100644
--- a/postgres.docker-compose.yml
+++ b/postgres.docker-compose.yml
@@ -51,8 +51,8 @@ services:
POSTGRES_USER: db_user
POSTGRES_PASSWORD: db_user@123
POSTGRES_DB: sts
- volumes:
- - "./.docker/sts-db/postgres:/var/lib/postgresql/data"
+# volumes:
+# - "./.docker/sts-db/postgres:/var/lib/postgresql/data"
ports:
- 5432:5432
# networks:
diff --git a/sts-persistence-jpa/src/main/java/de/adorsys/sts/persistence/jpa/entity/JpaSecret.java b/sts-persistence-jpa/src/main/java/de/adorsys/sts/persistence/jpa/entity/JpaSecret.java
index a5473015..45bc9452 100644
--- a/sts-persistence-jpa/src/main/java/de/adorsys/sts/persistence/jpa/entity/JpaSecret.java
+++ b/sts-persistence-jpa/src/main/java/de/adorsys/sts/persistence/jpa/entity/JpaSecret.java
@@ -12,8 +12,8 @@
public class JpaSecret {
@Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private int id;
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
private String subject;
diff --git a/sts-secret-server/src/test/java/de/adorsys/sts/secretserver/SecretServerApplicationIT.java b/sts-secret-server/src/test/java/de/adorsys/sts/secretserver/SecretServerApplicationIT.java
index f4d1fe89..9fdb663c 100644
--- a/sts-secret-server/src/test/java/de/adorsys/sts/secretserver/SecretServerApplicationIT.java
+++ b/sts-secret-server/src/test/java/de/adorsys/sts/secretserver/SecretServerApplicationIT.java
@@ -15,7 +15,6 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.test.annotation.DirtiesContext;
@@ -23,8 +22,6 @@
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
-import org.testcontainers.containers.PostgreSQLContainer;
-import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.Arrays;
@@ -95,7 +92,7 @@ void setup() {
}
-// @Test
+ @Test
void shouldReturnTheSameSecretForSameUser() {
String firstSecret = getDecryptedSecret(USERNAME_ONE, PASSWORD_ONE);
String secondSecret = getDecryptedSecret(USERNAME_ONE, PASSWORD_ONE);
@@ -103,7 +100,7 @@ void shouldReturnTheSameSecretForSameUser() {
assertThat(firstSecret, is(equalTo(secondSecret)));
}
- // @Test
+ @Test
void shouldReturnDifferentSecretsForDifferentUsers() throws Exception {
String firstSecret = getDecryptedSecret(USERNAME_ONE, PASSWORD_ONE);
String secondSecret = getDecryptedSecret(USERNAME_TWO, PASSWORD_TWO);
@@ -111,7 +108,7 @@ void shouldReturnDifferentSecretsForDifferentUsers() throws Exception {
assertThat(firstSecret, is(not(equalTo(secondSecret))));
}
- // @Test
+ @Test
void shouldNotReturnTheSameTokenForSameUser() throws Exception {
TokenResponse firstTokenResponse = getSecretServerToken(USERNAME_ONE, PASSWORD_ONE);
assertThat(firstTokenResponse.getAccess_token(), is(notNullValue()));
@@ -122,7 +119,7 @@ void shouldNotReturnTheSameTokenForSameUser() throws Exception {
assertThat(firstTokenResponse, is(not(equalTo(secondTokenResponse))));
}
- // @Test
+ @Test
void shouldNotGetSecretForInvalidAccessToken() throws Exception {
final String invalidAccessToken = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJvVjU2Uk9namthbTVzUmVqdjF6b1JVNmY" +
"1R3YtUGRTdjN2b1ZfRVY5MmxnIn0.eyJqdGkiOiI5NWY2MzQ4NC04MTk2LTQ2NzYtYjI4Ni1lYjY4YTFmOTZmYTAiLCJleHAiOjE1N" +
@@ -158,7 +155,7 @@ void shouldNotGetSecretForFakeAccessToken() throws Exception {
assertThat(((HttpClientErrorException) caughtException).getStatusCode(), is(equalTo(HttpStatus.FORBIDDEN)));
}
- // @Test
+ @Test
void shouldGetEmptySecretsForUnknownAudience() throws Exception {
Authentication.AuthenticationToken authToken = authentication.login(USERNAME_ONE, PASSWORD_ONE);
diff --git a/sts-spring/src/main/java/de/adorsys/sts/token/authentication/ConfigurationPropertiesAuthServerProvider.java b/sts-spring/src/main/java/de/adorsys/sts/token/authentication/ConfigurationPropertiesAuthServerProvider.java
index c57cfc2c..e50074f5 100644
--- a/sts-spring/src/main/java/de/adorsys/sts/token/authentication/ConfigurationPropertiesAuthServerProvider.java
+++ b/sts-spring/src/main/java/de/adorsys/sts/token/authentication/ConfigurationPropertiesAuthServerProvider.java
@@ -55,8 +55,7 @@ private AuthServer mapFromProperties(AuthServerConfigurationProperties.AuthServe
properties.getName(),
properties.getIssUrl(),
properties.getJwksUrl(),
- properties.getRefreshIntervalSeconds(),
- objectMapper
+ properties.getRefreshIntervalSeconds()
);
}
}
diff --git a/sts-spring/src/main/java/de/adorsys/sts/token/authentication/LoggingAuthServer.java b/sts-spring/src/main/java/de/adorsys/sts/token/authentication/LoggingAuthServer.java
index 8295ebc3..6aeebf19 100644
--- a/sts-spring/src/main/java/de/adorsys/sts/token/authentication/LoggingAuthServer.java
+++ b/sts-spring/src/main/java/de/adorsys/sts/token/authentication/LoggingAuthServer.java
@@ -10,17 +10,9 @@
import java.util.List;
public class LoggingAuthServer extends AuthServer {
- private static final Logger LOG = LoggerFactory.getLogger(LoggingBearerTokenValidator.class);
- private final ObjectMapper objectMapper;
- public LoggingAuthServer(String name, String issUrl, String jwksUrl, ObjectMapper objectMapper) {
- super(name, issUrl, jwksUrl);
- this.objectMapper = objectMapper;
- }
-
- public LoggingAuthServer(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds, ObjectMapper objectMapper) {
+ public LoggingAuthServer(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds) {
super(name, issUrl, jwksUrl, refreshIntervalSeconds);
- this.objectMapper = objectMapper;
}
@Override
diff --git a/sts-token-auth/pom.xml b/sts-token-auth/pom.xml
index caa20b48..c922839f 100644
--- a/sts-token-auth/pom.xml
+++ b/sts-token-auth/pom.xml
@@ -38,5 +38,17 @@
backport-util-concurrent
3.1
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.10.1
+ test
+
+
+
+ org.mockito
+ mockito-core
+ test
+
diff --git a/sts-token-auth/src/main/java/de/adorsys/sts/tokenauth/AuthServer.java b/sts-token-auth/src/main/java/de/adorsys/sts/tokenauth/AuthServer.java
index aa023767..f250344e 100644
--- a/sts-token-auth/src/main/java/de/adorsys/sts/tokenauth/AuthServer.java
+++ b/sts-token-auth/src/main/java/de/adorsys/sts/tokenauth/AuthServer.java
@@ -3,9 +3,12 @@
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.jwk.source.JWKSource;
-import com.nimbusds.jose.jwk.source.RemoteJWKSet;
+import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
import com.nimbusds.jose.proc.SecurityContext;
import lombok.Getter;
+import lombok.Setter;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
import java.net.URL;
import java.security.Key;
@@ -13,35 +16,40 @@
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
+@Slf4j
public class AuthServer {
+ @Setter
@Getter
private String name;
@Getter
private final String issUrl;
private final String jwksUrl;
- private int refreshIntervalSeconds = 600;
+ private final int refreshIntervalSeconds;
- private final ConcurrentHashMap jwkCache = new ConcurrentHashMap<>();
- private long lastCacheUpdate = 0;
+ @Setter
+ JWKSource jwkSource;
+
+ final ConcurrentHashMap jwkCache = new ConcurrentHashMap<>();
+ long lastCacheUpdate = 0;
public AuthServer(String name, String issUrl, String jwksUrl) {
- super();
- this.name = name;
- this.issUrl = issUrl;
- this.jwksUrl = jwksUrl;
+ this(name, issUrl, jwksUrl, 600);
}
+ @SneakyThrows
public AuthServer(String name, String issUrl, String jwksUrl, int refreshIntervalSeconds) {
super();
this.name = name;
this.issUrl = issUrl;
this.jwksUrl = jwksUrl;
this.refreshIntervalSeconds = refreshIntervalSeconds;
+
+ jwkSource = JWKSourceBuilder.create(new URL(this.jwksUrl)).build();
}
private void updateJwkCache() throws JsonWebKeyRetrievalException {
try {
- JWKSource jwkSource = new RemoteJWKSet<>(new URL(this.jwksUrl));
+
List jwks = jwkSource.get(new JWKSelector(new JWKMatcher.Builder().build()), null);
onJsonWebKeySetRetrieved(jwks);
@@ -83,11 +91,8 @@ public Key getJWK(String keyID) throws JsonWebKeyRetrievalException {
}
}
- public void setName(String name) {
- this.name = name;
- }
-
protected void onJsonWebKeySetRetrieved(List jwks) {
+ log.info("Retrieved {} keys from {}", jwks.size(), jwksUrl);
}
public static class JsonWebKeyRetrievalException extends RuntimeException {
diff --git a/sts-token-auth/src/test/java/de/adorsys/sts/tokenauth/AuthServerTest.java b/sts-token-auth/src/test/java/de/adorsys/sts/tokenauth/AuthServerTest.java
new file mode 100644
index 00000000..f0a91f1f
--- /dev/null
+++ b/sts-token-auth/src/test/java/de/adorsys/sts/tokenauth/AuthServerTest.java
@@ -0,0 +1,103 @@
+package de.adorsys.sts.tokenauth;
+
+import com.nimbusds.jose.RemoteKeySourceException;
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.JWKSelector;
+import com.nimbusds.jose.jwk.RSAKey;
+import com.nimbusds.jose.jwk.source.JWKSource;
+import com.nimbusds.jose.jwk.source.RemoteJWKSet;
+import com.nimbusds.jose.proc.SecurityContext;
+import com.nimbusds.jose.util.Base64URL;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+class AuthServerTest {
+
+ private AuthServer authServer;
+ private RemoteJWKSet mockRemoteJWKSet;
+
+ @BeforeEach
+ void setUp() throws Exception {
+ authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks", 10);
+ mockRemoteJWKSet = Mockito.mock(RemoteJWKSet.class);
+ JWK jwk = new RSAKey.Builder(new Base64URL("n"), new Base64URL("e")).keyID("testKey").build();
+ when(mockRemoteJWKSet.get(any(JWKSelector.class), any(SecurityContext.class))).thenReturn(Collections.singletonList(jwk));
+ }
+
+ @Test
+ void testCacheInitialization() {
+ assertTrue(authServer.jwkCache.isEmpty(), "Cache should be initially empty");
+ }
+
+ @Test
+ void testCacheUpdateAfterInterval() throws Exception {
+ // Simulieren, dass die letzte Aktualisierung lange zurĆ¼ckliegt
+ JWKSource mockJwkSource = Mockito.mock(JWKSource.class);
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(512); // 512-bit RSA key pair
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+ // Create a mock RSAKey from the generated key pair
+ RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()).keyID("testKey").build();
+
+ // Configure your AuthServer instance
+ AuthServer authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks");
+ authServer.setJwkSource(mockJwkSource); // Inject the mock
+
+ // Mock the JWKSource and configure it to return the mock RSAKey
+ Mockito.when(mockJwkSource.get(any(), any())).thenReturn(Collections.singletonList(rsaKey));
+ authServer.lastCacheUpdate = 0;
+ authServer.getJWK("testKey");
+
+ assertFalse(authServer.jwkCache.isEmpty(), "Cache should be updated after interval");
+ }
+
+ @Test
+ void testCacheUpdateOnNonExistingKey() {
+ assertThrows(AuthServer.JsonWebKeyRetrievalException.class, () -> authServer.getJWK("nonExistingKey"));
+ }
+
+ @Test
+ void testValidKeyRetrieval() throws Exception {
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(512); // 512-bit RSA key pair
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+ // Create a mock RSAKey from the generated key pair
+ RSAKey rsaKey = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()).keyID("testKey").build();
+
+ // Mock the JWKSource and configure it to return the mock RSAKey
+ JWKSource mockJwkSource = Mockito.mock(JWKSource.class);
+ Mockito.when(mockJwkSource.get(any(), any())).thenReturn(Collections.singletonList(rsaKey));
+
+ // Inject the mock JWKSource into your AuthServer
+ AuthServer authServer = new AuthServer("TestServer", "https://example.com/iss", "https://example.com/jwks");
+ // Assuming you have a method to set the JWKSource
+ authServer.setJwkSource(mockJwkSource);
+ // Now you can test your method
+ Key key = authServer.getJWK("testKey");
+
+ assertNotNull(key, "Should return a valid key for a valid keyID");
+ }
+
+ @Test
+ void testExceptionHandling() throws RemoteKeySourceException {
+ // Konfigurieren Sie das Mock-Objekt, um eine Ausnahme zu werfen
+ when(mockRemoteJWKSet.get(any(JWKSelector.class), any(SecurityContext.class))).thenThrow(new RuntimeException("Test Exception"));
+
+ assertThrows(AuthServer.JsonWebKeyRetrievalException.class, () -> authServer.getJWK("testKey"));
+ }
+
+
+}
\ No newline at end of file
diff --git a/sts-token-auth/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/sts-token-auth/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 00000000..1f0955d4
--- /dev/null
+++ b/sts-token-auth/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1 @@
+mock-maker-inline