From 01ca3b5452c02d96d8c390ed265a4f5159e68be9 Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 11 Nov 2024 13:18:49 +0530 Subject: [PATCH 01/44] feat(config-api): testng framework Signed-off-by: pujavs --- jans-config-api/common/pom.xml | 7 +- .../docs/jans-config-api-swagger.yaml | 16 +-- jans-config-api/pom.xml | 28 +++-- jans-config-api/server/pom.xml | 35 +++--- .../io/jans/configapi/BaseComponentTest.java | 111 ++++++++++++++++++ .../test/java/io/jans/configapi/BaseTest.java | 74 ++++++++++++ .../listener/ApiUnitTestListener.java | 75 ++++++++++++ .../test/resources/config-api-test.properties | 8 ++ .../server/src/test/resources/testng.xml | 24 ++++ 9 files changed, 335 insertions(+), 43 deletions(-) create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/BaseComponentTest.java create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java create mode 100644 jans-config-api/server/src/test/resources/config-api-test.properties create mode 100644 jans-config-api/server/src/test/resources/testng.xml diff --git a/jans-config-api/common/pom.xml b/jans-config-api/common/pom.xml index e052a271472..f80c029373c 100644 --- a/jans-config-api/common/pom.xml +++ b/jans-config-api/common/pom.xml @@ -40,10 +40,9 @@ maven-surefire-plugin - true - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index e86cd588929..c01675c844a 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,20 +9267,20 @@ components: type: string selected: type: boolean - whitePagesCanView: - type: boolean - adminCanEdit: - type: boolean userCanView: type: boolean adminCanView: type: boolean userCanEdit: type: boolean + adminCanEdit: + type: boolean userCanAccess: type: boolean adminCanAccess: type: boolean + whitePagesCanView: + type: boolean baseDn: type: string PatchRequest: @@ -10128,6 +10128,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10137,8 +10139,6 @@ components: - code - token - id_token - fapi: - type: boolean AuthenticationFilter: required: - baseDn @@ -11682,10 +11682,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/pom.xml b/jans-config-api/pom.xml index 87a360c6538..af4eb1c4f27 100644 --- a/jans-config-api/pom.xml +++ b/jans-config-api/pom.xml @@ -42,6 +42,7 @@ 5.0.1 0.9.5 + 7.8.0 2.0 5.7.0 3.8.0 @@ -88,11 +89,7 @@ Bouncy Castle https://repo1.maven.org/maven2/org/bouncycastle - - repository.jboss.org - JBoss Repository - https://repository.jboss.org/nexus/content/groups/public-jboss/ - + @@ -104,13 +101,13 @@ - - io.jans - jans-bom - ${jans.version} - import - pom - + + io.jans + jans-bom + ${jans.version} + import + pom + com.fasterxml.jackson jackson-bom @@ -327,6 +324,13 @@ ${rest-assured.version} test + + org.testng + testng + ${testng.version} + test + + com.intuit.karate karate-junit5 diff --git a/jans-config-api/server/pom.xml b/jans-config-api/server/pom.xml index d6a8c030ef2..1613cd8bd2a 100644 --- a/jans-config-api/server/pom.xml +++ b/jans-config-api/server/pom.xml @@ -194,6 +194,13 @@ rest-assured test + + org.testng + testng + test + + + com.intuit.karate karate-junit5 @@ -266,22 +273,15 @@ jans-config-api - ../profiles/${cfg}/config-build.properties ../profiles/${cfg}/config-api-test.properties - - - src/test/resources - true - - karate.properties - karate_jenkins.properties - test.properties - *.* - - - + + + src/test/resources + true + + @@ -388,12 +388,9 @@ maven-surefire-plugin - - - integration - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseComponentTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseComponentTest.java new file mode 100644 index 00000000000..fff3b01462c --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseComponentTest.java @@ -0,0 +1,111 @@ +/* + * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.core.test.base; + +import io.jans.as.common.service.common.InumService; +import io.jans.as.common.service.common.UserService; +import io.jans.as.model.config.StaticConfiguration; +import io.jans.as.model.crypto.AbstractCryptoProvider; +import io.jans.as.server.idgen.ws.rs.InumGenerator; +import io.jans.as.server.model.common.AuthorizationGrantList; +import io.jans.as.server.model.config.ConfigurationFactory; +import io.jans.as.server.service.CleanerTimer; +import io.jans.as.server.service.ClientService; +import io.jans.as.server.service.GrantService; +import io.jans.as.server.service.SessionIdService; +import io.jans.as.server.uma.service.UmaPctService; +import io.jans.as.server.uma.service.UmaPermissionService; +import io.jans.as.server.uma.service.UmaResourceService; +import io.jans.as.server.uma.service.UmaRptService; +import io.jans.orm.PersistenceEntryManager; +import io.jans.service.CacheService; +import io.jans.service.EncryptionService; +import io.jans.service.cdi.util.CdiUtil; + + +public abstract class BaseComponentTest extends BaseTest { + + public static void sleepSeconds(int p_seconds) { + try { + Thread.sleep(p_seconds * 1000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public static InumGenerator getInumGenerator() { + return CdiUtil.bean(InumGenerator.class); + } + + public static StaticConfiguration getStaticConfiguration() { + return CdiUtil.bean(StaticConfiguration.class); + } + + public ClientService getClientService() { + return CdiUtil.bean(ClientService.class); + } + + public InumService getInumService() { + return CdiUtil.bean(InumService.class); + } + + public CleanerTimer getCleanerTimer() { + return CdiUtil.bean(CleanerTimer.class); + } + + public CacheService getCacheService() { + return CdiUtil.bean(CacheService.class); + } + + public UmaRptService getUmaRptService() { + return CdiUtil.bean(UmaRptService.class); + } + + public UmaResourceService getUmaResourceService() { + return CdiUtil.bean(UmaResourceService.class); + } + + public UmaPermissionService getUmaPermissionService() { + return CdiUtil.bean(UmaPermissionService.class); + } + + public UmaPctService getUmaPctService() { + return CdiUtil.bean(UmaPctService.class); + } + + public AuthorizationGrantList getAuthorizationGrantList() { + return CdiUtil.bean(AuthorizationGrantList.class); + } + + public GrantService getGrantService() { + return CdiUtil.bean(GrantService.class); + } + + public EncryptionService getEncryptionService() { + return CdiUtil.bean(EncryptionService.class); + } + + public ConfigurationFactory getConfigurationFactory() { + return CdiUtil.bean(ConfigurationFactory.class); + } + + public AbstractCryptoProvider getAbstractCryptoProvider() { + return CdiUtil.bean(AbstractCryptoProvider.class); + } + + public SessionIdService getSessionIdService() { + return CdiUtil.bean(SessionIdService.class); + } + + public UserService getUserService() { + return CdiUtil.bean(UserService.class); + } + + public PersistenceEntryManager getPersistenceEntryManager() { + return CdiUtil.bean(PersistenceEntryManager.class); + } +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java new file mode 100644 index 00000000000..98cdf573fc5 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -0,0 +1,74 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.commons.codec.binary.Base64; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.testng.ITestContext; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeSuite; + +import static java.nio.charset.StandardCharsets.UTF_8; + + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Hashtable; +import java.util.Map; +import java.util.Properties; +import java.net.URLEncoder; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; + + +public class BaseTest { + + protected Logger logger = LogManager.getLogger(getClass()); + protected ObjectMapper mapper = new ObjectMapper(); + private static Map propertiesMap = null; + + @BeforeSuite + public void initTestSuite(ITestContext context) throws Exception { + + logger.info("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); + String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); + Properties prop = new Properties(); + prop.load(Files.newBufferedReader(Paths.get(propertiesFile), UTF_8)); + + propertiesMap = new Hashtable<>(); + prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); + context.getSuite().getXmlSuite().setParameters(propertiesMap); + } + + @AfterSuite + public void finalize() { + //cleanup + logger.info("After Suite finalize'"); + } + + + public String getAccessToken() throws Exception { + String mainUrl = propertiesMap.get("token.endpoint"); + String grantType = propertiesMap.get("token.grant.type"); + String clientId = propertiesMap.get("test.client.id"); + String clientSecret = propertiesMap.get("test.client.secret"); + String scopes = propertiesMap.get("test.scopes"); + String authStr = clientId+':'+clientSecret; + + String token = new String(Base64.decodeBase64(authStr), StandardCharsets.UTF_8); + String encodedScopes = URLDecoder.decode(scopes, "UTF-8"); + + + } + +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java b/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java new file mode 100644 index 00000000000..cb95b62d3ca --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java @@ -0,0 +1,75 @@ +/* + * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. + * + * Copyright (c) 2021, Janssen Project + */ +package io.jans.configapi.core.test.listener; + +import org.testng.ITestContext; +import org.testng.ITestListener; +import org.testng.ITestResult; +import org.testng.Reporter; + +import com.google.common.base.Throwables; + +public class ApiUnitTestListener implements ITestListener { + + @Override + public void onTestStart(ITestResult result) { + Reporter.log("Test STARTED: " + getTestInfo(result), true); + } + + @Override + public void onTestSuccess(ITestResult result) { + Reporter.log("Test SUCCESS: " + getTestInfo(result), true); + Reporter.log("", true); + } + + @Override + public void onTestFailure(ITestResult result) { + Reporter.log("Test FAILED: " + getTestInfo(result), true); + testFailed(result); + } + + @Override + public void onTestSkipped(ITestResult result) { + Reporter.log("Test SKIPPED: " + getTestInfo(result), true); + Reporter.log("", true); + } + + @Override + public void onTestFailedButWithinSuccessPercentage(ITestResult result) { + Reporter.log("Test FAILED with Success Percentage: " + getTestInfo(result), true); + testFailed(result); + } + + @Override + public void onStart(ITestContext context) { + } + + @Override + public void onFinish(ITestContext context) { + } + + private void testFailed(ITestResult result) { + Object[] parameters = result.getParameters(); + if(parameters != null) { + Reporter.log("Test Parameters: ", true); + for(Object parameter : parameters) { + Reporter.log("parameter = " + parameter, true); + } + } + Throwable throwable = result.getThrowable(); + if(throwable != null) { + Reporter.log("", true); + Reporter.log("Exception: ", true); + Reporter.log(Throwables.getStackTraceAsString(result.getThrowable()), true); + Reporter.log("", true); + } + } + + private String getTestInfo(ITestResult result) { + return result.getInstanceName() + "." + result.getName(); + } + +} diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties new file mode 100644 index 00000000000..4257f297907 --- /dev/null +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -0,0 +1,8 @@ +test.scopes=${test.scopes} + +# Test env Setting +token.endpoint=${token.endpoint} +token.grant.type=${token.grant.type} +test.client.id=${test.client.id} +test.client.secret=${test.client.secret} +test.issuer=${test.issuer} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml new file mode 100644 index 00000000000..fe7dfb0a894 --- /dev/null +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + From 7b9d278536433e6c50fab86b968c0e59a2f75465 Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 11 Nov 2024 19:44:36 +0530 Subject: [PATCH 02/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../test/java/io/jans/configapi/BaseTest.java | 60 ++- .../listener/ApiUnitTestListener.java | 0 .../rest/resource/ConfigResourceTest.java | 0 .../configapi/client/service/HttpService.java | 343 ++++++++++++++++++ 4 files changed, 397 insertions(+), 6 deletions(-) rename jans-config-api/server/src/test/java/io/jans/configapi/{ => client}/listener/ApiUnitTestListener.java (100%) rename jans-config-api/server/src/test/java/io/jans/configapi/{ => client}/rest/resource/ConfigResourceTest.java (100%) create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index 98cdf573fc5..c2516a1d677 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -9,20 +9,32 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.codec.binary.Base64; +import io.jans.as.client.dev.HostnameVerifierType; +import org.apache.commons.codec.binary.Base64; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.testng.ITestContext; -import org.testng.annotations.AfterSuite; -import org.testng.annotations.BeforeSuite; + import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.file.Files; import java.nio.file.Paths; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; import java.util.Hashtable; import java.util.Map; import java.util.Properties; @@ -30,12 +42,27 @@ import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import jakarta.ws.rs.core.UriBuilder; + +import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; +import org.jboss.resteasy.client.jaxrs.ResteasyClient; +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; +import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; +import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; + + +import org.testng.ITestContext; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeSuite; + public class BaseTest { protected Logger logger = LogManager.getLogger(getClass()); protected ObjectMapper mapper = new ObjectMapper(); private static Map propertiesMap = null; + private ApacheHttpClient43Engine engine; + @BeforeSuite public void initTestSuite(ITestContext context) throws Exception { @@ -48,6 +75,8 @@ public void initTestSuite(ITestContext context) throws Exception { propertiesMap = new Hashtable<>(); prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); context.getSuite().getXmlSuite().setParameters(propertiesMap); + + this.engine = createEngine(); } @AfterSuite @@ -58,7 +87,7 @@ public void finalize() { public String getAccessToken() throws Exception { - String mainUrl = propertiesMap.get("token.endpoint"); + String tokenUrl = propertiesMap.get("token.endpoint"); String grantType = propertiesMap.get("token.grant.type"); String clientId = propertiesMap.get("test.client.id"); String clientSecret = propertiesMap.get("test.client.secret"); @@ -67,8 +96,27 @@ public String getAccessToken() throws Exception { String token = new String(Base64.decodeBase64(authStr), StandardCharsets.UTF_8); String encodedScopes = URLDecoder.decode(scopes, "UTF-8"); + + ResteasyClient client = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(engine).build(); + ResteasyWebTarget target = client.target(UriBuilder.fromPath(tokenUrl)); } - + + + + + + private ApacheHttpClient43Engine createEngine() { + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + CloseableHttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(cm).build(); + cm.setMaxTotal(200); // Increase max total connection to 200 + cm.setDefaultMaxPerRoute(20); // Increase default max connection per route to 20 + ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient); + engine.setFollowRedirects(true); + + return engine; + } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java b/jans-config-api/server/src/test/java/io/jans/configapi/client/listener/ApiUnitTestListener.java similarity index 100% rename from jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java rename to jans-config-api/server/src/test/java/io/jans/configapi/client/listener/ApiUnitTestListener.java diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/client/rest/resource/ConfigResourceTest.java similarity index 100% rename from jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/client/rest/resource/ConfigResourceTest.java diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java b/jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java new file mode 100644 index 00000000000..3c12da399c5 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java @@ -0,0 +1,343 @@ +/* + * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.client; + + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.Map; +import java.util.Map.Entry; + +import javax.net.ssl.SSLContext; + +import org.apache.commons.codec.binary.Base64; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.DefaultProxyRoutePlanner; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.ssl.TrustStrategy; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; + +import io.jans.model.net.HttpServiceResponse; +import io.jans.util.StringHelper; +import io.jans.util.Util; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.lang.StringUtils; +import org.json.JSONObject; + + +public abstract class BaseHttpService implements Serializable { + + private static final long serialVersionUID = -2398422090669045605L; + + @Inject + private Logger log; + + private Base64 base64; + + private PoolingHttpClientConnectionManager connectionManager; + + @PostConstruct + public void init() { + connectionManager = new PoolingHttpClientConnectionManager(); + connectionManager.setMaxTotal(200); // Increase max total connection to 200 + connectionManager.setDefaultMaxPerRoute(50); // Increase default max connection per route to 50 + + this.base64 = new Base64(); + } + + public CloseableHttpClient getHttpsClientTrustAll() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext, + NoopHostnameVerifier.INSTANCE); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient() { + return getHttpsClient(RequestConfig.custom().build()); + } + + public CloseableHttpClient getHttpsClient(RequestConfig requestConfig) { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient(HttpRoutePlanner routerPlanner) { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + return getHttpsClient(RequestConfig.custom().build(), routerPlanner); + } + + public CloseableHttpClient getHttpsClient(RequestConfig requestConfig, HttpRoutePlanner routerPlanner) { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).setRoutePlanner(routerPlanner).build(); + } + + public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword, + String keyStoreType, String keyStorePath, String keyStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()) + .loadKeyMaterial(new File(keyStorePath), keyStorePassword.toCharArray(), keyStorePassword.toCharArray()).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, Map headers, String postData, ContentType contentType, String authType) { + + HttpPost httpPost = new HttpPost(uri); + + if(StringHelper.isEmpty(authType)) { + authType = "Basic "; + } + else { + authType = authType +" "; + } + if (StringHelper.isNotEmpty(authData)) { + httpPost.setHeader("Authorization", authType + authData); + } + + if (headers != null) { + for (Entry headerEntry : headers.entrySet()) { + httpPost.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } + } + + StringEntity stringEntity = new StringEntity(postData, contentType); + httpPost.setEntity(stringEntity); + + try { + HttpResponse httpResponse = httpClient.execute(httpPost); + + return new HttpServiceResponse(httpPost, httpResponse); + } catch (IOException ex) { + log.error("Failed to execute post request", ex); + } + + return null; + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, Map headers, String postData) { + return executePost(httpClient, uri, authData, headers, postData, null, null); + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, String postData, ContentType contentType) { + return executePost(httpClient, uri, authData, null, postData, contentType, null); + } + + public HttpServiceResponse executePost(String uri, String authData, Map headers, String postData, ContentType contentType, String authType) { + return executePost(this.getHttpsClient(), uri, authData, null, postData, contentType, authType); + } + + public String encodeBase64(String value) { + try { + return new String(base64.encode((value).getBytes(Util.UTF8)), Util.UTF8); + } catch (UnsupportedEncodingException ex) { + log.error("Failed to convert '{}' to base64", value, ex); + } + + return null; + } + + public String encodeUrl(String value) { + try { + return URLEncoder.encode(value, Util.UTF8); + } catch (UnsupportedEncodingException ex) { + log.error("Failed to encode url '{}'", value, ex); + } + + return null; + } + + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, Map headers) { + HttpGet httpGet = new HttpGet(requestUri); + + if (headers != null) { + for (Entry headerEntry : headers.entrySet()) { + httpGet.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } + } + + try { + HttpResponse httpResponse = httpClient.execute(httpGet); + + return new HttpServiceResponse(httpGet, httpResponse); + } catch (IOException ex) { + log.error("Failed to execute get request", ex); + } + + return null; + } + + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri) throws ClientProtocolException, IOException { + return executeGet(httpClient, requestUri, null); + } + + public byte[] getResponseContent(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { + return null; + } + + HttpEntity entity = httpResponse.getEntity(); + byte[] responseBytes = new byte[0]; + if (entity != null) { + responseBytes = EntityUtils.toByteArray(entity); + } + + // Consume response content + if (entity != null) { + EntityUtils.consume(entity); + } + + return responseBytes; + } + + public void consume(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { + return; + } + + // Consume response content + HttpEntity entity = httpResponse.getEntity(); + if (entity != null) { + EntityUtils.consume(entity); + } + } + + public String convertEntityToString(byte[] responseBytes) { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes); + } + + public String convertEntityToString(byte[] responseBytes, Charset charset) { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes, charset); + } + + public String convertEntityToString(byte[] responseBytes, String charsetName) throws UnsupportedEncodingException { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes, charsetName); + } + + public boolean isResponseStastusCodeOk(HttpResponse httpResponse) { + int responseStastusCode = httpResponse.getStatusLine().getStatusCode(); + if ((responseStastusCode == HttpStatus.SC_OK) || (responseStastusCode == HttpStatus.SC_CREATED) || (responseStastusCode == HttpStatus.SC_ACCEPTED) + || (responseStastusCode == HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION) || (responseStastusCode == HttpStatus.SC_NO_CONTENT) || (responseStastusCode == HttpStatus.SC_RESET_CONTENT) + || (responseStastusCode == HttpStatus.SC_PARTIAL_CONTENT) || (responseStastusCode == HttpStatus.SC_MULTI_STATUS)) { + return true; + } + + return false; + } + + public boolean isResponseStatusCodeOk(HttpResponse httpResponse) { + return isResponseStastusCodeOk(httpResponse); + } + + public boolean isContentTypeXml(HttpResponse httpResponse) { + Header contentType = httpResponse.getEntity().getContentType(); + if (contentType == null) { + return false; + } + + String contentTypeValue = contentType.getValue(); + if (StringHelper.equals(contentTypeValue, ContentType.APPLICATION_XML.getMimeType()) || StringHelper.equals(contentTypeValue, ContentType.TEXT_XML.getMimeType())) { + return true; + } + + return false; + } + + public String constructServerUrl(final HttpServletRequest request) { + int serverPort = request.getServerPort(); + + String redirectUrl; + if ((serverPort == 80) || (serverPort == 443)) { + redirectUrl = String.format("%s://%s%s", request.getScheme(), request.getServerName(), request.getContextPath()); + } else { + redirectUrl = String.format("%s://%s:%s%s", request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath()); + } + + return redirectUrl.toLowerCase(); + } + + public HttpRoutePlanner buildDefaultRoutePlanner(final String hostname, final int port, final String scheme) { + //Creating an HttpHost object for proxy + HttpHost proxyHost = new HttpHost(hostname, port, scheme); + + return new DefaultProxyRoutePlanner(proxyHost); + } + + public HttpRoutePlanner buildDefaultRoutePlanner(final String proxy) { + return buildDefaultRoutePlanner(proxy, -1, null); + } + +} From e9f7938e05495715f2da2fc5a4bf4087d71f7f72 Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 11 Nov 2024 19:46:56 +0530 Subject: [PATCH 03/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../src/test/java/io/jans/configapi/{ => client}/BaseTest.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename jans-config-api/server/src/test/java/io/jans/configapi/{ => client}/BaseTest.java (100%) diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java similarity index 100% rename from jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java From 27b14f63b4aceb5e611fb777db10563786ffdf9a Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 11 Nov 2024 19:50:34 +0530 Subject: [PATCH 04/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../src/test/java/io/jans/configapi/client/BaseTest.java | 2 +- .../jans/configapi/client/listener/ApiUnitTestListener.java | 2 +- .../java/io/jans/configapi/client/service/HttpService.java | 4 ++-- .../{client => }/rest/resource/ConfigResourceTest.java | 0 4 files changed, 4 insertions(+), 4 deletions(-) rename jans-config-api/server/src/test/java/io/jans/configapi/{client => }/rest/resource/ConfigResourceTest.java (100%) diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java index c2516a1d677..d3fb3140614 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi; +package io.jans.configapi.client; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/client/listener/ApiUnitTestListener.java b/jans-config-api/server/src/test/java/io/jans/configapi/client/listener/ApiUnitTestListener.java index cb95b62d3ca..0f0ad8454ce 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/client/listener/ApiUnitTestListener.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/client/listener/ApiUnitTestListener.java @@ -3,7 +3,7 @@ * * Copyright (c) 2021, Janssen Project */ -package io.jans.configapi.core.test.listener; +package io.jans.configapi.client.listener; import org.testng.ITestContext; import org.testng.ITestListener; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java b/jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java index 3c12da399c5..f740b17f906 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.client; +package io.jans.configapi.client.service; import java.io.File; @@ -59,7 +59,7 @@ import org.json.JSONObject; -public abstract class BaseHttpService implements Serializable { +public abstract class HttpService implements Serializable { private static final long serialVersionUID = -2398422090669045605L; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/client/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java similarity index 100% rename from jans-config-api/server/src/test/java/io/jans/configapi/client/rest/resource/ConfigResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java From e5f65eb20e9d4376d4c76f8639e9c7a6c3585199 Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 11 Nov 2024 20:37:03 +0530 Subject: [PATCH 05/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 16 +- .../docs/jans-admin-ui-plugin-swagger.yaml | 436 +++++++++--------- jans-config-api/pom.xml | 6 +- jans-config-api/server/pom.xml | 4 +- .../io/jans/configapi/BaseComponentTest.java | 111 ----- .../jans/configapi/{client => }/BaseTest.java | 2 +- .../listener/ApiUnitTestListener.java | 0 .../{client => }/service/HttpService.java | 0 8 files changed, 232 insertions(+), 343 deletions(-) delete mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/BaseComponentTest.java rename jans-config-api/server/src/test/java/io/jans/configapi/{client => }/BaseTest.java (99%) rename jans-config-api/server/src/test/java/io/jans/configapi/{client => }/listener/ApiUnitTestListener.java (100%) rename jans-config-api/server/src/test/java/io/jans/configapi/{client => }/service/HttpService.java (100%) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index c01675c844a..5fd16e35a9d 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,20 +9267,20 @@ components: type: string selected: type: boolean + whitePagesCanView: + type: boolean userCanView: type: boolean - adminCanView: + adminCanEdit: type: boolean userCanEdit: type: boolean - adminCanEdit: + adminCanView: type: boolean userCanAccess: type: boolean adminCanAccess: type: boolean - whitePagesCanView: - type: boolean baseDn: type: string PatchRequest: @@ -10128,8 +10128,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10139,6 +10137,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -11682,10 +11682,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/docs/jans-admin-ui-plugin-swagger.yaml b/jans-config-api/plugins/docs/jans-admin-ui-plugin-swagger.yaml index 6be724ff5b7..adae31a4cd4 100644 --- a/jans-config-api/plugins/docs/jans-admin-ui-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/jans-admin-ui-plugin-swagger.yaml @@ -10,19 +10,19 @@ info: url: https://github.com/JanssenProject/jans/blob/main/LICENSE version: 1.0.0 servers: - - url: https://jans.io/ - description: The Jans server +- url: https://jans.io/ + description: The Jans server tags: - - name: Admin UI - Role - - name: Admin UI - Permission - - name: Admin UI - Role-Permissions Mapping - - name: Admin UI - License - - name: Admin UI - Webhooks +- name: Admin UI - Role +- name: Admin UI - Permission +- name: Admin UI - Role-Permissions Mapping +- name: Admin UI - License +- name: Admin UI - Webhooks paths: /admin-ui/adminUIPermissions: get: tags: - - Admin UI - Permission + - Admin UI - Permission summary: Get all admin ui permissions description: Get all admin ui permissions operationId: get-all-adminui-permissions @@ -50,11 +50,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly put: tags: - - Admin UI - Permission + - Admin UI - Permission summary: Edit admin ui permissions description: Edit admin ui permissions operationId: edit-adminui-permission @@ -88,11 +88,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write post: tags: - - Admin UI - Permission + - Admin UI - Permission summary: Add admin ui permissions description: Add admin ui permissions operationId: add-adminui-permission @@ -126,12 +126,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write /admin-ui/adminUIRolePermissionsMapping: get: tags: - - Admin UI - Role-Permissions Mapping + - Admin UI - Role-Permissions Mapping summary: Get all admin ui role-permissions mapping description: Get all admin ui role-permissions mapping operationId: get-all-adminui-role-permissions @@ -159,11 +159,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly put: tags: - - Admin UI - Role-Permissions Mapping + - Admin UI - Role-Permissions Mapping summary: Map permissions to role description: Map permissions to role operationId: map-permissions-to-role @@ -197,11 +197,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write post: tags: - - Admin UI - Role-Permissions Mapping + - Admin UI - Role-Permissions Mapping summary: Add role-permissions mapping description: Add role-permissions mapping operationId: add-role-permissions-mapping @@ -235,12 +235,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write /admin-ui/adminUIRoles: get: tags: - - Admin UI - Role + - Admin UI - Role summary: Get all admin ui roles description: Get all admin ui roles operationId: get-all-adminui-roles @@ -268,11 +268,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly put: tags: - - Admin UI - Role + - Admin UI - Role summary: Edit admin ui role description: Edit admin ui role operationId: edit-adminui-role @@ -306,11 +306,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write post: tags: - - Admin UI - Role + - Admin UI - Role summary: Add admin ui role description: Add admin ui role operationId: add-adminui-role @@ -344,22 +344,22 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write /admin-ui/adminUIPermissions/{adminUIPermission}: get: tags: - - Admin UI - Permission + - Admin UI - Permission summary: Get admin ui permission by permission-name description: Get admin ui permission by permission-name operationId: get-adminui-permission parameters: - - name: adminUIPermission - in: path - description: Admin UI Permission - required: true - schema: - type: string + - name: adminUIPermission + in: path + description: Admin UI Permission + required: true + schema: + type: string responses: "200": description: Ok @@ -384,21 +384,21 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly delete: tags: - - Admin UI - Permission + - Admin UI - Permission summary: Delete admin ui permission by permission-name description: Delete admin ui permission by permission-name operationId: delete-adminui-permission parameters: - - name: adminUIPermission - in: path - description: Admin UI Permission - required: true - schema: - type: string + - name: adminUIPermission + in: path + description: Admin UI Permission + required: true + schema: + type: string responses: "200": description: Ok @@ -423,22 +423,22 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete /admin-ui/adminUIRoles/{adminUIRole}: get: tags: - - Admin UI - Role + - Admin UI - Role summary: Get admin ui role details by role-name description: Get admin ui role details by role-name operationId: get-adminui-role parameters: - - name: adminUIRole - in: path - description: Admin UI role - required: true - schema: - type: string + - name: adminUIRole + in: path + description: Admin UI role + required: true + schema: + type: string responses: "200": description: Ok @@ -463,21 +463,21 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly delete: tags: - - Admin UI - Role + - Admin UI - Role summary: Delete admin ui role by role-name description: Delete admin ui role by role-name operationId: delete-adminui-role parameters: - - name: adminUIRole - in: path - description: Admin UI role - required: true - schema: - type: string + - name: adminUIRole + in: path + description: Admin UI role + required: true + schema: + type: string responses: "200": description: Ok @@ -502,12 +502,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete /admin-ui/config: get: tags: - - Admin UI - Configuration + - Admin UI - Configuration summary: Get Admin UI editable configuration description: Get Admin UI editable configuration operationId: get-adminui-conf @@ -535,11 +535,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly put: tags: - - Admin UI - Configuration + - Admin UI - Configuration summary: Edit Admin UI editable configuration description: Edit Admin UI editable configuration operationId: edit-adminui-conf @@ -573,22 +573,22 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/properties.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/properties.write /admin-ui/adminUIRolePermissionsMapping/{adminUIRole}: get: tags: - - Admin UI - Role-Permissions Mapping + - Admin UI - Role-Permissions Mapping summary: Get admin ui role-permissions mapping by role-name description: Get admin ui role-permissions mapping by role-name operationId: get-adminui-role-permissions parameters: - - name: adminUIRole - in: path - description: Admin UI Role - required: true - schema: - type: string + - name: adminUIRole + in: path + description: Admin UI Role + required: true + schema: + type: string responses: "200": description: Ok @@ -613,21 +613,21 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly delete: tags: - - Admin UI - Role-Permissions Mapping + - Admin UI - Role-Permissions Mapping summary: Remove role-permissions mapping by role-name description: Remove role-permissions mapping by role-name operationId: remove-role-permissions-permission parameters: - - name: adminUIRole - in: path - description: role - required: true - schema: - type: string + - name: adminUIRole + in: path + description: role + required: true + schema: + type: string responses: "200": description: Ok @@ -652,12 +652,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete /admin-ui/license/activate: post: tags: - - Admin UI - License + - Admin UI - License summary: Activate license using license-key description: Activate license using license-key operationId: activate-adminui-license @@ -689,12 +689,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/license.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/license.write /admin-ui/license/details: get: tags: - - Admin UI - License + - Admin UI - License summary: Get admin ui license details description: Get admin ui license details operationId: get-adminui-license @@ -720,12 +720,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly /admin-ui/license/isActive: get: tags: - - Admin UI - License + - Admin UI - License summary: Check if admin-ui license is active description: Check if admin-ui license is active operationId: is-license-active @@ -751,12 +751,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly /admin-ui/license/isConfigValid: get: tags: - - Admin UI - License + - Admin UI - License summary: Is license configuration valid description: Is license configuration valid operationId: check-adminui-license-config @@ -782,12 +782,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly /admin-ui/license/retrieve: get: tags: - - Admin UI - License + - Admin UI - License summary: Retrieve license from SCAN description: Retrieve license from SCAN operationId: retrieve-license @@ -813,12 +813,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly /admin-ui/license/ssa: post: tags: - - Admin UI - License + - Admin UI - License summary: Save SSA in configuration description: Save SSA in configuration operationId: adminui-post-ssa @@ -850,12 +850,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/license.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/license.write /admin-ui/license/trial: get: tags: - - Admin UI - License + - Admin UI - License summary: Generate trial license description: Generate trial license operationId: get-trial-license @@ -881,59 +881,59 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly /admin-ui/webhook: get: tags: - - Admin UI - Webhooks + - Admin UI - Webhooks summary: Gets list of webhooks description: Gets list of webhooks operationId: get-all-webhooks parameters: - - name: limit - in: query - description: Search size - max size of the results to return - schema: - type: integer - format: int32 - default: 50 - - name: pattern - in: query - description: Search pattern - schema: - type: string - default: "" - - name: startIndex - in: query - description: The 1-based index of the first query result - schema: - type: integer - format: int32 - default: 0 - - name: sortBy - in: query - description: Attribute whose value will be used to order the returned response - schema: - type: string - default: inum - - name: sortOrder - in: query - description: Order in which the sortBy param is applied. Allowed values are - "ascending" and "descending" - schema: - type: string - default: ascending - - name: fieldValuePair - in: query - description: Field and value pair for seraching - schema: - type: string - default: "" - examples: - Field value example: - description: Field value example - value: "scopeType=spontaneous,defaultScope=true" + - name: limit + in: query + description: Search size - max size of the results to return + schema: + type: integer + format: int32 + default: 50 + - name: pattern + in: query + description: Search pattern + schema: + type: string + default: "" + - name: startIndex + in: query + description: The 1-based index of the first query result + schema: + type: integer + format: int32 + default: 0 + - name: sortBy + in: query + description: Attribute whose value will be used to order the returned response + schema: + type: string + default: inum + - name: sortOrder + in: query + description: Order in which the sortBy param is applied. Allowed values are + "ascending" and "descending" + schema: + type: string + default: ascending + - name: fieldValuePair + in: query + description: Field and value pair for seraching + schema: + type: string + default: "" + examples: + Field value example: + description: Field value example + value: "scopeType=spontaneous,defaultScope=true" responses: "200": description: Ok @@ -994,11 +994,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly put: tags: - - Admin UI - Webhooks + - Admin UI - Webhooks summary: Update Webhook description: Update Webhook operationId: put-webhook @@ -1070,11 +1070,11 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.write post: tags: - - Admin UI - Webhooks + - Admin UI - Webhooks summary: Create Webhook description: Create Webhook operationId: post-webhook @@ -1146,22 +1146,22 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.write + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.write /admin-ui/webhook/{webhookId}: delete: tags: - - Admin UI - Webhooks + - Admin UI - Webhooks summary: Delete Webhook description: Delete Webhook operationId: delete-Webhook-by-inum parameters: - - name: webhookId - in: path - description: Webhook identifier - required: true - schema: - type: string + - name: webhookId + in: path + description: Webhook identifier + required: true + schema: + type: string responses: "204": description: No Content @@ -1182,12 +1182,12 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.delete + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.delete /admin-ui/webhook/features: get: tags: - - Admin UI - Webhooks + - Admin UI - Webhooks summary: Gets list of Admin UI features description: Gets list of Admin UI features operationId: get-all-features @@ -1289,22 +1289,22 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly /admin-ui/webhook/features/{webhookId}: get: tags: - - Admin UI - Webhooks + - Admin UI - Webhooks summary: Gets list of Admin UI features mapped to webhookId description: Gets list of Admin UI features mapped to webhookId operationId: get-features-by-webhook-id parameters: - - name: webhookId - in: path - description: Webhook identifier - required: true - schema: - type: string + - name: webhookId + in: path + description: Webhook identifier + required: true + schema: + type: string responses: "200": description: Ok @@ -1338,22 +1338,22 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly /admin-ui/webhook/{featureId}: get: tags: - - Admin UI - Webhooks + - Admin UI - Webhooks summary: Gets list of Admin UI Webhooks mapped to featureId description: Gets list of Admin UI Webhooks mapped to featureId operationId: get-webhooks-by-feature-id parameters: - - name: featureId - in: path - description: Feature identifier - required: true - schema: - type: string + - name: featureId + in: path + description: Feature identifier + required: true + schema: + type: string responses: "200": description: Ok @@ -1409,22 +1409,22 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly /admin-ui/webhook/trigger/{featureId}: post: tags: - - Admin UI - Webhooks + - Admin UI - Webhooks summary: Trigger webhooks mapped to featureId description: Trigger webhooks mapped to featureId operationId: trigger-webhook parameters: - - name: featureId - in: path - description: Admin UI feature identifier - required: true - schema: - type: string + - name: featureId + in: path + description: Admin UI feature identifier + required: true + schema: + type: string requestBody: description: Webhook object content: @@ -1487,8 +1487,8 @@ paths: schema: $ref: '#/components/schemas/GenericResponse' security: - - oauth2: - - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly + - oauth2: + - https://jans.io/oauth/jans-auth-server/config/adminui/webhook.readonly components: schemas: AdminPermission: @@ -1635,8 +1635,8 @@ components: type: string WebhookEntry: required: - - displayName - - url + - displayName + - url type: object properties: dn: @@ -1696,11 +1696,11 @@ components: scopeType: type: string enum: - - openid - - dynamic - - uma - - spontaneous - - oauth + - openid + - dynamic + - uma + - spontaneous + - oauth claims: type: array items: @@ -1724,10 +1724,10 @@ components: creatorType: type: string enum: - - none - - client - - user - - auto + - none + - client + - user + - auto creationDate: type: string format: date-time @@ -1783,7 +1783,7 @@ components: type: object ShortCodeRequest: required: - - webhookId + - webhookId type: object properties: webhookId: diff --git a/jans-config-api/pom.xml b/jans-config-api/pom.xml index af4eb1c4f27..92123a27d2e 100644 --- a/jans-config-api/pom.xml +++ b/jans-config-api/pom.xml @@ -41,7 +41,7 @@ 4.7.5.Final 5.0.1 - 0.9.5 + 0.9.5 7.8.0 2.0 5.7.0 @@ -354,7 +354,7 @@ snakeyaml ${snake.version} - + net.masterthought cucumber-reporting diff --git a/jans-config-api/server/pom.xml b/jans-config-api/server/pom.xml index 1613cd8bd2a..438b6c84466 100644 --- a/jans-config-api/server/pom.xml +++ b/jans-config-api/server/pom.xml @@ -201,7 +201,7 @@ - + net.masterthought cucumber-reporting diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseComponentTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseComponentTest.java deleted file mode 100644 index fff3b01462c..00000000000 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseComponentTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi.core.test.base; - -import io.jans.as.common.service.common.InumService; -import io.jans.as.common.service.common.UserService; -import io.jans.as.model.config.StaticConfiguration; -import io.jans.as.model.crypto.AbstractCryptoProvider; -import io.jans.as.server.idgen.ws.rs.InumGenerator; -import io.jans.as.server.model.common.AuthorizationGrantList; -import io.jans.as.server.model.config.ConfigurationFactory; -import io.jans.as.server.service.CleanerTimer; -import io.jans.as.server.service.ClientService; -import io.jans.as.server.service.GrantService; -import io.jans.as.server.service.SessionIdService; -import io.jans.as.server.uma.service.UmaPctService; -import io.jans.as.server.uma.service.UmaPermissionService; -import io.jans.as.server.uma.service.UmaResourceService; -import io.jans.as.server.uma.service.UmaRptService; -import io.jans.orm.PersistenceEntryManager; -import io.jans.service.CacheService; -import io.jans.service.EncryptionService; -import io.jans.service.cdi.util.CdiUtil; - - -public abstract class BaseComponentTest extends BaseTest { - - public static void sleepSeconds(int p_seconds) { - try { - Thread.sleep(p_seconds * 1000L); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - public static InumGenerator getInumGenerator() { - return CdiUtil.bean(InumGenerator.class); - } - - public static StaticConfiguration getStaticConfiguration() { - return CdiUtil.bean(StaticConfiguration.class); - } - - public ClientService getClientService() { - return CdiUtil.bean(ClientService.class); - } - - public InumService getInumService() { - return CdiUtil.bean(InumService.class); - } - - public CleanerTimer getCleanerTimer() { - return CdiUtil.bean(CleanerTimer.class); - } - - public CacheService getCacheService() { - return CdiUtil.bean(CacheService.class); - } - - public UmaRptService getUmaRptService() { - return CdiUtil.bean(UmaRptService.class); - } - - public UmaResourceService getUmaResourceService() { - return CdiUtil.bean(UmaResourceService.class); - } - - public UmaPermissionService getUmaPermissionService() { - return CdiUtil.bean(UmaPermissionService.class); - } - - public UmaPctService getUmaPctService() { - return CdiUtil.bean(UmaPctService.class); - } - - public AuthorizationGrantList getAuthorizationGrantList() { - return CdiUtil.bean(AuthorizationGrantList.class); - } - - public GrantService getGrantService() { - return CdiUtil.bean(GrantService.class); - } - - public EncryptionService getEncryptionService() { - return CdiUtil.bean(EncryptionService.class); - } - - public ConfigurationFactory getConfigurationFactory() { - return CdiUtil.bean(ConfigurationFactory.class); - } - - public AbstractCryptoProvider getAbstractCryptoProvider() { - return CdiUtil.bean(AbstractCryptoProvider.class); - } - - public SessionIdService getSessionIdService() { - return CdiUtil.bean(SessionIdService.class); - } - - public UserService getUserService() { - return CdiUtil.bean(UserService.class); - } - - public PersistenceEntryManager getPersistenceEntryManager() { - return CdiUtil.bean(PersistenceEntryManager.class); - } -} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java similarity index 99% rename from jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index d3fb3140614..c2516a1d677 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/client/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.client; +package io.jans.configapi; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/client/listener/ApiUnitTestListener.java b/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java similarity index 100% rename from jans-config-api/server/src/test/java/io/jans/configapi/client/listener/ApiUnitTestListener.java rename to jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java similarity index 100% rename from jans-config-api/server/src/test/java/io/jans/configapi/client/service/HttpService.java rename to jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java From dc815fefb1de81ecd0269bdf7c0f9a9137fd7f3a Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 11 Nov 2024 20:48:08 +0530 Subject: [PATCH 06/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 18 +++++++++--------- .../listener/ApiUnitTestListener.java | 2 +- .../io/jans/configapi/service/HttpService.java | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 5fd16e35a9d..16f7267530a 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,20 +9267,20 @@ components: type: string selected: type: boolean - whitePagesCanView: + userCanEdit: type: boolean userCanView: type: boolean - adminCanEdit: - type: boolean - userCanEdit: - type: boolean adminCanView: type: boolean + adminCanEdit: + type: boolean userCanAccess: type: boolean adminCanAccess: type: boolean + whitePagesCanView: + type: boolean baseDn: type: string PatchRequest: @@ -11246,14 +11246,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: @@ -11682,10 +11682,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java b/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java index 0f0ad8454ce..bd68a087d1f 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java @@ -3,7 +3,7 @@ * * Copyright (c) 2021, Janssen Project */ -package io.jans.configapi.client.listener; +package io.jans.configapi.listener; import org.testng.ITestContext; import org.testng.ITestListener; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java index f740b17f906..af2c62fb37f 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.client.service; +package io.jans.configapi.service; import java.io.File; From 9c9ec7017c5842c72eb83c61339b7663906f6e59 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 12 Nov 2024 11:15:56 +0530 Subject: [PATCH 07/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../rest/resource/ConfigResourceTest.java | 2 +- .../test/resources/config-api-test.properties | 40 ++++++++++++++++--- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java index 34e4b478b39..3ce07f1e0e8 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java @@ -6,7 +6,7 @@ package io.jans.configapi.rest.resource; -import org.junit.jupiter.api.Test; +import org.testng.annotations.Test; import jakarta.ws.rs.core.MediaType; import static io.restassured.RestAssured.given; diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties index 4257f297907..c735935d9e1 100644 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -1,8 +1,36 @@ -test.scopes=${test.scopes} +scopes=${test.scopes} # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=${token.endpoint} +tokenGrantType=${token.grant.type} +clientId=${test.client.id} +clientSecret=${test.client.secret} +issuer=${test.issuer} + + +statUrl= "/jans-config-api/api/v1/stat" +healthUrl="/jans-config-api/api/v1/health" +acrsUrl="/jans-config-api/api/v1/acrs" +authConfigurationUrl="/jans-config-api/api/v1/jans-auth-server/config" +scriptsUrl="/jans-config-api/api/v1/config/scripts" +cacheUrl="/jans-config-api/api/v1/config/cache" +messageUrl="/jans-config-api/api/v1/config/message" +jwksUrl="/jans-config-api/api/v1/config/jwks" +ldapUrl="/jans-config-api/api/v1/config/database/ldap" +openidClientsUrl="/jans-config-api/api/v1/openid/clients" +scopesUrl="/jans-config-api/api/v1/scopes" +umaresourcesUrl="/jans-config-api/api/v1/uma/resources" +attributesUrl="/jans-config-api/api/v1/attributes" +smtpUrl="/jans-config-api/api/v1/config/smtp" +loggingUrl="/jans-config-api/api/v1/logging" +authHealthUrl="/jans-config-api/api/v1/jans-auth-server/health" +orgConfigurationUrl="/jans-config-api/api/v1/org" +userUrl="/jans-config-api/api/v1/user" +agamaUrl="/jans-config-api/api/v1/agama" +sessionUrl="/jans-config-api/api/v1/jans-auth-server/session" +pluginUrl="/jans-config-api/api/v1/plugin" +apiConfigUrl="/jans-config-api/api/v1/api-config" +agamaDeploymentUrl="/jans-config-api/api/v1/agama-deployment" +clientsAuthorizationsUrl="/jans-config-api/api/v1/clients/authorizations" +tokenUrl="/jans-config-api/api/v1/token" + From f7ac91ba9e317e4d0ac8e0e890350d4e171be4e0 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 12 Nov 2024 20:27:32 +0530 Subject: [PATCH 08/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- jans-config-api/common/pom.xml | 5 - .../docs/jans-config-api-swagger.yaml | 18 +- .../test/java/io/jans/configapi/BaseTest.java | 184 ++++--- .../io/jans/configapi/JenkinsTestRunner.java | 47 -- .../io/jans/configapi/KarateTestRunner.java | 18 - .../jans/configapi/service/HttpService.java | 463 +++++++++--------- .../configapi/service/ResteasyService.java | 104 ++++ 7 files changed, 483 insertions(+), 356 deletions(-) delete mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/JenkinsTestRunner.java delete mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/KarateTestRunner.java create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java diff --git a/jans-config-api/common/pom.xml b/jans-config-api/common/pom.xml index f80c029373c..dc4c61b7fd0 100644 --- a/jans-config-api/common/pom.xml +++ b/jans-config-api/common/pom.xml @@ -39,11 +39,6 @@ maven-surefire-plugin - - - target/test-classes/testng.xml - - diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 16f7267530a..2d24d3f5143 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,14 +9267,14 @@ components: type: string selected: type: boolean - userCanEdit: + adminCanView: type: boolean userCanView: type: boolean - adminCanView: - type: boolean adminCanEdit: type: boolean + userCanEdit: + type: boolean userCanAccess: type: boolean adminCanAccess: @@ -10128,6 +10128,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10137,8 +10139,6 @@ components: - code - token - id_token - fapi: - type: boolean AuthenticationFilter: required: - baseDn @@ -11246,14 +11246,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: @@ -11682,10 +11682,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index c2516a1d677..93dcc0ad742 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -6,68 +6,111 @@ package io.jans.configapi; +import io.jans.as.client.TokenRequest; +import io.jans.as.client.TokenResponse; +import io.jans.as.model.common.GrantType; +import io.jans.as.model.common.ScopeType; +import io.jans.as.model.uma.wrapper.Token; +import io.jans.as.model.util.Util; +import io.jans.configapi.service.ResteasyService; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import io.jans.as.client.dev.HostnameVerifierType; - -import org.apache.commons.codec.binary.Base64; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - +import io.jans.model.net.HttpServiceResponse; import static java.nio.charset.StandardCharsets.UTF_8; - - +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; + import java.util.Hashtable; import java.util.Map; import java.util.Properties; import java.net.URLEncoder; +import java.io.UnsupportedEncodingException; + +import jakarta.servlet.http.HttpServletRequest; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.util.*; +import java.util.Map.Entry; -import jakarta.ws.rs.core.UriBuilder; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CookieStore; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.entity.ContentType; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.SSLContexts; import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; +import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; import org.jboss.resteasy.client.jaxrs.ResteasyClient; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; - import org.testng.ITestContext; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeSuite; +import org.testng.annotations.BeforeTest; +import jakarta.annotation.PostConstruct; +import jakarta.ws.rs.core.UriBuilder; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedHashMap; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; public class BaseTest { - protected Logger logger = LogManager.getLogger(getClass()); - protected ObjectMapper mapper = new ObjectMapper(); + private static final String CONTENT_TYPE = "Content-Type"; + private static final String AUTHORIZATION = "Authorization"; + private static final long serialVersionUID = -2398422090669045605L; + protected Logger log = LogManager.getLogger(getClass()); + private Base64 base64; private static Map propertiesMap = null; - private ApacheHttpClient43Engine engine; - + private ResteasyService resteasyService; @BeforeSuite public void initTestSuite(ITestContext context) throws Exception { - logger.info("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); + resteasyService = new ResteasyService(); + log.info("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); Properties prop = new Properties(); prop.load(Files.newBufferedReader(Paths.get(propertiesFile), UTF_8)); @@ -75,48 +118,77 @@ public void initTestSuite(ITestContext context) throws Exception { propertiesMap = new Hashtable<>(); prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); context.getSuite().getXmlSuite().setParameters(propertiesMap); - - this.engine = createEngine(); + } @AfterSuite public void finalize() { - //cleanup - logger.info("After Suite finalize'"); + // cleanup + log.info("After Suite finalize'"); } - + @BeforeTest public String getAccessToken() throws Exception { - String tokenUrl = propertiesMap.get("token.endpoint"); - String grantType = propertiesMap.get("token.grant.type"); - String clientId = propertiesMap.get("test.client.id"); - String clientSecret = propertiesMap.get("test.client.secret"); - String scopes = propertiesMap.get("test.scopes"); - String authStr = clientId+':'+clientSecret; + String tokenUrl = propertiesMap.get("token.endpoint"); + String strGrantType = propertiesMap.get("token.grant.type"); + String clientId = propertiesMap.get("test.client.id"); + String clientSecret = propertiesMap.get("test.client.secret"); + String scopes = propertiesMap.get("test.scopes"); + String authStr = clientId + ':' + clientSecret; String token = new String(Base64.decodeBase64(authStr), StandardCharsets.UTF_8); String encodedScopes = URLDecoder.decode(scopes, "UTF-8"); - - ResteasyClient client = ((ResteasyClientBuilder) ResteasyClientBuilder.newBuilder()).httpEngine(engine).build(); - ResteasyWebTarget target = client.target(UriBuilder.fromPath(tokenUrl)); - - + GrantType grantType = GrantType.fromString(strGrantType); + String accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); + return accessToken; } + public String getToken(final String tokenUrl, final String clientId, final String clientSecret, + GrantType grantType, final String scopes) { + log.info("Request for token tokenUrl:{}, clientId:{}, grantType:{}, scopes:{}", tokenUrl, clientId, grantType, scopes); + String accessToken = null; + TokenResponse tokenResponse = this.requestAccessToken(tokenUrl, clientId, clientSecret, grantType, scopes); + if (tokenResponse != null) { + accessToken = tokenResponse.getAccessToken(); + log.trace("accessToken:{}, ", accessToken); + } + + return accessToken; + } - - - - private ApacheHttpClient43Engine createEngine() { - PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); - CloseableHttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) - .setConnectionManager(cm).build(); - cm.setMaxTotal(200); // Increase max total connection to 200 - cm.setDefaultMaxPerRoute(20); // Increase default max connection per route to 20 - ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient); - engine.setFollowRedirects(true); - - return engine; + public TokenResponse requestAccessToken(final String tokenUrl, final String clientId, final String clientSecret, + GrantType grantType, final String scope) { + log.info("Request for access token tokenUrl:{}, clientId:{},scope:{}", tokenUrl, clientId, scope); + Response response = null; + try { + if (grantType==null) { + grantType = GrantType.CLIENT_CREDENTIALS; + } + TokenRequest tokenRequest = new TokenRequest(grantType); + tokenRequest.setScope(scope); + tokenRequest.setAuthUsername(clientId); + tokenRequest.setAuthPassword(clientSecret); + Builder request = resteasyService.getClientBuilder(tokenUrl); + request.header(AUTHORIZATION, "Basic " + tokenRequest.getEncodedCredentials()); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + final MultivaluedHashMap multivaluedHashMap = new MultivaluedHashMap<>( + tokenRequest.getParameters()); + response = request.post(Entity.form(multivaluedHashMap)); + log.trace("Response for Access Token - response:{}", response); + if (response.getStatus() == 200) { + String entity = response.readEntity(String.class); + TokenResponse tokenResponse = new TokenResponse(); + tokenResponse.setEntity(entity); + tokenResponse.injectDataFromJson(entity); + return tokenResponse; + } + } finally { + + if (response != null) { + response.close(); + } + } + return null; } + } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/JenkinsTestRunner.java b/jans-config-api/server/src/test/java/io/jans/configapi/JenkinsTestRunner.java deleted file mode 100644 index d039e1f2040..00000000000 --- a/jans-config-api/server/src/test/java/io/jans/configapi/JenkinsTestRunner.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; - -import io.jans.as.common.model.registration.Client; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * @author Yuriy Zabrovarnyy - */ -public class JenkinsTestRunner { - - @Test - public void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/server/src/test/java/io/jans/configapi/KarateTestRunner.java deleted file mode 100644 index 34da4586ef9..00000000000 --- a/jans-config-api/server/src/test/java/io/jans/configapi/KarateTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.junit5.Karate; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java index af2c62fb37f..6bda59312b5 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java @@ -6,7 +6,6 @@ package io.jans.configapi.service; - import java.io.File; import java.io.IOException; import java.io.Serializable; @@ -23,6 +22,9 @@ import javax.net.ssl.SSLContext; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import org.apache.commons.codec.binary.Base64; import org.apache.http.Header; import org.apache.http.HttpEntity; @@ -47,7 +49,6 @@ import org.apache.http.ssl.SSLContexts; import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; -import org.slf4j.Logger; import io.jans.model.net.HttpServiceResponse; import io.jans.util.StringHelper; @@ -58,286 +59,306 @@ import org.apache.commons.lang.StringUtils; import org.json.JSONObject; +public class HttpService implements Serializable { -public abstract class HttpService implements Serializable { - - private static final long serialVersionUID = -2398422090669045605L; + private static final long serialVersionUID = -2398422090669045605L; + protected Logger log = LogManager.getLogger(getClass()); - @Inject - private Logger log; + private Base64 base64; - private Base64 base64; + private PoolingHttpClientConnectionManager connectionManager; - private PoolingHttpClientConnectionManager connectionManager; - - @PostConstruct - public void init() { + @PostConstruct + public void init() { connectionManager = new PoolingHttpClientConnectionManager(); connectionManager.setMaxTotal(200); // Increase max total connection to 200 connectionManager.setDefaultMaxPerRoute(50); // Increase default max connection per route to 50 this.base64 = new Base64(); - } + } + + public CloseableHttpClient getHttpsClientTrustAll() + throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); - public CloseableHttpClient getHttpsClientTrustAll() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext, + NoopHostnameVerifier.INSTANCE); - TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; - SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); - SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext, - NoopHostnameVerifier.INSTANCE); + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } - return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) - .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) - .setConnectionManager(connectionManager).build(); - } + public CloseableHttpClient getHttpsClient() { + return getHttpsClient(RequestConfig.custom().build()); + } - public CloseableHttpClient getHttpsClient() { - return getHttpsClient(RequestConfig.custom().build()); - } + public CloseableHttpClient getHttpsClient(RequestConfig requestConfig) { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); - public CloseableHttpClient getHttpsClient(RequestConfig requestConfig) { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } - return HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) - .setConnectionManager(connectionManager).build(); - } + public CloseableHttpClient getHttpsClient(HttpRoutePlanner routerPlanner) { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); - public CloseableHttpClient getHttpsClient(HttpRoutePlanner routerPlanner) { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + return getHttpsClient(RequestConfig.custom().build(), routerPlanner); + } - return getHttpsClient(RequestConfig.custom().build(), routerPlanner); - } + public CloseableHttpClient getHttpsClient(RequestConfig requestConfig, HttpRoutePlanner routerPlanner) { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); - public CloseableHttpClient getHttpsClient(RequestConfig requestConfig, HttpRoutePlanner routerPlanner) { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).setRoutePlanner(routerPlanner).build(); + } - return HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) - .setConnectionManager(connectionManager).setRoutePlanner(routerPlanner).build(); - } + public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword) + throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, + IOException { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); - public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); - SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()).build(); - SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } - return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) - .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) - .setConnectionManager(connectionManager).build(); - } + public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword, + String keyStoreType, String keyStorePath, String keyStorePassword) throws KeyManagementException, + NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { + log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); - public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword, - String keyStoreType, String keyStorePath, String keyStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()) + .loadKeyMaterial(new File(keyStorePath), keyStorePassword.toCharArray(), keyStorePassword.toCharArray()) + .build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); - SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()) - .loadKeyMaterial(new File(keyStorePath), keyStorePassword.toCharArray(), keyStorePassword.toCharArray()).build(); - SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } - return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) - .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) - .setConnectionManager(connectionManager).build(); - } + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, + Map headers, String postData, ContentType contentType, String authType) { - public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, Map headers, String postData, ContentType contentType, String authType) { - HttpPost httpPost = new HttpPost(uri); - if(StringHelper.isEmpty(authType)) { - authType = "Basic "; - } - else { - authType = authType +" "; + if (StringHelper.isEmpty(authType)) { + authType = "Basic "; + } else { + authType = authType + " "; } if (StringHelper.isNotEmpty(authData)) { - httpPost.setHeader("Authorization", authType + authData); + httpPost.setHeader("Authorization", authType + authData); } if (headers != null) { - for (Entry headerEntry : headers.entrySet()) { - httpPost.setHeader(headerEntry.getKey(), headerEntry.getValue()); - } + for (Entry headerEntry : headers.entrySet()) { + httpPost.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } } StringEntity stringEntity = new StringEntity(postData, contentType); - httpPost.setEntity(stringEntity); + httpPost.setEntity(stringEntity); try { - HttpResponse httpResponse = httpClient.execute(httpPost); + HttpResponse httpResponse = httpClient.execute(httpPost); - return new HttpServiceResponse(httpPost, httpResponse); - } catch (IOException ex) { - log.error("Failed to execute post request", ex); - } + return new HttpServiceResponse(httpPost, httpResponse); + } catch (IOException ex) { + log.error("Failed to execute post request", ex); + } return null; - } + } - public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, Map headers, String postData) { - return executePost(httpClient, uri, authData, headers, postData, null, null); - } + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, + Map headers, String postData) { + return executePost(httpClient, uri, authData, headers, postData, null, null); + } - public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, String postData, ContentType contentType) { + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, String postData, + ContentType contentType) { return executePost(httpClient, uri, authData, null, postData, contentType, null); - } - - public HttpServiceResponse executePost(String uri, String authData, Map headers, String postData, ContentType contentType, String authType) { - return executePost(this.getHttpsClient(), uri, authData, null, postData, contentType, authType); - } - - public String encodeBase64(String value) { - try { - return new String(base64.encode((value).getBytes(Util.UTF8)), Util.UTF8); - } catch (UnsupportedEncodingException ex) { - log.error("Failed to convert '{}' to base64", value, ex); - } - - return null; - } - - public String encodeUrl(String value) { - try { - return URLEncoder.encode(value, Util.UTF8); - } catch (UnsupportedEncodingException ex) { - log.error("Failed to encode url '{}'", value, ex); - } - - return null; - } - - public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, Map headers) { - HttpGet httpGet = new HttpGet(requestUri); - + } + + public HttpServiceResponse executePost(String uri, String authData, Map headers, String postData, + ContentType contentType, String authType) { + return executePost(this.getHttpsClient(), uri, authData, null, postData, contentType, authType); + } + + public String encodeBase64(String value) { + try { + return new String(base64.encode((value).getBytes(Util.UTF8)), Util.UTF8); + } catch (UnsupportedEncodingException ex) { + log.error("Failed to convert '{}' to base64", value, ex); + } + + return null; + } + + public String encodeUrl(String value) { + try { + return URLEncoder.encode(value, Util.UTF8); + } catch (UnsupportedEncodingException ex) { + log.error("Failed to encode url '{}'", value, ex); + } + + return null; + } + + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, Map headers) { + HttpGet httpGet = new HttpGet(requestUri); + if (headers != null) { - for (Entry headerEntry : headers.entrySet()) { - httpGet.setHeader(headerEntry.getKey(), headerEntry.getValue()); - } + for (Entry headerEntry : headers.entrySet()) { + httpGet.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } } - try { - HttpResponse httpResponse = httpClient.execute(httpGet); + try { + HttpResponse httpResponse = httpClient.execute(httpGet); - return new HttpServiceResponse(httpGet, httpResponse); - } catch (IOException ex) { - log.error("Failed to execute get request", ex); - } + return new HttpServiceResponse(httpGet, httpResponse); + } catch (IOException ex) { + log.error("Failed to execute get request", ex); + } - return null; - } + return null; + } - public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri) throws ClientProtocolException, IOException { - return executeGet(httpClient, requestUri, null); - } + public HttpServiceResponse executeGet(String requestUri, Map headers) { + HttpClient httpClient = this.getHttpsClient(); + return executeGet(httpClient, requestUri, headers); + } - public byte[] getResponseContent(HttpResponse httpResponse) throws IOException { - if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { - return null; + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri) + throws ClientProtocolException, IOException { + return executeGet(httpClient, requestUri, null); + } + + public byte[] getResponseContent(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { + return null; } HttpEntity entity = httpResponse.getEntity(); - byte[] responseBytes = new byte[0]; - if (entity != null) { - responseBytes = EntityUtils.toByteArray(entity); - } - - // Consume response content - if (entity != null) { - EntityUtils.consume(entity); - } - - return responseBytes; - } - - public void consume(HttpResponse httpResponse) throws IOException { - if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { - return; + byte[] responseBytes = new byte[0]; + if (entity != null) { + responseBytes = EntityUtils.toByteArray(entity); + } + + // Consume response content + if (entity != null) { + EntityUtils.consume(entity); + } + + return responseBytes; + } + + public void consume(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { + return; } - // Consume response content + // Consume response content HttpEntity entity = httpResponse.getEntity(); - if (entity != null) { - EntityUtils.consume(entity); - } - } - - public String convertEntityToString(byte[] responseBytes) { - if (responseBytes == null) { - return null; - } - - return new String(responseBytes); - } - - public String convertEntityToString(byte[] responseBytes, Charset charset) { - if (responseBytes == null) { - return null; - } - - return new String(responseBytes, charset); - } - - public String convertEntityToString(byte[] responseBytes, String charsetName) throws UnsupportedEncodingException { - if (responseBytes == null) { - return null; - } - - return new String(responseBytes, charsetName); - } - - public boolean isResponseStastusCodeOk(HttpResponse httpResponse) { - int responseStastusCode = httpResponse.getStatusLine().getStatusCode(); - if ((responseStastusCode == HttpStatus.SC_OK) || (responseStastusCode == HttpStatus.SC_CREATED) || (responseStastusCode == HttpStatus.SC_ACCEPTED) - || (responseStastusCode == HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION) || (responseStastusCode == HttpStatus.SC_NO_CONTENT) || (responseStastusCode == HttpStatus.SC_RESET_CONTENT) - || (responseStastusCode == HttpStatus.SC_PARTIAL_CONTENT) || (responseStastusCode == HttpStatus.SC_MULTI_STATUS)) { - return true; - } - - return false; - } - - public boolean isResponseStatusCodeOk(HttpResponse httpResponse) { - return isResponseStastusCodeOk(httpResponse); - } - - public boolean isContentTypeXml(HttpResponse httpResponse) { - Header contentType = httpResponse.getEntity().getContentType(); - if (contentType == null) { - return false; - } - - String contentTypeValue = contentType.getValue(); - if (StringHelper.equals(contentTypeValue, ContentType.APPLICATION_XML.getMimeType()) || StringHelper.equals(contentTypeValue, ContentType.TEXT_XML.getMimeType())) { - return true; - } - - return false; - } - - public String constructServerUrl(final HttpServletRequest request) { - int serverPort = request.getServerPort(); - - String redirectUrl; - if ((serverPort == 80) || (serverPort == 443)) { - redirectUrl = String.format("%s://%s%s", request.getScheme(), request.getServerName(), request.getContextPath()); - } else { - redirectUrl = String.format("%s://%s:%s%s", request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath()); - } - - return redirectUrl.toLowerCase(); + if (entity != null) { + EntityUtils.consume(entity); + } + } + + public String convertEntityToString(byte[] responseBytes) { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes); + } + + public String convertEntityToString(byte[] responseBytes, Charset charset) { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes, charset); + } + + public String convertEntityToString(byte[] responseBytes, String charsetName) throws UnsupportedEncodingException { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes, charsetName); + } + + public boolean isResponseStastusCodeOk(HttpResponse httpResponse) { + int responseStastusCode = httpResponse.getStatusLine().getStatusCode(); + if ((responseStastusCode == HttpStatus.SC_OK) || (responseStastusCode == HttpStatus.SC_CREATED) + || (responseStastusCode == HttpStatus.SC_ACCEPTED) + || (responseStastusCode == HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION) + || (responseStastusCode == HttpStatus.SC_NO_CONTENT) + || (responseStastusCode == HttpStatus.SC_RESET_CONTENT) + || (responseStastusCode == HttpStatus.SC_PARTIAL_CONTENT) + || (responseStastusCode == HttpStatus.SC_MULTI_STATUS)) { + return true; + } + + return false; } - public HttpRoutePlanner buildDefaultRoutePlanner(final String hostname, final int port, final String scheme) { - //Creating an HttpHost object for proxy - HttpHost proxyHost = new HttpHost(hostname, port, scheme); - - return new DefaultProxyRoutePlanner(proxyHost); + public boolean isResponseStatusCodeOk(HttpResponse httpResponse) { + return isResponseStastusCodeOk(httpResponse); + } + + public boolean isContentTypeXml(HttpResponse httpResponse) { + Header contentType = httpResponse.getEntity().getContentType(); + if (contentType == null) { + return false; + } + + String contentTypeValue = contentType.getValue(); + if (StringHelper.equals(contentTypeValue, ContentType.APPLICATION_XML.getMimeType()) + || StringHelper.equals(contentTypeValue, ContentType.TEXT_XML.getMimeType())) { + return true; + } + + return false; + } + + public String constructServerUrl(final HttpServletRequest request) { + int serverPort = request.getServerPort(); + + String redirectUrl; + if ((serverPort == 80) || (serverPort == 443)) { + redirectUrl = String.format("%s://%s%s", request.getScheme(), request.getServerName(), + request.getContextPath()); + } else { + redirectUrl = String.format("%s://%s:%s%s", request.getScheme(), request.getServerName(), + request.getServerPort(), request.getContextPath()); + } + + return redirectUrl.toLowerCase(); + } + + public HttpRoutePlanner buildDefaultRoutePlanner(final String hostname, final int port, final String scheme) { + // Creating an HttpHost object for proxy + HttpHost proxyHost = new HttpHost(hostname, port, scheme); + + return new DefaultProxyRoutePlanner(proxyHost); } - public HttpRoutePlanner buildDefaultRoutePlanner(final String proxy) { - return buildDefaultRoutePlanner(proxy, -1, null); + public HttpRoutePlanner buildDefaultRoutePlanner(final String proxy) { + return buildDefaultRoutePlanner(proxy, -1, null); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java b/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java new file mode 100644 index 00000000000..07beb1c1c44 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java @@ -0,0 +1,104 @@ +/* + * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.service; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.Map; +import java.util.Map.Entry; + +import javax.net.ssl.SSLContext; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.codec.binary.Base64; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.DefaultProxyRoutePlanner; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.ssl.TrustStrategy; +import org.apache.http.util.EntityUtils; + +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.client.ClientBuilder; +import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; +import org.jboss.resteasy.client.jaxrs.ResteasyClient; +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; +import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; + +import org.json.JSONObject; + +import io.jans.model.net.HttpServiceResponse; +import io.jans.util.StringHelper; +import io.jans.util.Util; + +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.servlet.http.HttpServletRequest; + +public class ResteasyService implements Serializable { + + protected Logger logger = LogManager.getLogger(getClass()); + + public ResteasyClient newClient(ClientHttpEngine engine) { + return ((ResteasyClientBuilder) ClientBuilder.newBuilder()).httpEngine(engine).build(); + } + + public Builder getClientBuilder(String url) { + return ClientBuilder.newClient().target(url).request(); + } + + public ApacheHttpClient43Engine createEngine() { + return createEngine(false); + } + + public ApacheHttpClient43Engine createEngine(boolean followRedirects) { + return createEngine(200, 20, CookieSpecs.STANDARD, followRedirects); + } + + public ApacheHttpClient43Engine createEngine(int maxTotal, int defaultMaxPerRoute, String cookieSpec, + boolean followRedirects) { + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + CloseableHttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(cookieSpec).build()) + .setConnectionManager(cm).build(); + cm.setMaxTotal(maxTotal); + cm.setDefaultMaxPerRoute(defaultMaxPerRoute); + final ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient); + engine.setFollowRedirects(followRedirects); + return engine; + } + +} From 69029365a3e68dee73712ae2f1426e2ecb8e7142 Mon Sep 17 00:00:00 2001 From: pujavs Date: Wed, 13 Nov 2024 21:05:40 +0530 Subject: [PATCH 09/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 10 +- .../test/java/io/jans/configapi/BaseTest.java | 26 ++- .../rest/resource/ClientResourceTest.java | 55 +++++++ .../rest/resource/ConfigResourceTest.java | 26 ++- .../jans/configapi/service/HttpService.java | 4 + .../config-api-test - Copy.properties | 43 +++++ .../test/resources/config-api-test.properties | 19 ++- .../json/openid/clients/admin-ui-client.json | 1 + .../resources/json/openid/clients/client.json | 55 +++++++ .../client_custom_attribute_patch.json | 13 ++ .../json/openid/clients/openid-client.json | 60 +++++++ .../openid/clients/openid_clients_create.json | 154 ++++++++++++++++++ .../resources/json/openid/scopes/scope.json | 14 ++ .../server/src/test/resources/log4j2-test.xml | 21 +++ .../server/src/test/resources/testng.xml | 12 +- 15 files changed, 486 insertions(+), 27 deletions(-) create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ClientResourceTest.java create mode 100644 jans-config-api/server/src/test/resources/config-api-test - Copy.properties create mode 100644 jans-config-api/server/src/test/resources/json/openid/clients/admin-ui-client.json create mode 100644 jans-config-api/server/src/test/resources/json/openid/clients/client.json create mode 100644 jans-config-api/server/src/test/resources/json/openid/clients/client_custom_attribute_patch.json create mode 100644 jans-config-api/server/src/test/resources/json/openid/clients/openid-client.json create mode 100644 jans-config-api/server/src/test/resources/json/openid/clients/openid_clients_create.json create mode 100644 jans-config-api/server/src/test/resources/json/openid/scopes/scope.json create mode 100644 jans-config-api/server/src/test/resources/log4j2-test.xml diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 2d24d3f5143..5baec642f59 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,18 +9267,18 @@ components: type: string selected: type: boolean - adminCanView: - type: boolean - userCanView: + userCanEdit: type: boolean adminCanEdit: type: boolean - userCanEdit: + adminCanView: type: boolean - userCanAccess: + userCanView: type: boolean adminCanAccess: type: boolean + userCanAccess: + type: boolean whitePagesCanView: type: boolean baseDn: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index 93dcc0ad742..6f4ecbfc400 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -12,7 +12,9 @@ import io.jans.as.model.common.ScopeType; import io.jans.as.model.uma.wrapper.Token; import io.jans.as.model.util.Util; +import io.jans.configapi.service.HttpService; import io.jans.configapi.service.ResteasyService; + import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -105,11 +107,15 @@ public class BaseTest { private Base64 base64; private static Map propertiesMap = null; private ResteasyService resteasyService; + private HttpService httpService; + protected String accessToken; @BeforeSuite public void initTestSuite(ITestContext context) throws Exception { resteasyService = new ResteasyService(); + httpService = new HttpService(); + log.info("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); Properties prop = new Properties(); @@ -118,6 +124,9 @@ public void initTestSuite(ITestContext context) throws Exception { propertiesMap = new Hashtable<>(); prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); context.getSuite().getXmlSuite().setParameters(propertiesMap); + + //accessToken + } @@ -128,7 +137,7 @@ public void finalize() { } @BeforeTest - public String getAccessToken() throws Exception { + public void getAccessToken() throws Exception { String tokenUrl = propertiesMap.get("token.endpoint"); String strGrantType = propertiesMap.get("token.grant.type"); String clientId = propertiesMap.get("test.client.id"); @@ -139,8 +148,8 @@ public String getAccessToken() throws Exception { String token = new String(Base64.decodeBase64(authStr), StandardCharsets.UTF_8); String encodedScopes = URLDecoder.decode(scopes, "UTF-8"); GrantType grantType = GrantType.fromString(strGrantType); - String accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); - return accessToken; + accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); + log.error("accessToken:{}", accessToken); } public String getToken(final String tokenUrl, final String clientId, final String clientSecret, @@ -190,5 +199,16 @@ public TokenResponse requestAccessToken(final String tokenUrl, final String clie } return null; } + + + protected HttpService getHttpService() { + return this.httpService; + } + + + protected ResteasyService getResteasyService() { + return this.resteasyService; + } + } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ClientResourceTest.java new file mode 100644 index 00000000000..6f9e0843d2e --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ClientResourceTest.java @@ -0,0 +1,55 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.rest.resource; + +import static io.restassured.RestAssured.given; +import io.jans.configapi.BaseTest; +import io.jans.model.net.HttpServiceResponse; +import jakarta.ws.rs.core.MediaType; + +import static org.testng.Assert.*; + +import java.util.Map; + +import org.apache.http.entity.ContentType; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + + +public class ClientResourceTest extends BaseTest{ + + private String clientId; + + @Parameters({"issuer", "openidClientsUrl"}) + @Test + public void getClients(final String issuer, final String openidClientsUrl) { + log.error("accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+openidClientsUrl).then().statusCode(200); + } + + @Parameters({"issuer", "openidClientsUrl", "openid_client1"}) + @Test + public void postClient(final String issuer, final String openidClientsUrl, final String json) { + log.error("accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); + log.info("Creating client using json string"); + + HttpServiceResponse httpServiceResponse = getHttpService().executePost(issuer+openidClientsUrl, "Basic ", null, json, + ContentType.APPLICATION_JSON, null); + assertFalse(httpServiceResponse==null); + + int statusCode = httpServiceResponse.getHttpResponse().getStatusLine().getStatusCode(); + + Status status = Status.fromStatusCode(statusCode); + + assertEquals(status, Status.OK.getStatusCode()); + } +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java index 3ce07f1e0e8..6c45e3da4a2 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java @@ -6,20 +6,34 @@ package io.jans.configapi.rest.resource; -import org.testng.annotations.Test; -import jakarta.ws.rs.core.MediaType; import static io.restassured.RestAssured.given; +import io.jans.configapi.BaseTest; +import jakarta.ws.rs.core.MediaType; + +import org.testng.annotations.Test; +import org.testng.annotations.Parameters; /** * @author Yuriy Zabrovarnyy */ -public class ConfigResourceTest { +public class ConfigResourceTest extends BaseTest{ + @Parameters({"issuer", "authConfigurationUrl"}) + @Test + public void getAuthAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { + log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+authConfigurationUrl).then().statusCode(200); + } + + @Parameters({"issuer", "authConfigurationUrl"}) @Test - public void patchAppConfigurationProperty() { + public void patchAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { + log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer 0ea2ce99-b741-4f5a-8fd7-26f52d057c19", null) + .header("Authorization", accessToken, null) .body("[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]") - .patch("/jans-config-api/api/v1/jans-auth-server/config").then().statusCode(200); + .patch(issuer+authConfigurationUrl).then().statusCode(200); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java index 6bda59312b5..17be894d8ba 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java @@ -160,6 +160,10 @@ public HttpServiceResponse executePost(HttpClient httpClient, String uri, String if (StringHelper.isNotEmpty(authData)) { httpPost.setHeader("Authorization", authType + authData); } + + if(contentType==null) { + contentType = ContentType.APPLICATION_JSON; + } if (headers != null) { for (Entry headerEntry : headers.entrySet()) { diff --git a/jans-config-api/server/src/test/resources/config-api-test - Copy.properties b/jans-config-api/server/src/test/resources/config-api-test - Copy.properties new file mode 100644 index 00000000000..5892a12bea4 --- /dev/null +++ b/jans-config-api/server/src/test/resources/config-api-test - Copy.properties @@ -0,0 +1,43 @@ +scopes=${test.scopes} + +# Test env Setting +tokenEndpoint=${token.endpoint} +tokenGrantType=${token.grant.type} +clientId=${test.client.id} +clientSecret=${test.client.secret} +issuer=${test.issuer} + + +statUrl= "/jans-config-api/api/v1/stat" +healthUrl="/jans-config-api/api/v1/health" +acrsUrl="/jans-config-api/api/v1/acrs" +authConfigurationUrl="/jans-config-api/api/v1/jans-auth-server/config" +scriptsUrl="/jans-config-api/api/v1/config/scripts" +cacheUrl="/jans-config-api/api/v1/config/cache" +messageUrl="/jans-config-api/api/v1/config/message" +jwksUrl="/jans-config-api/api/v1/config/jwks" +ldapUrl="/jans-config-api/api/v1/config/database/ldap" +openidClientsUrl="/jans-config-api/api/v1/openid/clients" +scopesUrl="/jans-config-api/api/v1/scopes" +umaresourcesUrl="/jans-config-api/api/v1/uma/resources" +attributesUrl="/jans-config-api/api/v1/attributes" +smtpUrl="/jans-config-api/api/v1/config/smtp" +loggingUrl="/jans-config-api/api/v1/logging" +authHealthUrl="/jans-config-api/api/v1/jans-auth-server/health" +orgConfigurationUrl="/jans-config-api/api/v1/org" +userUrl="/jans-config-api/api/v1/user" +agamaUrl="/jans-config-api/api/v1/agama" +sessionUrl="/jans-config-api/api/v1/jans-auth-server/session" +pluginUrl="/jans-config-api/api/v1/plugin" +apiConfigUrl="/jans-config-api/api/v1/api-config" +agamaDeploymentUrl="/jans-config-api/api/v1/agama-deployment" +clientsAuthorizationsUrl="/jans-config-api/api/v1/clients/authorizations" +tokenUrl="/jans-config-api/api/v1/token" + + +#openid-client +openid_client1=file:target/test-classes/json/openid/clients/client.json + +#openid-scopes +openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json + diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties index c735935d9e1..53efcfd3996 100644 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -1,11 +1,11 @@ -scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=${token.endpoint} -tokenGrantType=${token.grant.type} -clientId=${test.client.id} -clientSecret=${test.client.secret} -issuer=${test.issuer} +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info statUrl= "/jans-config-api/api/v1/stat" @@ -34,3 +34,10 @@ agamaDeploymentUrl="/jans-config-api/api/v1/agama-deployment" clientsAuthorizationsUrl="/jans-config-api/api/v1/clients/authorizations" tokenUrl="/jans-config-api/api/v1/token" + +#openid-client +openid_client1=file:target/test-classes/json/openid/clients/client.json + +#openid-scopes +openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json + diff --git a/jans-config-api/server/src/test/resources/json/openid/clients/admin-ui-client.json b/jans-config-api/server/src/test/resources/json/openid/clients/admin-ui-client.json new file mode 100644 index 00000000000..6d78adbb4d4 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/openid/clients/admin-ui-client.json @@ -0,0 +1 @@ +{"displayName":"FinalNewTestClient","clientName":"FinalNewTestClient","applicationType":"web","subjectType":"public","idTokenSignedResponseAlg":"HS256","tokenEndpointAuthMethod":"client_secret_post","accessTokenSigningAlg":"HS256","backchannelUserCodeParameter":false,"policyUri":"https://myclient.com/policy","tlsClientAuthSubjectDn":"tls auth","sectorIdentifierUri":"https://myclient.com/uri","redirectUris":["https://myclient.com/redirecturi"],"claimRedirectUris":["https://myclient.com/clainredirect"],"responseTypes":["code"],"grantTypes":["implicit","authorization_code"],"contacts":["sample@yahoo.fr"],"postLogoutRedirectUris":["https://myclient.com/postlogout"],"scopes":["inum=43F1,ou=scopes,o=jans"],"customAttributes":[{"name":"description","multiValued":false,"values":["MyClient description"]},{"name":"description","multiValued":false,"values":[null]}],"spontaneousScopes":["inum=C4F5,ou=scopes,o=jans"],"introspectionScripts":[],"spontaneousScopeScriptDns":[],"consentGatheringScripts":[],"rptClaimsScripts":[],"backchannelLogoutUri":["https://myclient.com/backchannel"],"postAuthnScripts":[],"additionalAudience":["audiance"],"attributes":{"tlsClientAuthSubjectDn":"tls auth","spontaneousScopes":["inum=C4F5,ou=scopes,o=jans"],"backchannelLogoutUri":["https://myclient.com/backchannel"],"additionalAudience":["audiance"],"introspectionScripts":[],"spontaneousScopeScriptDns":[],"consentGatheringScripts":[],"rptClaimsScripts":[],"postAuthnScripts":[]},"customObjectClasses":["top"],"deletable":false,"frontChannelLogoutSessionRequired":true,"requireAuthTime":true,"trustedClient":true,"persistClientAuthorizations":true,"includeClaimsInIdToken":true,"rptAsJwt":true,"accessTokenAsJwt":true,"disabled":false,"clientUri":"https://myclient.com/clienturi","initiateLoginUri":"https://myclient.com/loginuri","tosUri":"https://myclient.com/tosuri","idTokenTokenBindingCnf":"polling","refreshTokenLifetime":5,"oxdId":"sample","defaultMaxAge":5,"accessTokenLifetime":5,"authorizedOrigins":["https://myclient.com/origins"],"requestUris":["https://myclient.com/requesturi"],"idTokenEncryptedResponseAlg":"RSA-OAEP","idTokenEncryptedResponseEnc":"A256CBC+HS512","requestObjectEncryptionAlg":"RSA1_5","requestObjectSigningAlg":"ES512","requestObjectEncryptionEnc":"A256CBC+HS512","userInfoEncryptedResponseAlg":"RSA1_5","userInfoSignedResponseAlg":"ES384","userInfoEncryptedResponseEnc":"A128CBC+HS256","jwksUri":"https://myclient.com/jwksuri","jwks":"https://myclient.com/jwks","action_message":"savinf spsmslmsls"} diff --git a/jans-config-api/server/src/test/resources/json/openid/clients/client.json b/jans-config-api/server/src/test/resources/json/openid/clients/client.json new file mode 100644 index 00000000000..e18a1e3e1f0 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/openid/clients/client.json @@ -0,0 +1,55 @@ +{ + "applicationType": "web", + "description":"Description for test client", + "customObjectClasses":["top"], + "accessTokenAsJwt": false, + "claimRedirectUris": [ + ], + "deletable": false, + "disabled": false, + "requireAuthTime": false, + "clientName": "Jans Config API Test Client", + "clientSecret": "test1234", + "exp": "2130-09-28T23:00:00Z[UTC]", + "grantTypes": [ + "authorization_code", + "implicit", + "refresh_token", + "client_credentials", + "password" + ], + "responseTypes": ["code"], + "idTokenSignedResponseAlg": "RS256", + "accessTokenSigningAlg": "RS256", + "attributes": { + "tlsClientAuthSubjectDn":"", + "runIntrospectionScriptBeforeJwtCreation":false, + "keepClientAuthorizationAfterExpiration":false, + "allowSpontaneousScopes":false, + "spontaneousScopes":[],"spontaneousScopeScriptDns":[], + "backchannelLogoutUri":[],"backchannelLogoutSessionRequired":false, + "additionalAudience":[],"postAuthnScripts":[],"consentGatheringScripts":[], + "introspectionScripts":[],"rptClaimsScripts":[] + }, + "frontChannelLogoutSessionRequired": false, + "logoutUri": [ + ], + "persistClientAuthorizations": true, + "postLogoutRedirectUris": [ + ], + "redirectUris": [ + "http://localhost:8080" + ], + "scopes": [ + ], + "trustedClient": false, + "includeClaimsInIdToken": false, + "rptAsJwt": false, + "subjectType": "pairwise", + "tokenEndpointAuthMethod": "client_secret_basic", + "dynamicRegistrationCustomObjectClass": "MyDynamicRegistrationCustomObject", + "dynamicRegistrationCustomAttributes": [ + "jansTrustedClnt", + "myAttr1" + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/openid/clients/client_custom_attribute_patch.json b/jans-config-api/server/src/test/resources/json/openid/clients/client_custom_attribute_patch.json new file mode 100644 index 00000000000..f0ef5dbec6e --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/openid/clients/client_custom_attribute_patch.json @@ -0,0 +1,13 @@ +[ + { + "op": "replace", + "path": "/customAttributes", + "value":[ + { + "name": "customTest", + "multiValued": false, + "value": "ABC_Vaue_Patched" + } + ] + } +] diff --git a/jans-config-api/server/src/test/resources/json/openid/clients/openid-client.json b/jans-config-api/server/src/test/resources/json/openid/clients/openid-client.json new file mode 100644 index 00000000000..24da86ddd1f --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/openid/clients/openid-client.json @@ -0,0 +1,60 @@ +{ + "accessTokenAsJwt": false, + "attributes": { + "additionalAudience": [], + "allowSpontaneousScopes": false, + "backchannelLogoutSessionRequired": false, + "backchannelLogoutUri": [], + "consentGatheringScripts": [], + "introspectionScripts": [], + "keepClientAuthorizationAfterExpiration": false, + "postAuthnScripts": [], + "rptClaimsScripts": [], + "runIntrospectionScriptBeforeJwtCreation": false, + "spontaneousScopeScriptDns": [], + "spontaneousScopes": [] + }, + "claimRedirectURI": [ + "https://gluu.gasmyr.com/jans-auth/restv1/uma/gather_claims" + ], + "deletable": false, + "disabled": false, + "displayName": "Puja_Sharma_Test_Client_3", + "description":"OpenId Client added for testing", + "encodedClientSecret": "qaclientPassword", + "exp": "2120-09-28T23:00:00Z[UTC]", + "grantTypes": [ + "AUTHORIZATION_CODE" + ], + "idTokenSignedResponseAlg": "HS256", + "logoutSessionRequired": true, + "logoutUri": [ + "https://gluu.gasmyr.com/identity/ssologout.htm" + ], + "jansAppTyp": "WEB", + "jansPersistClntAuthzs": false, + "jansPostLogoutRedirectURI": [ + "https://gluu.gasmyr.com/identity/finishlogout.htm" + ], + "jansRedirectURI": [ + "https://gluu.gasmyr.com/identity/uri1" + ], + "jansScope": [ + "inum=F0C4,ou=scopes,o=gluu" + ], + "jansTrustedClnt": true, + "jansInclClaimsInIdTkn": false, + "responseTypes": [ + "CODE" + ], + "rptAsJwt": false, + "subjectType": "PUBLIC", + "tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC", + "customAttributes": [ + { + "name": "customTest", + "multiValued": false, + "value": "To test CustomAttribute for Puja_Sharma_Test_Client_3" + } + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/openid/clients/openid_clients_create.json b/jans-config-api/server/src/test/resources/json/openid/clients/openid_clients_create.json new file mode 100644 index 00000000000..bd5078f8eca --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/openid/clients/openid_clients_create.json @@ -0,0 +1,154 @@ +{ + "clientSecret": "test@123", + "clientName": "ABCDE", + "description": "sdjkhfjksdfjksdkfj", + "applicationType": "web", + "subjectType": "pairwise", + "initiateLoginUri": "DFGDFDFG", + "logoUri": "sdfsdfsdf", + "clientUri": "sdfsdf", + "tosUri": "fddfdfgdf", + "jwksUri": "JKHJKHSDHKJSDFH", + "jwks": "JKJKHJKJHK", + "expirable": [ + "on" + ], + "expirationDate": "2022-07-25T09:30:00.656Z", + "softwareStatement": "12", + "softwareVersion": "11", + "softwareId": "123", + "softwareSection": false, + "cibaSection": false, + "idTokenSignedResponseAlg": "HS256", + "idTokenEncryptedResponseAlg": "A128KW", + "tokenEndpointAuthMethod": "client_secret_post", + "accessTokenSigningAlg": "HS384", + "idTokenEncryptedResponseEnc": "A256CBC+HS512", + "requestObjectEncryptionAlg": "RSA-OAEP", + "requestObjectSigningAlg": "HS256", + "requestObjectEncryptionEnc": "A256CBC+HS512", + "userInfoEncryptedResponseAlg": "A128KW", + "userInfoSignedResponseAlg": "RS256", + "userInfoEncryptedResponseEnc": "A128GCM", + "idTokenTokenBindingCnf": "dsfsdfdsf", + "backchannelUserCodeParameter": true, + "refreshTokenLifetime": 2, + "defaultMaxAge": 2, + "accessTokenLifetime": 12, + "backchannelTokenDeliveryMode": "push", + "backchannelClientNotificationEndpoint": "sdhjfjhsdf", + "frontChannelLogoutUri": "dfdsdgsdg", + "policyUri": "sfsdsdf", + "sectorIdentifierUri": "HJKFDJHKHJKDS", + "redirectUris": [ + "sdfsdfsdf" + ], + "claimRedirectUris": [ + "NBMNSMNBSDMV" + ], + "authorizedOrigins": [ + "dgffddfg" + ], + "requestUris": [ + "FDDGDFGG" + ], + "postLogoutRedirectUris": [ + "sdfsdfds" + ], + "responseTypes": [ + "token" + ], + "grantTypes": [ + "implicit" + ], + "contacts": [ + "ashash@ggg.ccc" + ], + "defaultAcrValues": [ + "inum=3000-F75A,ou=scripts,o=jans" + ], + "scopes": [ + "inum=10B2,ou=scopes,o=jans" + ], + "attributes": { + "tlsClientAuthSubjectDn": "123", + "runIntrospectionScriptBeforeJwtCreation": "true", + "keepClientAuthorizationAfterExpiration": false, + "allowSpontaneousScopes": "true", + "backchannelLogoutSessionRequired": "true", + "backchannelLogoutUri": [ + "dsfsdfsdf" + ], + "rptClaimsScripts": [], + "consentGatheringScripts": [], + "spontaneousScopeScriptDns": [], + "introspectionScripts": [ + "inum=A44E-4F3D,ou=scripts,o=jans" + ], + "postAuthnScripts": [], + "additionalAudience": [ + "dsfsdfsdf" + ], + "spontaneousScopes": [ + "inum=1200.6928E4,ou=scopes,o=jans" + ], + "redirectUrisRegex": "sdfsdf", + "parLifetime": 3600, + "requirePar": true, + "jansDefaultPromptLogin": true, + "jansAuthorizedAcr": [ + "inum=3000-F75A,ou=scripts,o=jans" + ], + "updateTokenScriptDns": [], + "ropcScripts": [], + "jansAuthSignedRespAlg": "HS384", + "jansAuthEncRespAlg": "A128KW", + "jansAuthEncRespEnc": "A128GCM" + }, + "tlsClientAuthSubjectDn": "123", + "frontChannelLogoutSessionRequired": true, + "runIntrospectionScriptBeforeJwtCreation": "true", + "backchannelLogoutSessionRequired": "true", + "keepClientAuthorizationAfterExpiration": false, + "allowSpontaneousScopes": "true", + "spontaneousScopes": [ + "inum=1200.6928E4,ou=scopes,o=jans" + ], + "introspectionScripts": [ + "inum=A44E-4F3D,ou=scripts,o=jans" + ], + "spontaneousScopeScriptDns": [], + "consentGatheringScripts": [], + "redirectUrisRegex": "sdfsdf", + "parLifetime": "bnxcbmx", + "requirePar": true, + "updateTokenScriptDns": [], + "ropcScripts": [], + "authorizationSignedResponseAlg": "HS384", + "authorizationEncryptedResponseAlg": "A128KW", + "authorizationEncryptedResponseEnc": "A128GCM", + "postAuthnScripts": [], + "rptClaimsScripts": [], + "additionalAudience": [ + "dsfsdfsdf" + ], + "backchannelLogoutUri": [ + "dsfsdfsdf" + ], + "defaultPromptLogin": true, + "jansAuthorizedAcr": [ + "inum=3000-F75A,ou=scripts,o=jans" + ], + "customObjectClasses": [], + "requireAuthTime": true, + "trustedClient": true, + "persistClientAuthorizations": true, + "includeClaimsInIdToken": true, + "rptAsJwt": true, + "accessTokenAsJwt": true, + "disabled": true, + "claimRedirectURIs": [ + "NBMNSMNBSDMV" + ], + "action_message": "SDN KD KJDK " +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/openid/scopes/scope.json b/jans-config-api/server/src/test/resources/json/openid/scopes/scope.json new file mode 100644 index 00000000000..6890116e051 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/openid/scopes/scope.json @@ -0,0 +1,14 @@ +{ + "attributes": { + "notShowInDiscovery": false + }, + "defaultScope": false, + "description": "Kudia's basic information.", + "id": "kudia", + "jansClaim": [ + "inum=2B29,ou=attributes,o=gluu", + "inum=0C85,ou=attributes,o=gluu" + ], + "scopeType": "OPENID", + "umaType": false +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/log4j2-test.xml b/jans-config-api/server/src/test/resources/log4j2-test.xml new file mode 100644 index 00000000000..28f0d2bef4d --- /dev/null +++ b/jans-config-api/server/src/test/resources/log4j2-test.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index fe7dfb0a894..773651b5f94 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -2,20 +2,18 @@ - + - + - - + - + - - + From c05d3236df76fea6e598977564d15f029c758063 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 14 Nov 2024 20:50:54 +0530 Subject: [PATCH 10/44] feat(config-api): testng framework Signed-off-by: pujavs --- .../configapi/rest/health/ApiHealthTest.java | 54 + .../configapi/rest/resource/AcrsTest.java | 39 + .../DatabaseConnectionHealthTest.java | 54 + .../test/resources/config-api-test.properties | 3 + .../json/agama/agama-deployment.feature | 47 + .../resources/json/agama/agama-source.txt | 10 + .../test/resources/json/agama/agama.feature | 309 ++++ .../src/test/resources/json/agama/agama.json | 5 + .../src/test/resources/json/agama/agama1.json | 12 + .../json/attribute/attribute-for-patch.json | 27 + .../resources/json/attribute/attribute.json | 26 + .../json/attribute/attributes.feature | 198 +++ .../json/client-auth/client-auth.feature | 24 + .../json/config/api/properties.feature | 44 + .../resources/json/config/cache/cache.feature | 310 ++++ .../database/ldap/get-ldap-config.feature | 15 + .../json/config/database/ldap/ldap.feature | 161 +++ .../json/config/database/ldap/ldap.json | 19 + .../json/config/database/ldap/ldap_list.json | 21 + .../resources/json/config/jwks/jwk_key.json | 13 + .../resources/json/config/jwks/jwks-all.json | 191 +++ .../resources/json/config/jwks/jwks.feature | 85 ++ .../test/resources/json/config/jwks/jwks.json | 113 ++ .../json/config/jwks/jwks_patch.json | 20 + .../json/config/message/message.feature | 176 +++ .../json/config/org/org-config.feature | 45 + .../properties/authenticationFilters.json | 23 + .../backchannel/backchannel.feature | 49 + .../json/config/properties/ciba/ciba.feature | 221 +++ .../json/config/properties/ciba/ciba.json | 14 + .../clientAuthenticationFilters.json | 14 + .../json/config/properties/cors/cors.feature | 34 + .../json/config/properties/cors/cors.json | 26 + .../json/config/properties/custom.json | 14 + .../dynamic/registration/registration.feature | 129 ++ .../dynamic/registration/registration.json | 21 + .../properties/endpoints/endpoints.feature | 274 ++++ .../properties/endpoints/endpoints.json | 18 + .../properties/expiration/expiration.feature | 61 + .../properties/expiration/expiration.json | 5 + .../config/properties/grant/grant.feature | 44 + .../json/config/properties/grant/grant.json | 10 + .../config/properties/idToken/idToken.feature | 93 ++ .../config/properties/idToken/idToken.json | 26 + .../janssenpkcs/janssenpkcs.feature | 33 + .../properties/keys/regen/regen.feature | 38 + .../config/properties/keys/regen/regen.json | 5 + .../config/properties/metrics/metrics.feature | 66 + .../properties/openid/config/config.feature | 287 ++++ .../properties/openid/config/config.json | 79 ++ .../properties/pairwise/pairwise.feature | 103 ++ .../json/config/properties/properties.feature | 344 +++++ .../config/properties/request/object.feature | 33 + .../properties/response/modes/modes.feature | 33 + .../properties/response/types/type.feature | 33 + .../config/properties/server/cleanup.feature | 50 + .../config/properties/server/cleanup.json | 6 + .../config/properties/server/config.feature | 63 + .../json/config/properties/server/config.json | 26 + .../server/session/sessionId.feature | 99 ++ .../config/properties/subject/subject.feature | 38 + .../config/properties/subject/subject.json | 7 + .../config/properties/token/token.feature | 61 + .../json/config/properties/token/token.json | 6 + .../uma/configuration/configuration.feature | 118 ++ .../properties/user/info/userInfo.feature | 84 ++ .../scripts/custom/generic/all-script.json | 1249 +++++++++++++++++ .../scripts/custom/generic/custom.feature | 103 ++ .../scripts/custom/generic/post-script.json | 17 + .../scripts/custom/persons/person-script.json | 26 + .../custom/persons/person-scripts.feature | 122 ++ .../json/defaultAcr/defaultAcr.feature | 59 + .../resources/json/defaultAcr/defaultAcr.json | 3 + .../json/health/auth-server-health.feature | 13 + .../json/health/config-api-health.feature | 32 + .../json/health/server-health.feature | 14 + .../resources/json/logging/logging.feature | 37 + .../resources/json/plugins/plugin-all.json | 14 + .../resources/json/plugins/plugin.feature | 30 + .../resources/json/session/session.feature | 52 + .../src/test/resources/json/smtp/smtp.feature | 54 + .../src/test/resources/json/smtp/smtp.json | 12 + .../src/test/resources/json/stat/stat.feature | 24 + .../resources/json/token/client-token.feature | 27 + .../json/uma/resource/resources.feature | 107 ++ .../json/uma/resource/uma-resource.json | 16 + .../resources/json/uma/scopes/uma-scope.json | 10 + .../json/uma/scopes/umascopes.feature | 118 ++ 88 files changed, 6848 insertions(+) create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/rest/health/ApiHealthTest.java create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/AcrsTest.java create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/DatabaseConnectionHealthTest.java create mode 100644 jans-config-api/server/src/test/resources/json/agama/agama-deployment.feature create mode 100644 jans-config-api/server/src/test/resources/json/agama/agama-source.txt create mode 100644 jans-config-api/server/src/test/resources/json/agama/agama.feature create mode 100644 jans-config-api/server/src/test/resources/json/agama/agama.json create mode 100644 jans-config-api/server/src/test/resources/json/agama/agama1.json create mode 100644 jans-config-api/server/src/test/resources/json/attribute/attribute-for-patch.json create mode 100644 jans-config-api/server/src/test/resources/json/attribute/attribute.json create mode 100644 jans-config-api/server/src/test/resources/json/attribute/attributes.feature create mode 100644 jans-config-api/server/src/test/resources/json/client-auth/client-auth.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/api/properties.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/cache/cache.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/database/ldap/get-ldap-config.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/database/ldap/ldap.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/database/ldap/ldap.json create mode 100644 jans-config-api/server/src/test/resources/json/config/database/ldap/ldap_list.json create mode 100644 jans-config-api/server/src/test/resources/json/config/jwks/jwk_key.json create mode 100644 jans-config-api/server/src/test/resources/json/config/jwks/jwks-all.json create mode 100644 jans-config-api/server/src/test/resources/json/config/jwks/jwks.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/jwks/jwks.json create mode 100644 jans-config-api/server/src/test/resources/json/config/jwks/jwks_patch.json create mode 100644 jans-config-api/server/src/test/resources/json/config/message/message.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/org/org-config.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/authenticationFilters.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/backchannel/backchannel.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/ciba/ciba.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/ciba/ciba.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/clientAuthenticationFilters.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/cors/cors.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/cors/cors.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/custom.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/dynamic/registration/registration.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/dynamic/registration/registration.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/endpoints/endpoints.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/endpoints/endpoints.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/expiration/expiration.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/expiration/expiration.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/grant/grant.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/grant/grant.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/idToken/idToken.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/idToken/idToken.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/janssenpkcs/janssenpkcs.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/keys/regen/regen.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/keys/regen/regen.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/metrics/metrics.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/openid/config/config.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/openid/config/config.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/pairwise/pairwise.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/properties.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/request/object.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/response/modes/modes.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/response/types/type.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/server/cleanup.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/server/cleanup.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/server/config.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/server/config.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/server/session/sessionId.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/subject/subject.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/subject/subject.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/token/token.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/token/token.json create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/uma/configuration/configuration.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/properties/user/info/userInfo.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/all-script.json create mode 100644 jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/custom.feature create mode 100644 jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/post-script.json create mode 100644 jans-config-api/server/src/test/resources/json/config/scripts/custom/persons/person-script.json create mode 100644 jans-config-api/server/src/test/resources/json/config/scripts/custom/persons/person-scripts.feature create mode 100644 jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.feature create mode 100644 jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.json create mode 100644 jans-config-api/server/src/test/resources/json/health/auth-server-health.feature create mode 100644 jans-config-api/server/src/test/resources/json/health/config-api-health.feature create mode 100644 jans-config-api/server/src/test/resources/json/health/server-health.feature create mode 100644 jans-config-api/server/src/test/resources/json/logging/logging.feature create mode 100644 jans-config-api/server/src/test/resources/json/plugins/plugin-all.json create mode 100644 jans-config-api/server/src/test/resources/json/plugins/plugin.feature create mode 100644 jans-config-api/server/src/test/resources/json/session/session.feature create mode 100644 jans-config-api/server/src/test/resources/json/smtp/smtp.feature create mode 100644 jans-config-api/server/src/test/resources/json/smtp/smtp.json create mode 100644 jans-config-api/server/src/test/resources/json/stat/stat.feature create mode 100644 jans-config-api/server/src/test/resources/json/token/client-token.feature create mode 100644 jans-config-api/server/src/test/resources/json/uma/resource/resources.feature create mode 100644 jans-config-api/server/src/test/resources/json/uma/resource/uma-resource.json create mode 100644 jans-config-api/server/src/test/resources/json/uma/scopes/uma-scope.json create mode 100644 jans-config-api/server/src/test/resources/json/uma/scopes/umascopes.feature diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/health/ApiHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/health/ApiHealthTest.java new file mode 100644 index 00000000000..49d978cb09d --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/health/ApiHealthTest.java @@ -0,0 +1,54 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import static io.restassured.RestAssured.given; +import io.jans.configapi.BaseTest; +import jakarta.ws.rs.core.MediaType; + +import org.testng.annotations.Test; +import org.testng.annotations.Parameters; + +public class ApiHealthTest extends BaseTest{ + + @Parameters({"issuer", "healthUrl"}) + @Test + public void getHealthResponse(final String issuer, final String healthUrl) { + log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+healthUrl).then().statusCode(200); + } + + + @Parameters({"issuer", "healthUrl"}) + @Test + public void getServerStat(final String issuer, final String healthUrl) { + log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+healthUrl+"/server-stat").then().statusCode(200); + } + + @Parameters({"issuer", "healthUrl"}) + @Test + public void getApplicationVersion(final String issuer, final String healthUrl) { + log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+healthUrl+"/app-version").then().statusCode(200); + } + + @Parameters({"issuer", "healthUrl"}) + @Test + public void getServiceStatus(final String issuer, final String healthUrl) { + log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+healthUrl+"/service-status").then().statusCode(200); + } +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/AcrsTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/AcrsTest.java new file mode 100644 index 00000000000..dacefd78cdd --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/AcrsTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import static io.restassured.RestAssured.given; +import io.jans.configapi.BaseTest; +import jakarta.ws.rs.core.MediaType; + +import org.testng.annotations.Test; +import org.testng.annotations.Parameters; + +public class AcrsTest extends BaseTest{ + + @Parameters({"issuer", "acrsUrl"}) + @Test + public void getDefaultAuthenticationMethod(final String issuer, final String acrsUrl) { + log.error("accessToken:{}, issuer:{}, acrsUrl:{}", accessToken, issuer, acrsUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+acrsUrl).then().statusCode(200); + } + + + @Parameters({"issuer", "acrsUrl", "default_acr1"}) + @Test + public void postClient(final String issuer, final String openidClientsUrl, final String json) { + log.error("accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); + log.info("Creating client using json string"); + + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .body(json) + .put(issuer+acrsUrl).then().statusCode(200); + } +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/DatabaseConnectionHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/DatabaseConnectionHealthTest.java new file mode 100644 index 00000000000..49d978cb09d --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/DatabaseConnectionHealthTest.java @@ -0,0 +1,54 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import static io.restassured.RestAssured.given; +import io.jans.configapi.BaseTest; +import jakarta.ws.rs.core.MediaType; + +import org.testng.annotations.Test; +import org.testng.annotations.Parameters; + +public class ApiHealthTest extends BaseTest{ + + @Parameters({"issuer", "healthUrl"}) + @Test + public void getHealthResponse(final String issuer, final String healthUrl) { + log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+healthUrl).then().statusCode(200); + } + + + @Parameters({"issuer", "healthUrl"}) + @Test + public void getServerStat(final String issuer, final String healthUrl) { + log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+healthUrl+"/server-stat").then().statusCode(200); + } + + @Parameters({"issuer", "healthUrl"}) + @Test + public void getApplicationVersion(final String issuer, final String healthUrl) { + log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+healthUrl+"/app-version").then().statusCode(200); + } + + @Parameters({"issuer", "healthUrl"}) + @Test + public void getServiceStatus(final String issuer, final String healthUrl) { + log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+healthUrl+"/service-status").then().statusCode(200); + } +} diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties index 53efcfd3996..5e49eb48541 100644 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -35,6 +35,9 @@ clientsAuthorizationsUrl="/jans-config-api/api/v1/clients/authorizations" tokenUrl="/jans-config-api/api/v1/token" +#defaultAcr +default_acr1=file:target/test-classes/json/acr/defaultAcr.json + #openid-client openid_client1=file:target/test-classes/json/openid/clients/client.json diff --git a/jans-config-api/server/src/test/resources/json/agama/agama-deployment.feature b/jans-config-api/server/src/test/resources/json/agama/agama-deployment.feature new file mode 100644 index 00000000000..b5f7fcb1746 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/agama/agama-deployment.feature @@ -0,0 +1,47 @@ + +Feature: Agama Deployment + +Background: +* def mainUrl = agama_deployment_url +* def funGetEncodedValue = +""" +function(strValue) { +print(' strValue = '+strValue); +if(strValue == null || strValue.length==0){ +return strValue; +} +var URLEncoder = Java.type('java.net.URLEncoder'); +var encodedStrValue = URLEncoder.encode(strValue, "UTF-8"); +print(' encodedStrValue = '+encodedStrValue); +return encodedStrValue; +} +""" + +Scenario: Fetch all Agama deployment without bearer token + Given url mainUrl + '/list' + When method GET + Then status 401 + And print response + +@ignore +Scenario: Fetch all Agama deployment + Given url mainUrl + '/list' + And print 'accessToken = '+accessToken + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + +@ignore +Scenario: Fetch all Agama deployment + Given url mainUrl + '/list' + And print 'accessToken = '+accessToken + And header Authorization = 'Bearer ' + accessToken + And param start = 0 + And param count = 3 + When method GET + Then status 200 + And print response + + + diff --git a/jans-config-api/server/src/test/resources/json/agama/agama-source.txt b/jans-config-api/server/src/test/resources/json/agama/agama-source.txt new file mode 100644 index 00000000000..98a793ed038 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/agama/agama-source.txt @@ -0,0 +1,10 @@ +//This is a comment +//Another comment +Flow test + Basepath "hello" + +in = { name: "John" } +RRF "index.ftlh" in + +Log "Done!" +Finish "john_doe" diff --git a/jans-config-api/server/src/test/resources/json/agama/agama.feature b/jans-config-api/server/src/test/resources/json/agama/agama.feature new file mode 100644 index 00000000000..f663df12815 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/agama/agama.feature @@ -0,0 +1,309 @@ + +Feature: Agama flow + +Background: +* def mainUrl = agama_url +* def funGetEncodedValue = +""" +function(strValue) { +print(' strValue = '+strValue); +if(strValue == null || strValue.length==0){ +return strValue; +} +var URLEncoder = Java.type('java.net.URLEncoder'); +var encodedStrValue = URLEncoder.encode(strValue, "UTF-8"); +print(' encodedStrValue = '+encodedStrValue); +return encodedStrValue; +} +""" + +@ignore +Scenario: Fetch all agama without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + +@ignore +Scenario: Fetch all agama flows + Given url mainUrl + And print 'accessToken = '+accessToken + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + +@ignore +Scenario: Fetch agama flow by name + Given url mainUrl + And print 'accessToken = '+accessToken + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response[0].qname + Then def flowName = response[0].qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + +@ignore +@CreateUpdateDelete +Scenario: Create, update and delete agama flow + #Create agama flow + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('agama.json') + When method POST + Then status 201 + And print response + And print response.qname + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Fetch agama flow by name and with source + Given url mainUrl + '/' +encodedFlowName+ '?includeSource=true' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + Then def result = response + And print result + And print 'Old revision ='+response.revision + Then set result.revision = response.revision+1 + And print result + And print response.qname + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Update agama flow + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + And print response.qname + And print response.revision + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Fetch agama flow by name + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And print response.qname + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Fetch agama flow by name and with source + Given url mainUrl + '/' +encodedFlowName + '?includeSource=true' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Delete agama flow by name + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + And print response + +@ignore +@CreateFlowWithDataInRequestBodyUpdateDelete +Scenario: Create agama flow with source data in request body + #Create agama flow + Then def flowName = 'test' + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'text/plain' + And header Accept = 'application/json' + And request read('agama-source.txt') + When method POST + Then status 201 + And print response + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Fetch agama flow by name and with source + Given url mainUrl + '/' +encodedFlowName+ '?includeSource=true' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And print response.qname + Then def flowName = response.qname + And print flowName + Then def result = response + And print 'Old revision ='+response.revision + Then set result.revision = response.revision+1 + And print encodedFlowName + #Update agama flow + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + And print response.qname + And print response.revision + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Fetch agama flow by name + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And print response.qname + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Delete agama flow by name + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + And print response + +@ignore +@CreateAndUpdateFlowWithDataInRequestBodyUpdateDelete +Scenario: Create agama flow with source data in request body + #Create agama flow + Then def flowName = 'test' + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'text/plain' + And header Accept = 'application/json' + And request read('agama-source.txt') + When method POST + Then status 201 + And print response + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Fetch agama flow by name and with source + Given url mainUrl + '/' +encodedFlowName+ '?includeSource=true' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And print response.qname + Then def flowName = response.qname + And print flowName + Then def result = response + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Update agama flow + Given url mainUrl + '/source/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'text/plain' + And header Accept = 'application/json' + And request read('agama-source.txt') + When method PUT + Then status 200 + And print response + And print response.qname + And print response.revision + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Fetch agama flow by name + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And print response.qname + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Delete agama flow by name + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + And print response + +@ignore +@CreateAndPatchFlowAndDelete +Scenario: Create and Patch agama flow + #Create agama flow + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('agama.json') + When method POST + Then status 201 + And print response + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Fetch agama flow by name and with source + Given url mainUrl + '/' +encodedFlowName+ '?includeSource=true' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + Then def result = response + And print response.qname + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Patch agama flow + Then def revision_before = response.revision + And print 'revision = '+revision_before + Then def revision_updated = revision_before+1 + And print 'revision_updated = '+revision_updated + And print result.jansHideOnDiscovery + And def request_body = (result.revision == null ? "[ {\"op\":\"add\", \"path\": \"/revision\", \"value\":"+revision_updated+" } ]" : "[ {\"op\":\"replace\", \"path\": \"/revision\", \"value\":"+revision_updated+" } ]") + And print 'request_body ='+request_body + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + Then def flowName = response.qname + And print flowName + Then def encodedFlowName = funGetEncodedValue(flowName) + And print encodedFlowName + #Delete agama flow by name + Given url mainUrl + '/' +encodedFlowName + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + And print response diff --git a/jans-config-api/server/src/test/resources/json/agama/agama.json b/jans-config-api/server/src/test/resources/json/agama/agama.json new file mode 100644 index 00000000000..436410d5844 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/agama/agama.json @@ -0,0 +1,5 @@ +{ + "enabled": false, + "source":"Flow test\n\tBasepath \"hello\"\n\nin = { name: \"John\" }\nRRF \"index.ftlh\" in\n\nLog \"Done!\"\nFinish \"john_doe\"", + "qname": "test" +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/agama/agama1.json b/jans-config-api/server/src/test/resources/json/agama/agama1.json new file mode 100644 index 00000000000..c83d18a15b1 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/agama/agama1.json @@ -0,0 +1,12 @@ +{ + "enabled": false, + "revision": 1, + "transHash": "4", + "source":"Flow test\n\tBasepath \"hello\"\n\nin = { name: \"John\" }\nRRF \"index.ftlh\" in\n\nLog \"Done!\"\nFinish \"john_doe\"", + "qname": "test", + "metadata":{ + "funcName": "Test_fun_4", + "inputs":["1","abc","exyz"], + "timeout": 9600 + } +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/attribute/attribute-for-patch.json b/jans-config-api/server/src/test/resources/json/attribute/attribute-for-patch.json new file mode 100644 index 00000000000..702ced2c3cf --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/attribute/attribute-for-patch.json @@ -0,0 +1,27 @@ +{ + "adminCanAccess": true, + "adminCanEdit": true, + "adminCanView": true, + "custom": false, + "dataType": "string", + "description": "Test Attribute", + "displayName": "Test Attribute", + "editType": [ + "admin", + "user" + ], + "name": "testAttribute", + "origin": "jansPerson", + "jansMultivaluedAttr": false, + "status": "active", + "urn": "urn:mace:dir:attribute-def:testAttribute", + "userCanAccess": true, + "userCanEdit": true, + "userCanView": true, + "viewType": [ + "admin", + "user" + ], + "whitePagesCanView": false, + "jansHideOnDiscovery": true +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/attribute/attribute.json b/jans-config-api/server/src/test/resources/json/attribute/attribute.json new file mode 100644 index 00000000000..524420a6895 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/attribute/attribute.json @@ -0,0 +1,26 @@ +{ + "adminCanAccess": true, + "adminCanEdit": true, + "adminCanView": true, + "custom": false, + "dataType": "string", + "description": "QAAdded Attribute", + "displayName": "QAAdded Attribute", + "editType": [ + "admin", + "user" + ], + "name": "qaattribute", + "origin": "jansPerson", + "jansMultivaluedAttr": false, + "status": "active", + "urn": "urn:mace:dir:attribute-def:qaattribute", + "userCanAccess": true, + "userCanEdit": true, + "userCanView": true, + "viewType": [ + "admin", + "user" + ], + "whitePagesCanView": false +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/attribute/attributes.feature b/jans-config-api/server/src/test/resources/json/attribute/attributes.feature new file mode 100644 index 00000000000..649ea1c74a0 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/attribute/attributes.feature @@ -0,0 +1,198 @@ + +Feature: Attributes + +Background: +* def mainUrl = attributes_url + +Scenario: Fetch all attributes without bearer token + Given url mainUrl + When method GET + Then status 401 + + +Scenario: Fetch all attributes + Given url mainUrl + And print 'accessToken = '+accessToken + And print 'issuer = '+issuer + And header Authorization = 'Bearer ' + accessToken + #And header issuer = issuer + When method GET + Then status 200 + And print response + #And assert response.length != null + #And assert response.length >= 10 + +@ignore +Scenario: Fetch based on filter + Given url mainUrl + And print 'accessToken = '+accessToken + And print 'issuer = '+issuer + And header Authorization = 'Bearer ' + accessToken + #And header issuer = issuer + And param limit = 3 + And param pattern = 'edu' + And param startIndex = 1 + When method GET + Then status 200 + And print response + #And assert response.length != null + #And assert response.length >= 10 + +Scenario: Fetch the first three attributes + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And param limit = 3 + When method GET + Then status 200 + And print response + #And assert response.length == 3 + + +Scenario: Search attributes given a search pattern + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And param pattern = 'city' + When method GET + Then status 200 + And print response + #And assert response.length != 0 + +Scenario: Fetch all active attributes + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And param status = 'active' + When method GET + Then status 200 + And print response + +Scenario: Fetch the first three active attributes + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And param limit = 3 + And param status = 'active' + When method GET + Then status 200 + And print response + #And assert response.length == 3 + #And assert response[0].status == 'ACTIVE' + #And assert response[1].status == 'ACTIVE' + #And assert response[2].status == 'ACTIVE' + + +Scenario: Fetch the first three inactive attributes + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And param limit = 3 + And param status = 'inactive' + When method GET + Then status 200 + And print response + #And assert response.length == 3 + #And assert response[0].status == 'INACTIVE' + #And assert response[1].status == 'INACTIVE' + #And assert response[2].status == 'INACTIVE' + + +@ignore +@CreateUpdateDelete +Scenario: Create new attribute + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('attribute.json') + When method POST + Then status 201 + Then def result = response + Then set result.displayName = 'UpdatedQAAddedAttribute' + Then def inum_before = result.inum + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And assert response.displayName == 'UpdatedQAAddedAttribute' + And assert response.inum == inum_before + Given url mainUrl + '/' +response.inum + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + + +Scenario: Delete a non-existion attribute by inum + Given url mainUrl + '/1402.66633-8675-473e-a749' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 404 + + +Scenario: Get an attribute by inum(unexisting attribute) + Given url mainUrl + '/53553532727272772' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 404 + +@ignore +Scenario: Get an attribute by inum + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Given url mainUrl + '/' +response[0].inum + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + + +@ignore +@CreateUpdate +Scenario: Create new attribute + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('attribute-for-patch.json') + When method POST + Then status 201 + Then def result = response + Then set result.jansHideOnDiscovery = 'true' + Then def inum_before = result.inum + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + And print response.inum + Given url mainUrl + '/' +response.inum + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + +@ignore +Scenario: Patch jansHideOnDiscovery configuration for Country attribute + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And param pattern = 'street' + And param limit = 1 + When method GET + Then status 200 + And print response + And assert response.length == 1 + Then def result = response[0] + And def inum_before = result.inum + And print 'inum = '+inum_before + And print result.jansHideOnDiscovery + And def orig_jansHideOnDiscovery = (result.jansHideOnDiscovery == null ? false : result.jansHideOnDiscovery) + And print 'orig_jansHideOnDiscovery = '+orig_jansHideOnDiscovery + #And def new_jansHideOnDiscovery = (orig_jansHideOnDiscovery == null || orig_jansHideOnDiscovery == false ? true : false) + And def request_body = (result.jansHideOnDiscovery == null ? "[ {\"op\":\"add\", \"path\": \"/jansHideOnDiscovery\", \"value\":"+orig_jansHideOnDiscovery+" } ]" : "[ {\"op\":\"replace\", \"path\": \"/jansHideOnDiscovery\", \"value\":"+orig_jansHideOnDiscovery+" } ]") + And print 'request_body ='+request_body + Given url mainUrl + '/' +inum_before + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/client-auth/client-auth.feature b/jans-config-api/server/src/test/resources/json/client-auth/client-auth.feature new file mode 100644 index 00000000000..aea934d4f5a --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/client-auth/client-auth.feature @@ -0,0 +1,24 @@ + +Feature: Client Authorizations + +Background: +* def mainUrl = clients_authorizations_url + +Scenario: Fetch all clients authorizations without bearer token + Given url mainUrl + '/123' + When method GET + Then status 401 + + +Scenario: Fetch all clients authorizations + Given url mainUrl + '/123' + And print 'accessToken = '+accessToken + And print 'issuer = '+issuer + And header Authorization = 'Bearer ' + accessToken + #And header issuer = issuer + When method GET + Then status 200 + And print response + #And assert response.length != null + #And assert response.length >= 10 + diff --git a/jans-config-api/server/src/test/resources/json/config/api/properties.feature b/jans-config-api/server/src/test/resources/json/config/api/properties.feature new file mode 100644 index 00000000000..e6fa17bc6e6 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/api/properties.feature @@ -0,0 +1,44 @@ + +Feature: Verify Auth configuration endpoint + + Background: + * def mainUrl = api_config_url + + @config-get-error + Scenario: Retrieve configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + @config-get + Scenario: Retrieve configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @config-patch + Scenario: Patch configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And print 'response.loggingLevel = '+response.loggingLevel + And def request_body = (response.loggingLevel == null ? "[ {\"op\":\"add\", \"path\": \"/loggingLevel\", \"value\":\"DEBUG\" } ]" : "[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\":\"DEBUG\" } ]") + And print 'request_body ='+request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/cache/cache.feature b/jans-config-api/server/src/test/resources/json/config/cache/cache.feature new file mode 100644 index 00000000000..0737beca882 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/cache/cache.feature @@ -0,0 +1,310 @@ + +Feature: Verify Cache configuration endpoint + + Background: + * def mainUrl = cacheUrl + + @cache-get-error + Scenario: Retrieve Cache configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + @cache-get + Scenario: Retrieve Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @cache-patch + Scenario: Patch cacheProviderType configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.cacheProviderType + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/cacheProviderType\", \"value\":\""+response.cacheProviderType+"\" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @cache-patch + Scenario: Patch nativePersistenceConfiguration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.nativePersistenceConfiguration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/nativePersistenceConfiguration\", \"value\":"+response.nativePersistenceConfiguration+" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @cache-patch + Scenario: Patch inMemoryConfiguration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.inMemoryConfiguration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/inMemoryConfiguration\", \"value\":"+response.inMemoryConfiguration+" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @cache-patch + Scenario: Patch redisConfiguration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.redisConfiguration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/redisConfiguration\", \"value\":"+response.redisConfiguration+" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @cache-patch + Scenario: Patch memcachedConfiguration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.memcachedConfiguration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/memcachedConfiguration\", \"value\":"+response.memcachedConfiguration+" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @cache-get-redis + Scenario: Retrieve Redis Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'redis' + When method GET + Then status 200 + And print response + And assert response.length != null + + @cache-put-redis + Scenario: Update Redis Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'redis' + When method GET + Then status 200 + Then print response + Then def first_response = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'redis' + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + @cache-patch-redis + Scenario: Patch redis configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'redis' + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/defaultPutExpiration\", \"value\":"+response.defaultPutExpiration+"} ]" + And path 'redis' + Then print request + When method PATCH + Then status 200 + And print response + + @cache-get-in-memory + Scenario: Retrieve in-memory Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'in-memory' + When method GET + Then status 200 + And print response + And assert response.length != null + + @cache-put-in-memory + Scenario: Update in-memory Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'in-memory' + When method GET + Then status 200 + Then print response + Then def first_response = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'in-memory' + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + @cache-patch-in-memory + Scenario: Patch in-memory configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'in-memory' + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/defaultPutExpiration\", \"value\":"+response.defaultPutExpiration+" } ]" + And path 'in-memory' + Then print request + When method PATCH + Then status 200 + And print response + + @cache-get-native-persistence + Scenario: Retrieve native-persistence Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'native-persistence' + When method GET + Then status 200 + And print response + And assert response.length != null + + @cache-put-native-persistence + Scenario: Update native-persistence Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'native-persistence' + When method GET + Then status 200 + Then print response + Then def first_response = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'native-persistence' + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + @cache-patch-native-persistence + Scenario: Patch native-persistence configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'native-persistence' + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/defaultPutExpiration\", \"value\":"+response.defaultPutExpiration+"} ]" + And path 'native-persistence' + Then print request + When method PATCH + Then status 200 + And print response + + @cache-get-memcached + Scenario: Retrieve memcached Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'memcached' + When method GET + Then status 200 + And print response + And assert response.length != null + + @cache-put-memcached + Scenario: Update memcached Cache configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'memcached' + When method GET + Then status 200 + Then print response + Then def first_response = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'memcached' + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + + @cache-patch-memcached + Scenario: Patch memcached configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'memcached' + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/defaultPutExpiration\", \"value\":"+response.defaultPutExpiration+"} ]" + And path 'memcached' + Then print request + When method PATCH + Then status 200 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/database/ldap/get-ldap-config.feature b/jans-config-api/server/src/test/resources/json/config/database/ldap/get-ldap-config.feature new file mode 100644 index 00000000000..be874dad253 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/database/ldap/get-ldap-config.feature @@ -0,0 +1,15 @@ + +Feature: Verify LDAP configuration GET endpoint + + Background: + * def mainUrl = ldapUrl + + @ldap-config-get + Scenario: Retrieve LDAP configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap.feature b/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap.feature new file mode 100644 index 00000000000..ef50b1773bd --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap.feature @@ -0,0 +1,161 @@ + +@parallel=false +Feature: Verify LDAP configuration endpoint + + Background: + * def mainUrl = ldapUrl + * def result = call read('get-ldap-config.feature'); + * def funGetLdapConfig = +""" +function(ldap_array,ldap_id) { +print(' ldap_array = '+ldap_array); +print(' ldap_id = '+ldap_id); +var temp; +for (var i = 0; i < ldap_array.length; i++) { +print(' ldap_array[i] = '+ldap_array[i]); +if ( ldap_array[i].configId == ldap_id ){ + temp = ldap_array[i]; + print(' temp= '+temp); +} +} +return temp; +} +""" + + @ldap-config-get-without-bearer-token + Scenario: Get LDAP configuration By Name without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + @ignore + @ldap-config-get-by-name + Scenario: Get LDAP configuration By Name + And print result + And def first_response = result.response + And print first_response + Given url mainUrl + '/' +first_response[0].configId + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @ldap-config-get-by-name-invalid + Scenario: Get Non-existing LDAP configuration By Name + Given url mainUrl + '/' +'Non-existing-ldap' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 404 + And print response + And assert response.length != null + + @ldap-config-delete-by-name-invalid + Scenario: Delete Non-existing LDAP configuration By Name + Given url mainUrl + '/' +'Non-existing-ldap-XYZ' + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 404 + And print response + And assert response.length != null + + @ignore + @ldap-config-put + Scenario: Update LDAP configuration + And print result + And def first_response = result.response + And print first_response + And assert first_response.length != null + Then def result = first_response[0] + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + And print response.configId + And print response.version + + + @ignore + @ldap-config-delete-by-name-valid + Scenario: Delete LDAP configuration + And print result + And def first_response = result.response + And print first_response + And assert first_response.length != null + Then def data = funGetLdapConfig(first_response,'new_auth_ldap_server') + And print data + And match data != null + And print data.configId + Given url mainUrl + '/' +data.configId + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + And print response + And assert response.length != null + + @ignore + @ldap-config-patch + Scenario: Patch LDAP configuration + And print result + And def first_response = result.response + And print first_response + And assert first_response.length != null + And print 'Patch - ' + first_response[0].configId + Given url mainUrl + '/' +first_response[0].configId + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/maxConnections\", \"value\": "+first_response[0].maxConnections+"} ]" + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @ldap-config-post + Scenario: Add LDAP configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('ldap.json') + When method POST + Then status 201 + And print response + And assert response.length != null + And print response.configId + And print response.version + + @ignore + @ldap-config-post-same-name-ldap-error + Scenario: Add LDAP configuration with same name as existing + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('ldap.json') + When method POST + Then status 406 + And print response + + @ignore + @ldap-config-test + Scenario: Test LDAP configuration + #Given url mainUrl + Given url mainUrl + '/' +'auth_ldap_server' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And def result = response + And print result + Given url mainUrl + '/test/' + And header Authorization = 'Bearer ' + accessToken + And request result + When method POST + Then status 200 + And print response + + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap.json b/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap.json new file mode 100644 index 00000000000..7ca3b04ba4c --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap.json @@ -0,0 +1,19 @@ +{ + "bindPassword": "8OId4NKmlxY0eRdig9c1Dw==", + "level": 0, + "localPrimaryKey": "uid", + "version": 0, + "enabled": false, + "useSSL": true, + "bindDN": "cn=directory manager", + "servers": [ + "localhost:1636" + ], + "baseDNs": [ + "ou=people,o=gluu" + ], + "configId": "new_auth_ldap_server", + "useAnonymousBind": false, + "maxConnections": 1000, + "primaryKey": "uid" +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap_list.json b/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap_list.json new file mode 100644 index 00000000000..2c940d9b4ee --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/database/ldap/ldap_list.json @@ -0,0 +1,21 @@ +[ + { + "bindPassword": "8OId4NKmlxY0eRdig9c1Dw==", + "level": 0, + "localPrimaryKey": "uid", + "version": 0, + "enabled": false, + "useSSL": true, + "bindDN": "cn=directory manager", + "servers": [ + "localhost:1636" + ], + "baseDNs": [ + "ou=people,o=gluu" + ], + "configId": "auth_ldap_server", + "useAnonymousBind": false, + "maxConnections": 1000, + "primaryKey": "uid" + } +] \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/jwks/jwk_key.json b/jans-config-api/server/src/test/resources/json/config/jwks/jwk_key.json new file mode 100644 index 00000000000..c92b4a92a5d --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/jwks/jwk_key.json @@ -0,0 +1,13 @@ +{ + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "crv": "", + "kid": "test12345-66f1-4b4a-92ec-d969522f4cbc_sig_rs256", + "x5c": [ + "MIIDCTCCAfGgAwIBAgIgTN/ufyTSP6YI3xSN3Gv/z0eh6D+NiVjAgoHilvQmJzQwDQYJKoZIhvcNAQELBQAwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMTAyMjQxMzEwMjlaFw0yMTAyMjYxMzEwMzhaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyowxR94xQfv9qlTjtMutSLY3wKWIorgnzKZzAyEscNxqke6YwE+DsZ9OM5Zo3nk5LZpyJzJKk0jgL3ZR616j5j5d6tCmKt2DCQjnkeJjSRZz9A0XAE2RLW1taX37zKhtTNE9LJ4Wr/P3EioiW7Ax0w6QpBxbGFNmJ+HhzQrR8sXv8TtB47e1a/Zx/4lSx96VaVxaN8JQNGOlE5xcxUyzLZ64gdOEq8Igvt8R520jxMnguS5cNWR9ooZdyz13ujc+YYw2axFfTL96FDOUK5syXT52mF0XLcwPX2YTcKkTrIESiPNiSODqQMIxjs9MvJBEcJn8elBjrbltyb0yjBpV/AgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAEBQVhijiNBC90nU0WNVsWeuoady7/XgQ0an0CKrmvrRTw+nVRWa8UxS5LJu6I+/GIsHs5P8NBN9/slUZJQ2+tAai2ZNyxm+c63Y3KY5Tth9bxVugJzFKNpbFh7zqQ9mlTkYierrhyzwk5iXRmtkDoRANwCcs0yvPN3aC0ZF+ESpUk+FlHKOzb0hpip7NumHPAHbLXpdk1SNLvr4kdYQ9ZQSuIZETBwr2bbQF8KxMEqQMY1nJuJvPLdkFS7Eg+LkfJbpKMXUwUOdOtU/HoO1njwPWhVN4xOoXalpQmTowu0yc7H2vtZPEIyKJcURgYekZGKiBWin9Z7gD6C14JB4kKg==" + ], + "exp": 1614345038838, + "alg": "RS256", + "n": "sqMMUfeMUH7_apU47TLrUi2N8CliKK4J8ymcwMhLHDcapHumMBPg7GfTjOWaN55OS2acicySpNI4C92Ueteo-Y-XerQpirdgwkI55HiY0kWc_QNFwBNkS1tbWl9-8yobUzRPSyeFq_z9xIqIluwMdMOkKQcWxhTZifh4c0K0fLF7_E7QeO3tWv2cf-JUsfelWlcWjfCUDRjpROcXMVMsy2euIHThKvCIL7fEedtI8TJ4LkuXDVkfaKGXcs9d7o3PmGMNmsRX0y_ehQzlCubMl0-dphdFy3MD19mE3CpE6yBEojzYkjg6kDCMY7PTLyQRHCZ_HpQY625bcm9MowaVfw" + } \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/jwks/jwks-all.json b/jans-config-api/server/src/test/resources/json/config/jwks/jwks-all.json new file mode 100644 index 00000000000..f97e8bc10fe --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/jwks/jwks-all.json @@ -0,0 +1,191 @@ +{ + "keys": [ + { + "descr": "Signature Key: RSA RSASSA-PKCS1-v1_5 using SHA-256", + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "kid": "dca3a91b-dd1b-47b0-b7e7-aaf2ec3b9d5e_sig_rs256", + "x5c": [ + "MIIDCTCCAfGgAwIBAgIgf95rqCSrHjanJBBTIvH3DztRlQWwj8ALPz0TBLda6KAwDQYJKoZIhvcNAQELBQAwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMjEwMjQwOTE0MTdaFw0yMjEwMjYwOTE0MjZaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRdu67/p8Gaab5p5tSDbELvb0nTVm5LmmqPjnddxPpVmYnb0Xf26D8hSCasaE1cKvzv6if4eu/e+fxTmki8qJxsiEqJCjoOG0VysjTL2FGeywaohJ6zdZxyWh3QQ0+oOAQqqIBZ3FBvfRzkCXOvIrmGZaBJHLsABBhbcjncmViFFWkq7iSiB6kmYvD1YQp1iOZoKA2ICmxoeDBrtm/AGihlVa9hGl9m3kX+h0JnlKu6jwYteZGIhjMavqeWq821BM80Td7tt563P7D+Io2mmrO7aNGXpShOedQlLrODuCFq+6mJRDdTHh8AfofsMJcX5y46B6UGNSP8Ys+rPkV44KdAgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAkVKraMEmpqsAddmnq6ow0BvpSxFMtXSXJzJlhrrai7UeidyIMD6t9VEDDwj4N5TbvXPz9YjtVC5I7/yprcoqcb63m6TM7WvkB3blVG5JCP7RvI+t2/4q+0tMf4xSmJ7/lAREpCNhFr7FV+q74R6KaLvFsVRnQyGJKpjuFWV3itskexsjWhgvagt3iScWsoquGkzg1pqyn+z3P4FxEWA55Bl3wP4g+Ys79OzrBA9d/sz81xQGFRmIB7TyDz12OyCcdWQOMVxRrgKbz3FxsscE3+Z7Ie9FVpDIqeBo/xI8/q7CCDxCHTtiTQjGS5j/XV4VcPt7i9mrQsajbndCAmynVw==" + ], + "name": "id_token RS256 Sign Key", + "exp": 1666775666429, + "alg": "RS256", + "n": "0Xbuu_6fBmmm-aebUg2xC729J01ZuS5pqj453XcT6VZmJ29F39ug_IUgmrGhNXCr87-on-Hrv3vn8U5pIvKicbIhKiQo6DhtFcrI0y9hRnssGqISes3Wcclod0ENPqDgEKqiAWdxQb30c5AlzryK5hmWgSRy7AAQYW3I53JlYhRVpKu4kogepJmLw9WEKdYjmaCgNiApsaHgwa7ZvwBooZVWvYRpfZt5F_odCZ5Sruo8GLXmRiIYzGr6nlqvNtQTPNE3e7beetz-w_iKNppqzu2jRl6UoTnnUJS6zg7ghavupiUQ3Ux4fAH6H7DCXF-cuOgelBjUj_GLPqz5FeOCnQ" + }, + { + "descr": "Signature Key: RSA RSASSA-PKCS1-v1_5 using SHA-384", + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "kid": "80772339-b845-46c9-b185-e792596d3f60_sig_rs384", + "x5c": [ + "MIIDCjCCAfKgAwIBAgIhANBQZi8WsEmLvgk+JG8y1FQGR0G61l3eGKFuVtYV6tciMA0GCSqGSIb3DQEBDAUAMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE3WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm4T1IBZXVtek7bLlVmU4yy8qjI/1dipnS4TfB0C8gIN2Q2dB0aw4ee6DqrWfw+HblhJDamBdtm28k8LVDkbOC2E3dLhfiOXKtiIynvFO9kD3kPKrHwJ7OpsLow7CJoAG7usd5iPREeno/MyfchQBMT7FbtIwJ5tkU/kaHVPcaGL1yXcYwW7Pd+MmMhJn10jMgjsp1Ox2fRGPL8UBj98ppoOJV+cX0+X3R/YkDSSdEhrb27/strpxrJG3Xy5uh4O055+hlUn0aaIV1Nr1P6+62g1e3s8EyK7fZnM6kbxQkhN/VdNpl0CqSSqN0H/aQsoPTM+57h1kFEPWdHbQPAoaBwIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQEMBQADggEBAJIgf1diGfhmTmxzlKt0jHv0ATCzeIBCLBQrUF56KyOzsObouQxL3RGfak7EJLxWhC9eND9DyWpk3sQiypm4LHDrFDNcZcQ1ZCiFcd6/LGoTsNgT3cAaQdflBNTrkuhQPPHW6W4ZxoW75krliZAsp9QvWbu8BJB98kF4EfkfexwJ22hvoe/Eu9uO2/QE0mnw03U+WpVOilGNpsAoqbRZ1AFNNRaIeH/1aaT/ChxcLyvLaas/Q02D/p6jviWkgRYM2mIBSvgleHKQO5wzCVsopbYpkFogYpTNf6q6CMXncvmOBB+g+IXT8gKC2Mc00FWUuDIFUgJCRX7QpoFFXwql5/I=" + ], + "name": "id_token RS384 Sign Key", + "exp": 1666775666429, + "alg": "RS384", + "n": "m4T1IBZXVtek7bLlVmU4yy8qjI_1dipnS4TfB0C8gIN2Q2dB0aw4ee6DqrWfw-HblhJDamBdtm28k8LVDkbOC2E3dLhfiOXKtiIynvFO9kD3kPKrHwJ7OpsLow7CJoAG7usd5iPREeno_MyfchQBMT7FbtIwJ5tkU_kaHVPcaGL1yXcYwW7Pd-MmMhJn10jMgjsp1Ox2fRGPL8UBj98ppoOJV-cX0-X3R_YkDSSdEhrb27_strpxrJG3Xy5uh4O055-hlUn0aaIV1Nr1P6-62g1e3s8EyK7fZnM6kbxQkhN_VdNpl0CqSSqN0H_aQsoPTM-57h1kFEPWdHbQPAoaBw" + }, + { + "descr": "Signature Key: RSA RSASSA-PKCS1-v1_5 using SHA-512", + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "kid": "fd9389bb-1207-4c7c-88bd-9e3ab0f3f0ac_sig_rs512", + "x5c": [ + "MIIDCjCCAfKgAwIBAgIhAJDr8HefaC+vEAvJ0rfP3hOrdGwyjxYwSotcB491FLJLMA0GCSqGSIb3DQEBDQUAMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE4WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArxc+2RuMFXLcL/PTj4VybbnSET25kPb/F5NrW1/zjAuA/njkGyoKDCxN1jUcQ0PSFRWGcIPnF7eP8iU6Jf7NornY3OT318hHm6L9t6M0Hx6K+APBgAf6pNrQ7Y6EEnHMwQWPhS8tVNh/G7ckVOFtTKI0v3bvNwp2LADEsPgFoOFGo6V/YydjZrbCrFa1caTsX9WGCEPa6qZYTZSbCWCLR/1NwJ2EuFyTNs2UetLa7kCTv4NfCwjaXCwvH5EVbpUr/PY8CvfuacFSFdvkx0TKlwIcRvOxSL3XfE7dDVZ6DoaMax/sVdJ08U87F2KhhROPf+wrMN1vkVUE6VEkMY+0JwIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQENBQADggEBAEzw9RrC+kQ4Fyi9edL5b4f0YiQqCXPQeGXeiRAs+aFvZVvXwx2Idt4Ah5HBs7oGey1Yaoj/GNLxBe5iMd1sGk+QR7q6wtxAIr1r0ARAdVxlM8wEOtYAgIZqbRkv73gMyt5nDLPKhQMhDwRPpBT3iKhnGF95B2Q0FbkqJCLXY4KMfVn1ANNao3jUFeT7kbZF3nTH80y2iuyP2v8w6RjY8ko378D/Knp1TINX96oYbm3GCptO2DU7mykHB96hOh/KY3DivWxznaIKoKaU0FJYIAP83yITnJ8qkjeXOipTb3fvMYRg/ki1kBiiD8V+GI0p1MjRtdAtp6kmWmQLZg+yHRg=" + ], + "name": "id_token RS512 Sign Key", + "exp": 1666775666429, + "alg": "RS512", + "n": "rxc-2RuMFXLcL_PTj4VybbnSET25kPb_F5NrW1_zjAuA_njkGyoKDCxN1jUcQ0PSFRWGcIPnF7eP8iU6Jf7NornY3OT318hHm6L9t6M0Hx6K-APBgAf6pNrQ7Y6EEnHMwQWPhS8tVNh_G7ckVOFtTKI0v3bvNwp2LADEsPgFoOFGo6V_YydjZrbCrFa1caTsX9WGCEPa6qZYTZSbCWCLR_1NwJ2EuFyTNs2UetLa7kCTv4NfCwjaXCwvH5EVbpUr_PY8CvfuacFSFdvkx0TKlwIcRvOxSL3XfE7dDVZ6DoaMax_sVdJ08U87F2KhhROPf-wrMN1vkVUE6VEkMY-0Jw" + }, + { + "descr": "Signature Key: ECDSA using P-256 (secp256r1) and SHA-256", + "kty": "EC", + "use": "sig", + "crv": "P-256", + "kid": "1b4a4c44-4663-40f7-9e49-4cf1ccd91568_sig_es256", + "x5c": [ + "MIIBfTCCASSgAwIBAgIhAOxqrUaVo0XVfNvwDGt3NJE3YogX4hEHdqIGj3YRMP2+MAoGCCqGSM49BAMCMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE4WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfoM8AxICX7x9LBqZEVi7ggEu4nLiZdwojMKyiNE6dNFUALefe9ejqYGqxg2ISXjcfZKSsH/0h4woqt8MxSdTk6MnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMCA0cAMEQCIFvH+2Ix3jeHqw0hcm83nnIDuXE2Fk9mSlQDUGEOCUfRAiAGIEcVUqvPBiexpPJB+Tyl+6JeIwOI5DnsIRIdZtMM6Q==" + ], + "name": "id_token ES256 Sign Key", + "x": "foM8AxICX7x9LBqZEVi7ggEu4nLiZdwojMKyiNE6dNE", + "y": "VAC3n3vXo6mBqsYNiEl43H2SkrB_9IeMKKrfDMUnU5M", + "exp": 1666775666429, + "alg": "ES256" + }, + { + "descr": "Signature Key: ECDSA using secp256k1 and SHA-256", + "kty": "EC", + "use": "sig", + "crv": "P-256K", + "kid": "a2dbca16-4a7b-458a-8324-f866553c6135_sig_es256k", + "x5c": [ + "MIIBejCCASCgAwIBAgIgHPM2yIWT0/QoSffQsYMN9sCda5tmotFqdmob2inDou4wCgYIKoZIzj0EAwIwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMjEwMjQwOTE0MThaFw0yMjEwMjYwOTE0MjZaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwVjAQBgcqhkjOPQIBBgUrgQQACgNCAAQ/9BpgfKOdeRi3L3n+Mmat4KiGIJunGWnkQg6Wa6qPFtI+qlef2USK4lwRrSf+TxvR9HsaCqq4DkgfKXTzbxl7oycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwCgYIKoZIzj0EAwIDSAAwRQIhALew2FxbJ+7Khafw6pQg8IqKGp5/vUDRErpr9f155noBAiAcWi3sczGMC1Y/kwZDcjRVcCwNS1uOzSzGkX3xQPUS4g==" + ], + "name": "id_token ES256K Sign Key", + "x": "P_QaYHyjnXkYty95_jJmreCohiCbpxlp5EIOlmuqjxY", + "y": "0j6qV5_ZRIriXBGtJ_5PG9H0exoKqrgOSB8pdPNvGXs", + "exp": 1666775666429, + "alg": "ES256K" + }, + { + "descr": "Signature Key: ECDSA using P-384 (secp384r1) and SHA-384", + "kty": "EC", + "use": "sig", + "crv": "P-384", + "kid": "4b8c4a4d-ed06-41d5-a395-c9fe310aa1b2_sig_es384", + "x5c": [ + "MIIBuzCCAUGgAwIBAgIhAPkMA75M75uGAw4sOLj1qJZRGN3+Drjtf/+7D6A/mNGvMAoGCCqGSM49BAMDMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE4WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEmOyHruRxia8lKckotlkp8GA038ouYZTQslucQCZRbC6zZGEZturw1D7Sd7z5waIa4mKFTX+E1j8OEKbdPbGBE6/MaiQXHUTnWhsyAhofPHyLye76zrRgNjLmnfFYon6HoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwCgYIKoZIzj0EAwMDaAAwZQIwOkXPAea4Q/XeUFn5pEndSiO2oIPIL+vGdWZ98eqE72wMp1t0B9iVfICLvgHmKgkjAjEAlqWlICL1/45Pn5hFOs3z6UB0isZy9JA8dd1uEljfcmZv9PjBAa2Of7VkRYxFA7YP" + ], + "name": "id_token ES384 Sign Key", + "x": "mOyHruRxia8lKckotlkp8GA038ouYZTQslucQCZRbC6zZGEZturw1D7Sd7z5waIa", + "y": "4mKFTX-E1j8OEKbdPbGBE6_MaiQXHUTnWhsyAhofPHyLye76zrRgNjLmnfFYon6H", + "exp": 1666775666429, + "alg": "ES384" + }, + { + "descr": "Signature Key: ECDSA using P-521 (secp521r1) and SHA-512", + "kty": "EC", + "use": "sig", + "crv": "P-521", + "kid": "a9a729fe-3dfa-473d-b6ec-f9e3907d3b9b_sig_es512", + "x5c": [ + "MIICBTCCAWagAwIBAgIgSBMzUCcQQTNTP1stoDO8OnNQg3V6pJ0l/UOxCzmoboIwCgYIKoZIzj0EAwQwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMjEwMjQwOTE0MThaFw0yMjEwMjYwOTE0MjZaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAEegoUizxm3wdtpHpyP1WTjW7Y5VgI2eKVOKl4FiJCY3fxehtXVeqArFiYCo+RljGBAq2f/dttNcOO351Fi0Nc95wB7JCoJeq/a84fbTrc8W5XZ1+HnU06Y0FGITZbpghowox1pzSmOrMI+vyjVtgHTB+uDd8+yucUrKbr7N5LTBq1wyKMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMEA4GMADCBiAJCAJgO51ZIw9yv0jEkxj9pESaEJAiAeIkRXr6YojILE4P4hSJtbcRV3sZ7zFhOIc50OEmqBOZYlOTpH2Z4wkXfkQ7KAkIAq3Wfr1uRUKF63RGp9R5RDhRsX8RgKe3ze1O5E86uRe8Y/fRd4eFs1i0oaIUwJ2WOxkY4VTty6Cu7B6pGHrB+vqQ=" + ], + "name": "id_token ES512 Sign Key", + "x": "AR6ChSLPGbfB22kenI_VZONbtjlWAjZ4pU4qXgWIkJjd_F6G1dV6oCsWJgKj5GWMYECrZ_92201w47fnUWLQ1z3n", + "y": "eyQqCXqv2vOH2063PFuV2dfh51NOmNBRiE2W6YIaMKMdac0pjqzCPr8o1bYB0wfrg3fPsrnFKym6-zeS0watcMg", + "exp": 1666775666429, + "alg": "ES512" + }, + { + "descr": "Signature Key: RSASSA-PSS using SHA-256 and MGF1 with SHA-256", + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "kid": "75b6b370-d447-4c8e-8912-51d8bc95d6c6_sig_ps256", + "x5c": [ + "MIIDcTCCAiWgAwIBAgIgEKm7QdjAhBGEbX3TB3f6EsOCZgFNbEukvE8Cz/Kl/JswQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE5WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1FF6FSbVQKH7crwTPprDQlmo7wQ+47HaVLv+4gR3izZFgrLdezpexWvafKzghHhZO0YFge9hY+jx0lVy0fltFVULRucexhHIANAIvvL9aDorRPnbMV2EG4Yv0Xsy4ZC3fjNi5SidYydlYL8XL4jpdS1L58hWQzAL5uagojvwIlJ1H8m+aUTR8LyOecNjSar/jB/h6E8h/e1MCtqX56KD6F4euGAqDbt3GJsoUP+qch3RoPZdNxlY2wYLrprz7GukUvrZWgpX5dVVtrJkgYIVuNT3EtHvseL4SYkY7DGdR51ov2pu8dvAQ8x6Jyc/XXtNVzUF/rYPQfJkdYWlrMATmQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgA4IBAQAile70cfWTK+dTQOi6LWdN6ldAyieXOK9SsVN0EgQMhmLlXQlCGjRzypCrG0m778T/fqhT6ENlJ5jvIXfaCiq3bjrf6350fV9/70QBIvSGBa/SVwll1Y9464sB1BwCNd9DAvV0wPmEw7fwyW+Uh6PceNP4zOVfBReoP8kWFMhzpkbm0KwlAnJoRWniUt10RJqOWOUgvYpu4vWhy9EatSZMYxswRxuzW2JAFa7otOXbK7mCElboNIua9v4751N5HqZLmmOOpvKFTlbqzM5WHkWTfROfrm9cqpQWShg5uiuzjBBQiPiskrEjYRw+fQs3zDSbvIEdrx2FeAjuXCMoqyWQ" + ], + "name": "id_token PS256 Sign Key", + "exp": 1666775666429, + "alg": "PS256", + "n": "1FF6FSbVQKH7crwTPprDQlmo7wQ-47HaVLv-4gR3izZFgrLdezpexWvafKzghHhZO0YFge9hY-jx0lVy0fltFVULRucexhHIANAIvvL9aDorRPnbMV2EG4Yv0Xsy4ZC3fjNi5SidYydlYL8XL4jpdS1L58hWQzAL5uagojvwIlJ1H8m-aUTR8LyOecNjSar_jB_h6E8h_e1MCtqX56KD6F4euGAqDbt3GJsoUP-qch3RoPZdNxlY2wYLrprz7GukUvrZWgpX5dVVtrJkgYIVuNT3EtHvseL4SYkY7DGdR51ov2pu8dvAQ8x6Jyc_XXtNVzUF_rYPQfJkdYWlrMATmQ" + }, + { + "descr": "Signature Key: RSASSA-PSS using SHA-384 and MGF1 with SHA-384", + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "kid": "5006e6f7-bd41-4228-b413-236a6cd06e8f_sig_ps384", + "x5c": [ + "MIIDcjCCAiagAwIBAgIhAKe3eCpsdD8vEST+NTE0TjTApnfWOb3YiL7ihGnGHSpxMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMDAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMB4XDTIyMTAyNDA5MTQxOVoXDTIyMTAyNjA5MTQyNlowJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANHPn1MC1924tZBa4bf11TGqN7nrx/DWruol56RP7tts1kku5jbGVNVsUSseaAY7n5vAxxuxM8EEBnKkIIj/Z76s0RvG0N4RReua3qclpN0QUqxXtm0uugDs4P11nZwX7yZ89DHCWEr4lqG0Bp5sMR4fNWpx2ULpJOGNZKmcIYMmsYueJv8w5Ndg4Z5NDY1R6OGr642/bhowvQy2SX3cDQFV2sOM41DOxDQYwoAWZ/BJoroV9dKgNwKV8Wi/LTCBqLcH1uh3ffWLCoQqHWFZ5HGn+sN5xUiOeKHpIiQBAfX6rgbDrdBFeYWptrSSIPMVMIW5MrJpeTvdwxER/LeuqHkCAwEAAaMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMAOCAQEAQGXNsTojD8CGZ5rtETY7IQc3VskiPGzoHRTmgUqWP1sB6RwZKPrLdqP/CUvcKjwrxfALjhiB689l0Ec8qw9YzBzXB+qHc9JS1QnmRjmPAggShRajTxbyMIdHrQayGjZ+D4gvR8lPGGlbWM/KuNGBEouq5EH4lfIvPQdcgxutwqAtMxpSwIS5nlREsSAPoyO01aywcaQgeHFNhZX5xH/U1Rdt5czF00S/AgC5PYxVzlRDpnThMTjOu/zuOTBdGbjtnC4qP1YITn6EdCtp2pGQ068pArnjGIgSSxmDWISJBTBE6QwUgNX9J7V3B6Hxg6YU12WMvbXFTEikJRVtULbnuw==" + ], + "name": "id_token PS384 Sign Key", + "exp": 1666775666429, + "alg": "PS384", + "n": "0c-fUwLX3bi1kFrht_XVMao3uevH8Nau6iXnpE_u22zWSS7mNsZU1WxRKx5oBjufm8DHG7EzwQQGcqQgiP9nvqzRG8bQ3hFF65repyWk3RBSrFe2bS66AOzg_XWdnBfvJnz0McJYSviWobQGnmwxHh81anHZQukk4Y1kqZwhgyaxi54m_zDk12Dhnk0NjVHo4avrjb9uGjC9DLZJfdwNAVXaw4zjUM7ENBjCgBZn8EmiuhX10qA3ApXxaL8tMIGotwfW6Hd99YsKhCodYVnkcaf6w3nFSI54oekiJAEB9fquBsOt0EV5ham2tJIg8xUwhbkysml5O93DERH8t66oeQ" + }, + { + "descr": "Signature Key: RSASSA-PSS using SHA-512 and MGF1 with SHA-512", + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "kid": "bdc7de11-eeac-4814-a0f7-f02e5fe32005_sig_ps512", + "x5c": [ + "MIIDcTCCAiWgAwIBAgIgXxNyneXLuExN4eVmjyegbb5qwCC4KUomlf8LULpGwGQwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDIwWhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA93X7DgguE/GPsC5vpQa4yOnfyxNQAEzW9iaTjPAkcazuajvbPwXtk7l/BxBEWBtyFoIkMytWh3vyFQpSSYwEIOak5XSwSGBqynDOx78Xcqy6LhYv101YRItNhNL+0fGkLVqAJLYBQM3x4/e9wooilFTOtq9CbqYBV4wUZC3BwmMUGBr34xYWAyCdJfzgzDtm5vAxg33AaGbUQbh2yM3j97Eca3G6JxhNkAYriJfaycGr4vpmU5WHGcceccYSdiPBxxKblS14yB9WZsuBEciw2BVVhS+7oYYbPfimpUw9uNi4uQZkjoFk3ECd468IAKxEtYXBAMZok39irvaPnK6RGQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAA4IBAQCpr43l5d0qA/rljv3kOBz46o0nRMHw3UHqze/AaVeaOhAEMCmncgOrfjKNJmdcE1fW3kL6WEJ6PTF77/v26xb3xWX5nrbbpnftJ2iEXZk1lqhRCiccQv8EFIaLt1xuTw9nmMeUIRIsTE5rEbFJfzI5hEfQ9Kmeo4ZbW3qUuuaWiNsSR6HihuxekG8K4Y2ap6JwvLWaTSk7t2U96gjvUmkEWEaBjqexBhxNE5vPH3oCJj4132EWm364OCZbe0mT7e0eId++6G9EoO9hS7eu+NaRG2K8HvSgMC6C67VNHVoDy8m5niax8XBcqTM8mj8fkJ8C1y1TU0awlrNTTk4q5Rgz" + ], + "name": "id_token PS512 Sign Key", + "exp": 1666775666429, + "alg": "PS512", + "n": "93X7DgguE_GPsC5vpQa4yOnfyxNQAEzW9iaTjPAkcazuajvbPwXtk7l_BxBEWBtyFoIkMytWh3vyFQpSSYwEIOak5XSwSGBqynDOx78Xcqy6LhYv101YRItNhNL-0fGkLVqAJLYBQM3x4_e9wooilFTOtq9CbqYBV4wUZC3BwmMUGBr34xYWAyCdJfzgzDtm5vAxg33AaGbUQbh2yM3j97Eca3G6JxhNkAYriJfaycGr4vpmU5WHGcceccYSdiPBxxKblS14yB9WZsuBEciw2BVVhS-7oYYbPfimpUw9uNi4uQZkjoFk3ECd468IAKxEtYXBAMZok39irvaPnK6RGQ" + }, + { + "descr": "Encryption Key: RSAES-PKCS1-v1_5", + "kty": "RSA", + "e": "AQAB", + "use": "enc", + "kid": "49a80d60-c3da-4930-baae-75c1a93db1bf_enc_rsa1_5", + "x5c": [ + "MIIDCTCCAfGgAwIBAgIgf8De7cNPhPeX2SjsAhznXmKdMsyf5ErgdO0Q7NhZW/YwDQYJKoZIhvcNAQELBQAwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMjEwMjQwOTE0MjBaFw0yMjEwMjYwOTE0MjZaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfGSbYMhG6yMgyH+aFZko259ax4BX8rTKWCz4jhkZNtHNroEs7WNJoYbbyF0AFhL91oY1YM4EkqG9e+FB7/r9v2H38yu+9rkuXeYZcEqPKCd0EJcgGYFjGga4wj7sqygcZprl9bho3OnHEaHGonMNxcEzac32B1Pg0O6SLCKzUpB+JBeL21Xu4grAuc2DFNq7TkOYd341KTUZO6rDKIBszKJCfTd8Su7HvkaCsSDSP0o9uCGeCHDWIVReU840uOLGcv2ldwOOKwbt97ZyT7/01xQjS8A8XeMH+b+aKTEk5bR08o6CST26Q/ddjVnieCXc4ztAYYuLYzNc0j2MPwAy/AgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAVYCgI+jzc4MpfQa5mmiURvAt8yIPQQUKxEFeZAVleKrxKn0pPe2gJKOjFj8LqL4Jjz6Pzys3ERiQJu7fSfQHGqN7VL1x3K5wUZDWUTq25Ci0YL9gH5ByAUun+MN5uSKTNHHEUafgq5fhN4n4WRq4SPZPkieKvPPEv1PjT9cVmt8+kFLR2xiaJhLYz3z5qQzrj4BhbIwbqby7R329l8EBUrA0xLs8G65sHtCGTU33OdBmP38PvIPdVHjAed08LG+QfjLO98qE7fvGhx1HmnH1BifAOpLZsYu4zkTUF3ufcBYvdDpgwBOgjN67esi5qMMP/6OBXi0K2tsBz3mwpdGPUQ==" + ], + "name": "id_token RSA1_5 Encryption Key", + "exp": 1666775666429, + "alg": "RSA1_5", + "n": "nxkm2DIRusjIMh_mhWZKNufWseAV_K0ylgs-I4ZGTbRza6BLO1jSaGG28hdABYS_daGNWDOBJKhvXvhQe_6_b9h9_Mrvva5Ll3mGXBKjygndBCXIBmBYxoGuMI-7KsoHGaa5fW4aNzpxxGhxqJzDcXBM2nN9gdT4NDukiwis1KQfiQXi9tV7uIKwLnNgxTau05DmHd-NSk1GTuqwyiAbMyiQn03fErux75GgrEg0j9KPbghnghw1iFUXlPONLjixnL9pXcDjisG7fe2ck-_9NcUI0vAPF3jB_m_mikxJOW0dPKOgkk9ukP3XY1Z4ngl3OM7QGGLi2MzXNI9jD8AMvw" + }, + { + "descr": "Encryption Key: RSAES OAEP using default parameters", + "kty": "RSA", + "e": "AQAB", + "use": "enc", + "kid": "55aed597-4fc4-4dc7-babd-e1acf672c3c8_enc_rsa-oaep", + "x5c": [ + "MIIDCjCCAfKgAwIBAgIhAJESxnSQz5Ejg+hW70GYN7yOFQdtTxwpmRNGnq5ff/H2MA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDIxWhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1VVP4NEBRujsnuKZg4jqJBE51GVfgScBT9NLgkF3IErXZ7RL0XrOCD4wqhMQw7DREw9cQpumJ9Qi0quuAPWIjhfoslvTVLa8TlzpHky0xv10FFtB28Tf6n0BK7nYe/UJaQlbQYCO05VPlD8lBU8vNkNVA8ZS7KqWdoQQfZY02Y9CEsyLu8t/PRsP/6UrOhl1G6aGupvKVUeD9NFLubmP31MycJIG6EhdjUc1VLfjEcNHeQ7Py1w/BjWT2JX3aBBeQIICCrlG2gUGad4/01kk24nHY69wdshQ4LnjIRwoaALC4SI33ndsUEzHvWHTD4Wild+JJ+xp0efydRrSoKd89wIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBAMuwBGIPL1epfF5GnIU3XlKs91c9AbnsSxpW/zv3un+ptaYF5qCv9LlMaGx3r9d6oOj6wmf5A1sFEUuE0U+TMwoR7KS+flOrEfaCMi0qUbg245Lc+2tsnVVV133qXnsvRYig325WFC469ECjumeDjd0HKZIcs7qLQN//J3+uA0d/mKgW+fqkGO50qGGd6n8Emw4Gas3SUxqal5Yh1nnIPaVy7holjAO8Jsgjunf1s05EXWzL8BQm+qYiiuYPQM+Zm0I69fmo7GB55i9h8ejf3tQ6iAY7gfRX1c1zCpR7CvwE4iqujOvc61y8aFfTdC1rg+/YHsZnTrxaToSJKBo98uA=" + ], + "name": "id_token RSA-OAEP Encryption Key", + "exp": 1666775666429, + "alg": "RSA-OAEP", + "n": "1VVP4NEBRujsnuKZg4jqJBE51GVfgScBT9NLgkF3IErXZ7RL0XrOCD4wqhMQw7DREw9cQpumJ9Qi0quuAPWIjhfoslvTVLa8TlzpHky0xv10FFtB28Tf6n0BK7nYe_UJaQlbQYCO05VPlD8lBU8vNkNVA8ZS7KqWdoQQfZY02Y9CEsyLu8t_PRsP_6UrOhl1G6aGupvKVUeD9NFLubmP31MycJIG6EhdjUc1VLfjEcNHeQ7Py1w_BjWT2JX3aBBeQIICCrlG2gUGad4_01kk24nHY69wdshQ4LnjIRwoaALC4SI33ndsUEzHvWHTD4Wild-JJ-xp0efydRrSoKd89w" + }, + { + "descr": "Encryption Key: Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF", + "kty": "EC", + "use": "enc", + "crv": "P-256", + "kid": "0270a2b9-1200-42a2-9b12-e2fa89ce3bd0_enc_ecdh-es", + "x5c": [ + "MIIBfzCCASSgAwIBAgIhAIa6KUAXzFx537jBtB37JqtIquhWWkoqWtMzoDCj24LxMAoGCCqGSM49BAMCMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDIxWhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZx77ZxYm0XJKNpgxChTlK+NBJAtpZ+jWGjaXDFYgt3+x1IAktFvlkQraoWlJuQx+LfufqhL3Lm83ZetMowqKWqMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMCA0kAMEYCIQCT6uXIMyOg34+khFbRbrUxE/ozSVu3tE24Ofz3eFhtBAIhAINgdWN86TOOEAUXUr2ijmaAPBgn7mGoeg4c7FfyZTxn" + ], + "name": "id_token ECDH-ES Encryption Key", + "x": "Zx77ZxYm0XJKNpgxChTlK-NBJAtpZ-jWGjaXDFYgt38", + "y": "sdSAJLRb5ZEK2qFpSbkMfi37n6oS9y5vN2XrTKMKilo", + "exp": 1666775666429, + "alg": "ECDH-ES" + } + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/jwks/jwks.feature b/jans-config-api/server/src/test/resources/json/config/jwks/jwks.feature new file mode 100644 index 00000000000..89d7fe0bdfb --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/jwks/jwks.feature @@ -0,0 +1,85 @@ + +Feature: JWKS endpoint + + Background: + * def mainUrl = jwksUrl + + Scenario: Retrieve JWKS without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + + Scenario: Retrieve JWKS + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + Scenario: Patch JWKS with new key + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And print response.keys[0].exp + And request "[ {\"op\":\"replace\", \"path\": \"/keys/0/exp\", \"value\":\""+response.keys[0].exp+"\" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + Scenario: Put JWKS + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then print response + Then def first_response = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + Scenario: POST, GET, PATCH and selete a Key + #Given url mainUrl + '/test12345-66f1-4b4a-92ec-d969522f4cbc_sig_rs256' + #And header Authorization = 'Bearer ' + accessToken + #When method DELETE + #Then status 204 + Given url mainUrl + '/key' + And header Authorization = 'Bearer ' + accessToken + And request read('jwk_key.json') + When method POST + Then status 201 + And print response + Given url mainUrl + '/' +response.kid + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + Given url mainUrl + '/' +response.kid + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And print response.exp + And request "[ {\"op\":\"replace\", \"path\": \"/exp\", \"value\":\""+response.exp+"\" } ]" + Then print request + When method PATCH + Then status 200 + And print response + Given url mainUrl + '/test12345-66f1-4b4a-92ec-d969522f4cbc_sig_rs256' + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 diff --git a/jans-config-api/server/src/test/resources/json/config/jwks/jwks.json b/jans-config-api/server/src/test/resources/json/config/jwks/jwks.json new file mode 100644 index 00000000000..aaa2ac85f6d --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/jwks/jwks.json @@ -0,0 +1,113 @@ +{ + "keys" : [ { + "kty" : "RSA", + "e" : "AQAB", + "use" : "sig", + "crv" : "", + "kid" : "b9570bfb-276a-44aa-a97d-667b57587108_sig_rs256", + "x5c" : [ "MIIDBDCCAeygAwIBAgIhAOviRkmppgF16wC7nMg17Jt4P7lNoLglfLDxLAPYn4J0MA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjE3WhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzj1NEHyGk/ywG25py2s/zVVrRggzRO0jE6VOUvqUzsEJwt1aszQ4onFu6vgtjNwq2ZmEFZbw1Jw7dlz4Xrdj12pQlLVuEhyVaTziQp3LvspqxyACHQb8XSKFdKZaa1eBF8PGN5zDN/d+tIrAZYnQS2gH8BoPIuB3Z9AoCLTzifnPvmOwW/e+/Wags/ApZiEfF2Po0InV5NeJAyoIpaGhlwjqqOWXm/GpCASAk9ZD8Ebnmy9RM71zDCgmvq/hPueKnbNTZdQ3TQdzEuSwxbWEHu16v5MbF7QtNzvFSFlllhgwqI2ccEljDbs18j3DUS2B1VTTAr/DLR3SVyCYbKBbRQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBADaqrfVH1FX0FLp99TG9fHOiOMD12vsIPANb9QbIADineFrSvUI3zIX56PpvMT+EApaLPcIYSwG1YziWT1oGDGkfyinofSRGl4JcC63slChUBfjlBZlXTIlc7CJA7CfzO6BW3SvO0GPF0NStCUD9Ou4oOVaIc3XrPzhIAp71cF9iLFnQUK1hiD9NhQUm5v2Nq+sQdjAxSlqigXnc+rB9+V8snCkr9x9q1cysq1ZyCRT55psa53Irqtc50T2PHA6kyzEVW51+yFaZa8z+WMoofr6ndx2DFI7n5+8jFGs9WoP+/zV8E/XK61iy+EdXVjXQYVcArjEzeIahn8QOd/hUcfo=" ], + "exp" : 1599751946863, + "alg" : "RS256", + "n" : "zj1NEHyGk_ywG25py2s_zVVrRggzRO0jE6VOUvqUzsEJwt1aszQ4onFu6vgtjNwq2ZmEFZbw1Jw7dlz4Xrdj12pQlLVuEhyVaTziQp3LvspqxyACHQb8XSKFdKZaa1eBF8PGN5zDN_d-tIrAZYnQS2gH8BoPIuB3Z9AoCLTzifnPvmOwW_e-_Wags_ApZiEfF2Po0InV5NeJAyoIpaGhlwjqqOWXm_GpCASAk9ZD8Ebnmy9RM71zDCgmvq_hPueKnbNTZdQ3TQdzEuSwxbWEHu16v5MbF7QtNzvFSFlllhgwqI2ccEljDbs18j3DUS2B1VTTAr_DLR3SVyCYbKBbRQ" + }, { + "kty" : "RSA", + "e" : "AQAB", + "use" : "sig", + "crv" : "", + "kid" : "73d7df05-4f74-4b97-b1ad-409ac8366f6c_sig_rs384", + "x5c" : [ "MIIDAzCCAeugAwIBAgIgd+52BoAVgGuQ2FNHdDS396toOB4IR75RHW674ADcDh0wDQYJKoZIhvcNAQEMBQAwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA5MDgxNTMyMThaFw0yMDA5MTAxNTMyMjZaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPKfukpHh5egfqpIkNNmr/5XWjIcP6TkdlWARBcJfeCXDCUMBhh1SWXJgy8edPvbrMUxuQX/CorEM5LtoUgi4tHK2DRHa9IeZ8w/PYmLQipqcv7vsFbABiGvpQxYx88VDKTeH0RVzzKl+pqvqphSqj04rV6dGpNWJo7RMK3Cc6RkTtPR66neVeRi33ZJB0EyZ1TtZy8Qs5u66UaH+FkVjvWGFvXmSVc5cL3xCi9SmFwkmZPYR8B0zaUZNURDKlPEdxk8NWTdK2AsnRxGw/mS+VJjPLGinC9kGaEdzIKwCSrBwGmhlnnEKG/t3DAg2X95f+iztXrvBJDvolz9LLz16tAgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQwFAAOCAQEAy5IIlC1GFeGM2s8twBCZ04WmusrOlgyNDBCaji5LonAQWJobIVRr4bztjHJvPGa/bm5v1rVWf0Pafs9A2m81EnGl49UtrvGnOv/wvuHHoU+gbZJBLU2odTRegwlk1pnLDngd5SAPEM8+KhwtSKWYBZMlN2rZfbQ0MMW98DvNqsKUJzzQa46+NUhDalEphWxRdBRoN2NuZE35tSkiLk2sSGcHtrOV42lMa3nhEUFcfe+BsIflK5KxaWP5VNaCkabPUlBpcvxrQDWXDEmhVIADi4MzeiNO4BESw3u3L5zO19GozDi45UOqTQzhSEi+SZphi8Ylhet0Ol/9+jr/4OIHrQ==" ], + "exp" : 1599751946863, + "alg" : "RS384", + "n" : "zyn7pKR4eXoH6qSJDTZq_-V1oyHD-k5HZVgEQXCX3glwwlDAYYdUllyYMvHnT726zFMbkF_wqKxDOS7aFIIuLRytg0R2vSHmfMPz2Ji0IqanL-77BWwAYhr6UMWMfPFQyk3h9EVc8ypfqar6qYUqo9OK1enRqTViaO0TCtwnOkZE7T0eup3lXkYt92SQdBMmdU7WcvELObuulGh_hZFY71hhb15klXOXC98QovUphcJJmT2EfAdM2lGTVEQypTxHcZPDVk3StgLJ0cRsP5kvlSYzyxopwvZBmhHcyCsAkqwcBpoZZ5xChv7dwwINl_eX_os7V67wSQ76Jc_Sy89erQ" + }, { + "kty" : "RSA", + "e" : "AQAB", + "use" : "sig", + "crv" : "", + "kid" : "496d7428-e7ca-4478-bfc9-11f5e03df0c3_sig_rs512", + "x5c" : [ "MIIDBDCCAeygAwIBAgIhALcfg1yR7RpfrkQxqiLTGl1bVNQ/NxR9eknVcNDVgiLXMA0GCSqGSIb3DQEBDQUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjE5WhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAumiN4IX4kRc55haCN9/gCUy4gGknS8LwGUkd53ukePnVz1qJgWGaHfkmztiepmvLmiE5f4/0eUTr5gxnFTErQtI8mL+DAIo1yrw+/9TI6+cf+JOhgPfl7P475Za8SiRg295CUCQXCInMCBh7HV0Bm5QsHzMDYdDQuGMAlEfdVB2cpKwXZ+j9Nlbx/UWeHCHuaKyyHMtGDYd1jp/bce4ix5DdlndH6OuMGQ59DwyXPMWLMgaQ+EkcX7th5TfYTEa0ZiPTEmU3nEvAm04vu2MkolPEvviKmLu1QeYsQhgMMzi17+/8ZZlp3qJWjonoeWNtG4UIqvc3Mt3Lo7p/WKz18wIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQENBQADggEBALSFKriw7UgxRztq65MaxeiqmFDla81ylVcq+NL07NMispkmhDT00F+yuSi+YyBCIh1FExBnZj6+cFGAb0mwbCOEIgpiVluy9wHzcfg5aeoZr2ZWFmJjHVzq/1b/9+X8SP5cwwFEzkYEVwOu3bMmLE1QyHZwjNKoC2d30jSV5YTZEEmIWbjb6tT+l36W72Ei4Sy0AhHYpCMEvV0AoonRN4kfgtbTv94jKbDBURI/cBeffAzgGVdh/+NVi4qzZ2t27pLwtr3R7Gqn3xpdOnB98vNch/FPVg5i2BaSm5s6+fybIBlkMqBAf58YYVeQbCIqC9Z8ATl6vTKkXYsKZTtivDw=" ], + "exp" : 1599751946863, + "alg" : "RS512", + "n" : "umiN4IX4kRc55haCN9_gCUy4gGknS8LwGUkd53ukePnVz1qJgWGaHfkmztiepmvLmiE5f4_0eUTr5gxnFTErQtI8mL-DAIo1yrw-_9TI6-cf-JOhgPfl7P475Za8SiRg295CUCQXCInMCBh7HV0Bm5QsHzMDYdDQuGMAlEfdVB2cpKwXZ-j9Nlbx_UWeHCHuaKyyHMtGDYd1jp_bce4ix5DdlndH6OuMGQ59DwyXPMWLMgaQ-EkcX7th5TfYTEa0ZiPTEmU3nEvAm04vu2MkolPEvviKmLu1QeYsQhgMMzi17-_8ZZlp3qJWjonoeWNtG4UIqvc3Mt3Lo7p_WKz18w" + }, { + "kty" : "EC", + "use" : "sig", + "crv" : "P-256", + "kid" : "d367d67d-b37f-4b08-81fa-84b4c987afc3_sig_es256", + "x5c" : [ "MIIBdzCCAR6gAwIBAgIhAK2emGoVz5nJlXKsXFMxmTMBD9GmfcrPg3FRxKozPyg3MAoGCCqGSM49BAMCMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjE5WhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE18KafCZYAgursgoHnU1ut2UUV6SKr/kQ44WLt0IzJFXoyz8GtsXvqjzV9rkcHUEkV6AyhyL9Z7sVgn9253jQhaMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMCA0cAMEQCIFURCwsdDwk+OmV2ut1h50EwqZsbjLJ8JOy0GzcbXX/tAiAK6/vJ35TNS7xpO+fGb9ICjn1KzCeGFWMrIsC6eZWzug==" ], + "x" : "18KafCZYAgursgoHnU1ut2UUV6SKr_kQ44WLt0IzJFU", + "y" : "6Ms_BrbF76o81fa5HB1BJFegMoci_We7FYJ_dud40IU", + "exp" : 1599751946863, + "alg" : "ES256" + }, { + "kty" : "EC", + "use" : "sig", + "crv" : "P-384", + "kid" : "6e8830e0-7a8a-4679-8256-663b6890374c_sig_es384", + "x5c" : [ "MIIBtTCCATqgAwIBAgIgERC4xtLgpnMCjW2lXkb1YumMfwcUzpya5JDczd8Cp00wCgYIKoZIzj0EAwMwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA5MDgxNTMyMTlaFw0yMDA5MTAxNTMyMjZaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7K1xIcfy6p3Nv5W4vCIChYsAkLWl4q06TwYWGXlK9NFnNAd/z6QHLf1KKeLCAk6IOT1xhSEJmtLr+dX89JxyJV8pEGPJgb3jAq/kUjAiV53XZgKPKl490K9h/gEYo6qOjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADAKBggqhkjOPQQDAwNpADBmAjEAnYoxgRlKV6wCfkLZfRbtMXaMTk7Cb3IEyVd2/hzOoYRku7f3GWOmYnWHX7QiLzBQAjEAtPC4FqrmU4OSE/htC3d+grKop/cx9fc68Re+lJx8mvV5qbbJ4jsMJRkDvWdtpxxF" ], + "x" : "-ytcSHH8uqdzb-VuLwiAoWLAJC1peKtOk8GFhl5SvTRZzQHf8-kBy39SiniwgJOi", + "y" : "Dk9cYUhCZrS6_nV_PScciVfKRBjyYG94wKv5FIwIled12YCjypePdCvYf4BGKOqj", + "exp" : 1599751946863, + "alg" : "ES384" + }, { + "kty" : "EC", + "use" : "sig", + "crv" : "P-521", + "kid" : "fc52f71c-5677-4621-9b86-5d4264d4cb89_sig_es512", + "x5c" : [ "MIIB/zCCAWCgAwIBAgIgRs3ZEs9bIWkIGKve8Y0hwYKUnjdF5gaNbPKiBUlkiDUwCgYIKoZIzj0EAwQwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA5MDgxNTMyMjBaFw0yMDA5MTAxNTMyMjZaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACetWweGJigofZcb4UBiLdbL7TuFhEfJUXKIQZDau5Gm+2vpxXvwn/++xwB4XbWwRifBzfE04HQk260jc2hovD14wFKMV1KG3S/gRy0uJs4zcC03ZJNvDYseEwU4+wcLf1jipD5tlwLNUXwlK2cQpo8USu+nvkA8dko6Qa6kxd26SfMB6MnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMEA4GMADCBiAJCAOc7jyzI5I6LoOeSxPqGBOsw1LXEQ9Y5JYy3vQbZnCTMkBp3YNl0kqC5YGeqphfK+kolAHlzXmBEwWJssosXHVpSAkIAg6vBNorRjZxZ9n8j1WJuNQJpw8mcUKi3S9HPtxjaix8WD3PAI9Ale4++2qqcL8IN7+X6cGV555SIrU4t2RKT5/c=" ], + "x" : "nrVsHhiYoKH2XG-FAYi3Wy-07hYRHyVFyiEGQ2ruRpvtr6cV78J__vscAeF21sEYnwc3xNOB0JNutI3NoaLw9eM", + "y" : "AUoxXUobdL-BHLS4mzjNwLTdkk28Nix4TBTj7Bwt_WOKkPm2XAs1RfCUrZxCmjxRK76e-QDx2SjpBrqTF3bpJ8wH", + "exp" : 1599751946863, + "alg" : "ES512" + }, { + "kty" : "RSA", + "e" : "AQAB", + "use" : "sig", + "crv" : "", + "kid" : "d521319b-072f-4ee9-8424-03c36ebf2d73_sig_ps256", + "x5c" : [ "MIIDbDCCAiCgAwIBAgIhAK7FPZIFwZHkUMt7d+iD4lekMBx2XRby5RlTb39cTJppMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIBIDAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMB4XDTIwMDkwODE1MzIyMVoXDTIwMDkxMDE1MzIyNlowITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANND+hdT97J+sPjpLSOggo5x14LmIZVd6To+0sTSrgiJrkBboninj+ks/BJgVbCw0XF/tgHbTq3ieMAFTc9XjXjoL6NxskBfM3Mu6r/4OcTUzWrnm3sQ4IEKx3uYiKI3rxSlLsBmCrfn9GZRuH3dFWdW5i0d63pfeM0OOi7xLhNdbVxRxTsg3n8BzqQXsxTNrYTuOKPnwzrw0M19IQcvRHwY+EbU9z+Yk/14eUhsyshT+IjHQvzKAyHBV/dKLIl2JVjiHt7nxinMasfEaUuxdsXsf2PvWqZbuVtIN2qqO6kPbJdnAqIuL6OyeTTzuwtSi3mxBALVX+Ui1yG/quStSjkCAwEAAaMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAqLCfnuergo+JWjrXWJ4VPWCubuItdtroKY6In8s4nuTAYLctwOAlOn5l95oqetejacIxQkA4AB6pg1hKRKxWWaZiMpYM+PYlwU9lN0IfbPvr9CgYhioRXyPztjXOmt7P1OQpBGFHX2O65CgFz/c/PaA+2MhPtb6nfU4LxPTk7iOJkzJLzeuEPycdIaBO3tCA3hN4o+v2bsEkqQ9tMuxNWMi8raMdFed0oYrOyDgurvIgQDxW50GxJMhERkKT9LRMVZNsUqwr0St5fwJL+9Y1SszZVOLm5fXyiJ/QavOaTlOoZIbSRpqmf3kNAljrNTPkgvLH/T/ebcmLh814dM0tYw==" ], + "exp" : 1599751946863, + "alg" : "PS256", + "n" : "00P6F1P3sn6w-OktI6CCjnHXguYhlV3pOj7SxNKuCImuQFuieKeP6Sz8EmBVsLDRcX-2AdtOreJ4wAVNz1eNeOgvo3GyQF8zcy7qv_g5xNTNauebexDggQrHe5iIojevFKUuwGYKt-f0ZlG4fd0VZ1bmLR3rel94zQ46LvEuE11tXFHFOyDefwHOpBezFM2thO44o-fDOvDQzX0hBy9EfBj4RtT3P5iT_Xh5SGzKyFP4iMdC_MoDIcFX90osiXYlWOIe3ufGKcxqx8RpS7F2xex_Y-9aplu5W0g3aqo7qQ9sl2cCoi4vo7J5NPO7C1KLebEEAtVf5SLXIb-q5K1KOQ" + }, { + "kty" : "RSA", + "e" : "AQAB", + "use" : "sig", + "crv" : "", + "kid" : "ce9ea6f7-6522-4d2f-8ad9-9ce99eb7009e_sig_ps384", + "x5c" : [ "MIIDbDCCAiCgAwIBAgIhAMWm7mGmlN8U/ZBjvkFGZMA5wwOvvasjNBL613iQKTwEMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMDAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMB4XDTIwMDkwODE1MzIyMVoXDTIwMDkxMDE1MzIyNlowITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO1HF1uu5TxhdiMuAiVfyap8t/wZaHKnWWpIO13n8hsg+atAcRLQWGZCtzbZ3N4r2M2clKrICyxvy4eVK5mWYsWsaiMH5XpHmuu6QBLKur7KNIQww13r5236KsTf2Tb7l+4wBQtmo2MN81tT4VWg+gVz7zfvKnqLUHvFhexHOoNvkBAUeq0qxO+FwT9s1sCdKnmeioQBuCxdbFisKTWiulBBtNu6B0EL6BBynnhAQ/3VQhuEe0UFf1tgd8Gzi8HumP/YvYYCwRi15HCmQ1MwJtPRhAn8xgfdCo86yP5Iw5vX3d5AvxwUmf+tumPdPmWiSqsC2z3VTxnOvFvdRjrywa0CAwEAAaMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMAOCAQEAZPXVLMaR97iemBwAS4yUQkHYrtBtfJTIK6qd8H+ZewRjLpek+GHiAyo4gH90xoQICmQoLiOwi8McOG7JFd1Eymg8sV+qNKi4c8Cna/HdOp6ExTGvqYWkz9tGik9OVhIvggWmA0B8H+lXudzqkD+7AZkK/eVbHhMflFEhsCtsTnJ8zGpVmscX7eg97KzEGCAHaNKh/J0N0OVW875p7rIixuOxynPH+3lfBviMVmmIIOqZvd8pO6BIyWxTAS3d7nKsF9QI86HRr/bynUl1qyn9B3BCJT0RCd9byPW5a78xWZk03GA8UJWhV2g2Qt6ZO1A0e68SrHx2uHYIR6aXEU0TrQ==" ], + "exp" : 1599751946863, + "alg" : "PS384", + "n" : "7UcXW67lPGF2Iy4CJV_Jqny3_BlocqdZakg7XefyGyD5q0BxEtBYZkK3Ntnc3ivYzZyUqsgLLG_Lh5UrmZZixaxqIwflekea67pAEsq6vso0hDDDXevnbfoqxN_ZNvuX7jAFC2ajYw3zW1PhVaD6BXPvN-8qeotQe8WF7Ec6g2-QEBR6rSrE74XBP2zWwJ0qeZ6KhAG4LF1sWKwpNaK6UEG027oHQQvoEHKeeEBD_dVCG4R7RQV_W2B3wbOLwe6Y_9i9hgLBGLXkcKZDUzAm09GECfzGB90KjzrI_kjDm9fd3kC_HBSZ_626Y90-ZaJKqwLbPdVPGc68W91GOvLBrQ" + }, { + "kty" : "RSA", + "e" : "AQAB", + "use" : "sig", + "crv" : "", + "kid" : "79871adb-0b4d-4f85-995c-a34b6d1df522_sig_ps512", + "x5c" : [ "MIIDazCCAh+gAwIBAgIgfOQFwOuh1OnHzMeOOcD0m7muXOMvFpAf8pl7GEyJejUwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjIxWhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjsaqXikeYT3wxhGnGcOLsF/i+++Rv3ywZH8TAK4DCdZW0Vuq97YACZq6AF7TWlSrx4ujHkW4jcksqdrFVJCJ3ECS8HT3YutPJgi6s9mJo46dWBD5yZGr6DzdtRGCKeTLl4NOyl7JmYhj0qpHJhujp4R8Ns4znFPaG6QZprj1G7DcKMsJ/vEbRmVJVWoMqOlhpWQNods51b+7WnkKObEpk9m4wl9R4FA98Xsc46IXS8+dwvA9kJVfyVkRSgCjaHA69877+H4EjsCNN1DUS0MrLwliyvu4brLdbROirrjrQ+RIkJQqS/Q573qZW8R53xM8c+IbN0fa4hU2RCirKzC8GQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAA4IBAQAIDS3xGrrY4RboyoSuad/yXOlxelvMZFbHBoYszJcPZX4LvUR0GEJTF+MXFCYjhQmFrd9db2SIpcX2705clK1bq7MIaR7fPYAFeC7Or/8rzsdyCxDdfwM0cOIwZY06Pcmv2zuSFeVXweVU7GOw8GN0lMlkbWPR5DPjWSiLrBrWpNMF0DmoMZ63DzQVF7N/2LEjTA+5Z12PxLijVpPDY1UajB7MJVG78Ls4nnWgiDPdYyInFworv+A5aCqVYgXQ+QFEgSIfJZfr9VeVrJKCjferfnkMNDH3vlWSgEOp1YkQ2OU3hc3Kb1+mI4xiRYAy4ukLhs7KN6AZwYE+cA9URfyl" ], + "exp" : 1599751946863, + "alg" : "PS512", + "n" : "jsaqXikeYT3wxhGnGcOLsF_i---Rv3ywZH8TAK4DCdZW0Vuq97YACZq6AF7TWlSrx4ujHkW4jcksqdrFVJCJ3ECS8HT3YutPJgi6s9mJo46dWBD5yZGr6DzdtRGCKeTLl4NOyl7JmYhj0qpHJhujp4R8Ns4znFPaG6QZprj1G7DcKMsJ_vEbRmVJVWoMqOlhpWQNods51b-7WnkKObEpk9m4wl9R4FA98Xsc46IXS8-dwvA9kJVfyVkRSgCjaHA69877-H4EjsCNN1DUS0MrLwliyvu4brLdbROirrjrQ-RIkJQqS_Q573qZW8R53xM8c-IbN0fa4hU2RCirKzC8GQ" + }, { + "kty" : "RSA", + "e" : "AQAB", + "use" : "enc", + "crv" : "", + "kid" : "b9fbfa5b-e720-4602-88cc-fa25ca49b2f7_enc_rsa1_5", + "x5c" : [ "MIIDBDCCAeygAwIBAgIhANjrub7uPwzxastlEA+yUDinE2aijdIoK4TtWS3zjiYBMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjIyWhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxGv/3QD894qstz20lNiK1btBNz5i6WYxcGiX6oBKP3lU4t2LA3hPf9Kevxbgkcj/2SWdrNA2g0lSWIglb621qfMnz/2C42Bu1bOGEwR2T9HdC/dTN1nmmSEymej5tA5zs3qcxsrRjKBFRcKaktO5WUmoKDZNw+pVKWOr1DY+oQ4enuP/xdZ7JJsccR6487smDmwjNw3DymL388G8cCNri9rF/j4pRX+vJd9VSM8qZDKYk3s4qKkZ8PtJx+tITYPp7Yijw1u1zdEnEcLgZ5gmpCejhjWZAbxyhGahdL78Y7dR/KeL0Ukeo11hUER62KWVH7lSh/Ix2GaAYnqTbxBFHQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBAIiTUPWXODrcpRpvU1xW4NA2upMs5yKsrtPJmIOB07lxqEhX7rm/JXaDmy9sBCWDO4G56WnynXFjKON39w52PKtPBvtVqLVTpaVu5rTGva3Q/IFcRGMMTPr0HTMnuLUOy7tcyqOvcdAZnI/vLH+/ovxMBVC8q0jOms9XSvNMSUwisX/PckWMaCOb1f7Hmu3gLws45f9Tz/AKgnb4MQQ0kH1cQ1KmDpaQmK3OhelHHZ2JjtBJbL5Ig1sEffpySln8ZK07F3CSeeJAOhTr8bz8HyQ7rgTxFrs7oJs9rWbIiVqR138kEWKe8B6JTRujVGwb8zLuff490Jeix64U3mqQebM=" ], + "exp" : 1599751946863, + "alg" : "RSA1_5", + "n" : "xGv_3QD894qstz20lNiK1btBNz5i6WYxcGiX6oBKP3lU4t2LA3hPf9Kevxbgkcj_2SWdrNA2g0lSWIglb621qfMnz_2C42Bu1bOGEwR2T9HdC_dTN1nmmSEymej5tA5zs3qcxsrRjKBFRcKaktO5WUmoKDZNw-pVKWOr1DY-oQ4enuP_xdZ7JJsccR6487smDmwjNw3DymL388G8cCNri9rF_j4pRX-vJd9VSM8qZDKYk3s4qKkZ8PtJx-tITYPp7Yijw1u1zdEnEcLgZ5gmpCejhjWZAbxyhGahdL78Y7dR_KeL0Ukeo11hUER62KWVH7lSh_Ix2GaAYnqTbxBFHQ" + }, { + "kty" : "RSA", + "e" : "AQAB", + "use" : "enc", + "crv" : "", + "kid" : "d86d28c3-ccd5-4d38-8985-f6d6cfbf5688_enc_rsa-oaep", + "x5c" : [ "MIIDAzCCAeugAwIBAgIgGdQU0RWuwHvXO/24IJJNbVPOVcqSja8SfIzdYGtcG10wDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA5MDgxNTMyMjNaFw0yMDA5MTAxNTMyMjZaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKDOUm+qP2hSEiN3jZWa8Nvpm1kzAFGTtcyz6Bhdy4bI2NnKJEc+kQuPNB/+7ovX8jxfFwE/AWfh89QEXJizd4UJ3qfjKTYjmns60b2k8o1iGjkdWaNFzbVWfKgjhkfiobhZL5vZ3c4vYut4M++q7sTWM5cEyBfZlExD0NfS5F7omclnmMs/zb3QzCUrXbikS1qu5+LwIdslx3VrewmuYjlWOGgqK6jIMxJoOvt2OEvHqg4HyC0GMo3X8JUATwidEk9gMn2jJxj27P4P1Ac6TBIVZI/PAAv1fmam/LfMWPIBPRp84ekasCHWTKEThmuWfm3RAipVKyEn/dKqdwa2rDAgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAm8snq5tIpwFRKi9Q1llRkYSWTsa4ToskQjWD9hfo5EJesGBZmsGIRWpWKvT6z5vn06mU966lc3KVT59LPP7dEevl+VRrhN3imjC/QgURg2cn0xZEXB8UbMrfTXdGDlvHyLwkF06wPv7K4lg2bDm8teyrTnVkoMLoWzcIj5LXNREq2Mh2mSM2yCZ9haHBYj42vXhaQXUXe50ChtJP4o+auZA+XGM+veRm6fm4/zKccYsT4W3RjrBtK3pkcjcfzYsSATNwndkRxtKWFWPo6KRf6NGl8C20tq3qFQx3eRzw6QNJmQpjdhTuX03DZkCGfgRUq7WQCF/nvbTdTa22I8TWDg==" ], + "exp" : 1599751946863, + "alg" : "RSA-OAEP", + "n" : "ygzlJvqj9oUhIjd42VmvDb6ZtZMwBRk7XMs-gYXcuGyNjZyiRHPpELjzQf_u6L1_I8XxcBPwFn4fPUBFyYs3eFCd6n4yk2I5p7OtG9pPKNYho5HVmjRc21VnyoI4ZH4qG4WS-b2d3OL2LreDPvqu7E1jOXBMgX2ZRMQ9DX0uRe6JnJZ5jLP8290MwlK124pEtarufi8CHbJcd1a3sJrmI5VjhoKiuoyDMSaDr7djhLx6oOB8gtBjKN1_CVAE8InRJPYDJ9oycY9uz-D9QHOkwSFWSPzwAL9X5mpvy3zFjyAT0afOHpGrAh1kyhE4Zrln5t0QIqVSshJ_3SqncGtqww" + } ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/jwks/jwks_patch.json b/jans-config-api/server/src/test/resources/json/config/jwks/jwks_patch.json new file mode 100644 index 00000000000..af946915832 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/jwks/jwks_patch.json @@ -0,0 +1,20 @@ +[ + { + "op": "add", + "path": "/keys/1", + "value": { + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "crv": "", + "kid": "dd570bfb-276a-44aa-a97d-667b57587108_sig_rs256", + "x5c": [ + "MIIDBDCCAeygAwIBAgIhAOviRkmppgF16wC7nMg17Jt4P7lNoLglfLDxLAPYn4J0MA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjE3WhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzj1NEHyGk/ywG25py2s/zVVrRggzRO0jE6VOUvqUzsEJwt1aszQ4onFu6vgtjNwq2ZmEFZbw1Jw7dlz4Xrdj12pQlLVuEhyVaTziQp3LvspqxyACHQb8XSKFdKZaa1eBF8PGN5zDN/d+tIrAZYnQS2gH8BoPIuB3Z9AoCLTzifnPvmOwW/e+/Wags/ApZiEfF2Po0InV5NeJAyoIpaGhlwjqqOWXm/GpCASAk9ZD8Ebnmy9RM71zDCgmvq/hPueKnbNTZdQ3TQdzEuSwxbWEHu16v5MbF7QtNzvFSFlllhgwqI2ccEljDbs18j3DUS2B1VTTAr/DLR3SVyCYbKBbRQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBADaqrfVH1FX0FLp99TG9fHOiOMD12vsIPANb9QbIADineFrSvUI3zIX56PpvMT+EApaLPcIYSwG1YziWT1oGDGkfyinofSRGl4JcC63slChUBfjlBZlXTIlc7CJA7CfzO6BW3SvO0GPF0NStCUD9Ou4oOVaIc3XrPzhIAp71cF9iLFnQUK1hiD9NhQUm5v2Nq+sQdjAxSlqigXnc+rB9+V8snCkr9x9q1cysq1ZyCRT55psa53Irqtc50T2PHA6kyzEVW51+yFaZa8z+WMoofr6ndx2DFI7n5+8jFGs9WoP+/zV8E/XK61iy+EdXVjXQYVcArjEzeIahn8QOd/hUcfo=" + ], + "exp": 1599751946863, + "alg": "RS256", + "n": "zj1NEHyGk_ywG25py2s_zVVrRggzRO0jE6VOUvqUzsEJwt1aszQ4onFu6vgtjNwq2ZmEFZbw1Jw7dlz4Xrdj12pQlLVuEhyVaTziQp3LvspqxyACHQb8XSKFdKZaa1eBF8PGN5zDN_d-tIrAZYnQS2gH8BoPIuB3Z9AoCLTzifnPvmOwW_e-_Wags_ApZiEfF2Po0InV5NeJAyoIpaGhlwjqqOWXm_GpCASAk9ZD8Ebnmy9RM71zDCgmvq_hPueKnbNTZdQ3TQdzEuSwxbWEHu16v5MbF7QtNzvFSFlllhgwqI2ccEljDbs18j3DUS2B1VTTAr_DLR3SVyCYbKBbRQ" + } + } +] + diff --git a/jans-config-api/server/src/test/resources/json/config/message/message.feature b/jans-config-api/server/src/test/resources/json/config/message/message.feature new file mode 100644 index 00000000000..f3fac9eef5e --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/message/message.feature @@ -0,0 +1,176 @@ + +Feature: Verify Message configuration endpoint + + Background: + * def mainUrl = messageUrl + + @message-get-error + Scenario: Retrieve Message configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + @message-get + Scenario: Retrieve Message configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @message-patch + Scenario: Patch messageProviderType configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.messageProviderType + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/messageProviderType\", \"value\":\""+response.messageProviderType+"\" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @message-patch + Scenario: Patch redisConfiguration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.redisConfiguration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/redisConfiguration\", \"value\":"+response.redisConfiguration+" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @message-patch + Scenario: Patch postgresConfiguration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.postgresConfiguration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/postgresConfiguration\", \"value\":"+response.postgresConfiguration+" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @message-get-redis + Scenario: Retrieve Redis message configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'redis' + When method GET + Then status 200 + And print response + And assert response.length != null + + @message-put-redis + Scenario: Update Redis message configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'redis' + When method GET + Then status 200 + Then print response + Then def first_response = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'redis' + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + @message-patch-redis + Scenario: Patch Redis message configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'redis' + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/servers\", \"value\":\""+response.servers+"\"} ]" + And path 'redis' + Then print request + When method PATCH + Then status 200 + And print response + + @message-get-postgres + Scenario: Retrieve Postgres message configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'postgres' + When method GET + Then status 200 + And print response + And assert response.length != null + + @message-put-postgres + Scenario: Update Postgres message configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'postgres' + When method GET + Then status 200 + Then print response + Then def first_response = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'postgres' + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + @message-patch-postgres + Scenario: Patch Postgres message configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'postgres' + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/dbSchemaName\", \"value\":\""+response.dbSchemaName+"\"} ]" + And path 'postgres' + Then print request + When method PATCH + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/org/org-config.feature b/jans-config-api/server/src/test/resources/json/config/org/org-config.feature new file mode 100644 index 00000000000..756025630fe --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/org/org-config.feature @@ -0,0 +1,45 @@ + +Feature: Verify Organization configuration endpoint + + Background: + * def mainUrl = org_configuration_url + + @auth-config-get-error + Scenario: Retrieve Organization configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + @auth-config-get + Scenario: Retrieve Organization configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @auth-config-patch + Scenario: Patch Organization configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And print response.description + #And def request_body = (response.description == null ? "[ {\"op\":\"add\", \"path\": \"/description\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/description\", \"value\":"+response.description+" } ]") + And def request_body = (response.description == null ? "[ {\"op\":\"add\", \"path\": \"/description\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/description\", \"value\":\""+response.description+"\" } ]") + And print request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/authenticationFilters.json b/jans-config-api/server/src/test/resources/json/config/properties/authenticationFilters.json new file mode 100644 index 00000000000..edb80f4ccf5 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/authenticationFilters.json @@ -0,0 +1,23 @@ +{ + "authenticationFilters": [ + { + "filter": "(&(mail=*{0}*)(inum={1}))", + "bind": false, + "bindPasswordAttribute": "", + "baseDn": "ou=people,o=gluu" + }, + { + "filter": "uid={0}", + "bind": true, + "bindPasswordAttribute": "pwd", + "baseDn": "ou=people,o=gluu" + } + , + { + "filter": "uid={0}", + "bind": false, + "bindPasswordAttribute": "pwd", + "baseDn": "ou=people,o=gluu,uid=pujavs" + } + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/backchannel/backchannel.feature b/jans-config-api/server/src/test/resources/json/config/properties/backchannel/backchannel.feature new file mode 100644 index 00000000000..8365e9d3a0f --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/backchannel/backchannel.feature @@ -0,0 +1,49 @@ +@ignore +Feature: Verify backchannel configuration endpoint + +Background: + * def mainUrl = backchannelUrl + + @backchannel-get + Scenario: Retrieve backchannel configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @backchannel-put + Scenario: Update backchannel configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + #And print response + Then def first_response = response + #And print first_response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 200 + And print response + + + @error + Scenario: Error case while updating backchannel configuration min validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.backchannelAuthenticationResponseExpiresIn = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/ciba/ciba.feature b/jans-config-api/server/src/test/resources/json/config/properties/ciba/ciba.feature new file mode 100644 index 00000000000..d4d0a004b1d --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/ciba/ciba.feature @@ -0,0 +1,221 @@ +@ignore +Feature: Verify CIBA configuration endpoint + + Background: + * def mainUrl = cibaUrl + + @ignore + @ciba-put-json + Scenario: Update CIBA configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('ciba.json') + When method PUT + Then status 200 + And print response + And assert response.length != null + + @ciba-get + Scenario: Retrieve CIBA configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @ciba-put + Scenario: Update CIBA configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + #Then set result.cibaMaxExpirationTimeAllowedSec = 1000 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + + @ciba-error + Scenario: apiKey configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.apiKey = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @ciba-error + Scenario: authDomain configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.authDomain = '' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @ciba-error + Scenario: databaseURL configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.databaseURL = '' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @ciba-error + Scenario: projectId configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.projectId = '' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @ciba-error + Scenario: storageBucket configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.storageBucket = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @ciba-error + Scenario: messagingSenderId configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.messagingSenderId = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @ciba-error + Scenario: appId configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.appId = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @ciba-error + Scenario: notificationUrl configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.notificationUrl = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @ciba-error + Scenario: notificationKey configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.notificationKey = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @ciba-error + Scenario: publicVapidKey configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.publicVapidKey = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/ciba/ciba.json b/jans-config-api/server/src/test/resources/json/config/properties/ciba/ciba.json new file mode 100644 index 00000000000..a2cb6db256c --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/ciba/ciba.json @@ -0,0 +1,14 @@ +{ + "apiKey": "AIzaSyDwJtxZV-ApPlApt7HdXkleEZhseURgzHI", + "authDomain": "api-project-561176510817.firebaseapp.com", + "databaseURL": "https://api-project-561176510817.firebaseio.com", + "projectId": "api-project-561176510817", + "storageBucket": "api-project-561176510817.appspot.com", + "messagingSenderId": "561176510817", + "appId": "1:561176510817:web:8e327e72cd49e8d5", + "notificationUrl": "https://fcm.googleapis.com/fcm/send", + "notificationKey": "csyBj39m4uPHbs2oHeTw40KfgCiUbgxBKPPz6ZXgkpF4EMQvMOAHAoM7up1UlfHk9GD5QnqdMktzjpmEuKd5xlD2kRDhwMIJ8JYbTA5+Cv39CxuWOiFuuMPJZqg+VqT4X7Ne9sXvm3UtMe8PxmRAoXlSZ1kElT/AuQvC2+YyiqlmLpXoCU01waEtIajltap5TrFuXvAvkmYJjvCkFIdWsg==", + "publicVapidKey": "BOH-FKi3U-7cr5Wv3WeS8RJXXaGpf1R7tlgKSOvYCbFrJRaJER4kI_0xCN", + "cibaMaxExpirationTimeAllowedSec": 1800, + "cibaGrantLifeExtraTimeSec": 180, +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/clientAuthenticationFilters.json b/jans-config-api/server/src/test/resources/json/config/properties/clientAuthenticationFilters.json new file mode 100644 index 00000000000..6aff8183e13 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/clientAuthenticationFilters.json @@ -0,0 +1,14 @@ +{ + "clientAuthenticationFilters": [ + { + "filter": "myCustomAttr1={0}", + "bindPasswordAttribute": "", + "baseDn": "ou=clients,o=gluu" + }, + { + "filter": "myCustomAttr2={0}", + "bindNameAttribute": "", + "baseDn": "ou=clients,o=gluu,uid=pujavs" + } + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/cors/cors.feature b/jans-config-api/server/src/test/resources/json/config/properties/cors/cors.feature new file mode 100644 index 00000000000..54a0f75f17c --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/cors/cors.feature @@ -0,0 +1,34 @@ +@ignore +Feature: Verify Cors configuration filter endpoint + + Background: + * def mainUrl = corsUrl + + @cors-get + Scenario: Retrieve Cors configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @cors-put + Scenario: Update Cors configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + #And print response + Then def first_response = response + #And print first_response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/cors/cors.json b/jans-config-api/server/src/test/resources/json/config/properties/cors/cors.json new file mode 100644 index 00000000000..9b6d288da54 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/cors/cors.json @@ -0,0 +1,26 @@ +[ + { + "corsSupportCredentials": true, + "corsPreflightMaxAge": 1800, + "corsEnabled": true, + "corsAllowedMethods": "GET,POST,HEAD,OPTIONS", + "filterName": "CorsFilter", + "corsAllowedHeaders": "Origin,Authorization,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers", + "corsLoggingEnabled": false, + "corsAllowedOrigins": "*", + "corsExposedHeaders": "", + "corsRequestDecorate": true + }, + { + "corsSupportCredentials": false, + "corsPreflightMaxAge": -1, + "corsEnabled": true, + "corsAllowedMethods": "PUT", + "filterName": "CorsFilter_2", + "corsAllowedHeaders": "Access-Control-Request-Headers", + "corsLoggingEnabled": false, + "corsAllowedOrigins": "*", + "corsExposedHeaders": "", + "corsRequestDecorate": true + } +] \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/custom.json b/jans-config-api/server/src/test/resources/json/config/properties/custom.json new file mode 100644 index 00000000000..a2cb6db256c --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/custom.json @@ -0,0 +1,14 @@ +{ + "apiKey": "AIzaSyDwJtxZV-ApPlApt7HdXkleEZhseURgzHI", + "authDomain": "api-project-561176510817.firebaseapp.com", + "databaseURL": "https://api-project-561176510817.firebaseio.com", + "projectId": "api-project-561176510817", + "storageBucket": "api-project-561176510817.appspot.com", + "messagingSenderId": "561176510817", + "appId": "1:561176510817:web:8e327e72cd49e8d5", + "notificationUrl": "https://fcm.googleapis.com/fcm/send", + "notificationKey": "csyBj39m4uPHbs2oHeTw40KfgCiUbgxBKPPz6ZXgkpF4EMQvMOAHAoM7up1UlfHk9GD5QnqdMktzjpmEuKd5xlD2kRDhwMIJ8JYbTA5+Cv39CxuWOiFuuMPJZqg+VqT4X7Ne9sXvm3UtMe8PxmRAoXlSZ1kElT/AuQvC2+YyiqlmLpXoCU01waEtIajltap5TrFuXvAvkmYJjvCkFIdWsg==", + "publicVapidKey": "BOH-FKi3U-7cr5Wv3WeS8RJXXaGpf1R7tlgKSOvYCbFrJRaJER4kI_0xCN", + "cibaMaxExpirationTimeAllowedSec": 1800, + "cibaGrantLifeExtraTimeSec": 180, +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/dynamic/registration/registration.feature b/jans-config-api/server/src/test/resources/json/config/properties/dynamic/registration/registration.feature new file mode 100644 index 00000000000..8dbf5f898ae --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/dynamic/registration/registration.feature @@ -0,0 +1,129 @@ +@ignore +Feature: Verify DynamicRegistration configuration endpoint + + Background: + * def mainUrl = dynamicRegistrationUrl + + @ignore + @dynamicRegistration-put-json + Scenario: Update Dynamic Registration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('registration.json') + When method PUT + Then status 200 + And print response + And assert response.length != null + + @dynamicRegistration-get + Scenario: Retrieve Dynamic Registration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @dynamicRegistration-put + Scenario: Update Dynamic Registration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + @error + Scenario: dynamicRegistrationCustomObjectClass configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.dynamicRegistrationCustomObjectClass = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @error + Scenario: defaultSubjectType configuration cannot be other than public or pairwise + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.defaultSubjectType = 'abc' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @error + Scenario: dynamicRegistrationExpirationTime configuration should be int and not decimal + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.dynamicRegistrationExpirationTime = 20.5 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @error + Scenario: grantTypesSupportedByDynamicRegistration configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.grantTypesSupportedByDynamicRegistration = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @error + Scenario: dynamicRegistrationCustomAttributes configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.dynamicRegistrationCustomAttributes = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/dynamic/registration/registration.json b/jans-config-api/server/src/test/resources/json/config/properties/dynamic/registration/registration.json new file mode 100644 index 00000000000..2054ae09418 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/dynamic/registration/registration.json @@ -0,0 +1,21 @@ +{ + "dynamicRegistrationExpirationTime": 10, + "dynamicRegistrationScopesParamEnabled": true, + "dynamicRegistrationPersistClientAuthorizations": true, + "returnClientSecretOnRead": false, + "dynamicRegistrationPasswordGrantTypeEnabled": false, + "trustedClientEnabled": true, + "dynamicRegistrationCustomObjectClass": "MyDynamicRegistrationCustomObject", + "grantTypesSupportedByDynamicRegistration": [ + "REFRESH_TOKEN", + "OXAUTH_UMA_TICKET", + "IMPLICIT", + "CLIENT_CREDENTIALS", + "AUTHORIZATION_CODE" + ], + "dynamicRegistrationCustomAttributes": [ + "jansTrustedClnt" + ], + "defaultSubjectType": "pairwise", + "legacyDynamicRegistrationScopeParam": false +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/endpoints/endpoints.feature b/jans-config-api/server/src/test/resources/json/config/properties/endpoints/endpoints.feature new file mode 100644 index 00000000000..8af79c179f4 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/endpoints/endpoints.feature @@ -0,0 +1,274 @@ +@ignore +Feature: Verify jans-auth available endpoints. + + Background: + * def mainUrl = endpointsUrl + + @ignore + @endpoints-put-json + Scenario: Update available endpoints. + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('endpoints.json') + When method PUT + Then status 200 + And print response + And assert response.length != null + + @endpoints-get + Scenario: Retrieve available endpoints. + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @endpoints-put + Scenario: Update available endpoints. + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + @endpoints-error + Scenario: baseEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.baseEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: authorizationEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.authorizationEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: tokenEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.tokenEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: tokenRevocationEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.tokenRevocationEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: userInfoEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.userInfoEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: clientInfoEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.clientInfoEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: endSessionEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.endSessionEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: registrationEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.registrationEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: openIdDiscoveryEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.openIdDiscoveryEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: openIdConfigurationEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.openIdConfigurationEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: idGenerationEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.idGenerationEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @endpoints-error + Scenario: introspectionEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.introspectionEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @endpoints-error + Scenario: umaConfigurationEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.umaConfigurationEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response diff --git a/jans-config-api/server/src/test/resources/json/config/properties/endpoints/endpoints.json b/jans-config-api/server/src/test/resources/json/config/properties/endpoints/endpoints.json new file mode 100644 index 00000000000..f8a728bea00 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/endpoints/endpoints.json @@ -0,0 +1,18 @@ + { + "tokenRevocationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/revoke", + "introspectionEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/introspection", + "umaConfigurationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/uma2-configuration", + "clientInfoEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/clientinfo", + "authorizationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/authorize", + "authorizationChallengeEndpoint":"https://pujavs3.infinity.com/jans-auth/restv1/authorize-challenge", + "backchannelAuthenticationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/bc-authorize", + "baseEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1", + "tokenEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/token", + "endSessionEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/end_session", + "idGenerationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/id", + "backchannelDeviceRegistrationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/bc-deviceRegistration", + "openIdDiscoveryEndpoint": "https://pujavs3.infinity.com/.well-known/webfinger", + "openIdConfigurationEndpoint": "https://pujavs3.infinity.com/.well-known/openid-configuration", + "userInfoEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/userinfo", + "registrationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/register" +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/expiration/expiration.feature b/jans-config-api/server/src/test/resources/json/config/properties/expiration/expiration.feature new file mode 100644 index 00000000000..d1fd52a9230 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/expiration/expiration.feature @@ -0,0 +1,61 @@ +@ignore +Feature: Verify Expiration Notificator configuration endpoint + + Background: + * def mainUrl = expirationUrl + + @expiration-get + Scenario: Retrieve Expiration Notificator configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @expiration-put + Scenario: Update Expiration Notificator configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + #And print response + Then def first_response = response + #And print first_response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 200 + And print response + + @error + Scenario: Error case for expirationNotificatorMapSizeLimit configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.expirationNotificatorMapSizeLimit = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + @error + Scenario: Error case for expirationNotificatorIntervalInSeconds configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.expirationNotificatorIntervalInSeconds = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/expiration/expiration.json b/jans-config-api/server/src/test/resources/json/config/properties/expiration/expiration.json new file mode 100644 index 00000000000..872403ffbd6 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/expiration/expiration.json @@ -0,0 +1,5 @@ +{ + "expirationNotificatorIntervalInSeconds": 600, + "expirationNotificatorEnabled": false, + "expirationNotificatorMapSizeLimit": 100000 +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/grant/grant.feature b/jans-config-api/server/src/test/resources/json/config/properties/grant/grant.feature new file mode 100644 index 00000000000..479b1e16864 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/grant/grant.feature @@ -0,0 +1,44 @@ +@ignore +Feature: Verify supported Grant Type configuration endpoint + + Background: + * def mainUrl = grantUrl + + @grant-get + Scenario: Retrieve Grant Type configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @grant-put + Scenario: Update Grant Type configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('grant.json') + When method PUT + Then status 200 + And print response + And assert response.length != null + + + @error + Scenario: Error case while updating grantTypesSupported configuration min validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.grantTypesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/grant/grant.json b/jans-config-api/server/src/test/resources/json/config/properties/grant/grant.json new file mode 100644 index 00000000000..20e6e15282b --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/grant/grant.json @@ -0,0 +1,10 @@ + { + "grantTypesSupported": [ + "IMPLICIT", + "AUTHORIZATION_CODE", + "REFRESH_TOKEN", + "RESOURCE_OWNER_PASSWORD_CREDENTIALS", + "OXAUTH_UMA_TICKET", + "CLIENT_CREDENTIALS" + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/idToken/idToken.feature b/jans-config-api/server/src/test/resources/json/config/properties/idToken/idToken.feature new file mode 100644 index 00000000000..480110f3dd9 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/idToken/idToken.feature @@ -0,0 +1,93 @@ +@ignore +Feature: Verify idToken configuration endpoint + + Background: + * def mainUrl = idTokenUrl + + @idtoken-put-json + Scenario: Update idToken configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('idToken.json') + When method PUT + Then status 200 + And print response + + @idtoken-get + Scenario: Retrieve idToken configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @idtoken-put + Scenario: Update idToken configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + @error + Scenario: idTokenSigningAlgValuesSupported configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.idTokenSigningAlgValuesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @error + Scenario: idTokenEncryptionAlgValuesSupported configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.idTokenEncryptionAlgValuesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @error + Scenario: idTokenEncryptionEncValuesSupported configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.idTokenEncryptionEncValuesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/idToken/idToken.json b/jans-config-api/server/src/test/resources/json/config/properties/idToken/idToken.json new file mode 100644 index 00000000000..02d916a30be --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/idToken/idToken.json @@ -0,0 +1,26 @@ +{ + "idTokenSigningAlgValuesSupported": [ + "none", + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "idTokenEncryptionAlgValuesSupported": [ + "RSA1_5", + "RSA-OAEP", + "A128KW", + "A256KW" + ], + "idTokenEncryptionEncValuesSupported": [ + "A128CBC+HS256", + "A256CBC+HS512", + "A128GCM", + "A256GCM" + ] +} diff --git a/jans-config-api/server/src/test/resources/json/config/properties/janssenpkcs/janssenpkcs.feature b/jans-config-api/server/src/test/resources/json/config/properties/janssenpkcs/janssenpkcs.feature new file mode 100644 index 00000000000..a558ca8cbd6 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/janssenpkcs/janssenpkcs.feature @@ -0,0 +1,33 @@ +@ignore +Feature: Verify JanssenPKCS configuration endpoint + + Background: + * def mainUrl = janssenPKCSUrl + + @janssenPKCS-get + Scenario: Retrieve JanssenPKCS configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @janssenPKCS-put + Scenario: Update JanssenPKCS configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/keys/regen/regen.feature b/jans-config-api/server/src/test/resources/json/config/properties/keys/regen/regen.feature new file mode 100644 index 00000000000..e4edba692d2 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/keys/regen/regen.feature @@ -0,0 +1,38 @@ +@ignore +Feature: Verify Key Regeneration Resource endpoint + + Background: + * def mainUrl = keyRegenUrl + + @key-regen-get + Scenario: Retrieve Key Regeneration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @key-regen-put + Scenario: Update Key Regeneration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('regen.json') + When method PUT + Then status 200 + And print response + And assert response.length != null + + @error + Scenario: Error case for keyRegenerationInterval configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + Then def request_json = read('regen.json') + Then set request_json.keyRegenerationInterval = 0 + #And print request_json + And request request_json + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/keys/regen/regen.json b/jans-config-api/server/src/test/resources/json/config/properties/keys/regen/regen.json new file mode 100644 index 00000000000..9a655784798 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/keys/regen/regen.json @@ -0,0 +1,5 @@ +{ + "defaultSignatureAlgorithm": "RS256", + "keyRegenerationInterval": 48, + "keyRegenerationEnabled": true +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/metrics/metrics.feature b/jans-config-api/server/src/test/resources/json/config/properties/metrics/metrics.feature new file mode 100644 index 00000000000..5c686775283 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/metrics/metrics.feature @@ -0,0 +1,66 @@ +@ignore +Feature: Verify Metrics configuration endpoint + + Background: + * def mainUrl = metricsUrl + + @metrics-get + Scenario: Retrieve metrics configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @metrics-put + Scenario: Update metrics configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + @error + Scenario: metricReporterKeepDataDays cannot be less than 1 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.metricReporterKeepDataDays = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + @error + Scenario: metricReporterInterval cannot be less than 1 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.metricReporterInterval = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/openid/config/config.feature b/jans-config-api/server/src/test/resources/json/config/properties/openid/config/config.feature new file mode 100644 index 00000000000..3ee257285ad --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/openid/config/config.feature @@ -0,0 +1,287 @@ +@ignore +Feature: Verify OpenId configuration endpoint + + Background: + * def mainUrl = openidUrl + + @openid-get + Scenario: Retrieve OpenId configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @openid-put + Scenario: Update OpenId configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + #And print response + Then def first_response = response + #And print first_response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 200 + And print response + + + @error + Scenario: Error case for oxOpenIdConnectVersion configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.oxOpenIdConnectVersion = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + @error + Scenario: Error case for issuer configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.issuer = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + @error + Scenario: Error case for jwksUri configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.jwksUri = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for tokenEndpointAuthMethodsSupported configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.tokenEndpointAuthMethodsSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for tokenEndpointAuthSigningAlgValuesSupported configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.tokenEndpointAuthSigningAlgValuesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for serviceDocumentation configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.serviceDocumentation = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for uiLocalesSupported configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.uiLocalesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for opPolicyUri configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.opPolicyUri = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for opTosUri configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.opTosUri = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for checkSessionIFrame configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.checkSessionIFrame = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for displayValuesSupported configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.displayValuesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for claimTypesSupported configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.claimTypesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for claimsLocalesSupported configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.claimsLocalesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for idTokenTokenBindingCnfValuesSupported configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.idTokenTokenBindingCnfValuesSupported = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for spontaneousScopeLifetime configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.spontaneousScopeLifetime = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for openidSubAttribute configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.openidSubAttribute = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/openid/config/config.json b/jans-config-api/server/src/test/resources/json/config/properties/openid/config/config.json new file mode 100644 index 00000000000..98804774ef5 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/openid/config/config.json @@ -0,0 +1,79 @@ +{ + "openidSubAttribute": "inum", + "tokenEndpointAuthSigningAlgValuesSupported": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512" + ], + "claimsLocalesSupported": [ + "en" + ], + "keepAuthenticatorAttributesOnAcrChange": false, + "checkSessionIFrame": "https://pujavs3.infinity.com/jans-auth/opiframe.htm", + "clientWhiteList": [ + "*" + ], + "removeRefreshTokensForClientOnLogout": true, + "jwksUri": "https://pujavs3.infinity.com/jans-auth/restv1/jwks", + "customHeadersWithAuthorizationResponse": true, + "displayValuesSupported": [ + "page", + "popup" + ], + "issuer": "https://pujavs3.infinity.com", + "clientBlackList": [ + "*.attacker.com/*" + ], + "forceOfflineAccessScopeToEnableRefreshToken": true, + "deviceAuthzTokenPollInterval": 0, + "invalidateSessionCookiesAfterAuthorizationFlow": false, + "oxOpenIdConnectVersion": "openidconnect-1.0", + "openidScopeBackwardCompatibility": true, + "legacyIdTokenClaims": true, + "endSessionWithAccessToken": false, + "idTokenTokenBindingCnfValuesSupported": [ + "tbh" + ], + "serviceDocumentation": "http://gluu.org/docs", + "frontChannelLogoutSessionSupported": true, + "spontaneousScopeLifetime": 86400, + "forceIdTokenHintPrecense": false, + "rejectEndSessionIfIdTokenExpired": false, + "allowEndSessionWithUnmatchedSid": false, + "claimsParameterSupported": false, + "claimTypesSupported": [ + "normal" + ], + "deviceAuthzRequestExpiresIn": 0, + "requestUriParameterSupported": true, + "uiLocalesSupported": [ + "en", + "bg", + "de", + "es", + "fr", + "it", + "ru", + "tr" + ], + "useCacheForAllImplicitFlowObjects": false, + "requireRequestUriRegistration": false, + "skipAuthorizationForOpenIdScopeAndPairwiseId": false, + "opPolicyUri": "http://ox.gluu.org/doku.php?id=jans-auth:policy", + "opTosUri": "http://ox.gluu.org/doku.php?id=jans-auth:tos", + "introspectionAccessTokenMustHaveUmaProtectionScope": false, + "requestParameterSupported": true, + "tokenEndpointAuthMethodsSupported": [ + "client_secret_basic", + "client_secret_post", + "client_secret_jwt", + "private_key_jwt" + ], + "allowPostLogoutRedirectWithoutValidation": false +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/pairwise/pairwise.feature b/jans-config-api/server/src/test/resources/json/config/properties/pairwise/pairwise.feature new file mode 100644 index 00000000000..33441fb2136 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/pairwise/pairwise.feature @@ -0,0 +1,103 @@ +@ignore +Feature: Verify Pairwise configuration endpoint + + Background: + * def mainUrl = pairwiseUrl + + @pairwise-get + Scenario: Retrieve pairwise configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @pairwise-put + Scenario: Update pairwise configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + #Then set result.pairwiseIdType = 'algorithmic' + #Then set result.pairwiseCalculationKey = 'YQmxW1ciznJW0SojsddI5ksk' + #Then set result.pairwiseCalculationSalt = 'xewqsr9U3bO7HRAJYmu25' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + @error + Scenario: pairwiseIdType configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.pairwiseIdType = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @error + Scenario: pairwiseIdType configuration cannot be other than persistent or algorithmic + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.pairwiseIdType = 'xyz' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @error + Scenario: pairwiseCalculationKey configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.pairwiseCalculationKey = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @error + Scenario: pairwiseCalculationSalt configuration cannot be null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.pairwiseCalculationSalt = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/properties.feature b/jans-config-api/server/src/test/resources/json/config/properties/properties.feature new file mode 100644 index 00000000000..db9c9c33a54 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/properties.feature @@ -0,0 +1,344 @@ + +Feature: Verify Auth configuration endpoint + + Background: + * def mainUrl = authConfigurationUrl + + @auth-config-get-error + Scenario: Retrieve Auth configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + @auth-config-get + Scenario: Retrieve Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @ignore + @auth-config-get-persistence-details + Scenario: Get Persistence details + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And path 'persistence' + Then print url + When method GET + Then status 200 + And print response + + @auth-config-dcr-patch + Scenario: Patch dcrSignatureValidationEnabled configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + #And request "[ {\"op\":\"replace\", \"path\": \"/dcrSignatureValidationEnabled\", \"value\": "+(response.dcrSignatureValidationEnabled == null ? false : response.dcrSignatureValidationEnabled)+" } ,{\"op\":\"replace\", \"path\": \"/dcrSignatureValidationSoftwareStatementJwksURIClaim\", \"value\": "+(response.dcrSignatureValidationSoftwareStatementJwksURIClaim == null ? null : response.dcrSignatureValidationSoftwareStatementJwksURIClaim)+" } ,{\"op\":\"replace\", \"path\": \"/dcrSignatureValidationSoftwareStatementJwksClaim\", \"value\": \+(response.dcrSignatureValidationSoftwareStatementJwksClaim == null ? null : response.dcrSignatureValidationSoftwareStatementJwksClaim)+} ,{\"op\":\"replace\", \"path\": \"/dcrSignatureValidationJwksUri\", \"value\": +(response.dcrSignatureValidationJwksUri == null ? null : response.dcrSignatureValidationJwksUri)+},{\"op\":\"replace\", \"path\": \"/dcrSignatureValidationJwks\", \"value\": +(response.dcrSignatureValidationJwks == null ? null : response.dcrSignatureValidationJwks)+} }, {\"op\":\"replace\", \"path\": \"/dcrAuthorizationWithClientCredentials\", \"value\": +(response.dcrAuthorizationWithClientCredentials == null ? false : response.dcrAuthorizationWithClientCredentials)+" }]" + And def request_body = (response.dcrSignatureValidationEnabled == null ? "[ {\"op\":\"add\", \"path\": \"/dcrSignatureValidationEnabled\", \"value\":false } ]" : "[ {\"op\":\"replace\", \"path\": \"/dcrSignatureValidationEnabled\", \"value\":"+response.dcrSignatureValidationEnabled+" } ]") + And print 'request_body ='+request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + Scenario: Patch dcrSignatureValidationSoftwareStatementJwksURIClaim configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And def request_body = (response.dcrSignatureValidationSoftwareStatementJwksURIClaim == null ? "[ {\"op\":\"add\", \"path\": \"/dcrSignatureValidationSoftwareStatementJwksURIClaim\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/dcrSignatureValidationSoftwareStatementJwksURIClaim\", \"value\":\""+response.dcrSignatureValidationSoftwareStatementJwksURIClaim+"\" } ]") + And print 'request_body ='+request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-softwareStatementValidationType-patch + Scenario: Patch softwareStatementValidationType Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + #And request "[ {\"op\":\"replace\", \"path\": \"/softwareStatementValidationType\", \"value\": +(response.softwareStatementValidationType == null ? null : response.softwareStatementValidationType)+ } ,{\"op\":\"replace\", \"path\": \"/softwareStatementValidationClaimName\", \"value\": +(response.softwareStatementValidationClaimName == null ? null : response.softwareStatementValidationClaimName)+ } ]" + And def request_body = (response.softwareStatementValidationType == null ? "[ {\"op\":\"add\", \"path\": \"/softwareStatementValidationType\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/softwareStatementValidationType\", \"value\":\""+response.softwareStatementValidationType+"\" } ]") + And print 'request_body ='+request_body + And request request_body + Then print request + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-cleanServiceBaseDns-patch + Scenario: Patch cleanServiceBaseDns Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And def request_body = (response.cleanServiceBaseDns == null ? "[ {\"op\":\"add\", \"path\": \"/cleanServiceBaseDns\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/cleanServiceBaseDns\", \"value\":"+response.cleanServiceBaseDns+" } ]") + And print 'request_body ='+request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-statistical-patch + Scenario: Patch statistical Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/statTimerIntervalInSeconds\", \"value\": "+response.statTimerIntervalInSeconds+" },{\"op\":\"replace\", \"path\": \"/statWebServiceIntervalLimitInSeconds\", \"value\": "+response.statWebServiceIntervalLimitInSeconds+" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch + Scenario: Patch loggingLevel Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And request "[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]" + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch + Scenario: Patch clientBlackList Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + #And request "[ {\"op\":\"replace\", \"path\": \"/clientBlackList\", \"value\": ['/*.attacker.com/*','/*.hackers.com/*']\" } ]" + And def request_body = (response.clientBlackList == null ? "[ {\"op\":\"add\", \"path\": \"/clientBlackList\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/clientBlackList\", \"value\":"+response.clientBlackList+" } ]") + And print 'request_body ='+request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch + Scenario: Patch clientAuthenticationFilters Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + #And request "[ {\"op\":\"replace\", \"path\": \"/clientAuthenticationFilters\", \"value\": read('clientAuthenticationFilters.json')\" } ]" + And def request_body = (response.clientAuthenticationFilters == null ? "[ {\"op\":\"add\", \"path\": \"/clientAuthenticationFilters\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/clientAuthenticationFilters\", \"value\":"+response.clientAuthenticationFilters+" } ]") + And print 'request_body ='+request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch + Scenario: Patch authenticationFilters Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And def request_body = (response.authenticationFilters == null ? "[ {\"op\":\"add\", \"path\": \"/authenticationFilters\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/authenticationFilters\", \"value\":"+response.authenticationFilters+"} ]") + And print 'request_body ='+request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch + Scenario: Patch keyAlgsAllowedForGeneration Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + #And def request_body = (response.keyAlgsAllowedForGeneration == null ? "[ {\"op\":\"add\", \"path\": \"/keyAlgsAllowedForGeneration\", \"value\":[\"RS256\"\,\"PS256\"] } ]" : "[ {\"op\":\"replace\", \"path\": \"/keyAlgsAllowedForGeneration\", \"value\":"+response.keyAlgsAllowedForGeneration+"} ]") + And def request_body = (response.keyAlgsAllowedForGeneration == null ? "[ {\"op\":\"add\", \"path\": \"/keyAlgsAllowedForGeneration\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/keyAlgsAllowedForGeneration\", \"value\":"+response.keyAlgsAllowedForGeneration+"} ]") + And print 'request_body ='+request_body + And request request_body + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch-discoveryAllowedKeys + Scenario: Patch discoveryAllowedKeys Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And def request_body = (response.discoveryAllowedKeys == null ? "[ {\"op\":\"add\", \"path\": \"/discoveryAllowedKeys\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/discoveryAllowedKeys\", \"value\":"+response.discoveryAllowedKeys+"} ]") + #And def request_body = (response.discoveryAllowedKeys == null ? "[ {\"op\":\"add\", \"path\": \"/discoveryAllowedKeys\", \"value\":[\"authorization_endpoint\",\"claims_parameter_supported\"] } ]" : "[ {\"op\":\"replace\", \"path\": \"/discoveryAllowedKeys\", \"value\":"+response.discoveryAllowedKeys+"} ]") + And print 'request_body ='+request_body + And request request_body + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch-dcrSignatureValidationSharedSecret -field + Scenario: Patch dcrSignatureValidationSharedSecret Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And def request_body = (response.dcrSignatureValidationSharedSecret == null ? "[ {\"op\":\"add\", \"path\": \"/dcrSignatureValidationSharedSecret\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/dcrSignatureValidationSharedSecret\", \"value\":\""+response.dcrSignatureValidationSharedSecret+"\" } ]") + And print 'request_body ='+request_body + And request request_body + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch-allowIdTokenWithoutImplicitGrantType + Scenario: Patch allowIdTokenWithoutImplicitGrantType Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And def request_body = (response.allowIdTokenWithoutImplicitGrantType == null ? "[ {\"op\":\"add\", \"path\": \"/allowIdTokenWithoutImplicitGrantType\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/allowIdTokenWithoutImplicitGrantType\", \"value\":"+response.allowIdTokenWithoutImplicitGrantType+"} ]") + And print 'request_body ='+request_body + And request request_body + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch-keySignWithSameKeyButDiffAlg + Scenario: Patch keySignWithSameKeyButDiffAlg Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And def request_body = (response.keySignWithSameKeyButDiffAlg == null ? "[ {\"op\":\"add\", \"path\": \"/keySignWithSameKeyButDiffAlg\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/keySignWithSameKeyButDiffAlg\", \"value\":"+response.keySignWithSameKeyButDiffAlg+"} ]") + And print 'request_body ='+request_body + And request request_body + When method PATCH + Then status 200 + And print response + + @ignore + @auth-config-patch-staticKid + Scenario: Patch staticKid Auth configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And header Accept = 'application/json' + And def request_body = (response.staticKid == null ? "[ {\"op\":\"add\", \"path\": \"/staticKid\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/staticKid\", \"value\":\""+response.staticKid+"\"} ]") + And print 'request_body ='+request_body + And request request_body + When method PATCH + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/request/object.feature b/jans-config-api/server/src/test/resources/json/config/properties/request/object.feature new file mode 100644 index 00000000000..b829bb7f44a --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/request/object.feature @@ -0,0 +1,33 @@ +@ignore +Feature: Verify RequestObject configuration endpoint + + Background: + * def mainUrl = requestObjectUrl + + @request_object-get + Scenario: Retrieve RequestObject configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @request_object-put + Scenario: Update RequestObject configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/response/modes/modes.feature b/jans-config-api/server/src/test/resources/json/config/properties/response/modes/modes.feature new file mode 100644 index 00000000000..0839593a138 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/response/modes/modes.feature @@ -0,0 +1,33 @@ +@ignore +Feature: Verify ResponseMode configuration endpoint + + Background: + * def mainUrl = responseModeUrl + + @responses_modes-get + Scenario: Retrieve ResponseMode configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @responses_modes-put + Scenario: Update ResponseMode configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/response/types/type.feature b/jans-config-api/server/src/test/resources/json/config/properties/response/types/type.feature new file mode 100644 index 00000000000..309b8efead6 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/response/types/type.feature @@ -0,0 +1,33 @@ +@ignore +Feature: Verify ResponseTypes configuration endpoint + + Background: + * def mainUrl = responsesTypesUrl + + @responses_types-get + Scenario: Retrieve ResponseType configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @responses_types-put + Scenario: Update ResponseType configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/server/cleanup.feature b/jans-config-api/server/src/test/resources/json/config/properties/server/cleanup.feature new file mode 100644 index 00000000000..f9c3f2da493 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/server/cleanup.feature @@ -0,0 +1,50 @@ +@ignore +Feature: Verify Server cleanup configuration endpoint + + Background: + * def mainUrl = serverCleanupUrl + + @server-get + Scenario: Retrieve Server cleanup configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @server-put + Scenario: Update Server cleanup configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('cleanup.json') + When method PUT + Then status 200 + And print response + And assert response.length != null + + @error + Scenario: Error case for cleanServiceInterval configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + Then def request_json = read('cleanup.json') + Then set request_json.cleanServiceInterval = 0 + #And print request_json + And request request_json + When method PUT + Then status 400 + And print response + + @error + Scenario: Error case for cleanServiceBatchChunkSize configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + Then def request_json = read('cleanup.json') + Then set request_json.cleanServiceBatchChunkSize = 0 + #And print request_json + And request request_json + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/server/cleanup.json b/jans-config-api/server/src/test/resources/json/config/properties/server/cleanup.json new file mode 100644 index 00000000000..704c9b7f820 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/server/cleanup.json @@ -0,0 +1,6 @@ +{ + "cleanServiceBatchChunkSize": 10000, + "cleanServiceInterval": 60, + "cleanServiceBaseDns": [ + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/server/config.feature b/jans-config-api/server/src/test/resources/json/config/properties/server/config.feature new file mode 100644 index 00000000000..87cf1dc78b0 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/server/config.feature @@ -0,0 +1,63 @@ +@ignore +Feature: Verify Server config configuration endpoint + + Background: + * def mainUrl = serverConfigUrl + + @server-get + Scenario: Retrieve Server config configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @server-put + Scenario: Update Server config configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + #And print response + Then def first_response = response + #And print first_response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 200 + And print response + + @error + Scenario: Error case for oxId configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.oxId = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + + @error + Scenario: Error case for configurationUpdateInterval configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + Then def first_response = response + Then set first_response.configurationUpdateInterval = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/server/config.json b/jans-config-api/server/src/test/resources/json/config/properties/server/config.json new file mode 100644 index 00000000000..9248a4bb6a8 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/server/config.json @@ -0,0 +1,26 @@ +{ + "useLocalCache": true, + "logClientNameOnClientAuthentication": false, + "fapiCompatibility": false, + "logClientIdOnClientAuthentication": true, + "errorReasonEnabled": false, + "cssLocation": "", + "jsLocation": "", + "clientRegDefaultToCodeFlowWithRefresh": true, + "introspectionScriptBackwardCompatibility": false, + "oxId": "https://pujavs3.infinity.com/oxid/service/gluu/inum", + "configurationUpdateInterval": 3600, + "authorizationRequestCustomAllowedParameters": [ + "customParam2", + "customParam3", + "customParam1" + ], + "disableU2fEndpoint": false, + "errorHandlingMethod": "INTERNAL", + "imgLocation": "", + "consentGatheringScriptBackwardCompatibility": false, + "personCustomObjectClassList": [ + "jansCustomPerson", + "jansPerson" + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/server/session/sessionId.feature b/jans-config-api/server/src/test/resources/json/config/properties/server/session/sessionId.feature new file mode 100644 index 00000000000..249e224a544 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/server/session/sessionId.feature @@ -0,0 +1,99 @@ +@ignore +Feature: Verify SessionId configuration endpoint + + Background: + * def mainUrl = sessionIdUrl + + @sessionid-get + Scenario: Retrieve SessionId configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @sessionid-put + Scenario: Update SessionId configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + @sessionid-error + Scenario: sessionIdUnusedLifetime configuration cannot be less than 1 (one) + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.sessionIdUnusedLifetime = -8 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @sessionid-error + Scenario: sessionIdUnusedLifetime configuration cannot be less than 1 (one) + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.sessionIdUnauthenticatedUnusedLifetime = -2 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @sessionid-error + Scenario: sessionIdLifetime configuration cannot be less than -1 (minus one) + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.sessionIdUnauthenticatedUnusedLifetime = -3 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @sessionid-error + Scenario: sessionIdCookieLifetime configuration cannot be less than -1 (minus one) + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.sessionIdCookieLifetime = -5 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/subject/subject.feature b/jans-config-api/server/src/test/resources/json/config/properties/subject/subject.feature new file mode 100644 index 00000000000..58a53ef79de --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/subject/subject.feature @@ -0,0 +1,38 @@ +@ignore +Feature: Verify Subject configuration endpoint + + Background: + * def mainUrl = subjectUrl + + @subject-get + Scenario: Retrieve Subject configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @subject-put + Scenario: Update Subject configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('subject.json') + When method PUT + Then status 200 + And print response + And assert response.length != null + + @error + Scenario: Error case for subjectTypesSupported configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + Then def request_json = read('subject.json') + Then set request_json.subjectTypesSupported = null + And print request_json + And request request_json + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/subject/subject.json b/jans-config-api/server/src/test/resources/json/config/properties/subject/subject.json new file mode 100644 index 00000000000..dfa9a632981 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/subject/subject.json @@ -0,0 +1,7 @@ + { + "subjectTypesSupported": [ + "public", + "pairwise" + ], + "shareSubjectIdBetweenClientsWithSameSectorId": true +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/token/token.feature b/jans-config-api/server/src/test/resources/json/config/properties/token/token.feature new file mode 100644 index 00000000000..f32a2ba31f2 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/token/token.feature @@ -0,0 +1,61 @@ +@ignore +Feature: Verify Token configuration endpoint + + Background: + * def mainUrl = tokenUrl + + @token-get + Scenario: Retrieve Token configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @token-put + Scenario: Update Token configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('token.json') + When method PUT + Then status 200 + And print response + And assert response.length != null + + @error + Scenario: Error case for authorizationCodeLifetime configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + Then def request_json = read('token.json') + Then set request_json.authorizationCodeLifetime = 0 + And print request_json + And request request_json + When method PUT + Then status 400 + And print response + + @error + Scenario: Error case for refreshTokenLifetime configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + Then def request_json = read('token.json') + Then set request_json.refreshTokenLifetime = 0 + And print request_json + And request request_json + When method PUT + Then status 400 + And print response + + @error + Scenario: Error case for accessTokenLifetime configuration validation + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + Then def request_json = read('token.json') + Then set request_json.accessTokenLifetime = 0 + And print request_json + And request request_json + When method PUT + Then status 400 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/token/token.json b/jans-config-api/server/src/test/resources/json/config/properties/token/token.json new file mode 100644 index 00000000000..c571aadcb21 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/token/token.json @@ -0,0 +1,6 @@ + { + "persistRefreshToken": true, + "authorizationCodeLifetime": 60, + "refreshTokenLifetime": 14400, + "accessTokenLifetime": 300 +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/uma/configuration/configuration.feature b/jans-config-api/server/src/test/resources/json/config/properties/uma/configuration/configuration.feature new file mode 100644 index 00000000000..61d15304c64 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/uma/configuration/configuration.feature @@ -0,0 +1,118 @@ +@ignore +Feature: Verify UmaConfiguration endpoint + + Background: + * def mainUrl = umaConfigurationUrl + + @uma-get + Scenario: Retrieve UmaConfiguration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @uma-put + Scenario: Update UmaConfiguration configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + @uma-error + Scenario: umaConfigurationEndpoint configuration cannot be null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.umaConfigurationEndpoint = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @uma-error + Scenario: umaRptLifetime configuration cannot be less than 1 (one) + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.umaRptLifetime = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @uma-error + Scenario: umaTicketLifetime configuration cannot be less than 1 (one) + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.umaTicketLifetime = -100 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @uma-error + Scenario: umaPctLifetime configuration cannot be less than 1 (one) + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.umaPctLifetime = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @uma-error + Scenario: umaResourceLifetime configuration cannot be less than 1 (one) + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.umaResourceLifetime = 0 + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/properties/user/info/userInfo.feature b/jans-config-api/server/src/test/resources/json/config/properties/user/info/userInfo.feature new file mode 100644 index 00000000000..251652abb0f --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/properties/user/info/userInfo.feature @@ -0,0 +1,84 @@ +@ignore +Feature: Verify UserInfo configuration endpoint + + Background: + * def mainUrl = userInfoUrl + + @userInfo-get + Scenario: Retrieve UserInfo configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @userInfo-put + Scenario: Update UserInfo configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + + @userInfo-error + Scenario: userInfoSigningAlgValuesSupported configuration is null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.userInfoSigningAlgValuesSupported = '' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @userInfo-error + Scenario: userInfoEncryptionAlgValuesSupported configuration is null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.userInfoEncryptionAlgValuesSupported = '' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + @userInfo-error + Scenario: userInfoEncryptionEncValuesSupported configuration is null or empty + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.userInfoEncryptionEncValuesSupported = '' + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/all-script.json b/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/all-script.json new file mode 100644 index 00000000000..c3cf5e2763c --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/all-script.json @@ -0,0 +1,1249 @@ + [ + { + "internal": false, + "level": 1, + "programmingLanguage": "PYTHON", + "description": "Introspection Custom Parameters Sample Script", + "locationType": "LDAP", + "dn": "inum=2DAF-BA90,ou=scripts,o=gluu", + "inum": "2DAF-BA90", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2019, Gluu\n#\n# Author: Yuriy Mochan\n#\n#\n\nfrom org.gluu.model.custom.script.type.introspection import IntrospectionType\nfrom org.gluu.oxauth.model.common import AuthorizationGrantList\nfrom org.gluu.oxauth.service import SessionIdService\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom java.lang import String\n\nclass Introspection(IntrospectionType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Introspection script. Initializing ...\"\n print \"Introspection script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Introspection script. Destroying ...\"\n print \"Introspection script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns boolean, true - apply introspection method, false - ignore it.\n # This method is called after introspection response is ready. This method can modify introspection response.\n # Note :\n # responseAsJsonObject - is org.codehaus.jettison.json.JSONObject, you can use any method to manipulate json\n # context is reference of org.gluu.oxauth.service.external.context.ExternalIntrospectionContext (in https://github.com/GluuFederation/oxauth project, )\n def modifyResponse(self, responseAsJsonObject, context):\n token = context.getHttpRequest().getParameter(\"token\")\n if token is None:\n print \"Introspection. There is no token in request\"\n return False\n\n authorizationGrantList = CdiUtil.bean(AuthorizationGrantList)\n authorizationGrant = authorizationGrantList.getAuthorizationGrantByAccessToken(token);\n if authorizationGrant is None:\n print \"Introspection. Failed to load authorization grant by token\"\n return False\n\n # Put user_id into response\n responseAsJsonObject.accumulate(\"user_id\", authorizationGrant.getUser().getUserId())\n\n # Put custom parameters into response\n sessionDn = authorizationGrant.getSessionDn();\n if sessionDn is None:\n # There is no session\n return True\n\n sessionIdService = CdiUtil.bean(SessionIdService)\n session = sessionIdService.getSessionById(sessionDn)\n if sessionDn is None:\n print \"Introspection. Failed to load session '%s'\" % sessionDn\n return False\n\n # Return session_id\n responseAsJsonObject.accumulate(\"session_id\", sessionDn)\n \n sessionAttributes = session.getSessionAttributes()\n if sessionAttributes is None:\n # There is no session attributes\n return True\n\n # Append custom claims\n if sessionAttributes.containsKey(\"custom1\"):\n responseAsJsonObject.accumulate(\"custom1\", sessionAttributes.get(\"custom1\"))\n if sessionAttributes.containsKey(\"custom2\"):\n responseAsJsonObject.accumulate(\"custom2\", sessionAttributes.get(\"custom2\"))\n\n return True\n\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "INTROSPECTION", + "name": "introspection_custom_params", + "modified": false, + "baseDn": "inum=2DAF-BA90,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 1, + "programmingLanguage": "PYTHON", + "description": "Resource Owner Password Credentials Example", + "locationType": "LDAP", + "dn": "inum=2DAF-AA91,ou=scripts,o=gluu", + "inum": "2DAF-AA91", + "script": "from org.gluu.model.custom.script.type.owner import ResourceOwnerPasswordCredentialsType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom java.lang import String\n\nclass ResourceOwnerPasswordCredentials(ResourceOwnerPasswordCredentialsType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"ROPC script. Initializing ...\"\n\n self.usernameParamName = \"username\"\n self.passwordParamName = \"password\"\n\n print \"ROPC script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"ROPC script. Destroying ...\"\n print \"ROPC script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns True and set user into context when user authenticated succesfully\n # Returns False when user not authenticated or it's needed to cancel notmal flow\n # Note :\n # context is reference of org.gluu.oxauth.service.external.context.ExternalResourceOwnerPasswordCredentialsContext#ExternalResourceOwnerPasswordCredentialsContext (in https://github.com/GluuFederation/oxauth project, )\n def authenticate(self, context):\n print \"ROPC script. Authenticate\"\n deviceIdParam = context.getHttpRequest().getParameterValues(\"device_id\")\n if deviceIdParam != None and (deviceIdParam.lenght > 0 ):\n result = deviceIdParam[0] == \"device_id_1\"\n if not result:\n return False\n\n # Set auntenticated user in context\n # context.setUser(user)\n return True\n\n # Do generic authentication in other cases\n authService = CdiUtil.bean(AuthenticationService)\n\n username = context.getHttpRequest().getParameter(self.usernameParamName)\n password = context.getHttpRequest().getParameter(self.passwordParamName)\n result = authService.authenticate(username, password)\n if not result:\n print \"ROPC script. Authenticate. Could not authenticate user '%s' \" % username\n return False\n\n context.setUser(authService.getAuthenticatedUser())\n\n return True\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "RESOURCE_OWNER_PASSWORD_CREDENTIALS", + "name": "resource_owner_password_credentials_example", + "modified": false, + "baseDn": "inum=2DAF-AA91,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 1, + "programmingLanguage": "PYTHON", + "description": "Frontchannel logout Sample", + "locationType": "LDAP", + "dn": "inum=2DAF-CA90,ou=scripts,o=gluu", + "inum": "2DAF-CA90", + "script": "# Copyright (c) 2020, Gluu\n#\n# Author: Yuriy Zabrovarnyy\n#\n\nfrom org.gluu.model.custom.script.type.logout import EndSessionType\nfrom java.lang import String\n\nclass EndSession(EndSessionType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"EndSession script. Initializing ...\"\n print \"EndSession script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"EndSession script. Destroying ...\"\n print \"EndSession script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns string, it must be valid HTML (with iframes according to spec http://openid.net/specs/openid-connect-frontchannel-1_0.html)\n # This method is called on `/end_session` after actual session is killed and oxauth construct HTML to return to RP.\n # Note :\n # context is reference of org.gluu.oxauth.service.external.context.EndSessionContext (in https://github.com/GluuFederation/oxauth project, )\n def getFrontchannelHtml(self, context):\n return \"\"", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "END_SESSION", + "name": "frontchannel_logout_sample", + "modified": false, + "baseDn": "inum=2DAF-CA90,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 1, + "programmingLanguage": "PYTHON", + "description": "Sample UMA Claims Gathering", + "locationType": "LDAP", + "dn": "inum=2DAF-F996,ou=scripts,o=gluu", + "inum": "2DAF-F996", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2017, Gluu\r\n#\r\n# Author: Yuriy Zabrovarnyy\r\n#\r\n\r\nfrom org.gluu.model.custom.script.type.uma import UmaClaimsGatheringType\r\n\r\nclass UmaClaimsGathering(UmaClaimsGatheringType):\r\n\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Claims-Gathering. Initializing ...\"\r\n print \"Claims-Gathering. Initialized successfully\"\r\n\r\n return True\r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Claims-Gathering. Destroying ...\"\r\n print \"Claims-Gathering. Destroyed successfully\"\r\n return True\r\n\r\n def getApiVersion(self):\r\n return 11\r\n\r\n\r\n # Main gather method. Must return True (if gathering performed successfully) or False (if fail).\r\n # Method must set claim into context (via context.putClaim('name', value)) in order to persist it (otherwise it will be lost).\r\n # All user entered values can be access via Map context.getPageClaims()\r\n def gather(self, step, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaGatherContext\r\n print \"Claims-Gathering. Gathering ...\"\r\n\r\n if step == 1:\r\n if (context.getPageClaims().containsKey(\"country\")):\r\n country = context.getPageClaims().get(\"country\")\r\n print \"Country: \" + country\r\n\r\n context.putClaim(\"country\", country)\r\n return True\r\n\r\n print \"Claims-Gathering. 'country' is not provided on step 1.\"\r\n return False\r\n\r\n elif step == 2:\r\n if (context.getPageClaims().containsKey(\"city\")):\r\n city = context.getPageClaims().get(\"city\")\r\n print \"City: \" + city\r\n\r\n context.putClaim(\"city\", city)\r\n print \"Claims-Gathering. 'city' is not provided on step 2.\"\r\n return True\r\n\r\n return False\r\n\r\n def getNextStep(self, step, context):\r\n return -1\r\n\r\n def prepareForStep(self, step, context):\r\n if step == 10 and not context.isAuthenticated():\r\n # user is not authenticated, so we are redirecting user to authorization endpoint\r\n # client_id is specified via configuration attribute.\r\n # Make sure that given client has redirect_uri to Claims-Gathering Endpoint with parameter authentication=true\r\n # Sample https://sample.com/restv1/uma/gather_claims?authentication=true\r\n # If redirect to external url is performated, make sure that viewAction has onPostback=\"true\" (otherwise redirect will not work)\r\n # After user is authenticated then within the script it's possible to get user attributes as\r\n # context.getUser(\"uid\", \"sn\")\r\n # If user is authenticated to current AS (to the same server, not external one) then it's possible to\r\n # access Connect session attributes directly (no need to obtain id_token after redirect with 'code').\r\n # To fetch attributes please use getConnectSessionAttributes() method.\r\n\r\n print \"User is not authenticated. Redirect for authentication ...\"\r\n clientId = context.getConfigurationAttributes().get(\"client_id\").getValue2()\r\n redirectUri = context.getClaimsGatheringEndpoint() + \"?authentication=true\" # without authentication=true parameter it will not work\r\n authorizationUrl = context.getAuthorizationEndpoint() + \"?client_id=\" + clientId + \"&redirect_uri=\" + redirectUri + \"&scope=openid&response_type=code\"\r\n context.redirectToExternalUrl(authorizationUrl) # redirect to external url\r\n return False\r\n if step == 10 and context.isAuthenticated(): # example how to get session attribute if user is authenticated to same AS\r\n arc = context.getConnectSessionAttributes().get(\"acr\")\r\n\r\n return True\r\n\r\n def getStepsCount(self, context):\r\n return 2\r\n\r\n def getPageForStep(self, step, context):\r\n if step == 1:\r\n return \"/uma2/sample/country.xhtml\"\r\n elif step == 2:\r\n return \"/uma2/sample/city.xhtml\"\r\n return \"\"", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "UMA_CLAIMS_GATHERING", + "name": "sampleClaimsGathering", + "modified": false, + "baseDn": "inum=2DAF-F996,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 1, + "programmingLanguage": "PYTHON", + "description": "Super Gluu RO Password Credentials Script", + "locationType": "LDAP", + "dn": "inum=B8FD-4C11,ou=scripts,o=gluu", + "inum": "B8FD-4C11", + "script": "# Super Gluu Radius Resource Owner Password Credentials Script\n# Copyright (c) 2019 Gluu Inc.\n\nfrom java.util import Date , HashMap\nfrom org.gluu.oxnotify.client import NotifyClientFactory\n\nfrom org.gluu.model.custom.script.type.owner import ResourceOwnerPasswordCredentialsType\nfrom org.gluu.oxauth.model.common import SessionIdState\nfrom org.gluu.oxauth.model.config import ConfigurationFactory , Constants\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.common import EncryptionService, UserService\nfrom org.gluu.oxauth.service.push.sns import PushPlatform, PushSnsService\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\nfrom gluu_common import PushNotificationManager, NetworkApi, GeolocationData, SuperGluuRequestBuilder\n\nimport java\nimport json\nimport sys\n\n\nclass ResourceOwnerPasswordCredentials(ResourceOwnerPasswordCredentialsType):\n def __init__(self,currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n self.initiateAuthStepName = \"initiate_auth\"\n self.verifyAuthStepName = \"verify_auth\"\n self.resendNotificationStepName = \"resend_notification\"\n self.stepParamName = \"__step\"\n self.acrvaluesParamName = \"__acr_values\"\n self.usernameParamName = \"username\"\n self.passwordParamName = \"__password\"\n self.idtokenParamName = \"__id_token\"\n self.sessionIdParamName = \"__session_id\"\n self.remoteIpParamName = \"__remote_ip\"\n self.sessionIdClaimName = \"__session_id\"\n self.clientIdSessionParamName = \"__client_id\"\n self.authSchemeParamName = \"__auth_scheme\"\n self.oneStepAuthScheme = \"onestep\"\n self.twoStepAuthScheme = \"twostep\"\n \n def init(self, customScript, configurationAttributes):\n\n print \"Super-Gluu-RO Init\"\n if not configurationAttributes.containsKey(\"application_id\"):\n print \"Super-Gluu-Radius RO PW Init Failed. application_id property is required\"\n return False\n \n if not configurationAttributes.containsKey(\"credentials_file\"):\n print \"Super-Gluu-RO Init Failed. credentials_file is required\"\n return False\n \n notificationServiceMode = None\n if configurationAttributes.containsKey(\"notification_service_mode\"):\n notificationServiceMode = configurationAttributes.get(\"notification_service_mode\").getValue2()\n \n \n self.applicationId = \"*\" # wildcard. Selects all devices irrespective of the application \n if configurationAttributes.containsKey(\"application_id\"):\n self.applicationId = configurationAttributes.get(\"application_id\").getValue2()\n \n credentialsFile = configurationAttributes.get(\"credentials_file\").getValue2()\n\n if configurationAttributes.containsKey(\"push_notification_title\"):\n self.pushNotificationManager.titleTemplate = configurationAttributes.get(\"push_notification_title\").getValue2()\n \n if configurationAttributes.containsKey(\"push_notification_message\"):\n self.pushNotificationManager.messageTemplate = configurationAttributes.get(\"push_notification_message\").getValue2()\n \n self.authWithoutPassword = False\n if configurationAttributes.containsKey(\"auth_without_password\"):\n auth_without_password = configurationAttributes.get(\"auth_without_password\").getValue2()\n if StringHelper.equalsIgnoreCase(auth_without_password,\"yes\"):\n self.authWithoutPassword = True\n \n self.issuerId = CdiUtil.bean(ConfigurationFactory).getAppConfiguration().getIssuer()\n if configurationAttributes.containsKey(\"issuer_id\"):\n self.issuerId = configurationAttributes.get(\"issuer_id\").getValue2()\n \n self.pushNotificationManager = PushNotificationManager(notificationServiceMode,credentialsFile)\n self.networkApi = NetworkApi()\n\n return True\n \n def destroy(self, configurationAttributes):\n\n print \"Super-Gluu-RO. Destroy\"\n self.pushNotificationManager = None\n print \"Super-Gluu-RO. Destroyed Successfully\"\n\n return True\n \n def getApiVersion(self):\n return 11\n \n def authenticate(self, context): \n if self.perform_preliminary_user_authentication(context) == False:\n print \"Super-Gluu-RO. User authentication state not validated\"\n return False\n \n step = context.getHttpRequest().getParameter(self.stepParamName)\n if StringHelper.equalsIgnoreCase(step,self.initiateAuthStepName):\n return self.initiate_authentication(context)\n elif StringHelper.equalsIgnoreCase(step,self.resendNotificationStepName):\n return self.resend_push_notification(context)\n elif StringHelper.equalsIgnoreCase(step,self.verifyAuthStepName):\n return self.verify_authentication(context)\n else:\n context.setUser(None)\n print \"Super-Gluu-RO. Unknown authentication step '%s'\" % step\n return False\n \n def initiate_authentication(self, context):\n print \"Super-Gluu-RO initiatate_authentication\"\n\n authscheme = context.getHttpRequest().getParameter(self.authSchemeParamName)\n if authscheme == None:\n authscheme = self.twoStepAuthScheme\n \n if StringHelper.equalsIgnoreCase(authscheme,self.oneStepAuthScheme):\n print \"Super-Gluu-RO using one-step authentication\"\n print \"User '%s' authenticated using one-step\" % context.getUser().getUserId()\n return True\n elif StringHelper.equalsIgnoreCase(authscheme,self.twoStepAuthScheme):\n print \"Super-Gluu-RO using two-step authentication\"\n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n sessionId = self.new_unauthenticated_session(context.getUser(),client)\n # set session id in identity object \n # this will be used by our dynamic scope script \n identity = CdiUtil.bean(Identity)\n identity.setSessionId(sessionId)\n if not self.send_push_notification_to_user(sessionId,context):\n print \"Send push notification to user '%s' failed\" % context.getUser().getUserId()\n context.setUser(None)\n return False\n print \"Super-Gluu-RO initiate_authentication complete\"\n return True\n else:\n print \"Super-Gluu-RO. Unknown authentication scheme specified '%s'\" % authscheme\n context.setUser(None)\n return False\n \n \n print \"Super-Gluu-RO using two-step authentication\"\n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n sessionId = self.new_unauthenticated_session(context.getUser(),client)\n # set session id in identity object\n # this will be used by our dynamic scope script\n identity = CdiUtil.bean(Identity)\n identity.setSessionId(sessionId)\n if not self.send_push_notification_to_user(sessionId,context):\n print \"Send push notification to user '%s' failed \" % context.getUser().getUserId()\n context.setUser(None)\n return False\n print \"Super-Gluu-RO initiate_authentication complete\"\n return True\n \n def resend_push_notification(self,context):\n print \"Super-Gluu-RO resend_push_notification\"\n\n sessionIdService = CdiUtil.bean(SessionIdService)\n session_id = context.getHttpRequest().getParameter(self.sessionIdParamName)\n if session_id == None:\n print \"Super-Gluu-RO. No session_id was specified for resend_push_notification\"\n context.setUser(None)\n return False\n \n sessionId = sessionIdService.getSessionId(session_id)\n if sessionId == None:\n print \"Super-Gluu-RO. Session '%s' does not exist or has expired\" % session_id\n context.setUser(None)\n return False\n \n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n if not self.verify_session_ownership(sessionId,context.getUser(),client):\n print \"Super-Gluu-RO. resend_push_notification_failed due to invalid session ownership\"\n context.setUser(None)\n return False\n \n self.send_push_notification_to_user(sessionId,context)\n print \"Super-Gluu-RO resend_push_notification complete\"\n return True\n \n def verify_authentication(self, context):\n print \"Super-Gluu-RO verify_authentication\"\n session_id = context.getHttpRequest().getParameter(self.sessionIdParamName)\n sessionId = CdiUtil.bean(SessionIdService).getSessionId(session_id)\n if sessionId == None:\n print \"Super-Gluu-RO.verify_authentication failed. Session {%s} does not exist or has expired\" % session_id\n context.setUser(None)\n return False\n \n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n if not self.verify_session_ownership(sessionId,context.getUser(),client):\n print \"Super-Gluu-RO. verify_authentication failed due to invalid session ownership\"\n context.setUser(None)\n return False\n \n if not self.is_session_authenticated(sessionId):\n print \"Super-Gluu-Ro. verify_authentication failed. Session is not authenticated\"\n context.setUser(None)\n return False\n \n print \"Super-Gluu-RO verify_authentication complete\"\n return True\n \n def perform_preliminary_user_authentication(self, context):\n username = context.getHttpRequest().getParameter(self.usernameParamName)\n if self.authWithoutPassword:\n userService = CdiUtil.bean(UserService)\n user = userService.getUser(username,\"uid\")\n if user == None:\n print \"Super-Gluu-RO. User '%s' not found\" % username\n return False\n context.setUser(user)\n print \"Super-Gluu-RO. User '%s' authenticated without password\" % username\n return True\n \n password = context.getHttpRequest().getParameter(self.passwordParamName)\n authService = CdiUtil.bean(AuthenticationService)\n if authService.authenticate(username, password) == False:\n print \"Super-Gluu-RO. Could not authenticate user '%s' \" % username\n return False\n\n context.setUser(authService.getAuthenticatedUser())\n return True\n \n def new_unauthenticated_session(self,user,client):\n sessionIdService = CdiUtil.bean(SessionIdService)\n authDate = Date()\n sid_attrs = HashMap()\n sid_attrs.put(Constants.AUTHENTICATED_USER,user.getUserId())\n sid_attrs.put(self.clientIdSessionParamName,client.getClientId())\n sessionId = sessionIdService.generateUnauthenticatedSessionId(user.getDn(),authDate,SessionIdState.UNAUTHENTICATED,sid_attrs,True)\n print \"Super-Gluu-RO. Generated session id. DN: '%s'\" % sessionId.getDn()\n return sessionId\n \n def send_push_notification_to_user(self, sessionId,context):\n remote_ip = context.getHttpRequest().getParameter(self.remoteIpParamName)\n if remote_ip == None or (remote_ip != None and StringHelper.isEmpty(remote_ip)):\n remote_ip = self.networkApi.get_remote_ip_from_request(context.getHttpRequest())\n \n user = context.getUser()\n srbuilder = SuperGluuRequestBuilder()\n srbuilder.username = user.getUserId()\n srbuilder.app = self.applicationId\n srbuilder.issuer = self.issuerId\n srbuilder.state = sessionId.getId()\n srbuilder.requestLocation(self.networkApi.get_geolocation_data(remote_ip))\n srbuilder.req_ip = remote_ip \n device_count = self.pushNotificationManager.sendPushNotification(user,self.applicationId,srbuilder.build())\n \n if device_count == 0:\n print \"User %s has no device enrolled for Super-Gluu authentication\" % user.getUserId()\n return False\n return True\n\n \n\n def is_session_authenticated(self, sessionId):\n if sessionId == None:\n return False\n \n state = sessionId.getState()\n custom_state = sessionId.getSessionAttributes().get(SessionIdService.SESSION_CUSTOM_STATE)\n if state == None:\n print \"Super-Gluu-RO. Session {%s} has no state variable set\" % sessionId.getId()\n return False\n \n state_unauthenticated = SessionIdState.UNAUTHENTICATED == state\n state_authenticated = SessionIdState.AUTHENTICATED == state\n custom_state_declined = StringHelper.equalsIgnoreCase(\"declined\",custom_state) \n custom_state_expired = StringHelper.equalsIgnoreCase(\"expired\",custom_state)\n custom_stated_approved = StringHelper.equalsIgnoreCase(\"approved\",custom_state)\n\n if state_unauthenticated and (custom_state_declined or custom_state_expired):\n print \"Super-Gluu-RO. Session {%s} isn't authenticated\" % sessionId.getId()\n return False\n \n if state_authenticated or (state_unauthenticated and custom_stated_approved):\n print \"Super-Gluu-RO. Session {%s} is authenticated\" % sessionId.getId()\n return True\n\n return False\n \n # this function verifies if the session was created when invoked with the \n # current client's credentials and with the current user's credentials\n\n def verify_session_ownership(self, sessionId, user, client):\n session_attributes = sessionId.getSessionAttributes()\n client_id = session_attributes.get(self.clientIdSessionParamName)\n if not StringHelper.equalsIgnoreCase(client.getClientId(),client_id):\n print \"Super-Gluu-RO. Session {%s} client_id mismatch\" % sessionId.getId()\n return False\n \n user_id = session_attributes.get(Constants.AUTHENTICATED_USER)\n if not StringHelper.equalsIgnoreCase(user_id,user.getUserId()):\n print \"Super-Gluu-RO. Session {%s} user_id mismatch\" % sessionId.getId() \n return False\n \n return True\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "RESOURCE_OWNER_PASSWORD_CREDENTIALS", + "name": "super_gluu_ro", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "/etc/certs/super_gluu_creds.json", + "value1": "credentials_file" + }, + { + "hide": false, + "value2": "gluu", + "value1": "notification_service_mode" + }, + { + "hide": false, + "value2": "https://pujavs4.2.gluu.server/identity/authcode.htm", + "value1": "application_id" + } + ], + "baseDn": "inum=B8FD-4C11,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 1, + "programmingLanguage": "PYTHON", + "description": "Introspection Sample Script", + "locationType": "LDAP", + "dn": "inum=2DAF-AA90,ou=scripts,o=gluu", + "inum": "2DAF-AA90", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2018, Gluu\n#\n# Author: Yuriy Zabrovarnyy\n#\n#\n\nfrom org.gluu.model.custom.script.type.introspection import IntrospectionType\nfrom java.lang import String\n\nclass Introspection(IntrospectionType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Introspection script. Initializing ...\"\n print \"Introspection script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Introspection script. Destroying ...\"\n print \"Introspection script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns boolean, true - apply introspection method, false - ignore it.\n # This method is called after introspection response is ready. This method can modify introspection response.\n # Note :\n # responseAsJsonObject - is org.codehaus.jettison.json.JSONObject, you can use any method to manipulate json\n # context is reference of org.gluu.oxauth.service.external.context.ExternalIntrospectionContext (in https://github.com/GluuFederation/oxauth project, )\n def modifyResponse(self, responseAsJsonObject, context):\n responseAsJsonObject.accumulate(\"key_from_script\", \"value_from_script\")\n return True\n\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "INTROSPECTION", + "name": "introspection_sample", + "modified": false, + "baseDn": "inum=2DAF-AA90,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 1, + "programmingLanguage": "PYTHON", + "description": "Resource Owner Password Credentials Custom Parameters Example", + "locationType": "LDAP", + "dn": "inum=2DAF-BA91,ou=scripts,o=gluu", + "inum": "2DAF-BA91", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2019, Gluu\n#\n# Author: Yuriy Mochan\n#\n#\n\nfrom org.gluu.model.custom.script.type.owner import ResourceOwnerPasswordCredentialsType\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.model.common import SessionIdState\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.model.authorize import AuthorizeRequestParam\nfrom org.gluu.oxauth.model.config import Constants\nfrom org.gluu.util import StringHelper\nfrom java.lang import String\nfrom java.util import Date, HashMap\n\nclass ResourceOwnerPasswordCredentials(ResourceOwnerPasswordCredentialsType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"ROPC script. Initializing ...\"\n print \"ROPC script. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"ROPC script. Destroying ...\"\n print \"ROPC script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns True and set user into context when user authenticated succesfully\n # Returns False when user not authenticated or it's needed to cancel notmal flow\n # Note :\n # context is reference of org.gluu.oxauth.service.external.context.ExternalResourceOwnerPasswordCredentialsContext#ExternalResourceOwnerPasswordCredentialsContext (in https://github.com/GluuFederation/oxauth project, )\n def authenticate(self, context):\n print \"ROPC script. Authenticate\"\n\n # Do generic authentication\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n username = context.getHttpRequest().getParameter(\"username\")\n password = context.getHttpRequest().getParameter(\"password\")\n result = authenticationService.authenticate(username, password)\n if not result:\n print \"ROPC script. Authenticate. Could not authenticate user '%s' \" % username\n return False\n\n context.setUser(authenticationService.getAuthenticatedUser())\n print \"ROPC script. Authenticate. User '%s' authenticated successfully\" % username\n \n\n # Get cusom parameters from request\n customParam1Value = context.getHttpRequest().getParameter(\"custom1\")\n customParam2Value = context.getHttpRequest().getParameter(\"custom2\")\n\n customParameters = {}\n customParameters[\"custom1\"] = customParam1Value\n customParameters[\"custom2\"] = customParam2Value\n print \"ROPC script. Authenticate. User '%s'. Creating authenticated session with custom attributes: '%s'\" % (username, customParameters)\n\n session = self.createNewAuthenticatedSession(context, customParameters)\n \n # This is needed to allow store in token entry sessionId\n authenticationService.configureEventUser(session)\n\n print \"ROPC script. Authenticate. User '%s'. Created authenticated session: '%s'\" % (username, customParameters)\n\n return True\n\n def createNewAuthenticatedSession(self, context, customParameters={}):\n sessionIdService = CdiUtil.bean(SessionIdService)\n\n user = context.getUser()\n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n\n # Add mandatory session parameters\n sessionAttributes = HashMap()\n sessionAttributes.put(Constants.AUTHENTICATED_USER, user.getUserId())\n sessionAttributes.put(AuthorizeRequestParam.CLIENT_ID, client.getClientId())\n sessionAttributes.put(AuthorizeRequestParam.PROMPT, \"\")\n\n # Add custom session parameters\n for key, value in customParameters.iteritems():\n if StringHelper.isNotEmpty(value):\n sessionAttributes.put(key, value)\n\n # Generate authenticated session\n sessionId = sessionIdService.generateAuthenticatedSessionId(context.getHttpRequest(), user.getDn(), sessionAttributes)\n\n print \"ROPC script. Generated session id. DN: '%s'\" % sessionId.getDn()\n\n return sessionId\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "RESOURCE_OWNER_PASSWORD_CREDENTIALS", + "name": "resource_owner_password_credentials_custom_params_example", + "modified": false, + "baseDn": "inum=2DAF-BA91,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 10, + "programmingLanguage": "PYTHON", + "description": "Firebase notification sender", + "locationType": "LDAP", + "dn": "inum=C1BA-C1BA,ou=scripts,o=gluu", + "inum": "C1BA-C1BA", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2018, Gluu\n#\n# Author: Milton BO\n#\n#\n\nfrom org.gluu.oxauth.client.fcm import FirebaseCloudMessagingResponse\nfrom org.gluu.oxauth.client.fcm import FirebaseCloudMessagingClient\nfrom org.gluu.oxauth.client.fcm import FirebaseCloudMessagingRequest\nfrom org.gluu.oxauth.util import RedirectUri\nfrom org.gluu.model.custom.script.type.ciba import EndUserNotificationType\nfrom java.lang import String\nfrom java.util import UUID\n\nclass EndUserNotification(EndUserNotificationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, configurationAttributes):\n print \"Firebase EndUserNotification script. Initializing ...\"\n print \"Firebase EndUserNotification script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Firebase EndUserNotification script. Destroying ...\"\n print \"Firebase EndUserNotification script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 1\n\n # Returns boolean true or false depending on the process, if the notification\n # is sent successfully or not.\n def notifyEndUser(self, context):\n print 'Sending push notification using Firebase Cloud Messaging'\n appConfiguration = context.getAppConfiguration()\n encryptionService = context.getEncryptionService()\n clientId = appConfiguration.getBackchannelClientId()\n redirectUri = appConfiguration.getBackchannelRedirectUri()\n url = appConfiguration.getCibaEndUserNotificationConfig().getNotificationUrl()\n key = encryptionService.decrypt(appConfiguration.getCibaEndUserNotificationConfig().getNotificationKey(), True)\n to = context.getDeviceRegistrationToken()\n title = \"oxAuth Authentication Request\"\n body = \"Client Initiated Backchannel Authentication (CIBA)\"\n\n authorizationRequestUri = RedirectUri(appConfiguration.getAuthorizationEndpoint())\n authorizationRequestUri.addResponseParameter(\"client_id\", clientId)\n authorizationRequestUri.addResponseParameter(\"response_type\", \"id_token\")\n authorizationRequestUri.addResponseParameter(\"scope\", context.getScope())\n authorizationRequestUri.addResponseParameter(\"acr_values\", context.getAcrValues())\n authorizationRequestUri.addResponseParameter(\"redirect_uri\", redirectUri)\n authorizationRequestUri.addResponseParameter(\"state\", UUID.randomUUID().toString())\n authorizationRequestUri.addResponseParameter(\"nonce\", UUID.randomUUID().toString())\n authorizationRequestUri.addResponseParameter(\"prompt\", \"consent\")\n authorizationRequestUri.addResponseParameter(\"auth_req_id\", context.getAuthReqId())\n\n clickAction = authorizationRequestUri.toString()\n\n firebaseCloudMessagingRequest = FirebaseCloudMessagingRequest(key, to, title, body, clickAction)\n firebaseCloudMessagingClient = FirebaseCloudMessagingClient(url)\n firebaseCloudMessagingClient.setRequest(firebaseCloudMessagingRequest)\n firebaseCloudMessagingResponse = firebaseCloudMessagingClient.exec()\n\n responseStatus = firebaseCloudMessagingResponse.getStatus()\n print \"CIBA: firebase cloud messaging result status \" + str(responseStatus)\n return (responseStatus >= 200 and responseStatus < 300 )\n\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "CIBA_END_USER_NOTIFICATION", + "name": "firebase_ciba_end_user_notification", + "modified": false, + "baseDn": "inum=C1BA-C1BA,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 10, + "programmingLanguage": "PYTHON", + "description": "Sample authentication module", + "locationType": "LDAP", + "dn": "inum=A51E-76DA,ou=scripts,o=gluu", + "inum": "A51E-76DA", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.util import StringHelper\n\nimport java\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Basic. Initialization\"\n print \"Basic. Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"Basic. Destroy\"\n print \"Basic. Destroyed successfully\"\n return True\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def getApiVersion(self):\n return 11\n\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n if (step == 1):\n print \"Basic. Authenticate for step 1\"\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if (not logged_in):\n return False\n\n return True\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n if (step == 1):\n print \"Basic. Prepare for Step 1\"\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 1\n\n def getPageForStep(self, configurationAttributes, step):\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "basic", + "modified": false, + "baseDn": "inum=A51E-76DA,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 10, + "programmingLanguage": "PYTHON", + "description": "Consent Gathering script", + "locationType": "LDAP", + "dn": "inum=DAA9-BA60,ou=scripts,o=gluu", + "inum": "DAA9-BA60", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2017, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.authz import ConsentGatheringType\nfrom org.gluu.util import StringHelper\n\nimport java\nimport random\n\nclass ConsentGathering(ConsentGatheringType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Consent-Gathering. Initializing ...\"\n print \"Consent-Gathering. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Consent-Gathering. Destroying ...\"\n print \"Consent-Gathering. Destroyed successfully\"\n\n return True\n\n def getApiVersion(self):\n return 1\n\n # Main consent-gather method. Must return True (if gathering performed successfully) or False (if fail).\n # All user entered values can be access via Map context.getPageAttributes()\n def authorize(self, step, context): # context is reference of org.gluu.oxauth.service.external.context.ConsentGatheringContext\n print \"Consent-Gathering. Authorizing...\"\n\n if step == 1:\n allowButton = context.getRequestParameters().get(\"authorizeForm:allowButton\")\n if (allowButton != None) and (len(allowButton) > 0):\n print \"Consent-Gathering. Authorization success for step 1\"\n return True\n\n print \"Consent-Gathering. Authorization declined for step 1\"\n elif step == 2:\n allowButton = context.getRequestParameters().get(\"authorizeForm:allowButton\")\n if (allowButton != None) and (len(allowButton) > 0):\n print \"Consent-Gathering. Authorization success for step 2\"\n return True\n\n print \"Consent-Gathering. Authorization declined for step 2\"\n\n return False\n\n def getNextStep(self, step, context):\n return -1\n\n def prepareForStep(self, step, context):\n if not context.isAuthenticated():\n print \"User is not authenticated. Aborting authorization flow ...\"\n return False\n\n if step == 2:\n pageAttributes = context.getPageAttributes()\n \n # Generate random consent gathering request\n consentRequest = \"Requested transaction #%s approval for the amount of sum $ %s.00\" % ( random.randint(100000, 1000000), random.randint(1, 100) )\n pageAttributes.put(\"consent_request\", consentRequest)\n return True\n\n return True\n\n def getStepsCount(self, context):\n return 11\n\n def getPageForStep(self, step, context):\n if step == 1:\n return \"/authz/authorize.xhtml\"\n elif step == 2:\n return \"/authz/transaction.xhtml\"\n\n return \"\"\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "CONSENT_GATHERING", + "name": "consent_gathering", + "modified": false, + "baseDn": "inum=DAA9-BA60,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 20, + "programmingLanguage": "PYTHON", + "description": "Basic (with user locking) authentication module", + "locationType": "LDAP", + "dn": "inum=4BBE-C6A8,ou=scripts,o=gluu", + "inum": "4BBE-C6A8", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n# Author: Gasmyr Mougang\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.service import CacheService\nfrom org.gluu.util import StringHelper\nfrom org.gluu.persist.exception import AuthenticationException\nfrom javax.faces.application import FacesMessage\nfrom org.gluu.jsf2.message import FacesMessages\nfrom java.time import LocalDateTime, Duration\nfrom java.time.format import DateTimeFormatter\n\nimport java\nimport datetime\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Basic (lock account). Initialization\"\n\n self.invalidLoginCountAttribute = \"oxCountInvalidLogin\"\n if configurationAttributes.containsKey(\"invalid_login_count_attribute\"):\n self.invalidLoginCountAttribute = configurationAttributes.get(\"invalid_login_count_attribute\").getValue2()\n else:\n print \"Basic (lock account). Initialization. Using default attribute\"\n\n self.maximumInvalidLoginAttemps = 3\n if configurationAttributes.containsKey(\"maximum_invalid_login_attemps\"):\n self.maximumInvalidLoginAttemps = StringHelper.toInteger(configurationAttributes.get(\"maximum_invalid_login_attemps\").getValue2())\n else:\n print \"Basic (lock account). Initialization. Using default number attempts\"\n\n self.lockExpirationTime = 180\n if configurationAttributes.containsKey(\"lock_expiration_time\"):\n self.lockExpirationTime = StringHelper.toInteger(configurationAttributes.get(\"lock_expiration_time\").getValue2())\n else:\n print \"Basic (lock account). Initialization. Using default lock expiration time\"\n\n\n print \"Basic (lock account). Initialized successfully. invalid_login_count_attribute: '%s', maximum_invalid_login_attemps: '%s', lock_expiration_time: '%s'\" % (self.invalidLoginCountAttribute, self.maximumInvalidLoginAttemps, self.lockExpirationTime)\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Basic (lock account). Destroy\"\n print \"Basic (lock account). Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n if step == 1:\n print \"Basic (lock account). Authenticate for step 1\"\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n cacheService = CdiUtil.bean(CacheService)\n userService = CdiUtil.bean(UserService)\n\n\n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n try:\n logged_in = authenticationService.authenticate(user_name, user_password)\n except AuthenticationException:\n print \"Basic (lock account). Authenticate. Failed to authenticate user '%s'\" % user_name\n\n if logged_in:\n self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(0))\n else:\n countInvalidLoginArributeValue = self.getUserAttributeValue(user_name, self.invalidLoginCountAttribute)\n userSatus = self.getUserAttributeValue(user_name, \"gluuStatus\")\n print \"Current user '%s' status is '%s'\" % ( user_name, userSatus )\n\n countInvalidLogin = StringHelper.toInteger(countInvalidLoginArributeValue, 0)\n\n if countInvalidLogin < self.maximumInvalidLoginAttemps:\n countInvalidLogin = countInvalidLogin + 1\n remainingAttempts = self.maximumInvalidLoginAttemps - countInvalidLogin\n\n print \"Remaining login count attempts '%s' for user '%s'\" % ( remainingAttempts, user_name )\n\n self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(countInvalidLogin))\n if remainingAttempts > 0 and userSatus == \"active\":\n facesMessages.add(FacesMessage.SEVERITY_INFO, StringHelper.toString(remainingAttempts)+\" more attempt(s) before account is LOCKED!\")\n\n if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and ((userSatus == None) or (userSatus == \"active\")):\n print \"Basic (lock account). Locking '%s' for '%s' seconds\" % ( user_name, self.lockExpirationTime)\n self.lockUser(user_name)\n return False\n\n if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and userSatus == \"inactive\":\n print \"Basic (lock account). User '%s' is locked. Checking if we can unlock him\" % user_name\n \n unlock_and_authenticate = False\n\n object_from_store = cacheService.get(None, \"lock_user_\" + user_name)\n if object_from_store == None:\n # Object in cache was expired. We need to unlock user\n print \"Basic (lock account). User locking details for user '%s' not exists\" % user_name\n unlock_and_authenticate = True\n else:\n # Analyze object from cache\n user_lock_details = json.loads(object_from_store)\n\n user_lock_details_locked = user_lock_details['locked']\n user_lock_details_created = user_lock_details['created']\n user_lock_details_created_date = LocalDateTime.parse(user_lock_details_created, DateTimeFormatter.ISO_LOCAL_DATE_TIME)\n user_lock_details_created_diff = Duration.between(user_lock_details_created_date, LocalDateTime.now()).getSeconds()\n print \"Basic (lock account). Get user '%s' locking details. locked: '%s', Created: '%s', Difference in seconds: '%s'\" % ( user_name, user_lock_details_locked, user_lock_details_created, user_lock_details_created_diff )\n\n if user_lock_details_locked and user_lock_details_created_diff >= self.lockExpirationTime:\n print \"Basic (lock account). Unlocking user '%s' after lock expiration\" % user_name\n unlock_and_authenticate = True\n\n if unlock_and_authenticate:\n self.unLockUser(user_name)\n self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(0))\n logged_in = authenticationService.authenticate(user_name, user_password)\n if not logged_in:\n # Update number of attempts \n self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(1))\n if self.maximumInvalidLoginAttemps == 1:\n # Lock user if maximum count login attempts is 1 \n self.lockUser(user_name)\n return False\n\n\n return logged_in\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n if step == 1:\n print \"Basic (lock account). Prepare for Step 1\"\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 1\n\n def getPageForStep(self, configurationAttributes, step):\n return \"\"\n \n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def getUserAttributeValue(self, user_name, attribute_name):\n if StringHelper.isEmpty(user_name):\n return None\n\n userService = CdiUtil.bean(UserService)\n\n find_user_by_uid = userService.getUser(user_name, attribute_name)\n if find_user_by_uid == None:\n return None\n\n custom_attribute_value = userService.getCustomAttribute(find_user_by_uid, attribute_name)\n if custom_attribute_value == None:\n return None\n \n attribute_value = custom_attribute_value.getValue()\n\n print \"Basic (lock account). Get user attribute. User's '%s' attribute '%s' value is '%s'\" % (user_name, attribute_name, attribute_value)\n\n return attribute_value\n\n def setUserAttributeValue(self, user_name, attribute_name, attribute_value):\n if StringHelper.isEmpty(user_name):\n return None\n\n userService = CdiUtil.bean(UserService)\n\n find_user_by_uid = userService.getUser(user_name)\n if find_user_by_uid == None:\n return None\n \n userService.setCustomAttribute(find_user_by_uid, attribute_name, attribute_value)\n updated_user = userService.updateUser(find_user_by_uid)\n\n print \"Basic (lock account). Set user attribute. User's '%s' attribute '%s' value is '%s'\" % (user_name, attribute_name, attribute_value)\n\n return updated_user\n\n def lockUser(self, user_name):\n if StringHelper.isEmpty(user_name):\n return None\n\n userService = CdiUtil.bean(UserService)\n cacheService= CdiUtil.bean(CacheService)\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n\n find_user_by_uid = userService.getUser(user_name)\n if (find_user_by_uid == None):\n return None\n\n status_attribute_value = userService.getCustomAttribute(find_user_by_uid, \"gluuStatus\")\n if status_attribute_value != None:\n user_status = status_attribute_value.getValue()\n if StringHelper.equals(user_status, \"inactive\"):\n print \"Basic (lock account). Lock user. User '%s' locked already\" % user_name\n return\n \n userService.setCustomAttribute(find_user_by_uid, \"gluuStatus\", \"inactive\")\n updated_user = userService.updateUser(find_user_by_uid)\n\n object_to_store = json.dumps({'locked': True, 'created': LocalDateTime.now().toString()}, separators=(',',':'))\n\n cacheService.put(StringHelper.toString(self.lockExpirationTime), \"lock_user_\"+user_name, object_to_store);\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Your account is locked. Please try again after \" + StringHelper.toString(self.lockExpirationTime) + \" secs\")\n\n print \"Basic (lock account). Lock user. User '%s' locked\" % user_name\n\n def unLockUser(self, user_name):\n if StringHelper.isEmpty(user_name):\n return None\n\n userService = CdiUtil.bean(UserService)\n cacheService= CdiUtil.bean(CacheService)\n\n find_user_by_uid = userService.getUser(user_name)\n if (find_user_by_uid == None):\n return None\n\n object_to_store = json.dumps({'locked': False, 'created': LocalDateTime.now().toString()}, separators=(',',':'))\n cacheService.put(StringHelper.toString(self.lockExpirationTime), \"lock_user_\"+user_name, object_to_store);\n\n userService.setCustomAttribute(find_user_by_uid, \"gluuStatus\", \"active\")\n userService.setCustomAttribute(find_user_by_uid, self.invalidLoginCountAttribute, None)\n updated_user = userService.updateUser(find_user_by_uid)\n\n\n print \"Basic (lock account). Lock user. User '%s' unlocked\" % user_name\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + }, + { + "value2": "interactive", + "value1": "usage_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "basic_lock", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "oxCountInvalidLogin", + "value1": "invalid_login_count_attribute" + }, + { + "hide": false, + "value2": "3", + "value1": "maximum_invalid_login_attemps" + }, + { + "hide": false, + "value2": "120", + "value1": "lock_expiration_time" + } + ], + "baseDn": "inum=4BBE-C6A8,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 30, + "programmingLanguage": "PYTHON", + "description": "Cert authentication module", + "locationType": "LDAP", + "dn": "inum=2124-0CF1,ou=scripts,o=gluu", + "inum": "2124-0CF1", + "script": "#\n# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom javax.faces.context import FacesContext\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.util import StringHelper\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.oxauth.service.common import EncryptionService\nfrom java.util import Arrays\nfrom org.gluu.oxauth.cert.fingerprint import FingerprintHelper\nfrom org.gluu.oxauth.cert.validation import GenericCertificateVerifier, PathCertificateVerifier, OCSPCertificateVerifier, CRLCertificateVerifier\nfrom org.gluu.oxauth.cert.validation.model import ValidationStatus\nfrom org.gluu.oxauth.util import CertUtil\nfrom org.gluu.oxauth.model.util import CertUtils\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.apache.http.params import CoreConnectionPNames\n\nimport sys\nimport base64\nimport urllib\n\nimport java\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Cert. Initialization\"\n\n if not (configurationAttributes.containsKey(\"chain_cert_file_path\")):\n print \"Cert. Initialization. Property chain_cert_file_path is mandatory\"\n return False\n\n if not (configurationAttributes.containsKey(\"map_user_cert\")):\n print \"Cert. Initialization. Property map_user_cert is mandatory\"\n return False\n\n chain_cert_file_path = configurationAttributes.get(\"chain_cert_file_path\").getValue2()\n\n self.chain_certs = CertUtil.loadX509CertificateFromFile(chain_cert_file_path)\n if self.chain_certs == None:\n print \"Cert. Initialization. Failed to load chain certificates from '%s'\" % chain_cert_file_path\n return False\n\n print \"Cert. Initialization. Loaded '%d' chain certificates\" % self.chain_certs.size()\n \n crl_max_response_size = 5 * 1024 * 1024 # 10Mb\n if configurationAttributes.containsKey(\"crl_max_response_size\"):\n crl_max_response_size = StringHelper.toInteger(configurationAttributes.get(\"crl_max_response_size\").getValue2(), crl_max_response_size)\n print \"Cert. Initialization. CRL max response size is '%d'\" % crl_max_response_size\n\n # Define array to order methods correctly\n self.validator_types = [ 'generic', 'path', 'ocsp', 'crl']\n self.validators = { 'generic' : [GenericCertificateVerifier(), False],\n 'path' : [PathCertificateVerifier(False), False],\n 'ocsp' : [OCSPCertificateVerifier(), False],\n 'crl' : [CRLCertificateVerifier(crl_max_response_size), False] }\n\n for type in self.validator_types:\n validator_param_name = \"use_%s_validator\" % type\n if configurationAttributes.containsKey(validator_param_name):\n validator_status = StringHelper.toBoolean(configurationAttributes.get(validator_param_name).getValue2(), False)\n self.validators[type][1] = validator_status\n\n print \"Cert. Initialization. Validation method '%s' status: '%s'\" % (type, self.validators[type][1])\n\n self.map_user_cert = StringHelper.toBoolean(configurationAttributes.get(\"map_user_cert\").getValue2(), False)\n print \"Cert. Initialization. map_user_cert: '%s'\" % self.map_user_cert\n\n self.enabled_recaptcha = self.initRecaptcha(configurationAttributes)\n print \"Cert. Initialization. enabled_recaptcha: '%s'\" % self.enabled_recaptcha\n\n print \"Cert. Initialized successfully\"\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Cert. Destroy\"\n\n for type in self.validator_types:\n self.validators[type][0].destroy()\n\n print \"Cert. Destroyed successfully\"\n\n return True\n\n def getApiVersion(self):\n return 11\n\n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n user_name = credentials.getUsername()\n\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n if step == 1:\n print \"Cert. Authenticate for step 1\"\n login_button = ServerUtil.getFirstValue(requestParameters, \"loginForm:loginButton\")\n if StringHelper.isEmpty(login_button):\n print \"Cert. Authenticate for step 1. Form were submitted incorrectly\"\n return False\n if self.enabled_recaptcha:\n print \"Cert. Authenticate for step 1. Validating recaptcha response\"\n recaptcha_response = ServerUtil.getFirstValue(requestParameters, \"g-recaptcha-response\")\n\n recaptcha_result = self.validateRecaptcha(recaptcha_response)\n print \"Cert. Authenticate for step 1. recaptcha_result: '%s'\" % recaptcha_result\n \n return recaptcha_result\n\n return True\n elif step == 2:\n print \"Cert. Authenticate for step 2\"\n\n # Validate if user selected certificate\n cert_x509 = self.getSessionAttribute(\"cert_x509\")\n if cert_x509 == None:\n print \"Cert. Authenticate for step 2. User not selected any certs\"\n identity.setWorkingParameter(\"cert_selected\", False)\n \n # Return True to inform user how to reset workflow\n return True\n else:\n identity.setWorkingParameter(\"cert_selected\", True)\n x509Certificate = self.certFromString(cert_x509)\n\n subjectX500Principal = x509Certificate.getSubjectX500Principal()\n print \"Cert. Authenticate for step 2. User selected certificate with DN '%s'\" % subjectX500Principal\n \n # Validate certificates which user selected\n valid = self.validateCertificate(x509Certificate)\n if not valid:\n print \"Cert. Authenticate for step 2. Certificate DN '%s' is not valid\" % subjectX500Principal\n identity.setWorkingParameter(\"cert_valid\", False)\n \n # Return True to inform user how to reset workflow\n return True\n\n identity.setWorkingParameter(\"cert_valid\", True)\n \n # Calculate certificate fingerprint\n x509CertificateFingerprint = self.calculateCertificateFingerprint(x509Certificate)\n identity.setWorkingParameter(\"cert_x509_fingerprint\", x509CertificateFingerprint)\n print \"Cert. Authenticate for step 2. Fingerprint is '%s' of certificate with DN '%s'\" % (x509CertificateFingerprint, subjectX500Principal)\n \n # Attempt to find user by certificate fingerprint\n cert_user_external_uid = \"cert:%s\" % x509CertificateFingerprint\n print \"Cert. Authenticate for step 2. Attempting to find user by oxExternalUid attribute value %s\" % cert_user_external_uid\n\n find_user_by_external_uid = userService.getUserByAttribute(\"oxExternalUid\", cert_user_external_uid)\n if find_user_by_external_uid == None:\n print \"Cert. Authenticate for step 2. Failed to find user\"\n \n if self.map_user_cert:\n print \"Cert. Authenticate for step 2. Storing cert_user_external_uid for step 3\"\n identity.setWorkingParameter(\"cert_user_external_uid\", cert_user_external_uid)\n return True\n else:\n print \"Cert. Authenticate for step 2. Mapping cert to user account is not allowed\"\n identity.setWorkingParameter(\"cert_count_login_steps\", 2)\n return False\n\n foundUserName = find_user_by_external_uid.getUserId()\n print \"Cert. Authenticate for step 2. foundUserName: \" + foundUserName\n\n logged_in = False\n userService = CdiUtil.bean(UserService)\n logged_in = authenticationService.authenticate(foundUserName)\n \n print \"Cert. Authenticate for step 2. Setting count steps to 2\"\n identity.setWorkingParameter(\"cert_count_login_steps\", 2)\n\n return logged_in\n elif step == 3:\n print \"Cert. Authenticate for step 3\"\n\n cert_user_external_uid = self.getSessionAttribute(\"cert_user_external_uid\")\n if cert_user_external_uid == None:\n print \"Cert. Authenticate for step 3. cert_user_external_uid is empty\"\n return False\n\n user_password = credentials.getPassword()\n\n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if (not logged_in):\n return False\n\n # Double check just to make sure. We did checking in previous step\n # Check if there is user which has cert_user_external_uid\n # Avoid mapping user cert to more than one IDP account\n find_user_by_external_uid = userService.getUserByAttribute(\"oxExternalUid\", cert_user_external_uid)\n if find_user_by_external_uid == None:\n # Add cert_user_external_uid to user's external GUID list\n find_user_by_external_uid = userService.addUserAttribute(user_name, \"oxExternalUid\", cert_user_external_uid)\n if find_user_by_external_uid == None:\n print \"Cert. Authenticate for step 3. Failed to update current user\"\n return False\n\n return True\n \n return True\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n print \"Cert. Prepare for step %d\" % step\n identity = CdiUtil.bean(Identity)\n \n if step == 1:\n if self.enabled_recaptcha:\n identity.setWorkingParameter(\"recaptcha_site_key\", self.recaptcha_creds['site_key'])\n elif step == 2:\n # Store certificate in session\n facesContext = CdiUtil.bean(FacesContext)\n externalContext = facesContext.getExternalContext()\n request = externalContext.getRequest()\n\n # Try to get certificate from header X-ClientCert\n clientCertificate = externalContext.getRequestHeaderMap().get(\"X-ClientCert\")\n if clientCertificate != None:\n x509Certificate = self.certFromPemString(clientCertificate)\n identity.setWorkingParameter(\"cert_x509\", self.certToString(x509Certificate))\n print \"Cert. Prepare for step 2. Storing user certificate obtained from 'X-ClientCert' header\"\n return True\n\n # Try to get certificate from attribute javax.servlet.request.X509Certificate\n x509Certificates = request.getAttribute('javax.servlet.request.X509Certificate')\n if (x509Certificates != None) and (len(x509Certificates) > 0):\n identity.setWorkingParameter(\"cert_x509\", self.certToString(x509Certificates[0]))\n print \"Cert. Prepare for step 2. Storing user certificate obtained from 'javax.servlet.request.X509Certificate' attribute\"\n return True\n\n if step < 4:\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return Arrays.asList(\"cert_selected\", \"cert_valid\", \"cert_x509\", \"cert_x509_fingerprint\", \"cert_count_login_steps\", \"cert_user_external_uid\")\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n cert_count_login_steps = self.getSessionAttribute(\"cert_count_login_steps\")\n if cert_count_login_steps != None:\n return cert_count_login_steps\n else:\n return 3\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 1:\n return \"/auth/cert/login.xhtml\"\n if step == 2:\n return \"/auth/cert/cert-login.xhtml\"\n elif step == 3:\n cert_selected = self.getSessionAttribute(\"cert_selected\")\n if True != cert_selected:\n return \"/auth/cert/cert-not-selected.xhtml\"\n\n cert_valid = self.getSessionAttribute(\"cert_valid\")\n if True != cert_valid:\n return \"/auth/cert/cert-invalid.xhtml\"\n \n return \"/login.xhtml\"\n\n return \"\"\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def processBasicAuthentication(self, credentials):\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if (not logged_in):\n return None\n\n find_user_by_uid = authenticationService.getAuthenticatedUser()\n if (find_user_by_uid == None):\n print \"Cert. Process basic authentication. Failed to find user '%s'\" % user_name\n return None\n \n return find_user_by_uid\n\n def getSessionAttribute(self, attribute_name):\n identity = CdiUtil.bean(Identity)\n\n # Try to get attribute value from Seam event context\n if identity.isSetWorkingParameter(attribute_name):\n return identity.getWorkingParameter(attribute_name)\n \n # Try to get attribute from persistent session\n session_id = identity.getSessionId()\n if session_id == None:\n return None\n\n session_attributes = session_id.getSessionAttributes()\n if session_attributes == None:\n return None\n\n if session_attributes.containsKey(attribute_name):\n return session_attributes.get(attribute_name)\n\n return None\n\n def calculateCertificateFingerprint(self, x509Certificate):\n print \"Cert. Calculate fingerprint for certificate DN '%s'\" % x509Certificate.getSubjectX500Principal()\n \n publicKey = x509Certificate.getPublicKey()\n \n # Use oxAuth implementation\n fingerprint = FingerprintHelper.getPublicKeySshFingerprint(publicKey)\n \n return fingerprint \n\n def validateCertificate(self, x509Certificate):\n subjectX500Principal = x509Certificate.getSubjectX500Principal()\n\n print \"Cert. Validating certificate with DN '%s'\" % subjectX500Principal\n \n validation_date = java.util.Date()\n\n for type in self.validator_types:\n if self.validators[type][1]:\n result = self.validators[type][0].validate(x509Certificate, self.chain_certs, validation_date)\n print \"Cert. Validate certificate: '%s'. Validation method '%s' result: '%s'\" % (subjectX500Principal, type, result)\n \n if (result.getValidity() != ValidationStatus.CertificateValidity.VALID):\n print \"Cert. Certificate: '%s' is invalid\" % subjectX500Principal\n return False\n \n return True\n\n def certToString(self, x509Certificate):\n if x509Certificate == None:\n return None\n return base64.b64encode(x509Certificate.getEncoded())\n\n def certFromString(self, x509CertificateEncoded):\n x509CertificateDecoded = base64.b64decode(x509CertificateEncoded)\n return CertUtils.x509CertificateFromBytes(x509CertificateDecoded)\n\n def certFromPemString(self, pemCertificate):\n x509CertificateEncoded = pemCertificate.replace(\"-----BEGIN CERTIFICATE-----\", \"\").replace(\"-----END CERTIFICATE-----\", \"\").strip()\n return self.certFromString(x509CertificateEncoded)\n\n def initRecaptcha(self, configurationAttributes):\n print \"Cert. Initialize recaptcha\"\n if not configurationAttributes.containsKey(\"credentials_file\"):\n return False\n\n cert_creds_file = configurationAttributes.get(\"credentials_file\").getValue2()\n\n # Load credentials from file\n f = open(cert_creds_file, 'r')\n try:\n creds = json.loads(f.read())\n except:\n print \"Cert. Initialize recaptcha. Failed to load credentials from file: %s\" % cert_creds_file\n return False\n finally:\n f.close()\n \n try:\n recaptcha_creds = creds[\"recaptcha\"]\n except:\n print \"Cert. Initialize recaptcha. Invalid credentials file '%s' format:\" % cert_creds_file\n return False\n \n self.recaptcha_creds = None\n if recaptcha_creds[\"enabled\"]:\n print \"Cert. Initialize recaptcha. Recaptcha is enabled\"\n\n encryptionService = CdiUtil.bean(EncryptionService)\n\n site_key = recaptcha_creds[\"site_key\"]\n secret_key = recaptcha_creds[\"secret_key\"]\n\n try:\n site_key = encryptionService.decrypt(site_key)\n except:\n # Ignore exception. Value is not encrypted\n print \"Cert. Initialize recaptcha. Assuming that 'site_key' in not encrypted\"\n\n try:\n secret_key = encryptionService.decrypt(secret_key)\n except:\n # Ignore exception. Value is not encrypted\n print \"Cert. Initialize recaptcha. Assuming that 'secret_key' in not encrypted\"\n\n \n self.recaptcha_creds = { 'site_key' : site_key, \"secret_key\" : secret_key }\n print \"Cert. Initialize recaptcha. Recaptcha is configured correctly\"\n\n return True\n else:\n print \"Cert. Initialize recaptcha. Recaptcha is disabled\"\n\n return False\n\n def validateRecaptcha(self, recaptcha_response):\n print \"Cert. Validate recaptcha response\"\n\n facesContext = CdiUtil.bean(FacesContext)\n request = facesContext.getExternalContext().getRequest()\n\n remoteip = ServerUtil.getIpAddress(request)\n print \"Cert. Validate recaptcha response. remoteip: '%s'\" % remoteip\n\n httpService = CdiUtil.bean(HttpService)\n\n http_client = httpService.getHttpsClient()\n http_client_params = http_client.getParams()\n http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000)\n \n recaptcha_validation_url = \"https://www.google.com/recaptcha/api/siteverify\"\n recaptcha_validation_request = urllib.urlencode({ \"secret\" : self.recaptcha_creds['secret_key'], \"response\" : recaptcha_response, \"remoteip\" : remoteip })\n recaptcha_validation_headers = { \"Content-type\" : \"application/x-www-form-urlencoded\", \"Accept\" : \"application/json\" }\n\n try:\n http_service_response = httpService.executePost(http_client, recaptcha_validation_url, None, recaptcha_validation_headers, recaptcha_validation_request)\n http_response = http_service_response.getHttpResponse()\n except:\n print \"Cert. Validate recaptcha response. Exception: \", sys.exc_info()[1]\n return False\n\n try:\n if not httpService.isResponseStastusCodeOk(http_response):\n print \"Cert. Validate recaptcha response. Get invalid response from validation server: \", str(http_response.getStatusLine().getStatusCode())\n httpService.consume(http_response)\n return False\n \n response_bytes = httpService.getResponseContent(http_response)\n response_string = httpService.convertEntityToString(response_bytes)\n httpService.consume(http_response)\n finally:\n http_service_response.closeConnection()\n\n if response_string == None:\n print \"Cert. Validate recaptcha response. Get empty response from validation server\"\n return False\n \n response = json.loads(response_string)\n \n return response[\"success\"]\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + }, + { + "value2": "interactive", + "value1": "usage_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "cert", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "/etc/certs/chain_cert.pem", + "value1": "chain_cert_file_path" + }, + { + "hide": false, + "value2": "/etc/certs/cert_creds.json", + "value1": "credentials_file" + }, + { + "hide": false, + "value2": "true", + "value1": "map_user_cert" + }, + { + "hide": false, + "value2": "true", + "value1": "use_generic_validator" + }, + { + "hide": false, + "value2": "true", + "value1": "use_path_validator" + }, + { + "hide": false, + "value2": "false", + "value1": "use_ocsp_validator" + }, + { + "hide": false, + "value2": "false", + "value1": "use_crl_validator" + }, + { + "hide": false, + "value2": "10485760", + "value1": "crl_max_response_size" + } + ], + "baseDn": "inum=2124-0CF1,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 40, + "programmingLanguage": "PYTHON", + "description": "OTP Validation of passwords using Yubicloud authentication module", + "locationType": "LDAP", + "dn": "inum=24FD-B96E,ou=scripts,o=gluu", + "inum": "24FD-B96E", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan, Arunmozhi\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import UserService\nfrom org.gluu.util import StringHelper\n\nimport java\n\nimport urllib2\nimport urllib\nimport uuid\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Yubicloud. Initialization\"\n\n self.api_server = configurationAttributes.get(\"yubicloud_uri\").getValue2()\n self.api_key = configurationAttributes.get(\"yubicloud_api_key\").getValue2()\n self.client_id = configurationAttributes.get(\"yubicloud_id\").getValue2()\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Yubicloud. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n if (step == 1):\n print \"Yubicloud. Authenticate for step 1\"\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n username = credentials.getUsername()\n otp = credentials.getPassword()\n\n # Validate otp length\n if len(otp) < 32 or len(otp) > 48:\n print \"Yubicloud. Invalid OTP length\"\n return False\n\n user_service = CdiUtil.bean(UserService)\n user = user_service.getUser(username)\n\n public_key = user.getAttribute('yubikeyId')\n\n # Match the user with the yubikey\n if public_key not in otp:\n print \"Yubicloud. Public Key not matching OTP\"\n return False\n\n data = \"\"\n try:\n nonce = str(uuid.uuid4()).replace(\"-\", \"\")\n params = urllib.urlencode({\"id\": self.client_id, \"otp\": otp, \"nonce\": nonce})\n url = \"https://\" + self.api_server + \"/wsapi/2.0/verify/?\" + params\n f = urllib2.urlopen(url)\n data = f.read()\n except Exception as e:\n print \"Yubicloud. Exception \", e\n\n if 'status=OK' in data:\n user_service.authenticate(username)\n print \"Yubicloud. Authentication Successful\"\n return True\n\n print \"Yubicloud. End of Step 1. Returning False.\"\n return False\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n if (step == 1):\n print \"Yubicloud. Prepare for Step 1\"\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 1\n\n def getPageForStep(self, configurationAttributes, step):\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "yubicloud", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "api.yubico.com", + "value1": "yubicloud_uri" + }, + { + "hide": false, + "value1": "yubicloud_api_key" + }, + { + "hide": false, + "value1": "yubicloud_id" + } + ], + "baseDn": "inum=24FD-B96E,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 40, + "programmingLanguage": "PYTHON", + "description": "HOTP/TOPT authentication module", + "locationType": "LDAP", + "dn": "inum=5018-D4BF,ou=scripts,o=gluu", + "inum": "5018-D4BF", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\n# Requires the following custom properties and values:\n# otp_type: totp/hotp\n# issuer: Gluu Inc\n# otp_conf_file: /etc/certs/otp_configuration.json\n#\n# These are non mandatory custom properties and values:\n# label: Gluu OTP\n# qr_options: { width: 400, height: 400 }\n# registration_uri: https://ce-dev.gluu.org/identity/register\n\nimport jarray\nimport json\nimport sys\nfrom com.google.common.io import BaseEncoding\nfrom com.lochbridge.oath.otp import HOTP\nfrom com.lochbridge.oath.otp import HOTPValidator\nfrom com.lochbridge.oath.otp import HmacShaAlgorithm\nfrom com.lochbridge.oath.otp import TOTP\nfrom com.lochbridge.oath.otp.keyprovisioning import OTPAuthURIBuilder\nfrom com.lochbridge.oath.otp.keyprovisioning import OTPKey\nfrom com.lochbridge.oath.otp.keyprovisioning.OTPKey import OTPType\nfrom java.security import SecureRandom\nfrom java.util import Arrays\nfrom java.util.concurrent import TimeUnit\nfrom javax.faces.application import FacesMessage\nfrom org.gluu.jsf2.message import FacesMessages\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"OTP. Initialization\"\n\n if not configurationAttributes.containsKey(\"otp_type\"):\n print \"OTP. Initialization. Property otp_type is mandatory\"\n return False\n self.otpType = configurationAttributes.get(\"otp_type\").getValue2()\n\n if not self.otpType in [\"hotp\", \"totp\"]:\n print \"OTP. Initialization. Property value otp_type is invalid\"\n return False\n\n if not configurationAttributes.containsKey(\"issuer\"):\n print \"OTP. Initialization. Property issuer is mandatory\"\n return False\n self.otpIssuer = configurationAttributes.get(\"issuer\").getValue2()\n\n self.customLabel = None\n if configurationAttributes.containsKey(\"label\"):\n self.customLabel = configurationAttributes.get(\"label\").getValue2()\n\n self.customQrOptions = {}\n if configurationAttributes.containsKey(\"qr_options\"):\n self.customQrOptions = configurationAttributes.get(\"qr_options\").getValue2()\n\n self.registrationUri = None\n if configurationAttributes.containsKey(\"registration_uri\"):\n self.registrationUri = configurationAttributes.get(\"registration_uri\").getValue2()\n\n validOtpConfiguration = self.loadOtpConfiguration(configurationAttributes)\n if not validOtpConfiguration:\n return False\n\n print \"OTP. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"OTP. Destroy\"\n print \"OTP. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n print \"getNextStep Invoked\"\n # If user not pass current step change step to previous\n identity = CdiUtil.bean(Identity)\n retry_current_step = identity.getWorkingParameter(\"retry_current_step\")\n if retry_current_step:\n print \"OTP. Get next step. Retrying current step %s\" % step\n # Remove old QR code\n #identity.setWorkingParameter(\"super_gluu_request\", \"timeout\")\n resultStep = step\n return resultStep\n return -1\n\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n self.setRequestScopedParameters(identity)\n\n if step == 1:\n print \"OTP. Authenticate for step 1\"\n authenticated_user = self.processBasicAuthentication(credentials)\n if authenticated_user == None:\n return False\n\n otp_auth_method = \"authenticate\"\n # Uncomment this block if you need to allow user second OTP registration\n #enrollment_mode = ServerUtil.getFirstValue(requestParameters, \"loginForm:registerButton\")\n #if StringHelper.isNotEmpty(enrollment_mode):\n # otp_auth_method = \"enroll\"\n\n if otp_auth_method == \"authenticate\":\n user_enrollments = self.findEnrollments(authenticated_user.getUserId())\n if len(user_enrollments) == 0:\n otp_auth_method = \"enroll\"\n print \"OTP. Authenticate for step 1. There is no OTP enrollment for user '%s'. Changing otp_auth_method to '%s'\" % (authenticated_user.getUserId(), otp_auth_method)\n\n if otp_auth_method == \"enroll\":\n print \"OTP. Authenticate for step 1. Setting count steps: '%s'\" % 3\n identity.setWorkingParameter(\"otp_count_login_steps\", 3)\n\n print \"OTP. Authenticate for step 1. otp_auth_method: '%s'\" % otp_auth_method\n identity.setWorkingParameter(\"otp_auth_method\", otp_auth_method)\n\n return True\n elif step == 2:\n print \"OTP. Authenticate for step 2\"\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"OTP. Authenticate for step 2. Failed to determine user name\"\n return False\n\n session_id_validation = self.validateSessionId(identity)\n if not session_id_validation:\n return False\n\n # Restore state from session\n identity.setWorkingParameter(\"retry_current_step\", False)\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n if otp_auth_method == 'enroll':\n auth_result = ServerUtil.getFirstValue(requestParameters, \"auth_result\")\n if not StringHelper.isEmpty(auth_result):\n # defect fix #1225 - Retry the step, show QR code again\n if auth_result == 'timeout':\n\t\t\t\t\t\tprint \"OTP. QR-code timeout. Authenticate for step %s. Reinitializing current step\" % step\n\t\t\t\t\t\tidentity.setWorkingParameter(\"retry_current_step\", True)\n\t\t\t\t\t\treturn True\n\n print \"OTP. Authenticate for step 2. User not enrolled OTP\"\n return False\n\n print \"OTP. Authenticate for step 2. Skipping this step during enrollment\"\n return True\n\n otp_auth_result = self.processOtpAuthentication(requestParameters, user.getUserId(), identity, otp_auth_method)\n print \"OTP. Authenticate for step 2. OTP authentication result: '%s'\" % otp_auth_result\n\n return otp_auth_result\n elif step == 3:\n print \"OTP. Authenticate for step 3\"\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"OTP. Authenticate for step 2. Failed to determine user name\"\n return False\n\n session_id_validation = self.validateSessionId(identity)\n if not session_id_validation:\n return False\n\n # Restore state from session\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n if otp_auth_method != 'enroll':\n return False\n\n otp_auth_result = self.processOtpAuthentication(requestParameters, user.getUserId(), identity, otp_auth_method)\n print \"OTP. Authenticate for step 3. OTP authentication result: '%s'\" % otp_auth_result\n\n return otp_auth_result\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n self.setRequestScopedParameters(identity)\n\n if step == 1:\n print \"OTP. Prepare for step 1\"\n\n return True\n elif step == 2:\n print \"OTP. Prepare for step 2\"\n\n session_id_validation = self.validateSessionId(identity)\n if not session_id_validation:\n return False\n\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n print \"OTP. Prepare for step 2. otp_auth_method: '%s'\" % otp_auth_method\n\n if otp_auth_method == 'enroll':\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"OTP. Prepare for step 2. Failed to load user enty\"\n return False\n\n if self.otpType == \"hotp\":\n otp_secret_key = self.generateSecretHotpKey()\n otp_enrollment_request = self.generateHotpSecretKeyUri(otp_secret_key, self.otpIssuer, user.getAttribute(\"displayName\"))\n elif self.otpType == \"totp\":\n otp_secret_key = self.generateSecretTotpKey()\n otp_enrollment_request = self.generateTotpSecretKeyUri(otp_secret_key, self.otpIssuer, user.getAttribute(\"displayName\"))\n else:\n print \"OTP. Prepare for step 2. Unknown OTP type: '%s'\" % self.otpType\n return False\n\n print \"OTP. Prepare for step 2. Prepared enrollment request for user: '%s'\" % user.getUserId()\n identity.setWorkingParameter(\"otp_secret_key\", self.toBase64Url(otp_secret_key))\n identity.setWorkingParameter(\"otp_enrollment_request\", otp_enrollment_request)\n\n return True\n elif step == 3:\n print \"OTP. Prepare for step 3\"\n\n session_id_validation = self.validateSessionId(identity)\n if not session_id_validation:\n return False\n\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n print \"OTP. Prepare for step 3. otp_auth_method: '%s'\" % otp_auth_method\n\n if otp_auth_method == 'enroll':\n return True\n\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return Arrays.asList(\"otp_auth_method\", \"otp_count_login_steps\", \"otp_secret_key\", \"otp_enrollment_request\",\"retry_current_step\")\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n identity = CdiUtil.bean(Identity)\n\n if identity.isSetWorkingParameter(\"otp_count_login_steps\"):\n return StringHelper.toInteger(\"%s\" % identity.getWorkingParameter(\"otp_count_login_steps\"))\n else:\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 2:\n identity = CdiUtil.bean(Identity)\n\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n print \"OTP. Gep page for step 2. otp_auth_method: '%s'\" % otp_auth_method\n\n if otp_auth_method == 'enroll':\n return \"/auth/otp/enroll.xhtml\"\n else:\n return \"/auth/otp/otplogin.xhtml\"\n elif step == 3:\n return \"/auth/otp/otplogin.xhtml\"\n\n return \"\"\n\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def setRequestScopedParameters(self, identity):\n if self.registrationUri != None:\n identity.setWorkingParameter(\"external_registration_uri\", self.registrationUri)\n\n if self.customLabel != None:\n identity.setWorkingParameter(\"qr_label\", self.customLabel)\n\n identity.setWorkingParameter(\"qr_options\", self.customQrOptions)\n\n def loadOtpConfiguration(self, configurationAttributes):\n print \"OTP. Load OTP configuration\"\n if not configurationAttributes.containsKey(\"otp_conf_file\"):\n return False\n\n otp_conf_file = configurationAttributes.get(\"otp_conf_file\").getValue2()\n\n # Load configuration from file\n f = open(otp_conf_file, 'r')\n try:\n otpConfiguration = json.loads(f.read())\n except:\n print \"OTP. Load OTP configuration. Failed to load configuration from file:\", otp_conf_file\n return False\n finally:\n f.close()\n\n # Check configuration file settings\n try:\n self.hotpConfiguration = otpConfiguration[\"hotp\"]\n self.totpConfiguration = otpConfiguration[\"totp\"]\n \n hmacShaAlgorithm = self.totpConfiguration[\"hmacShaAlgorithm\"]\n hmacShaAlgorithmType = None\n\n if StringHelper.equalsIgnoreCase(hmacShaAlgorithm, \"sha1\"):\n hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_1\n elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, \"sha256\"):\n hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_256\n elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, \"sha512\"):\n hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_512\n else:\n print \"OTP. Load OTP configuration. Invalid TOTP HMAC SHA algorithm: '%s'\" % hmacShaAlgorithm\n \n self.totpConfiguration[\"hmacShaAlgorithmType\"] = hmacShaAlgorithmType\n except:\n print \"OTP. Load OTP configuration. Invalid configuration file '%s' format. Exception: '%s'\" % (otp_conf_file, sys.exc_info()[1])\n return False\n \n\n return True\n\n def processBasicAuthentication(self, credentials):\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return None\n\n find_user_by_uid = authenticationService.getAuthenticatedUser()\n if find_user_by_uid == None:\n print \"OTP. Process basic authentication. Failed to find user '%s'\" % user_name\n return None\n \n return find_user_by_uid\n\n def findEnrollments(self, user_name, skipPrefix = True):\n result = []\n\n userService = CdiUtil.bean(UserService)\n user = userService.getUser(user_name, \"oxExternalUid\")\n if user == None:\n print \"OTP. Find enrollments. Failed to find user\"\n return result\n \n user_custom_ext_attribute = userService.getCustomAttribute(user, \"oxExternalUid\")\n if user_custom_ext_attribute == None:\n return result\n\n otp_prefix = \"%s:\" % self.otpType\n \n otp_prefix_length = len(otp_prefix) \n for user_external_uid in user_custom_ext_attribute.getValues():\n index = user_external_uid.find(otp_prefix)\n if index != -1:\n if skipPrefix:\n enrollment_uid = user_external_uid[otp_prefix_length:]\n else:\n enrollment_uid = user_external_uid\n\n result.append(enrollment_uid)\n \n return result\n\n def validateSessionId(self, identity):\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"OTP. Validate session id. Failed to determine session_id\"\n return False\n\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n if not otp_auth_method in ['enroll', 'authenticate']:\n print \"OTP. Validate session id. Failed to authenticate user. otp_auth_method: '%s'\" % otp_auth_method\n return False\n\n return True\n\n def processOtpAuthentication(self, requestParameters, user_name, identity, otp_auth_method):\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n\n userService = CdiUtil.bean(UserService)\n\n otpCode = ServerUtil.getFirstValue(requestParameters, \"loginForm:otpCode\")\n if StringHelper.isEmpty(otpCode):\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to authenticate. OTP code is empty\")\n print \"OTP. Process OTP authentication. otpCode is empty\"\n\n return False\n \n if otp_auth_method == \"enroll\":\n # Get key from session\n otp_secret_key_encoded = identity.getWorkingParameter(\"otp_secret_key\")\n if otp_secret_key_encoded == None:\n print \"OTP. Process OTP authentication. OTP secret key is invalid\"\n return False\n \n otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)\n\n if self.otpType == \"hotp\":\n validation_result = self.validateHotpKey(otp_secret_key, 1, otpCode)\n \n if (validation_result != None) and validation_result[\"result\"]:\n print \"OTP. Process HOTP authentication during enrollment. otpCode is valid\"\n # Store HOTP Secret Key and moving factor in user entry\n otp_user_external_uid = \"hotp:%s;%s\" % ( otp_secret_key_encoded, validation_result[\"movingFactor\"] )\n\n # Add otp_user_external_uid to user's external GUID list\n find_user_by_external_uid = userService.addUserAttribute(user_name, \"oxExternalUid\", otp_user_external_uid)\n if find_user_by_external_uid != None:\n return True\n\n print \"OTP. Process HOTP authentication during enrollment. Failed to update user entry\"\n elif self.otpType == \"totp\":\n validation_result = self.validateTotpKey(otp_secret_key, otpCode,user_name)\n if (validation_result != None) and validation_result[\"result\"]:\n print \"OTP. Process TOTP authentication during enrollment. otpCode is valid\"\n # Store TOTP Secret Key and moving factor in user entry\n otp_user_external_uid = \"totp:%s\" % otp_secret_key_encoded\n\n # Add otp_user_external_uid to user's external GUID list\n find_user_by_external_uid = userService.addUserAttribute(user_name, \"oxExternalUid\", otp_user_external_uid)\n if find_user_by_external_uid != None:\n return True\n\n print \"OTP. Process TOTP authentication during enrollment. Failed to update user entry\"\n elif otp_auth_method == \"authenticate\":\n user_enrollments = self.findEnrollments(user_name)\n\n if len(user_enrollments) == 0:\n print \"OTP. Process OTP authentication. There is no OTP enrollment for user '%s'\" % user_name\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"There is no valid OTP user enrollments\")\n return False\n\n if self.otpType == \"hotp\":\n for user_enrollment in user_enrollments:\n user_enrollment_data = user_enrollment.split(\";\")\n otp_secret_key_encoded = user_enrollment_data[0]\n\n # Get current moving factor from user entry\n moving_factor = StringHelper.toInteger(user_enrollment_data[1])\n otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)\n\n # Validate TOTP\n validation_result = self.validateHotpKey(otp_secret_key, moving_factor, otpCode)\n if (validation_result != None) and validation_result[\"result\"]:\n print \"OTP. Process HOTP authentication during authentication. otpCode is valid\"\n otp_user_external_uid = \"hotp:%s;%s\" % ( otp_secret_key_encoded, moving_factor )\n new_otp_user_external_uid = \"hotp:%s;%s\" % ( otp_secret_key_encoded, validation_result[\"movingFactor\"] )\n \n # Update moving factor in user entry\n find_user_by_external_uid = userService.replaceUserAttribute(user_name, \"oxExternalUid\", otp_user_external_uid, new_otp_user_external_uid)\n if find_user_by_external_uid != None:\n return True\n \n print \"OTP. Process HOTP authentication during authentication. Failed to update user entry\"\n elif self.otpType == \"totp\":\n for user_enrollment in user_enrollments:\n otp_secret_key = self.fromBase64Url(user_enrollment)\n\n # Validate TOTP\n validation_result = self.validateTotpKey(otp_secret_key, otpCode, user_name)\n if (validation_result != None) and validation_result[\"result\"]:\n print \"OTP. Process TOTP authentication during authentication. otpCode is valid\"\n return True\n\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to authenticate. OTP code is invalid\")\n print \"OTP. Process OTP authentication. OTP code is invalid\"\n\n return False\n\n # Shared HOTP/TOTP methods\n def generateSecretKey(self, keyLength):\n bytes = jarray.zeros(keyLength, \"b\")\n secureRandom = SecureRandom()\n secureRandom.nextBytes(bytes)\n \n return bytes\n \n # HOTP methods\n def generateSecretHotpKey(self):\n keyLength = self.hotpConfiguration[\"keyLength\"]\n \n return self.generateSecretKey(keyLength)\n\n def generateHotpKey(self, secretKey, movingFactor):\n digits = self.hotpConfiguration[\"digits\"]\n\n hotp = HOTP.key(secretKey).digits(digits).movingFactor(movingFactor).build()\n \n return hotp.value()\n\n def validateHotpKey(self, secretKey, movingFactor, totpKey):\n lookAheadWindow = self.hotpConfiguration[\"lookAheadWindow\"]\n digits = self.hotpConfiguration[\"digits\"]\n\n htopValidationResult = HOTPValidator.lookAheadWindow(lookAheadWindow).validate(secretKey, movingFactor, digits, totpKey)\n if htopValidationResult.isValid():\n return { \"result\": True, \"movingFactor\": htopValidationResult.getNewMovingFactor() }\n\n return { \"result\": False, \"movingFactor\": None }\n\n def generateHotpSecretKeyUri(self, secretKey, issuer, userDisplayName):\n digits = self.hotpConfiguration[\"digits\"]\n\n secretKeyBase32 = self.toBase32(secretKey)\n otpKey = OTPKey(secretKeyBase32, OTPType.HOTP)\n label = issuer + \" %s\" % userDisplayName\n\n otpAuthURI = OTPAuthURIBuilder.fromKey(otpKey).label(label).issuer(issuer).digits(digits).build()\n\n return otpAuthURI.toUriString()\n\n # TOTP methods\n def generateSecretTotpKey(self):\n keyLength = self.totpConfiguration[\"keyLength\"]\n \n return self.generateSecretKey(keyLength)\n\n def generateTotpKey(self, secretKey):\n digits = self.totpConfiguration[\"digits\"]\n timeStep = self.totpConfiguration[\"timeStep\"]\n hmacShaAlgorithmType = self.totpConfiguration[\"hmacShaAlgorithmType\"]\n\n totp = TOTP.key(secretKey).digits(digits).timeStep(TimeUnit.SECONDS.toMillis(timeStep)).hmacSha(hmacShaAlgorithmType).build()\n \n return totp.value()\n\n def validateTotpKey(self, secretKey, totpKey, user_name):\n localTotpKey = self.generateTotpKey(secretKey)\n cachedOTP = self.getCachedOTP(user_name)\n\n if StringHelper.equals(localTotpKey, totpKey) and not StringHelper.equals(localTotpKey, cachedOTP):\n userService = CdiUtil.bean(UserService)\n if cachedOTP is None:\n userService.addUserAttribute(user_name, \"oxOTPCache\",localTotpKey)\n else :\n userService.replaceUserAttribute(user_name, \"oxOTPCache\", cachedOTP, localTotpKey)\n print \"OTP. Caching OTP: '%s'\" % localTotpKey\n return { \"result\": True }\n return { \"result\": False }\n\t\n def getCachedOTP(self, user_name):\n userService = CdiUtil.bean(UserService)\n user = userService.getUser(user_name, \"oxOTPCache\")\n if user is None:\n print \"OTP. Get Cached OTP. Failed to find OTP\"\n return None\n customAttribute = userService.getCustomAttribute(user, \"oxOTPCache\")\n \n if customAttribute is None:\n print \"OTP. Custom attribute is null\"\n return None\n user_cached_OTP = customAttribute.getValue()\n if user_cached_OTP is None:\n print \"OTP. no OTP is present in LDAP\"\n return None\n \n print \"OTP.Cached OTP: '%s'\" % user_cached_OTP\n return user_cached_OTP\n \n def generateTotpSecretKeyUri(self, secretKey, issuer, userDisplayName):\n digits = self.totpConfiguration[\"digits\"]\n timeStep = self.totpConfiguration[\"timeStep\"]\n\n secretKeyBase32 = self.toBase32(secretKey)\n otpKey = OTPKey(secretKeyBase32, OTPType.TOTP)\n label = issuer + \" %s\" % userDisplayName\n\n otpAuthURI = OTPAuthURIBuilder.fromKey(otpKey).label(label).issuer(issuer).digits(digits).timeStep(TimeUnit.SECONDS.toMillis(timeStep)).build()\n\n return otpAuthURI.toUriString()\n\n # Utility methods\n def toBase32(self, bytes):\n return BaseEncoding.base32().omitPadding().encode(bytes)\n\n def toBase64Url(self, bytes):\n return BaseEncoding.base64Url().encode(bytes)\n\n def fromBase64Url(self, chars):\n return BaseEncoding.base64Url().decode(chars)\n\n\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + }, + { + "value2": "interactive", + "value1": "usage_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "otp", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "totp", + "value1": "otp_type" + }, + { + "hide": false, + "value2": "/etc/certs/otp_configuration.json", + "value1": "otp_conf_file" + }, + { + "hide": false, + "value2": "Gluu Inc", + "value1": "issuer" + }, + { + "hide": false, + "value2": "Gluu OTP", + "value1": "label" + }, + { + "hide": false, + "value2": "{ size: 400, mSize: 0.05 }", + "value1": "qr_options" + }, + { + "hide": false, + "value2": "https://pujavs4.2.gluu.server/identity/register", + "value1": "registration_uri" + } + ], + "baseDn": "inum=5018-D4BF,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 40, + "programmingLanguage": "PYTHON", + "description": "Passport authentication module", + "locationType": "LDAP", + "dn": "inum=2FDB-CF02,ou=scripts,o=gluu", + "inum": "2FDB-CF02", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2019, Gluu\n#\n# Author: Jose Gonzalez\n# Author: Yuriy Movchan\n#\nfrom org.gluu.jsf2.service import FacesService\nfrom org.gluu.jsf2.message import FacesMessages\n\nfrom org.gluu.oxauth.model.common import User, WebKeyStorage\nfrom org.gluu.oxauth.model.configuration import AppConfiguration\nfrom org.gluu.oxauth.model.crypto import CryptoProviderFactory\nfrom org.gluu.oxauth.model.jwt import Jwt, JwtClaimName\nfrom org.gluu.oxauth.model.util import Base64Util\nfrom org.gluu.oxauth.service import AppInitializer, AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService, EncryptionService\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.config.oxtrust import LdapOxPassportConfiguration\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.persist import PersistenceEntryManager\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\nfrom java.util import ArrayList, Arrays, Collections\n\nfrom javax.faces.application import FacesMessage\nfrom javax.faces.context import FacesContext\n\nimport json\nimport sys\nimport datetime\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Passport. init called\"\n\n self.extensionModule = self.loadExternalModule(configurationAttributes.get(\"extension_module\"))\n extensionResult = self.extensionInit(configurationAttributes)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. init. Behaviour is social\"\n success = self.processKeyStoreProperties(configurationAttributes)\n\n if success:\n self.providerKey = \"provider\"\n self.customAuthzParameter = self.getCustomAuthzParameter(configurationAttributes.get(\"authz_req_param_provider\"))\n self.passportDN = self.getPassportConfigDN()\n print \"Passport. init. Initialization success\"\n else:\n print \"Passport. init. Initialization failed\"\n return success\n\n\n def destroy(self, configurationAttributes):\n print \"Passport. destroy called\"\n return True\n\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n\n extensionResult = self.extensionAuthenticate(configurationAttributes, requestParameters, step)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. authenticate for step %s called\" % str(step)\n identity = CdiUtil.bean(Identity)\n\n if step == 1:\n # Get JWT token\n jwt_param = ServerUtil.getFirstValue(requestParameters, \"user\")\n\n if jwt_param != None:\n print \"Passport. authenticate for step 1. JWT user profile token found\"\n\n # Parse JWT and validate\n jwt = Jwt.parse(jwt_param)\n if not self.validSignature(jwt):\n return False\n\n if self.jwtHasExpired(jwt):\n return False\n\n (user_profile, jsonp) = self.getUserProfile(jwt)\n if user_profile == None:\n return False\n\n return self.attemptAuthentication(identity, user_profile, jsonp)\n\n #See passportlogin.xhtml\n provider = ServerUtil.getFirstValue(requestParameters, \"loginForm:provider\")\n if StringHelper.isEmpty(provider):\n\n #it's username + passw auth\n print \"Passport. authenticate for step 1. Basic authentication detected\"\n logged_in = False\n\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n authenticationService = CdiUtil.bean(AuthenticationService)\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n print \"Passport. authenticate for step 1. Basic authentication returned: %s\" % logged_in\n return logged_in\n\n elif provider in self.registeredProviders:\n #it's a recognized external IDP\n identity.setWorkingParameter(\"selectedProvider\", provider)\n print \"Passport. authenticate for step 1. Retrying step 1\"\n #see prepareForStep (step = 1)\n return True\n\n if step == 2:\n mail = ServerUtil.getFirstValue(requestParameters, \"loginForm:email\")\n jsonp = identity.getWorkingParameter(\"passport_user_profile\")\n\n if mail == None:\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email was missing in user profile\")\n elif jsonp != None:\n # Completion of profile takes place\n user_profile = json.loads(jsonp)\n user_profile[\"mail\"] = [ mail ]\n\n return self.attemptAuthentication(identity, user_profile, jsonp)\n\n print \"Passport. authenticate for step 2. Failed: expected mail value in HTTP request and json profile in session\"\n return False\n\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n\n extensionResult = self.extensionPrepareForStep(configurationAttributes, requestParameters, step)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. prepareForStep called %s\" % str(step)\n identity = CdiUtil.bean(Identity)\n\n if step == 1:\n #re-read the strategies config (for instance to know which strategies have enabled the email account linking)\n self.parseProviderConfigs()\n identity.setWorkingParameter(\"externalProviders\", json.dumps(self.registeredProviders))\n\n providerParam = self.customAuthzParameter\n url = None\n\n sessionAttributes = identity.getSessionId().getSessionAttributes()\n self.skipProfileUpdate = StringHelper.equalsIgnoreCase(sessionAttributes.get(\"skipPassportProfileUpdate\"), \"true\")\n\n #this param could have been set previously in authenticate step if current step is being retried\n provider = identity.getWorkingParameter(\"selectedProvider\")\n if provider != None:\n url = self.getPassportRedirectUrl(provider)\n identity.setWorkingParameter(\"selectedProvider\", None)\n\n elif providerParam != None:\n paramValue = sessionAttributes.get(providerParam)\n\n if paramValue != None:\n print \"Passport. prepareForStep. Found value in custom param of authorization request: %s\" % paramValue\n provider = self.getProviderFromJson(paramValue)\n\n if provider == None:\n print \"Passport. prepareForStep. A provider value could not be extracted from custom authorization request parameter\"\n elif not provider in self.registeredProviders:\n print \"Passport. prepareForStep. Provider '%s' not part of known configured IDPs/OPs\" % provider\n else:\n url = self.getPassportRedirectUrl(provider)\n\n if url == None:\n print \"Passport. prepareForStep. A page to manually select an identity provider will be shown\"\n else:\n facesService = CdiUtil.bean(FacesService)\n facesService.redirectToExternalURL(url)\n\n return True\n\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n print \"Passport. getExtraParametersForStep called\"\n if step == 1:\n return Arrays.asList(\"selectedProvider\", \"externalProviders\")\n elif step == 2:\n return Arrays.asList(\"passport_user_profile\")\n return None\n\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n print \"Passport. getCountAuthenticationSteps called\"\n identity = CdiUtil.bean(Identity)\n if identity.getWorkingParameter(\"passport_user_profile\") != None:\n return 2\n return 1\n\n\n def getPageForStep(self, configurationAttributes, step):\n print \"Passport. getPageForStep called\"\n\n extensionResult = self.extensionGetPageForStep(configurationAttributes, step)\n if extensionResult != None:\n return extensionResult\n\n if step == 1:\n return \"/auth/passport/passportlogin.xhtml\"\n return \"/auth/passport/passportpostlogin.xhtml\"\n\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n\n if step == 1:\n identity = CdiUtil.bean(Identity)\n provider = identity.getWorkingParameter(\"selectedProvider\")\n if provider != None:\n return 1\n\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n# Extension module related functions\n\n def extensionInit(self, configurationAttributes):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.init(configurationAttributes)\n\n\n def extensionAuthenticate(self, configurationAttributes, requestParameters, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.authenticate(configurationAttributes, requestParameters, step)\n\n\n def extensionPrepareForStep(self, configurationAttributes, requestParameters, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.prepareForStep(configurationAttributes, requestParameters, step)\n\n\n def extensionGetPageForStep(self, configurationAttributes, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.getPageForStep(configurationAttributes, step)\n\n# Initalization routines\n\n def loadExternalModule(self, simpleCustProperty):\n\n if simpleCustProperty != None:\n print \"Passport. loadExternalModule. Loading passport extension module...\"\n moduleName = simpleCustProperty.getValue2()\n try:\n module = __import__(moduleName)\n return module\n except:\n print \"Passport. loadExternalModule. Failed to load module %s\" % moduleName\n print \"Exception: \", sys.exc_info()[1]\n print \"Passport. loadExternalModule. Flow will be driven entirely by routines of main passport script\"\n return None\n\n\n def processKeyStoreProperties(self, attrs):\n file = attrs.get(\"key_store_file\")\n password = attrs.get(\"key_store_password\")\n\n if file != None and password != None:\n file = file.getValue2()\n password = password.getValue2()\n\n if StringHelper.isNotEmpty(file) and StringHelper.isNotEmpty(password):\n self.keyStoreFile = file\n self.keyStorePassword = password\n return True\n\n print \"Passport. readKeyStoreProperties. Properties key_store_file or key_store_password not found or empty\"\n return False\n\n\n def getCustomAuthzParameter(self, simpleCustProperty):\n\n customAuthzParameter = None\n if simpleCustProperty != None:\n prop = simpleCustProperty.getValue2()\n if StringHelper.isNotEmpty(prop):\n customAuthzParameter = prop\n\n if customAuthzParameter == None:\n print \"Passport. getCustomAuthzParameter. No custom param for OIDC authz request in script properties\"\n print \"Passport. getCustomAuthzParameter. Passport flow cannot be initiated by doing an OpenID connect authorization request\"\n else:\n print \"Passport. getCustomAuthzParameter. Custom param for OIDC authz request in script properties: %s\" % customAuthzParameter\n\n return customAuthzParameter\n\n# Configuration parsing\n\n def getPassportConfigDN(self):\n\n f = open('/etc/gluu/conf/gluu.properties', 'r')\n for line in f:\n prop = line.split(\"=\")\n if prop[0] == \"oxpassport_ConfigurationEntryDN\":\n prop.pop(0)\n break\n\n f.close()\n return \"=\".join(prop).strip()\n\n\n def parseAllProviders(self):\n\n registeredProviders = {}\n print \"Passport. parseAllProviders. Adding providers\"\n entryManager = CdiUtil.bean(PersistenceEntryManager)\n\n config = LdapOxPassportConfiguration()\n config = entryManager.find(config.getClass(), self.passportDN).getPassportConfiguration()\n config = config.getProviders() if config != None else config\n\n if config != None and len(config) > 0:\n for prvdetails in config:\n if prvdetails.isEnabled():\n registeredProviders[prvdetails.getId()] = {\n \"emailLinkingSafe\": prvdetails.isEmailLinkingSafe(),\n \"requestForEmail\" : prvdetails.isRequestForEmail(),\n \"logo_img\": prvdetails.getLogoImg(),\n \"displayName\": prvdetails.getDisplayName(),\n \"type\": prvdetails.getType()\n }\n\n return registeredProviders\n\n\n def parseProviderConfigs(self):\n\n registeredProviders = {}\n try:\n registeredProviders = self.parseAllProviders()\n toRemove = []\n\n for provider in registeredProviders:\n if registeredProviders[provider][\"type\"] == \"saml\":\n toRemove.append(provider)\n else:\n registeredProviders[provider][\"saml\"] = False\n\n for provider in toRemove:\n registeredProviders.pop(provider)\n\n if len(registeredProviders.keys()) > 0:\n print \"Passport. parseProviderConfigs. Configured providers:\", registeredProviders\n else:\n print \"Passport. parseProviderConfigs. No providers registered yet\"\n except:\n print \"Passport. parseProviderConfigs. An error occurred while building the list of supported authentication providers\", sys.exc_info()[1]\n\n self.registeredProviders = registeredProviders\n\n# Auxiliary routines\n\n def getProviderFromJson(self, providerJson):\n\n provider = None\n try:\n obj = json.loads(Base64Util.base64urldecodeToString(providerJson))\n provider = obj[self.providerKey]\n except:\n print \"Passport. getProviderFromJson. Could not parse provided Json string. Returning None\"\n\n return provider\n\n\n def getPassportRedirectUrl(self, provider):\n\n # provider is assumed to exist in self.registeredProviders\n url = None\n try:\n facesContext = CdiUtil.bean(FacesContext)\n tokenEndpoint = \"https://%s/passport/token\" % facesContext.getExternalContext().getRequest().getServerName()\n\n httpService = CdiUtil.bean(HttpService)\n httpclient = httpService.getHttpsClient()\n\n print \"Passport. getPassportRedirectUrl. Obtaining token from passport at %s\" % tokenEndpoint\n resultResponse = httpService.executeGet(httpclient, tokenEndpoint, Collections.singletonMap(\"Accept\", \"text/json\"))\n httpResponse = resultResponse.getHttpResponse()\n bytes = httpService.getResponseContent(httpResponse)\n\n response = httpService.convertEntityToString(bytes)\n print \"Passport. getPassportRedirectUrl. Response was %s\" % httpResponse.getStatusLine().getStatusCode()\n\n tokenObj = json.loads(response)\n url = \"/passport/auth/%s/%s\" % (provider, tokenObj[\"token_\"])\n except:\n print \"Passport. getPassportRedirectUrl. Error building redirect URL: \", sys.exc_info()[1]\n\n return url\n\n\n def validSignature(self, jwt):\n\n print \"Passport. validSignature. Checking JWT token signature\"\n valid = False\n\n try:\n appConfiguration = AppConfiguration()\n appConfiguration.setWebKeysStorage(WebKeyStorage.KEYSTORE)\n appConfiguration.setKeyStoreFile(self.keyStoreFile)\n appConfiguration.setKeyStoreSecret(self.keyStorePassword)\n appConfiguration.setKeyRegenerationEnabled(False)\n\n cryptoProvider = CryptoProviderFactory.getCryptoProvider(appConfiguration)\n valid = cryptoProvider.verifySignature(jwt.getSigningInput(), jwt.getEncodedSignature(), jwt.getHeader().getKeyId(),\n None, None, jwt.getHeader().getSignatureAlgorithm())\n except:\n print \"Exception: \", sys.exc_info()[1]\n\n print \"Passport. validSignature. Validation result was %s\" % valid\n return valid\n\n\n def jwtHasExpired(self, jwt):\n # Check if jwt has expired\n jwt_claims = jwt.getClaims()\n try:\n exp_date = jwt_claims.getClaimAsDate(JwtClaimName.EXPIRATION_TIME)\n hasExpired = exp_date < datetime.datetime.now()\n except:\n print \"Exception: The JWT does not have '%s' attribute\" % JwtClaimName.EXPIRATION_TIME\n return False\n\n return hasExpired\n\n\n def getUserProfile(self, jwt):\n jwt_claims = jwt.getClaims()\n user_profile_json = None\n\n try:\n user_profile_json = CdiUtil.bean(EncryptionService).decrypt(jwt_claims.getClaimAsString(\"data\"))\n user_profile = json.loads(user_profile_json)\n except:\n print \"Passport. getUserProfile. Problem obtaining user profile json representation\"\n\n return (user_profile, user_profile_json)\n\n\n def attemptAuthentication(self, identity, user_profile, user_profile_json):\n\n uidKey = \"uid\"\n if not self.checkRequiredAttributes(user_profile, [uidKey, self.providerKey]):\n return False\n\n provider = user_profile[self.providerKey]\n if not provider in self.registeredProviders:\n print \"Passport. attemptAuthentication. Identity Provider %s not recognized\" % provider\n return False\n\n uid = user_profile[uidKey][0]\n externalUid = \"passport-%s:%s\" % (provider, uid)\n\n userService = CdiUtil.bean(UserService)\n userByUid = userService.getUserByAttribute(\"oxExternalUid\", externalUid)\n\n email = None\n if \"mail\" in user_profile:\n email = user_profile[\"mail\"]\n if len(email) == 0:\n email = None\n else:\n email = email[0]\n user_profile[\"mail\"] = [ email ]\n\n if email == None and self.registeredProviders[provider][\"requestForEmail\"]:\n print \"Passport. attemptAuthentication. Email was not received\"\n\n if userByUid != None:\n # This avoids asking for the email over every login attempt\n email = userByUid.getAttribute(\"mail\")\n if email != None:\n print \"Passport. attemptAuthentication. Filling missing email value with %s\" % email\n user_profile[\"mail\"] = [ email ]\n\n if email == None:\n # Store user profile in session and abort this routine\n identity.setWorkingParameter(\"passport_user_profile\", user_profile_json)\n return True\n\n userByMail = None if email == None else userService.getUserByAttribute(\"mail\", email)\n\n # Determine if we should add entry, update existing, or deny access\n doUpdate = False\n doAdd = False\n if userByUid != None:\n print \"User with externalUid '%s' already exists\" % externalUid\n if userByMail == None:\n doUpdate = True\n else:\n if userByMail.getUserId() == userByUid.getUserId():\n doUpdate = True\n else:\n print \"Users with externalUid '%s' and mail '%s' are different. Access will be denied. Impersonation attempt?\" % (externalUid, email)\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email value corresponds to an already existing provisioned account\")\n else:\n if userByMail == None:\n doAdd = True\n elif self.registeredProviders[provider][\"emailLinkingSafe\"]:\n\n tmpList = userByMail.getAttributeValues(\"oxExternalUid\")\n tmpList = ArrayList() if tmpList == None else ArrayList(tmpList)\n tmpList.add(externalUid)\n userByMail.setAttribute(\"oxExternalUid\", tmpList)\n\n userByUid = userByMail\n print \"External user supplying mail %s will be linked to existing account '%s'\" % (email, userByMail.getUserId())\n doUpdate = True\n else:\n print \"An attempt to supply an email of an existing user was made. Turn on 'emailLinkingSafe' if you want to enable linking\"\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email value corresponds to an already existing account. If you already have a username and password use those instead of an external authentication site to get access.\")\n\n username = None\n try:\n if doUpdate:\n username = userByUid.getUserId()\n print \"Passport. attemptAuthentication. Updating user %s\" % username\n self.updateUser(userByUid, user_profile, userService)\n elif doAdd:\n print \"Passport. attemptAuthentication. Creating user %s\" % externalUid\n newUser = self.addUser(externalUid, user_profile, userService)\n username = newUser.getUserId()\n except:\n print \"Exception: \", sys.exc_info()[1]\n print \"Passport. attemptAuthentication. Authentication failed\"\n return False\n\n if username == None:\n print \"Passport. attemptAuthentication. Authentication attempt was rejected\"\n return False\n else:\n logged_in = CdiUtil.bean(AuthenticationService).authenticate(username)\n print \"Passport. attemptAuthentication. Authentication for %s returned %s\" % (username, logged_in)\n return logged_in\n\n\n def setMessageError(self, severity, msg):\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n facesMessages.clear()\n facesMessages.add(severity, msg)\n\n\n def checkRequiredAttributes(self, profile, attrs):\n\n for attr in attrs:\n if (not attr in profile) or len(profile[attr]) == 0:\n print \"Passport. checkRequiredAttributes. Attribute '%s' is missing in profile\" % attr\n return False\n return True\n\n\n def addUser(self, externalUid, profile, userService):\n\n newUser = User()\n #Fill user attrs\n newUser.setAttribute(\"oxExternalUid\", externalUid)\n self.fillUser(newUser, profile)\n newUser = userService.addUser(newUser, True)\n return newUser\n\n\n def updateUser(self, foundUser, profile, userService):\n\n # when this is false, there might still some updates taking place (e.g. not related to profile attrs released by external provider)\n if (not self.skipProfileUpdate):\n self.fillUser(foundUser, profile)\n userService.updateUser(foundUser)\n\n\n def fillUser(self, foundUser, profile):\n\n for attr in profile:\n # \"provider\" is disregarded if part of mapping\n if attr != self.providerKey:\n values = profile[attr]\n print \"%s = %s\" % (attr, values)\n foundUser.setAttribute(attr, values)\n\n if attr == \"mail\":\n oxtrustMails = []\n for mail in values:\n oxtrustMails.append('{\"value\":\"%s\",\"primary\":false}' % mail)\n foundUser.setAttribute(\"oxTrustEmail\", oxtrustMails)\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "passport_social", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "/etc/certs/passport-rp.jks", + "value1": "key_store_file" + }, + { + "hide": false, + "value2": "secret", + "value1": "key_store_password" + } + ], + "baseDn": "inum=2FDB-CF02,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 45, + "programmingLanguage": "PYTHON", + "description": "SMPP SMS authentication module", + "locationType": "LDAP", + "dn": "inum=09A0-93D7,ou=scripts,o=gluu", + "inum": "09A0-93D7", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2018, Gluu\n# Copyright (c) 2019, Tele2\n\n# Author: Jose Gonzalez\n# Author: Gasmyr Mougang\n# Author: Stefan Andersson\n\nfrom java.util import Arrays, Date\nfrom java.io import IOException\nfrom java.lang import Enum\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom javax.faces.application import FacesMessage\nfrom org.gluu.jsf2.message import FacesMessages\n\nfrom org.jsmpp import InvalidResponseException, PDUException\nfrom org.jsmpp.bean import Alphabet, BindType, ESMClass, GeneralDataCoding, MessageClass, NumberingPlanIndicator, RegisteredDelivery, SMSCDeliveryReceipt, TypeOfNumber\nfrom org.jsmpp.extra import NegativeResponseException, ResponseTimeoutException\nfrom org.jsmpp.session import BindParameter, SMPPSession\nfrom org.jsmpp.util import AbsoluteTimeFormatter, TimeFormatter\nimport random\n\n\nclass SmppAttributeError(Exception):\n pass\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n self.identity = CdiUtil.bean(Identity)\n\n def get_and_parse_smpp_config(self, config, attribute, _type = None, convert = False, optional = False, default_desc = None):\n try:\n value = config.get(attribute).getValue2()\n except:\n if default_desc:\n default_desc = \" using default '{}'\".format(default_desc)\n else:\n default_desc = \"\"\n\n if optional:\n raise SmppAttributeError(\"SMPP missing optional configuration attribute '{}'{}\".format(attribute, default_desc))\n else:\n raise SmppAttributeError(\"SMPP missing required configuration attribute '{}'\".format(attribute))\n\n if _type and issubclass(_type, Enum):\n try:\n return getattr(_type, value)\n except AttributeError:\n raise SmppAttributeError(\"SMPP could not find attribute '{}' in {}\".format(attribute, _type))\n\n if convert:\n try:\n value = int(value)\n except AttributeError:\n try:\n value = int(value, 16)\n except AttributeError:\n raise SmppAttributeError(\"SMPP could not parse value '{}' of attribute '{}'\".format(value, attribute))\n\n return value\n\n def init(self, customScript, configurationAttributes):\n print(\"SMPP Initialization\")\n\n self.TIME_FORMATTER = AbsoluteTimeFormatter()\n\n self.SMPP_SERVER = None\n self.SMPP_PORT = None\n\n self.SYSTEM_ID = None\n self.PASSWORD = None\n\n # Setup some good defaults for TON, NPI and source (from) address\n # TON (Type of Number), NPI (Number Plan Indicator)\n self.SRC_ADDR_TON = TypeOfNumber.ALPHANUMERIC # Alphanumeric\n self.SRC_ADDR_NPI = NumberingPlanIndicator.ISDN # ISDN (E163/E164)\n self.SRC_ADDR = \"Gluu OTP\"\n\n # Don't touch these unless you know what your doing, we don't handle number reformatting for\n # any other type than international.\n self.DST_ADDR_TON = TypeOfNumber.INTERNATIONAL # International\n self.DST_ADDR_NPI = NumberingPlanIndicator.ISDN # ISDN (E163/E164)\n\n # Priority flag and data_coding bits\n self.PRIORITY_FLAG = 3 # Very Urgent (ANSI-136), Emergency (IS-95)\n self.DATA_CODING_ALPHABET = Alphabet.ALPHA_DEFAULT # SMS default alphabet\n self.DATA_CODING_MESSAGE_CLASS = MessageClass.CLASS1 # EM (Mobile Equipment (mobile memory), normal message\n\n # Required server settings\n try:\n self.SMPP_SERVER = self.get_and_parse_smpp_config(configurationAttributes, \"smpp_server\")\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.SMPP_PORT = self.get_and_parse_smpp_config(configurationAttributes, \"smpp_port\", convert = True)\n except SmppAttributeError as e:\n print(e)\n\n if None in (self.SMPP_SERVER, self.SMPP_PORT):\n print(\"SMPP smpp_server and smpp_port is empty, will not enable SMPP service\")\n return False\n\n # Optional system_id and password for bind auth\n try:\n self.SYSTEM_ID = self.get_and_parse_smpp_config(configurationAttributes, \"system_id\", optional = True)\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.PASSWORD = self.get_and_parse_smpp_config(configurationAttributes, \"password\", optional = True)\n except SmppAttributeError as e:\n print(e)\n\n if None in (self.SYSTEM_ID, self.PASSWORD):\n print(\"SMPP Authentication disabled\")\n\n # From number and to number settings\n try:\n self.SRC_ADDR_TON = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"source_addr_ton\",\n _type = TypeOfNumber,\n optional = True,\n default_desc = self.SRC_ADDR_TON\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.SRC_ADDR_NPI = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"source_addr_npi\",\n _type = NumberingPlanIndicator,\n optional = True,\n default_desc = self.SRC_ADDR_NPI\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.SRC_ADDR = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"source_addr\",\n optional = True,\n default_desc = self.SRC_ADDR\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.DST_ADDR_TON = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"dest_addr_ton\",\n _type = TypeOfNumber,\n optional = True,\n default_desc = self.DST_ADDR_TON\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.DST_ADDR_NPI = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"dest_addr_npi\",\n _type = NumberingPlanIndicator,\n optional = True,\n default_desc = self.DST_ADDR_NPI\n )\n except SmppAttributeError as e:\n print(e)\n\n # Priority flag and data coding, don't touch these unless you know what your doing...\n try:\n self.PRIORITY_FLAG = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"priority_flag\",\n convert = True,\n optional = True,\n default_desc = \"3 (Very Urgent, Emergency)\"\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.DATA_CODING_ALPHABET = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"data_coding_alphabet\",\n _type = Alphabet,\n optional = True,\n default_desc = self.DATA_CODING_ALPHABET\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.DATA_CODING_MESSAGE_CLASS = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"data_coding_alphabet\",\n _type = MessageClass,\n optional = True,\n default_desc = self.DATA_CODING_MESSAGE_CLASS\n )\n except SmppAttributeError as e:\n print(e)\n\n print(\"SMPP Initialized successfully\")\n return True\n\n def destroy(self, configurationAttributes):\n print(\"SMPP Destroy\")\n print(\"SMPP Destroyed successfully\")\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n\n session_attributes = self.identity.getSessionId().getSessionAttributes()\n form_passcode = ServerUtil.getFirstValue(requestParameters, \"passcode\")\n\n print(\"SMPP form_response_passcode: {}\".format(str(form_passcode)))\n\n if step == 1:\n print(\"SMPP Step 1 Password Authentication\")\n credentials = self.identity.getCredentials()\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return False\n\n # Get the Person's number and generate a code\n foundUser = None\n try:\n foundUser = authenticationService.getAuthenticatedUser()\n except:\n print(\"SMPP Error retrieving user {} from LDAP\".format(user_name))\n return False\n\n mobile_number = None\n try:\n isVerified = foundUser.getAttribute(\"phoneNumberVerified\")\n if isVerified:\n mobile_number = foundUser.getAttribute(\"employeeNumber\")\n if not mobile_number:\n mobile_number = foundUser.getAttribute(\"mobile\")\n if not mobile_number:\n mobile_number = foundUser.getAttribute(\"telephoneNumber\")\n if not mobile_number:\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to determine mobile phone number\")\n print(\"SMPP Error finding mobile number for user '{}'\".format(user_name))\n return False\n except Exception as e:\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to determine mobile phone number\")\n print(\"SMPP Error finding mobile number for {}: {}\".format(user_name, e))\n return False\n\n # Generate Random six digit code\n code = random.randint(100000, 999999)\n\n # Get code and save it in LDAP temporarily with special session entry\n self.identity.setWorkingParameter(\"code\", code)\n\n self.identity.setWorkingParameter(\"mobile_number\", mobile_number)\n self.identity.getSessionId().getSessionAttributes().put(\"mobile_number\", mobile_number)\n if not self.sendMessage(mobile_number, str(code)):\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to send message to mobile phone\")\n return False\n\n return True\n elif step == 2:\n # Retrieve the session attribute\n print(\"SMPP Step 2 SMS/OTP Authentication\")\n code = session_attributes.get(\"code\")\n print(\"SMPP Code: {}\".format(str(code)))\n\n if code is None:\n print(\"SMPP Failed to find previously sent code\")\n return False\n\n if form_passcode is None:\n print(\"SMPP Passcode is empty\")\n return False\n\n if len(form_passcode) != 6:\n print(\"SMPP Passcode from response is not 6 digits: {}\".format(form_passcode))\n return False\n\n if form_passcode == code:\n print(\"SMPP SUCCESS! User entered the same code!\")\n return True\n\n print(\"SMPP failed, user entered the wrong code! {} != {}\".format(form_passcode, code))\n facesMessages.add(facesMessage.SEVERITY_ERROR, \"Incorrect SMS code, please try again.\")\n return False\n\n print(\"SMPP ERROR: step param not found or != (1|2)\")\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n if step == 1:\n print(\"SMPP Prepare for Step 1\")\n return True\n elif step == 2:\n print(\"SMPP Prepare for Step 2\")\n return True\n\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n if step == 2:\n return Arrays.asList(\"code\")\n\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 2:\n return \"/auth/otp_sms/otp_sms.xhtml\"\n\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def sendMessage(self, number, code):\n status = False\n session = SMPPSession()\n session.setTransactionTimer(10000)\n\n # We only handle international destination number reformatting.\n # All others may vary by configuration decisions taken on SMPP\n # server side which we have no clue about.\n if self.DST_ADDR_TON == TypeOfNumber.INTERNATIONAL and number.startswith(\"+\"):\n number = number[1:]\n\n try:\n print(\"SMPP Connecting\")\n reference_id = session.connectAndBind(\n self.SMPP_SERVER,\n self.SMPP_PORT,\n BindParameter(\n BindType.BIND_TX,\n self.SYSTEM_ID,\n self.PASSWORD,\n None,\n self.SRC_ADDR_TON,\n self.SRC_ADDR_NPI,\n None\n )\n )\n print(\"SMPP Connected to server with system id {}\".format(reference_id))\n\n try:\n message_id = session.submitShortMessage(\n \"CMT\",\n self.SRC_ADDR_TON,\n self.SRC_ADDR_NPI,\n self.SRC_ADDR,\n self.DST_ADDR_TON,\n self.DST_ADDR_NPI,\n number,\n ESMClass(),\n 0,\n self.PRIORITY_FLAG,\n self.TIME_FORMATTER.format(Date()),\n None,\n RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT),\n 0,\n GeneralDataCoding(\n self.DATA_CODING_ALPHABET,\n self.DATA_CODING_MESSAGE_CLASS,\n False\n ),\n 0,\n code\n )\n print(\"SMPP Message '{}' sent to #{} with message id {}\".format(code, number, message_id))\n status = True\n except PDUException as e:\n print(\"SMPP Invalid PDU parameter: {}\".format(e))\n except ResponseTimeoutException as e:\n print(\"SMPP Response timeout: {}\".format(e))\n except InvalidResponseException as e:\n print(\"SMPP Receive invalid response: {}\".format(e))\n except NegativeResponseException as e:\n print(\"SMPP Receive negative response: {}\".format(e))\n except IOException as e:\n print(\"SMPP IO error occured: {}\".format(e))\n finally:\n session.unbindAndClose()\n except IOException as e:\n print(\"SMPP Failed connect and bind to host: {}\".format(e))\n\n return status\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "smpp", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value1": "smpp_server", + "description": "IP or FQDN of SMPP server" + }, + { + "hide": false, + "value1": "smpp_port", + "description": "TCP port of the SMPP server" + }, + { + "hide": false, + "value1": "system_id", + "description": "Use if SMPP server requires authentication" + }, + { + "hide": false, + "value1": "password", + "description": "Use if SMPP server requires authentication" + }, + { + "hide": false, + "value1": "source_addr_ton", + "description": "Type of number, eg ALPHANUMERIC, INTERNATIONAL" + }, + { + "hide": false, + "value1": "source_addr", + "description": "From number/name" + } + ], + "baseDn": "inum=09A0-93D7,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 50, + "programmingLanguage": "PYTHON", + "description": "ThumbSignIn authentication module", + "locationType": "LDAP", + "dn": "inum=92F0-759E,ou=scripts,o=gluu", + "inum": "92F0-759E", + "script": "# Author: ThumbSignIn\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.util import StringHelper\nfrom org.gluu.oxauth.util import ServerUtil\nfrom com.pramati.ts.thumbsignin_java_sdk import ThumbsigninApiController\nfrom org.json import JSONObject\nfrom org.gluu.oxauth.model.util import Base64Util\nfrom java.lang import String\n\nimport java\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n\n def __init__(self, current_time_millis):\n self.currentTimeMillis = current_time_millis\n self.thumbsigninApiController = ThumbsigninApiController()\n\n def init(self, customScript, configuration_attributes):\n print \"ThumbSignIn. Initialization\"\n\n global ts_host\n ts_host = configuration_attributes.get(\"ts_host\").getValue2()\n print \"ThumbSignIn. Initialization. Value of ts_host is %s\" % ts_host\n\n global ts_api_key\n ts_api_key = configuration_attributes.get(\"ts_apiKey\").getValue2()\n print \"ThumbSignIn. Initialization. Value of ts_api_key is %s\" % ts_api_key\n\n global ts_api_secret\n ts_api_secret = configuration_attributes.get(\"ts_apiSecret\").getValue2()\n\n global ts_statusPath\n ts_statusPath = \"/ts/secure/txn-status/\"\n\n global AUTHENTICATE\n AUTHENTICATE = \"authenticate\"\n\n global REGISTER\n REGISTER = \"register\"\n\n global TRANSACTION_ID\n TRANSACTION_ID = \"transactionId\"\n\n global USER_ID\n USER_ID = \"userId\"\n\n global USER_LOGIN_FLOW\n USER_LOGIN_FLOW = \"userLoginFlow\"\n\n global THUMBSIGNIN_AUTHENTICATION\n THUMBSIGNIN_AUTHENTICATION = \"ThumbSignIn_Authentication\"\n\n global THUMBSIGNIN_REGISTRATION\n THUMBSIGNIN_REGISTRATION = \"ThumbSignIn_Registration\"\n\n global THUMBSIGNIN_LOGIN_POST_REGISTRATION\n THUMBSIGNIN_LOGIN_POST_REGISTRATION = \"ThumbSignIn_RegistrationSucess\"\n\n global RELYING_PARTY_ID\n RELYING_PARTY_ID = \"relyingPartyId\"\n\n global RELYING_PARTY_LOGIN_URL\n RELYING_PARTY_LOGIN_URL = \"relyingPartyLoginUrl\"\n\n global TSI_LOGIN_PAGE\n TSI_LOGIN_PAGE = \"/auth/thumbsignin/tsLogin.xhtml\"\n\n global TSI_REGISTER_PAGE\n TSI_REGISTER_PAGE = \"/auth/thumbsignin/tsRegister.xhtml\"\n\n global TSI_LOGIN_POST_REGISTRATION_PAGE\n TSI_LOGIN_POST_REGISTRATION_PAGE = \"/auth/thumbsignin/tsRegistrationSuccess.xhtml\"\n\n print \"ThumbSignIn. Initialized successfully\"\n return True\n\n @staticmethod\n def set_relying_party_login_url(identity):\n print \"ThumbSignIn. Inside set_relying_party_login_url...\"\n session_id = identity.getSessionId()\n session_attribute = session_id.getSessionAttributes()\n state_jwt_token = session_attribute.get(\"state\")\n print \"ThumbSignIn. Value of state_jwt_token is %s\" % state_jwt_token\n relying_party_login_url = \"\"\n if (state_jwt_token is None) or (\".\" not in state_jwt_token):\n print \"ThumbSignIn. Value of state parameter is not in the format of JWT Token\"\n identity.setWorkingParameter(RELYING_PARTY_LOGIN_URL, relying_party_login_url)\n return None\n\n state_jwt_token_array = String(state_jwt_token).split(\"\\\\.\")\n state_jwt_token_payload = state_jwt_token_array[1]\n state_payload_str = String(Base64Util.base64urldecode(state_jwt_token_payload), \"UTF-8\")\n state_payload_json = JSONObject(state_payload_str)\n print \"ThumbSignIn. Value of state JWT token Payload is %s\" % state_payload_json\n if state_payload_json.has(\"additional_claims\"):\n additional_claims = state_payload_json.get(\"additional_claims\")\n relying_party_id = additional_claims.get(RELYING_PARTY_ID)\n print \"ThumbSignIn. Value of relying_party_id is %s\" % relying_party_id\n identity.setWorkingParameter(RELYING_PARTY_ID, relying_party_id)\n\n if String(relying_party_id).startsWith(\"google.com\"):\n # google.com/a/unphishableenterprise.com\n relying_party_id_array = String(relying_party_id).split(\"/\")\n google_domain = relying_party_id_array[2]\n print \"ThumbSignIn. Value of google_domain is %s\" % google_domain\n relying_party_login_url = \"https://www.google.com/accounts/AccountChooser?hd=\"+ google_domain + \"%26continue=https://apps.google.com/user/hub\"\n # elif (String(relying_party_id).startsWith(\"xyz\")):\n # relying_party_login_url = \"xyz.com\"\n else:\n # If relying_party_login_url is empty, Gluu's default login URL will be used\n relying_party_login_url = \"\"\n\n print \"ThumbSignIn. Value of relying_party_login_url is %s\" % relying_party_login_url\n identity.setWorkingParameter(RELYING_PARTY_LOGIN_URL, relying_party_login_url)\n return None\n\n def initialize_thumbsignin(self, identity, request_path):\n # Invoking the authenticate/register ThumbSignIn API via the Java SDK\n thumbsignin_response = self.thumbsigninApiController.handleThumbSigninRequest(request_path, ts_api_key, ts_api_secret)\n print \"ThumbSignIn. Value of thumbsignin_response is %s\" % thumbsignin_response\n\n thumbsignin_response_json = JSONObject(thumbsignin_response)\n transaction_id = thumbsignin_response_json.get(TRANSACTION_ID)\n status_request_type = \"authStatus\" if request_path == AUTHENTICATE else \"regStatus\"\n status_request = status_request_type + \"/\" + transaction_id\n print \"ThumbSignIn. Value of status_request is %s\" % status_request\n\n authorization_header = self.thumbsigninApiController.getAuthorizationHeaderJsonStr(status_request, ts_api_key, ts_api_secret)\n print \"ThumbSignIn. Value of authorization_header is %s\" % authorization_header\n # {\"authHeader\":\"HmacSHA256 Credential=X,SignedHeaders=accept;content-type;x-ts-date,Signature=X\",\"XTsDate\":\"X\"}\n authorization_header_json = JSONObject(authorization_header)\n auth_header = authorization_header_json.get(\"authHeader\")\n x_ts_date = authorization_header_json.get(\"XTsDate\")\n\n tsi_response_key = \"authenticateResponseJsonStr\" if request_path == AUTHENTICATE else \"registerResponseJsonStr\"\n identity.setWorkingParameter(tsi_response_key, thumbsignin_response)\n identity.setWorkingParameter(\"authorizationHeader\", auth_header)\n identity.setWorkingParameter(\"xTsDate\", x_ts_date)\n return None\n\n def prepareForStep(self, configuration_attributes, request_parameters, step):\n print \"ThumbSignIn. Inside prepareForStep. Step %d\" % step\n identity = CdiUtil.bean(Identity)\n authentication_service = CdiUtil.bean(AuthenticationService)\n\n identity.setWorkingParameter(\"ts_host\", ts_host)\n identity.setWorkingParameter(\"ts_statusPath\", ts_statusPath)\n\n self.set_relying_party_login_url(identity)\n\n if step == 1 or step == 3:\n print \"ThumbSignIn. Prepare for step 1\"\n self.initialize_thumbsignin(identity, AUTHENTICATE)\n return True\n\n elif step == 2:\n print \"ThumbSignIn. Prepare for step 2\"\n if identity.isSetWorkingParameter(USER_LOGIN_FLOW):\n user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW)\n print \"ThumbSignIn. Value of user_login_flow is %s\" % user_login_flow\n user = authentication_service.getAuthenticatedUser()\n if user is None:\n print \"ThumbSignIn. Prepare for step 2. Failed to determine user name\"\n return False\n user_name = user.getUserId()\n print \"ThumbSignIn. Prepare for step 2. user_name: \" + user_name\n if user_name is None:\n return False\n identity.setWorkingParameter(USER_ID, user_name)\n self.initialize_thumbsignin(identity, REGISTER + \"/\" + user_name)\n return True\n else:\n return False\n\n def get_user_id_from_thumbsignin(self, request_parameters):\n transaction_id = ServerUtil.getFirstValue(request_parameters, TRANSACTION_ID)\n print \"ThumbSignIn. Value of transaction_id is %s\" % transaction_id\n get_user_request = \"getUser/\" + transaction_id\n print \"ThumbSignIn. Value of get_user_request is %s\" % get_user_request\n\n get_user_response = self.thumbsigninApiController.handleThumbSigninRequest(get_user_request, ts_api_key, ts_api_secret)\n print \"ThumbSignIn. Value of get_user_response is %s\" % get_user_response\n get_user_response_json = JSONObject(get_user_response)\n thumbsignin_user_id = get_user_response_json.get(USER_ID)\n print \"ThumbSignIn. Value of thumbsignin_user_id is %s\" % thumbsignin_user_id\n return thumbsignin_user_id\n\n def authenticate(self, configuration_attributes, request_parameters, step):\n print \"ThumbSignIn. Inside authenticate. Step %d\" % step\n authentication_service = CdiUtil.bean(AuthenticationService)\n identity = CdiUtil.bean(Identity)\n\n identity.setWorkingParameter(\"ts_host\", ts_host)\n identity.setWorkingParameter(\"ts_statusPath\", ts_statusPath)\n\n if step == 1 or step == 3:\n print \"ThumbSignIn. Authenticate for Step %d\" % step\n\n login_flow = ServerUtil.getFirstValue(request_parameters, \"login_flow\")\n print \"ThumbSignIn. Value of login_flow parameter is %s\" % login_flow\n\n # Logic for ThumbSignIn Authentication Flow (Either step 1 or step 3)\n if login_flow == THUMBSIGNIN_AUTHENTICATION or login_flow == THUMBSIGNIN_LOGIN_POST_REGISTRATION:\n identity.setWorkingParameter(USER_LOGIN_FLOW, login_flow)\n print \"ThumbSignIn. Value of userLoginFlow is %s\" % identity.getWorkingParameter(USER_LOGIN_FLOW)\n logged_in_status = authentication_service.authenticate(self.get_user_id_from_thumbsignin(request_parameters))\n print \"ThumbSignIn. logged_in status : %r\" % logged_in_status\n return logged_in_status\n\n # Logic for traditional login flow (step 1)\n print \"ThumbSignIn. User credentials login flow\"\n identity.setWorkingParameter(USER_LOGIN_FLOW, THUMBSIGNIN_REGISTRATION)\n print \"ThumbSignIn. Value of userLoginFlow is %s\" % identity.getWorkingParameter(USER_LOGIN_FLOW)\n logged_in = self.authenticate_user_credentials(identity, authentication_service)\n print \"ThumbSignIn. Status of User Credentials based Authentication : %r\" % logged_in\n\n # When the traditional login fails, reinitialize the ThumbSignIn data before sending error response to UI\n if not logged_in:\n self.initialize_thumbsignin(identity, AUTHENTICATE)\n return False\n\n print \"ThumbSignIn. Authenticate successful for step %d\" % step\n return True\n\n elif step == 2:\n print \"ThumbSignIn. Registration flow (step 2)\"\n self.verify_user_login_flow(identity)\n\n user = self.get_authenticated_user_from_gluu(authentication_service)\n if user is None:\n print \"ThumbSignIn. Registration flow (step 2). Failed to determine user name\"\n return False\n\n user_name = user.getUserId()\n print \"ThumbSignIn. Registration flow (step 2) successful. user_name: %s\" % user_name\n return True\n\n else:\n return False\n\n def authenticate_user_credentials(self, identity, authentication_service):\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n print \"ThumbSignIn. user_name: \" + user_name\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = self.authenticate_user_in_gluu_ldap(authentication_service, user_name, user_password)\n return logged_in\n\n @staticmethod\n def authenticate_user_in_gluu_ldap(authentication_service, user_name, user_password):\n return authentication_service.authenticate(user_name, user_password)\n\n @staticmethod\n def get_authenticated_user_from_gluu(authentication_service):\n return authentication_service.getAuthenticatedUser()\n\n @staticmethod\n def verify_user_login_flow(identity):\n if identity.isSetWorkingParameter(USER_LOGIN_FLOW):\n user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW)\n print \"ThumbSignIn. Value of user_login_flow is %s\" % user_login_flow\n else:\n identity.setWorkingParameter(USER_LOGIN_FLOW, THUMBSIGNIN_REGISTRATION)\n print \"ThumbSignIn. Setting the value of user_login_flow to %s\" % identity.getWorkingParameter(USER_LOGIN_FLOW)\n\n def getExtraParametersForStep(self, configuration_attributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configuration_attributes):\n print \"ThumbSignIn. Inside getCountAuthenticationSteps..\"\n identity = CdiUtil.bean(Identity)\n\n user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW)\n print \"ThumbSignIn. Value of userLoginFlow is %s\" % user_login_flow\n if user_login_flow == THUMBSIGNIN_AUTHENTICATION:\n print \"ThumbSignIn. Total Authentication Steps is: 1\"\n return 1\n print \"ThumbSignIn. Total Authentication Steps is: 3\"\n return 3\n\n def getPageForStep(self, configuration_attributes, step):\n print \"ThumbSignIn. Inside getPageForStep. Step %d\" % step\n if step == 3:\n return TSI_LOGIN_POST_REGISTRATION_PAGE\n thumbsignin_page = TSI_REGISTER_PAGE if step == 2 else TSI_LOGIN_PAGE\n return thumbsignin_page\n\n def destroy(self, configurationAttributes):\n print \"ThumbSignIn. Destroy\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + }, + { + "value2": "interactive", + "value1": "usage_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "thumb_sign_in", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "https://ts.host.com", + "value1": "ts_host" + }, + { + "hide": false, + "value2": "ts_api_key", + "value1": "ts_apiKey" + }, + { + "hide": false, + "value2": "ts_api_secret", + "value1": "ts_apiSecret" + } + ], + "baseDn": "inum=92F0-759E,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 50, + "programmingLanguage": "PYTHON", + "description": "DUO authentication module", + "locationType": "LDAP", + "dn": "inum=5018-F9CF,ou=scripts,o=gluu", + "inum": "5018-F9CF", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.service import MailService\nfrom org.gluu.util import ArrayHelper\nfrom org.gluu.util import StringHelper\nfrom java.util import Arrays\n\nimport duo_web\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Duo. Initialization\"\n\n duo_creds_file = configurationAttributes.get(\"duo_creds_file\").getValue2()\n # Load credentials from file\n f = open(duo_creds_file, 'r')\n try:\n creds = json.loads(f.read())\n except:\n print \"Duo. Initialization. Failed to load creds from file:\", duo_creds_file\n return False\n finally:\n f.close()\n\n self.ikey = str(creds[\"ikey\"])\n self.skey = str(creds[\"skey\"])\n self.akey = str(creds[\"akey\"])\n\n self.use_duo_group = False\n if (configurationAttributes.containsKey(\"duo_group\")):\n self.duo_group = configurationAttributes.get(\"duo_group\").getValue2()\n self.use_duo_group = True\n print \"Duo. Initialization. Using Duo only if user belong to group:\", self.duo_group\n\n self.use_audit_group = False\n if (configurationAttributes.containsKey(\"audit_group\")):\n self.audit_group = configurationAttributes.get(\"audit_group\").getValue2()\n\n if (not configurationAttributes.containsKey(\"audit_group_email\")):\n print \"Duo. Initialization. Property audit_group_email is not specified\"\n return False\n\n self.audit_email = configurationAttributes.get(\"audit_group_email\").getValue2()\n self.use_audit_group = True\n\n print \"Duo. Initialization. Using audito group:\", self.audit_group\n \n if (self.use_duo_group or self.use_audit_group):\n if (not configurationAttributes.containsKey(\"audit_attribute\")):\n print \"Duo. Initialization. Property audit_attribute is not specified\"\n return False\n else:\n self.audit_attribute = configurationAttributes.get(\"audit_attribute\").getValue2()\n\n print \"Duo. Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"Duo. Destroy\"\n print \"Duo. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n duo_host = configurationAttributes.get(\"duo_host\").getValue2()\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n\n if (step == 1):\n print \"Duo. Authenticate for step 1\"\n\n # Check if user authenticated already in another custom script\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n \n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n userService = CdiUtil.bean(UserService)\n logged_in = authenticationService.authenticate(user_name, user_password)\n \n if (not logged_in):\n return False\n \n user = authenticationService.getAuthenticatedUser()\n\n if (self.use_duo_group):\n print \"Duo. Authenticate for step 1. Checking if user belong to Duo group\"\n is_member_duo_group = self.isUserMemberOfGroup(user, self.audit_attribute, self.duo_group)\n if (is_member_duo_group):\n print \"Duo. Authenticate for step 1. User '\" + user.getUserId() + \"' member of Duo group\"\n duo_count_login_steps = 2\n else:\n self.processAuditGroup(user)\n duo_count_login_steps = 1\n\n identity.setWorkingParameter(\"duo_count_login_steps\", duo_count_login_steps)\n\n return True\n elif (step == 2):\n print \"Duo. Authenticate for step 2\"\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"Duo. Authenticate for step 2. Failed to determine user name\"\n return False\n\n user_name = user.getUserId()\n\n sig_response_array = requestParameters.get(\"sig_response\")\n if ArrayHelper.isEmpty(sig_response_array):\n print \"Duo. Authenticate for step 2. sig_response is empty\"\n return False\n\n duo_sig_response = sig_response_array[0]\n\n print \"Duo. Authenticate for step 2. duo_sig_response: \" + duo_sig_response\n\n authenticated_username = duo_web.verify_response(self.ikey, self.skey, self.akey, duo_sig_response)\n\n print \"Duo. Authenticate for step 2. authenticated_username: \" + authenticated_username + \", expected user_name: \" + user_name\n\n if (not StringHelper.equals(user_name, authenticated_username)):\n return False\n\n self.processAuditGroup(user)\n\n return True\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n duo_host = configurationAttributes.get(\"duo_host\").getValue2()\n\n if (step == 1):\n print \"Duo. Prepare for step 1\"\n\n return True\n elif (step == 2):\n print \"Duo. Prepare for step 2\"\n\n user = authenticationService.getAuthenticatedUser()\n if (user == None):\n print \"Duo. Prepare for step 2. Failed to determine user name\"\n return False\n user_name = user.getUserId()\n\n duo_sig_request = duo_web.sign_request(self.ikey, self.skey, self.akey, user_name)\n print \"Duo. Prepare for step 2. duo_sig_request: \" + duo_sig_request\n \n identity.setWorkingParameter(\"duo_host\", duo_host)\n identity.setWorkingParameter(\"duo_sig_request\", duo_sig_request)\n\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n if step == 2:\n return Arrays.asList(\"duo_count_login_steps\", \"cas2_user_uid\")\n\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n identity = CdiUtil.bean(Identity)\n if (identity.isSetWorkingParameter(\"duo_count_login_steps\")):\n return int(identity.getWorkingParameter(\"duo_count_login_steps\"))\n\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if (step == 2):\n return \"/auth/duo/duologin.xhtml\"\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def isUserMemberOfGroup(self, user, attribute, group):\n is_member = False\n member_of_list = user.getAttributeValues(attribute)\n if (member_of_list != None):\n for member_of in member_of_list:\n if StringHelper.equalsIgnoreCase(group, member_of) or member_of.endswith(group):\n is_member = True\n break\n\n return is_member\n\n def processAuditGroup(self, user):\n if (self.use_audit_group):\n is_member = self.isUserMemberOfGroup(user, self.audit_attribute, self.audit_group)\n if (is_member):\n print \"Duo. Authenticate for processAuditGroup. User '\" + user.getUserId() + \"' member of audit group\"\n print \"Duo. Authenticate for processAuditGroup. Sending e-mail about user '\" + user.getUserId() + \"' login to\", self.audit_email\n \n # Send e-mail to administrator\n user_id = user.getUserId()\n mailService = CdiUtil.bean(MailService)\n subject = \"User log in: \" + user_id\n body = \"User log in: \" + user_id\n mailService.sendMail(self.audit_email, subject, body)\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "duo", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "/etc/certs/duo_creds.json", + "value1": "duo_creds_file" + }, + { + "hide": false, + "value2": "api-random.duosecurity.com", + "value1": "duo_host" + } + ], + "baseDn": "inum=5018-F9CF,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 50, + "programmingLanguage": "PYTHON", + "description": "Twilio SMS authentication module", + "locationType": "LDAP", + "dn": "inum=09A0-93D6,ou=scripts,o=gluu", + "inum": "09A0-93D6", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2018, Gluu\r\n#\r\n# Author: Jose Gonzalez\r\n# Author: Gasmyr Mougang\r\n\r\nfrom org.gluu.service.cdi.util import CdiUtil\r\nfrom org.gluu.oxauth.security import Identity\r\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\r\nfrom org.gluu.oxauth.service import AuthenticationService\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.oxauth.util import ServerUtil\r\nfrom org.gluu.util import StringHelper, ArrayHelper\r\nfrom java.util import Arrays\r\nfrom javax.faces.application import FacesMessage\r\nfrom org.gluu.jsf2.message import FacesMessages\r\n\r\nimport com.twilio.Twilio as Twilio\r\nimport com.twilio.rest.api.v2010.account.Message as Message\r\nimport com.twilio.type.PhoneNumber as PhoneNumber\r\nimport org.codehaus.jettison.json.JSONArray as JSONArray\r\n\r\n\r\nimport java\r\nimport random\r\nimport jarray\r\n\r\nclass PersonAuthentication(PersonAuthenticationType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n self.mobile_number = None\r\n self.identity = CdiUtil.bean(Identity)\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Twilio SMS. Initialization\"\r\n self.ACCOUNT_SID = None\r\n self.AUTH_TOKEN = None\r\n self.FROM_NUMBER = None\r\n\r\n # Get Custom Properties\r\n try:\r\n self.ACCOUNT_SID = configurationAttributes.get(\"twilio_sid\").getValue2()\r\n except:\r\n print 'TwilioSMS, Missing required configuration attribute \"twilio_sid\"'\r\n\r\n try:\r\n self.AUTH_TOKEN = configurationAttributes.get(\"twilio_token\").getValue2()\r\n except:\r\n print'TwilioSMS, Missing required configuration attribute \"twilio_token\"'\r\n try:\r\n self.FROM_NUMBER = configurationAttributes.get(\"from_number\").getValue2()\r\n except:\r\n print'TwilioSMS, Missing required configuration attribute \"from_number\"'\r\n\r\n if None in (self.ACCOUNT_SID, self.AUTH_TOKEN, self.FROM_NUMBER):\r\n print \"twilio_sid, twilio_token, from_number is empty ... returning False\"\r\n return False\r\n\r\n print \"Twilio SMS. Initialized successfully\"\r\n\r\n return True\r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Twilio SMS. Destroy\"\r\n print \"Twilio SMS. Destroyed successfully\"\r\n return True\r\n\r\n def getApiVersion(self):\r\n return 11\r\n \r\n def getAuthenticationMethodClaims(self, requestParameters):\r\n return None\r\n \r\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\r\n return True\r\n\r\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\r\n return None\r\n\r\n def authenticate(self, configurationAttributes, requestParameters, step):\r\n userService = CdiUtil.bean(UserService)\r\n authenticationService = CdiUtil.bean(AuthenticationService)\r\n\r\n facesMessages = CdiUtil.bean(FacesMessages)\r\n facesMessages.setKeepMessages()\r\n\r\n session_attributes = self.identity.getSessionId().getSessionAttributes()\r\n form_passcode = ServerUtil.getFirstValue(requestParameters, \"passcode\")\r\n form_name = ServerUtil.getFirstValue(requestParameters, \"TwilioSmsloginForm\")\r\n\r\n print \"TwilioSMS. form_response_passcode: %s\" % str(form_passcode)\r\n\r\n if step == 1:\r\n print \"TwilioSMS. Step 1 Password Authentication\"\r\n credentials = self.identity.getCredentials()\r\n\r\n user_name = credentials.getUsername()\r\n user_password = credentials.getPassword()\r\n\r\n logged_in = False\r\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\r\n logged_in = authenticationService.authenticate(user_name, user_password)\r\n\r\n if not logged_in:\r\n return False\r\n\r\n # Get the Person's number and generate a code\r\n foundUser = None\r\n try:\r\n foundUser = authenticationService.getAuthenticatedUser()\r\n except:\r\n print 'TwilioSMS, Error retrieving user %s from LDAP' % (user_name)\r\n return False\r\n\r\n try:\r\n isVerified = foundUser.getAttribute(\"phoneNumberVerified\")\r\n if isVerified:\r\n self.mobile_number = foundUser.getAttribute(\"employeeNumber\")\r\n if self.mobile_number == None:\r\n self.mobile_number = foundUser.getAttribute(\"mobile\")\r\n if self.mobile_number == None:\r\n self.mobile_number = foundUser.getAttribute(\"telephoneNumber\")\r\n if self.mobile_number == None:\r\n print \"TwilioSMS, Error finding mobile number for user '%s'\" % user_name \r\n \r\n except:\r\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to determine mobile phone number\")\r\n print 'TwilioSMS, Error finding mobile number for \"%s\". Exception: %s` % (user_name, sys.exc_info()[1])`'\r\n return False\r\n\r\n # Generate Random six digit code and store it in array\r\n code = random.randint(100000, 999999)\r\n\r\n # Get code and save it in LDAP temporarily with special session entry\r\n self.identity.setWorkingParameter(\"code\", code)\r\n\r\n try:\r\n Twilio.init(self.ACCOUNT_SID, self.AUTH_TOKEN);\r\n message = Message.creator(PhoneNumber(self.mobile_number), PhoneNumber(self.FROM_NUMBER), str(code)).create();\r\n print \"++++++++++++++++++++++++++++++++++++++++++++++\"\r\n print 'TwilioSMs, Message Sid: %s' % (message.getSid())\r\n print 'TwilioSMs, User phone: %s' % (self.mobile_number)\r\n print \"++++++++++++++++++++++++++++++++++++++++++++++\"\r\n self.identity.setWorkingParameter(\"mobile_number\", self.mobile_number)\r\n self.identity.getSessionId().getSessionAttributes().put(\"mobile_number\",self.mobile_number)\r\n self.identity.setWorkingParameter(\"mobile\", self.mobile_number)\r\n self.identity.getSessionId().getSessionAttributes().put(\"mobile\",self.mobile_number)\r\n print \"++++++++++++++++++++++++++++++++++++++++++++++\"\r\n print \"Number: %s\" % (self.identity.getWorkingParameter(\"mobile_number\"))\r\n print \"Mobile: %s\" % (self.identity.getWorkingParameter(\"mobile\"))\r\n print \"++++++++++++++++++++++++++++++++++++++++++++++\"\r\n return True\r\n except Exception, ex:\r\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to send message to mobile phone\")\r\n print \"TwilioSMS. Error sending message to Twilio\"\r\n print \"TwilioSMS. Unexpected error:\", ex\r\n\r\n return False\r\n elif step == 2:\r\n # Retrieve the session attribute\r\n print \"TwilioSMS. Step 2 SMS/OTP Authentication\"\r\n code = session_attributes.get(\"code\")\r\n print \"----------------------------------\"\r\n print \"TwilioSMS. Code: %s\" % str(code)\r\n print \"----------------------------------\"\r\n\r\n if code is None:\r\n print \"TwilioSMS. Failed to find previously sent code\"\r\n return False\r\n\r\n if form_passcode is None:\r\n print \"TwilioSMS. Passcode is empty\"\r\n return False\r\n\r\n if len(form_passcode) != 6:\r\n print \"TwilioSMS. Passcode from response is not 6 digits: %s\" % form_passcode\r\n return False\r\n\r\n if form_passcode == code:\r\n print \"TiwlioSMS, SUCCESS! User entered the same code!\"\r\n return True\r\n\r\n print \"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\" \r\n print \"TwilioSMS. FAIL! User entered the wrong code! %s != %s\" % (form_passcode, code)\r\n print \"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\" \r\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Incorrect Twilio code, please try again.\")\r\n\r\n return False\r\n\r\n print \"TwilioSMS. ERROR: step param not found or != (1|2)\"\r\n\r\n return False\r\n\r\n def prepareForStep(self, configurationAttributes, requestParameters, step):\r\n if step == 1:\r\n print \"TwilioSMS. Prepare for Step 1\"\r\n return True\r\n elif step == 2:\r\n print \"TwilioSMS. Prepare for Step 2\"\r\n return True\r\n return False\r\n\r\n def getExtraParametersForStep(self, configurationAttributes, step):\r\n if step == 2:\r\n return Arrays.asList(\"code\")\r\n\r\n return None\r\n\r\n def getCountAuthenticationSteps(self, configurationAttributes):\r\n return 2\r\n\r\n def getPageForStep(self, configurationAttributes, step):\r\n if step == 2:\r\n return \"/auth/otp_sms/otp_sms.xhtml\"\r\n\r\n return \"\"\r\n \r\n def getNextStep(self, configurationAttributes, requestParameters, step):\r\n return -1\r\n\r\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\r\n print \"Get external logout URL call\"\r\n return None\r\n \r\n def logout(self, configurationAttributes, requestParameters):\r\n return True\r\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "twilio_sms", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value1": "twilio_sid", + "description": "Twilio account SID" + }, + { + "hide": false, + "value1": "twilio_token", + "description": "Twilio API token" + }, + { + "hide": false, + "value1": "from_number", + "description": "Twilio phone number with SMS capabilities" + } + ], + "baseDn": "inum=09A0-93D6,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 50, + "programmingLanguage": "PYTHON", + "description": "Fido U2F authentication module", + "locationType": "LDAP", + "dn": "inum=8BAF-80D6,ou=scripts,o=gluu", + "inum": "8BAF-80D6", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2016, Gluu\r\n#\r\n# Author: Yuriy Movchan\r\n#\r\n\r\nimport java\r\nimport sys\r\nfrom javax.ws.rs.core import Response\r\nfrom org.jboss.resteasy.client import ClientResponseFailure\r\nfrom org.jboss.resteasy.client.exception import ResteasyClientException\r\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\r\nfrom org.gluu.oxauth.client.fido.u2f import FidoU2fClientFactory\r\nfrom org.gluu.oxauth.model.config import Constants\r\nfrom org.gluu.oxauth.security import Identity\r\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.oxauth.service.fido.u2f import DeviceRegistrationService\r\nfrom org.gluu.oxauth.util import ServerUtil\r\nfrom org.gluu.service.cdi.util import CdiUtil\r\nfrom org.gluu.util import StringHelper\r\n\r\n\r\nclass PersonAuthentication(PersonAuthenticationType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"U2F. Initialization\"\r\n\r\n print \"U2F. Initialization. Downloading U2F metadata\"\r\n u2f_server_uri = configurationAttributes.get(\"u2f_server_uri\").getValue2()\r\n u2f_server_metadata_uri = u2f_server_uri + \"/.well-known/fido-u2f-configuration\"\r\n\r\n metaDataConfigurationService = FidoU2fClientFactory.instance().createMetaDataConfigurationService(u2f_server_metadata_uri)\r\n\r\n max_attempts = 20\r\n for attempt in range(1, max_attempts + 1):\r\n try:\r\n self.metaDataConfiguration = metaDataConfigurationService.getMetadataConfiguration()\r\n break\r\n except ClientResponseFailure, ex:\r\n # Detect if last try or we still get Service Unavailable HTTP error\r\n if (attempt == max_attempts) or (ex.getResponse().getResponseStatus() != Response.Status.SERVICE_UNAVAILABLE):\r\n raise ex\r\n\r\n java.lang.Thread.sleep(3000)\r\n print \"Attempting to load metadata: %d\" % attempt\r\n except ResteasyClientException, ex:\r\n # Detect if last try or we still get Service Unavailable HTTP error\r\n if attempt == max_attempts:\r\n raise ex\r\n\r\n java.lang.Thread.sleep(3000)\r\n print \"Attempting to load metadata: %d\" % attempt\r\n \r\n print \"U2F. Initialized successfully\"\r\n return True \r\n\r\n def destroy(self, configurationAttributes):\r\n print \"U2F. Destroy\"\r\n print \"U2F. Destroyed successfully\"\r\n return True\r\n\r\n def getApiVersion(self):\r\n return 11\r\n \r\n def getAuthenticationMethodClaims(self, requestParameters):\r\n return None\r\n \r\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\r\n return True\r\n\r\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\r\n return None\r\n\r\n def authenticate(self, configurationAttributes, requestParameters, step):\r\n authenticationService = CdiUtil.bean(AuthenticationService)\r\n\r\n identity = CdiUtil.bean(Identity)\r\n credentials = identity.getCredentials()\r\n\r\n user_name = credentials.getUsername()\r\n\r\n if (step == 1):\r\n print \"U2F. Authenticate for step 1\"\r\n\r\n user_password = credentials.getPassword()\r\n logged_in = False\r\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\r\n userService = CdiUtil.bean(UserService)\r\n logged_in = authenticationService.authenticate(user_name, user_password)\r\n\r\n if (not logged_in):\r\n return False\r\n\r\n return True\r\n elif (step == 2):\r\n print \"U2F. Authenticate for step 2\"\r\n\r\n token_response = ServerUtil.getFirstValue(requestParameters, \"tokenResponse\")\r\n if token_response == None:\r\n print \"U2F. Authenticate for step 2. tokenResponse is empty\"\r\n return False\r\n\r\n auth_method = ServerUtil.getFirstValue(requestParameters, \"authMethod\")\r\n if auth_method == None:\r\n print \"U2F. Authenticate for step 2. authMethod is empty\"\r\n return False\r\n\r\n authenticationService = CdiUtil.bean(AuthenticationService)\r\n user = authenticationService.getAuthenticatedUser()\r\n if (user == None):\r\n print \"U2F. Prepare for step 2. Failed to determine user name\"\r\n return False\r\n\r\n if (auth_method == 'authenticate'):\r\n print \"U2F. Prepare for step 2. Call FIDO U2F in order to finish authentication workflow\"\r\n authenticationRequestService = FidoU2fClientFactory.instance().createAuthenticationRequestService(self.metaDataConfiguration)\r\n authenticationStatus = authenticationRequestService.finishAuthentication(user.getUserId(), token_response)\r\n\r\n if (authenticationStatus.getStatus() != Constants.RESULT_SUCCESS):\r\n print \"U2F. Authenticate for step 2. Get invalid authentication status from FIDO U2F server\"\r\n return False\r\n\r\n return True\r\n elif (auth_method == 'enroll'):\r\n print \"U2F. Prepare for step 2. Call FIDO U2F in order to finish registration workflow\"\r\n registrationRequestService = FidoU2fClientFactory.instance().createRegistrationRequestService(self.metaDataConfiguration)\r\n registrationStatus = registrationRequestService.finishRegistration(user.getUserId(), token_response)\r\n\r\n if (registrationStatus.getStatus() != Constants.RESULT_SUCCESS):\r\n print \"U2F. Authenticate for step 2. Get invalid registration status from FIDO U2F server\"\r\n return False\r\n\r\n return True\r\n else:\r\n print \"U2F. Prepare for step 2. Authenticatiod method is invalid\"\r\n return False\r\n\r\n return False\r\n else:\r\n return False\r\n\r\n def prepareForStep(self, configurationAttributes, requestParameters, step):\r\n identity = CdiUtil.bean(Identity)\r\n\r\n if (step == 1):\r\n return True\r\n elif (step == 2):\r\n print \"U2F. Prepare for step 2\"\r\n\r\n session = CdiUtil.bean(SessionIdService).getSessionId()\r\n if session == None:\r\n print \"U2F. Prepare for step 2. Failed to determine session_id\"\r\n return False\r\n\r\n authenticationService = CdiUtil.bean(AuthenticationService)\r\n user = authenticationService.getAuthenticatedUser()\r\n if (user == None):\r\n print \"U2F. Prepare for step 2. Failed to determine user name\"\r\n return False\r\n\r\n u2f_application_id = configurationAttributes.get(\"u2f_application_id\").getValue2()\r\n\r\n # Check if user have registered devices\r\n deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)\r\n\r\n userInum = user.getAttribute(\"inum\")\r\n\r\n registrationRequest = None\r\n authenticationRequest = None\r\n\r\n deviceRegistrations = deviceRegistrationService.findUserDeviceRegistrations(userInum, u2f_application_id)\r\n if (deviceRegistrations.size() > 0):\r\n print \"U2F. Prepare for step 2. Call FIDO U2F in order to start authentication workflow\"\r\n\r\n try:\r\n authenticationRequestService = FidoU2fClientFactory.instance().createAuthenticationRequestService(self.metaDataConfiguration)\r\n authenticationRequest = authenticationRequestService.startAuthentication(user.getUserId(), None, u2f_application_id, session.getId())\r\n except ClientResponseFailure, ex:\r\n if (ex.getResponse().getResponseStatus() != Response.Status.NOT_FOUND):\r\n print \"U2F. Prepare for step 2. Failed to start authentication workflow. Exception:\", sys.exc_info()[1]\r\n return False\r\n else:\r\n print \"U2F. Prepare for step 2. Call FIDO U2F in order to start registration workflow\"\r\n registrationRequestService = FidoU2fClientFactory.instance().createRegistrationRequestService(self.metaDataConfiguration)\r\n registrationRequest = registrationRequestService.startRegistration(user.getUserId(), u2f_application_id, session.getId())\r\n\r\n identity.setWorkingParameter(\"fido_u2f_authentication_request\", ServerUtil.asJson(authenticationRequest))\r\n identity.setWorkingParameter(\"fido_u2f_registration_request\", ServerUtil.asJson(registrationRequest))\r\n\r\n return True\r\n elif (step == 3):\r\n print \"U2F. Prepare for step 3\"\r\n\r\n return True\r\n else:\r\n return False\r\n\r\n def getExtraParametersForStep(self, configurationAttributes, step):\r\n return None\r\n\r\n def getCountAuthenticationSteps(self, configurationAttributes):\r\n return 2\r\n\r\n def getPageForStep(self, configurationAttributes, step):\r\n if (step == 2):\r\n return \"/auth/u2f/login.xhtml\"\r\n\r\n return \"\"\r\n\r\n def getNextStep(self, configurationAttributes, requestParameters, step):\r\n return -1\r\n\r\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\r\n print \"Get external logout URL call\"\r\n return None\r\n\r\n def logout(self, configurationAttributes, requestParameters):\r\n return True\r\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "u2f", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "https://pujavs4.2.gluu.server", + "value1": "u2f_application_id" + }, + { + "hide": false, + "value2": "https://pujavs4.2.gluu.server", + "value1": "u2f_server_uri" + } + ], + "baseDn": "inum=8BAF-80D6,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 60, + "programmingLanguage": "PYTHON", + "description": "Passport SAML authentication module", + "locationType": "LDAP", + "dn": "inum=D40C-1CA4,ou=scripts,o=gluu", + "inum": "D40C-1CA4", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2019, Gluu\n#\n# Author: Jose Gonzalez\n# Author: Yuriy Movchan\n# Author: Christian Eland\n#\n\nfrom org.gluu.jsf2.service import FacesService\nfrom org.gluu.jsf2.message import FacesMessages\n\nfrom org.gluu.oxauth.model.common import User, WebKeyStorage\nfrom org.gluu.oxauth.model.configuration import AppConfiguration\nfrom org.gluu.oxauth.model.crypto import CryptoProviderFactory\nfrom org.gluu.oxauth.model.jwt import Jwt, JwtClaimName\nfrom org.gluu.oxauth.model.util import Base64Util\nfrom org.gluu.oxauth.service import AppInitializer, AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService, EncryptionService\nfrom org.gluu.oxauth.model.authorize import AuthorizeRequestParam\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.config.oxtrust import LdapOxPassportConfiguration\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.persist import PersistenceEntryManager\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\nfrom java.util import ArrayList, Arrays, Collections, HashSet\nfrom org.gluu.oxauth.model.exception import InvalidJwtException\nfrom javax.faces.application import FacesMessage\nfrom javax.faces.context import FacesContext\n\nimport json\nimport sys\nimport datetime\nimport base64\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n\n print \"Passport. init called\"\n\n self.extensionModule = self.loadExternalModule(configurationAttributes.get(\"extension_module\"))\n extensionResult = self.extensionInit(configurationAttributes)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. init. Behaviour is inbound SAML\"\n success = self.processKeyStoreProperties(configurationAttributes)\n\n if success:\n self.providerKey = \"provider\"\n self.customAuthzParameter = self.getCustomAuthzParameter(configurationAttributes.get(\"authz_req_param_provider\"))\n self.passportDN = self.getPassportConfigDN()\n print \"Passport. init. Initialization success\"\n else:\n print \"Passport. init. Initialization failed\"\n return success\n\n\n def destroy(self, configurationAttributes):\n print \"Passport. destroy called\"\n return True\n\n\n def getApiVersion(self):\n return 11\n\n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n\n extensionResult = self.extensionAuthenticate(configurationAttributes, requestParameters, step)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. authenticate for step %s called\" % str(step)\n identity = CdiUtil.bean(Identity)\n\n # Loading self.registeredProviders in case passport destroyed\n if not hasattr(self,'registeredProviders'):\n print \"Passport. Fetching registered providers.\"\n self.parseProviderConfigs()\n\n if step == 1:\n\n jwt_param = None\n\n if self.isInboundFlow(identity):\n # if is idp-initiated inbound flow\n print \"Passport. authenticate for step 1. Detected idp-initiated inbound Saml flow\"\n # get request from session attributes\n jwt_param = identity.getSessionId().getSessionAttributes().get(AuthorizeRequestParam.STATE)\n print \"Passport. authenticate. step ==1. if self.isInboundFlow(identity):.\"\n print \"jwt_param = %s\" % jwt_param\n # now jwt_param != None\n\n\n\n if jwt_param == None:\n print \"Entered if jwt_param == None\"\n # gets jwt parameter \"user\" sent after authentication by passport (if exists)\n jwt_param = ServerUtil.getFirstValue(requestParameters, \"user\")\n\n\n if jwt_param != None:\n # and now that the jwt_param user exists...\n print \"Entered if jwt_param != None\"\n print \"Passport. authenticate for step 1. JWT user profile token found\"\n\n if self.isInboundFlow(identity):\n jwt_param = base64.urlsafe_b64decode(str(jwt_param+'=='))\n\n # Parse JWT and validate\n jwt = Jwt.parse(jwt_param)\n\n if not self.validSignature(jwt):\n return False\n\n if self.jwtHasExpired(jwt):\n return False\n\n # Gets user profile as string and json using the information on JWT\n (user_profile, jsonp) = self.getUserProfile(jwt)\n\n if user_profile == None:\n return False\n\n sessionAttributes = identity.getSessionId().getSessionAttributes()\n self.skipProfileUpdate = StringHelper.equalsIgnoreCase(sessionAttributes.get(\"skipPassportProfileUpdate\"), \"true\")\n\n return self.attemptAuthentication(identity, user_profile, jsonp)\n\n #See passportlogin.xhtml\n print \"-------------============------------\"\n provider = ServerUtil.getFirstValue(requestParameters, \"loginForm:provider\")\n print \"authenticate() - provider = %s\" % str(provider)\n\n\n print \"authenticate - self.registeredProviders: %s\" % str(self.registeredProviders)\n if StringHelper.isEmpty(provider):\n\n #it's username + passw auth\n print \"Passport. authenticate for step 1. Basic authentication detected\"\n logged_in = False\n\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n authenticationService = CdiUtil.bean(AuthenticationService)\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n print \"Passport. authenticate for step 1. Basic authentication returned: %s\" % logged_in\n return logged_in\n\n\n\n elif provider in self.registeredProviders:\n # user selected provider\n # it's a recognized external IDP\n\n identity.setWorkingParameter(\"selectedProvider\", provider)\n print \"Passport. authenticate for step 1. Retrying step 1\"\n\n #see prepareForStep (step = 1)\n return True\n\n if step == 2:\n mail = ServerUtil.getFirstValue(requestParameters, \"loginForm:email\")\n jsonp = identity.getWorkingParameter(\"passport_user_profile\")\n\n if mail == None:\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email was missing in user profile\")\n elif jsonp != None:\n # Completion of profile takes place\n user_profile = json.loads(jsonp)\n user_profile[\"mail\"] = [ mail ]\n\n return self.attemptAuthentication(identity, user_profile, jsonp)\n\n print \"Passport. authenticate for step 2. Failed: expected mail value in HTTP request and json profile in session\"\n return False\n\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n\n extensionResult = self.extensionPrepareForStep(configurationAttributes, requestParameters, step)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. prepareForStep called %s\" % str(step)\n identity = CdiUtil.bean(Identity)\n\n if step == 1:\n #re-read the strategies config (for instance to know which strategies have enabled the email account linking)\n self.parseProviderConfigs()\n identity.setWorkingParameter(\"externalProviders\", json.dumps(self.registeredProviders))\n\n providerParam = self.customAuthzParameter\n url = None\n\n sessionAttributes = identity.getSessionId().getSessionAttributes()\n self.skipProfileUpdate = StringHelper.equalsIgnoreCase(sessionAttributes.get(\"skipPassportProfileUpdate\"), \"true\")\n\n #this param could have been set previously in authenticate step if current step is being retried\n provider = identity.getWorkingParameter(\"selectedProvider\")\n print \"prepareForStep %s - provider = %s\" % (str(step), str(provider))\n\n # if there is a selectedProvider\n if provider != None:\n\n # get the redirect URL to use at facesService.redirectToExternalURL() that sends /passport/auth//\n url = self.getPassportRedirectUrl(provider)\n print \"prepareForStep %s - url = %s\" % (str(step), url)\n\n # sets selectedProvider back to None\n identity.setWorkingParameter(\"selectedProvider\", None)\n\n # if there is customAuthzParameter\n elif providerParam != None:\n\n\n # get it from sessionAtributes\n paramValue = sessionAttributes.get(providerParam)\n\n #if exists\n if paramValue != None:\n print \"Passport. prepareForStep. Found value in custom param of authorization request: %s\" % paramValue\n provider = self.getProviderFromJson(paramValue)\n\n if provider == None:\n print \"Passport. prepareForStep. A provider value could not be extracted from custom authorization request parameter\"\n elif not provider in self.registeredProviders:\n print \"Passport. prepareForStep. Provider '%s' not part of known configured IDPs/OPs\" % provider\n else:\n url = self.getPassportRedirectUrl(provider)\n\n\n # if no provider selected yet...\n if url == None:\n print \"Passport. prepareForStep. A page to manually select an identity provider will be shown\"\n\n # else already got the /passport/auth// url...\n else:\n\n facesService = CdiUtil.bean(FacesService)\n\n # redirects to Passport getRedirectURL - sends browser to IDP.\n print \"Passport. Redirecting to external url: %s\" + url\n\n facesService.redirectToExternalURL(url)\n\n return True\n\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n print \"Passport. getExtraParametersForStep called for step %s\" % str(step)\n if step == 1:\n return Arrays.asList(\"selectedProvider\", \"externalProviders\")\n elif step == 2:\n return Arrays.asList(\"passport_user_profile\")\n return None\n\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n print \"Passport. getCountAuthenticationSteps called\"\n identity = CdiUtil.bean(Identity)\n if identity.getWorkingParameter(\"passport_user_profile\") != None:\n return 2\n return 1\n\n\n def getPageForStep(self, configurationAttributes, step):\n print \"Passport. getPageForStep called\"\n\n extensionResult = self.extensionGetPageForStep(configurationAttributes, step)\n if extensionResult != None:\n return extensionResult\n\n if step == 1:\n identity = CdiUtil.bean(Identity)\n print \"Passport. getPageForStep. Entered if step ==1\"\n if self.isInboundFlow(identity):\n print \"Passport. getPageForStep for step 1. Detected inbound Saml flow\"\n return \"/postlogin.xhtml\"\n print \"Passport. getPageForStep 1. NormalFlow, returning passportlogin.xhtml\"\n return \"/auth/passport/passportlogin.xhtml\"\n\n return \"/auth/passport/passportpostlogin.xhtml\"\n\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n if step == 1:\n identity = CdiUtil.bean(Identity)\n provider = identity.getWorkingParameter(\"selectedProvider\")\n if provider != None:\n return 1\n\n return -1\n\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n# Extension module related functions\n\n def extensionInit(self, configurationAttributes):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.init(configurationAttributes)\n\n\n def extensionAuthenticate(self, configurationAttributes, requestParameters, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.authenticate(configurationAttributes, requestParameters, step)\n\n\n def extensionPrepareForStep(self, configurationAttributes, requestParameters, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.prepareForStep(configurationAttributes, requestParameters, step)\n\n\n def extensionGetPageForStep(self, configurationAttributes, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.getPageForStep(configurationAttributes, step)\n\n# Initalization routines\n\n def loadExternalModule(self, simpleCustProperty):\n\n if simpleCustProperty != None:\n print \"Passport. loadExternalModule. Loading passport extension module...\"\n moduleName = simpleCustProperty.getValue2()\n try:\n module = __import__(moduleName)\n return module\n except:\n print \"Passport. loadExternalModule. Failed to load module %s\" % moduleName\n print \"Exception: \", sys.exc_info()[1]\n print \"Passport. loadExternalModule. Flow will be driven entirely by routines of main passport script\"\n return None\n\n\n def processKeyStoreProperties(self, attrs):\n file = attrs.get(\"key_store_file\")\n password = attrs.get(\"key_store_password\")\n\n if file != None and password != None:\n file = file.getValue2()\n password = password.getValue2()\n\n if StringHelper.isNotEmpty(file) and StringHelper.isNotEmpty(password):\n self.keyStoreFile = file\n self.keyStorePassword = password\n return True\n\n print \"Passport. readKeyStoreProperties. Properties key_store_file or key_store_password not found or empty\"\n return False\n\n\n def getCustomAuthzParameter(self, simpleCustProperty):\n\n customAuthzParameter = None\n if simpleCustProperty != None:\n prop = simpleCustProperty.getValue2()\n if StringHelper.isNotEmpty(prop):\n customAuthzParameter = prop\n\n if customAuthzParameter == None:\n print \"Passport. getCustomAuthzParameter. No custom param for OIDC authz request in script properties\"\n print \"Passport. getCustomAuthzParameter. Passport flow cannot be initiated by doing an OpenID connect authorization request\"\n else:\n print \"Passport. getCustomAuthzParameter. Custom param for OIDC authz request in script properties: %s\" % customAuthzParameter\n\n return customAuthzParameter\n\n# Configuration parsing\n\n def getPassportConfigDN(self):\n\n f = open('/etc/gluu/conf/gluu.properties', 'r')\n for line in f:\n prop = line.split(\"=\")\n if prop[0] == \"oxpassport_ConfigurationEntryDN\":\n prop.pop(0)\n break\n\n f.close()\n return \"=\".join(prop).strip()\n\n\n def parseAllProviders(self):\n\n registeredProviders = {}\n print \"Passport. parseAllProviders. Adding providers\"\n entryManager = CdiUtil.bean(PersistenceEntryManager)\n\n config = LdapOxPassportConfiguration()\n config = entryManager.find(config.getClass(), self.passportDN).getPassportConfiguration()\n config = config.getProviders() if config != None else config\n\n if config != None and len(config) > 0:\n for prvdetails in config:\n if prvdetails.isEnabled():\n registeredProviders[prvdetails.getId()] = {\n \"emailLinkingSafe\": prvdetails.isEmailLinkingSafe(),\n \"requestForEmail\" : prvdetails.isRequestForEmail(),\n \"logo_img\": prvdetails.getLogoImg(),\n \"displayName\": prvdetails.getDisplayName(),\n \"type\": prvdetails.getType()\n }\n\n return registeredProviders\n\n\n def parseProviderConfigs(self):\n\n registeredProviders = {}\n try:\n registeredProviders = self.parseAllProviders()\n toRemove = []\n\n for provider in registeredProviders:\n if registeredProviders[provider][\"type\"] != \"saml\":\n toRemove.append(provider)\n else:\n registeredProviders[provider][\"saml\"] = True\n\n for provider in toRemove:\n registeredProviders.pop(provider)\n\n\n if len(registeredProviders.keys()) > 0:\n print \"Passport. parseProviderConfigs. Configured providers:\", registeredProviders\n else:\n print \"Passport. parseProviderConfigs. No providers registered yet\"\n except:\n print \"Passport. parseProviderConfigs. An error occurred while building the list of supported authentication providers\", sys.exc_info()[1]\n\n\n print \"parseProviderConfigs - registeredProviders = %s\" % str(registeredProviders)\n self.registeredProviders = registeredProviders\n print \"parseProviderConfigs - self.registeredProviders = %s\" % str(self.registeredProviders)\n\n# Auxiliary routines\n\n def getProviderFromJson(self, providerJson):\n\n provider = None\n try:\n obj = json.loads(Base64Util.base64urldecodeToString(providerJson))\n provider = obj[self.providerKey]\n except:\n print \"Passport. getProviderFromJson. Could not parse provided Json string. Returning None\"\n\n return provider\n\n\n def getPassportRedirectUrl(self, provider):\n\n # provider is assumed to exist in self.registeredProviders\n url = None\n try:\n facesContext = CdiUtil.bean(FacesContext)\n tokenEndpoint = \"https://%s/passport/token\" % facesContext.getExternalContext().getRequest().getServerName()\n\n httpService = CdiUtil.bean(HttpService)\n httpclient = httpService.getHttpsClient()\n\n print \"Passport. getPassportRedirectUrl. Obtaining token from passport at %s\" % tokenEndpoint\n resultResponse = httpService.executeGet(httpclient, tokenEndpoint, Collections.singletonMap(\"Accept\", \"text/json\"))\n httpResponse = resultResponse.getHttpResponse()\n\n bytes = httpService.getResponseContent(httpResponse)\n\n response = httpService.convertEntityToString(bytes)\n print \"Passport. getPassportRedirectUrl. Response was %s\" % httpResponse.getStatusLine().getStatusCode()\n\n tokenObj = json.loads(response)\n\n url = \"/passport/auth/%s/%s\" % (provider, tokenObj[\"token_\"])\n\n except:\n print \"Passport. getPassportRedirectUrl. Error building redirect URL: \", sys.exc_info()[1]\n\n return url\n\n\n def validSignature(self, jwt):\n\n print \"Passport. validSignature. Checking JWT token signature\"\n valid = False\n\n try:\n\n appConfiguration = AppConfiguration()\n appConfiguration.setWebKeysStorage(WebKeyStorage.KEYSTORE)\n appConfiguration.setKeyStoreFile(self.keyStoreFile)\n appConfiguration.setKeyStoreSecret(self.keyStorePassword)\n appConfiguration.setKeyRegenerationEnabled(False)\n\n cryptoProvider = CryptoProviderFactory.getCryptoProvider(appConfiguration)\n\n\n alg_string = str(jwt.getHeader().getSignatureAlgorithm())\n signature_string = str(jwt.getEncodedSignature())\n\n if alg_string == \"none\" or alg_string == \"None\" or alg_string == \"NoNe\" or alg_string == \"nONE\" or alg_string == \"NONE\" or alg_string == \"NonE\" or alg_string == \"nOnE\":\n # blocks none attack\n\n print \"WARNING: JWT Signature algorithm is none\"\n valid = False\n\n elif alg_string != \"RS512\":\n # blocks anything that's not RS512\n\n print \"WARNING: JWT Signature algorithm is NOT RS512\"\n valid = False\n\n elif signature_string == \"\" :\n # blocks empty signature string\n print \"WARNING: JWT Signature not sent\"\n valid = False\n\n else:\n\n # class extends AbstractCryptoProvider\n ''' on version 4.2 .getAlgorithm() method was renamed to .getSignatureAlgorithm()\n for older versions:\n valid = cryptoProvider.verifySignature(jwt.getSigningInput(), jwt.getEncodedSignature(), jwt.getHeader().getKeyId(),\n None, None, jwt.getHeader().getAlgorithm())\n '''\n\n # working on 4.2:\n valid = cryptoProvider.verifySignature(jwt.getSigningInput(), jwt.getEncodedSignature(), jwt.getHeader().getKeyId(),\n None, None, jwt.getHeader().getSignatureAlgorithm())\n\n except:\n print \"Exception: \", sys.exc_info()[1]\n\n print \"Passport. validSignature. Validation result was %s\" % valid\n\n return valid\n\n\n def jwtHasExpired(self, jwt):\n # Check if jwt has expired\n jwt_claims = jwt.getClaims()\n try:\n exp_date = jwt_claims.getClaimAsDate(JwtClaimName.EXPIRATION_TIME)\n hasExpired = exp_date < datetime.datetime.now()\n except:\n print \"Exception: The JWT does not have '%s' attribute\" % JwtClaimName.EXPIRATION_TIME\n return False\n\n return hasExpired\n\n\n def getUserProfile(self, jwt):\n\n # getClaims method located at org.gluu.oxauth.model.token.JsonWebResponse.java as a org.gluu.oxauth.model.jwt.JwtClaims object\n jwt_claims = jwt.getClaims()\n\n user_profile_json = None\n\n try:\n # public String getClaimAsString(String key)\n user_profile_json = CdiUtil.bean(EncryptionService).decrypt(jwt_claims.getClaimAsString(\"data\"))\n\n user_profile = json.loads(user_profile_json)\n except:\n print \"Passport. getUserProfile. Problem obtaining user profile json representation\"\n\n return (user_profile, user_profile_json)\n\n\n def attemptAuthentication(self, identity, user_profile, user_profile_json):\n\n print \"Entered attemptAuthentication...\"\n uidKey = \"uid\"\n if not self.checkRequiredAttributes(user_profile, [uidKey, self.providerKey]):\n return False\n\n provider = user_profile[self.providerKey]\n print \"user_profile[self.providerKey] = %s\" % str(user_profile[self.providerKey])\n if not provider in self.registeredProviders:\n print \"Entered if note provider in self.registeredProviers:\"\n print \"Passport. attemptAuthentication. Identity Provider %s not recognized\" % provider\n return False\n\n print \"attemptAuthentication. user_profile = %s\" % user_profile\n print \"user_profile[uidKey] = %s\" % user_profile[uidKey]\n uid = user_profile[uidKey][0]\n print \"attemptAuthentication - uid = %s\" % uid\n externalUid = \"passport-%s:%s:%s\" % (\"saml\", provider, uid)\n\n userService = CdiUtil.bean(UserService)\n userByUid = self.getUserByExternalUid(uid, provider, userService)\n\n email = None\n if \"mail\" in user_profile:\n email = user_profile[\"mail\"]\n if len(email) == 0:\n email = None\n else:\n email = email[0]\n user_profile[\"mail\"] = [ email ]\n\n if email == None and self.registeredProviders[provider][\"requestForEmail\"]:\n print \"Passport. attemptAuthentication. Email was not received\"\n\n if userByUid != None:\n # This avoids asking for the email over every login attempt\n email = userByUid.getAttribute(\"mail\")\n if email != None:\n print \"Passport. attemptAuthentication. Filling missing email value with %s\" % email\n user_profile[\"mail\"] = [ email ]\n\n if email == None:\n # Store user profile in session and abort this routine\n identity.setWorkingParameter(\"passport_user_profile\", user_profile_json)\n return True\n\n userByMail = None if email == None else userService.getUserByAttribute(\"mail\", email)\n\n # Determine if we should add entry, update existing, or deny access\n doUpdate = False\n doAdd = False\n if userByUid != None:\n print \"User with externalUid '%s' already exists\" % externalUid\n if userByMail == None:\n doUpdate = True\n else:\n if userByMail.getUserId() == userByUid.getUserId():\n doUpdate = True\n else:\n print \"Users with externalUid '%s' and mail '%s' are different. Access will be denied. Impersonation attempt?\" % (externalUid, email)\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email value corresponds to an already existing provisioned account\")\n else:\n if userByMail == None:\n doAdd = True\n elif self.registeredProviders[provider][\"emailLinkingSafe\"]:\n\n tmpList = userByMail.getAttributeValues(\"oxExternalUid\")\n tmpList = ArrayList() if tmpList == None else ArrayList(tmpList)\n tmpList.add(externalUid)\n userByMail.setAttribute(\"oxExternalUid\", tmpList)\n\n userByUid = userByMail\n print \"External user supplying mail %s will be linked to existing account '%s'\" % (email, userByMail.getUserId())\n doUpdate = True\n else:\n print \"An attempt to supply an email of an existing user was made. Turn on 'emailLinkingSafe' if you want to enable linking\"\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email value corresponds to an already existing account. If you already have a username and password use those instead of an external authentication site to get access.\")\n\n username = None\n try:\n if doUpdate:\n username = userByUid.getUserId()\n print \"Passport. attemptAuthentication. Updating user %s\" % username\n self.updateUser(userByUid, user_profile, userService)\n elif doAdd:\n print \"Passport. attemptAuthentication. Creating user %s\" % externalUid\n newUser = self.addUser(externalUid, user_profile, userService)\n username = newUser.getUserId()\n except:\n print \"Exception: \", sys.exc_info()[1]\n print \"Passport. attemptAuthentication. Authentication failed\"\n return False\n\n if username == None:\n print \"Passport. attemptAuthentication. Authentication attempt was rejected\"\n return False\n else:\n logged_in = CdiUtil.bean(AuthenticationService).authenticate(username)\n print \"Passport. attemptAuthentication. Authentication for %s returned %s\" % (username, logged_in)\n return logged_in\n\n\n def getUserByExternalUid(self, uid, provider, userService):\n newFormat = \"passport-%s:%s:%s\" % (\"saml\", provider, uid)\n user = userService.getUserByAttribute(\"oxExternalUid\", newFormat)\n\n if user == None:\n oldFormat = \"passport-%s:%s\" % (\"saml\", uid)\n user = userService.getUserByAttribute(\"oxExternalUid\", oldFormat)\n\n if user != None:\n # Migrate to newer format\n list = HashSet(user.getAttributeValues(\"oxExternalUid\"))\n list.remove(oldFormat)\n list.add(newFormat)\n user.setAttribute(\"oxExternalUid\", ArrayList(list))\n print \"Migrating user's oxExternalUid to newer format 'passport-saml:provider:uid'\"\n userService.updateUser(user)\n\n return user\n\n\n def setMessageError(self, severity, msg):\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n facesMessages.clear()\n facesMessages.add(severity, msg)\n\n\n def checkRequiredAttributes(self, profile, attrs):\n\n for attr in attrs:\n if (not attr in profile) or len(profile[attr]) == 0:\n print \"Passport. checkRequiredAttributes. Attribute '%s' is missing in profile\" % attr\n return False\n return True\n\n\n def addUser(self, externalUid, profile, userService):\n print \"Passport. Entered addUser().\"\n print \"Passport. addUser. externalUid = %s\" % externalUid\n print \"Passport. addUser. profile = %s\" % profile\n newUser = User()\n #Fill user attrs\n newUser.setAttribute(\"oxExternalUid\", externalUid)\n self.fillUser(newUser, profile)\n newUser = userService.addUser(newUser, True)\n return newUser\n\n\n def updateUser(self, foundUser, profile, userService):\n # when this is false, there might still some updates taking place (e.g. not related to profile attrs released by external provider)\n if (not self.skipProfileUpdate):\n self.fillUser(foundUser, profile)\n userService.updateUser(foundUser)\n\n\n def fillUser(self, foundUser, profile):\n print\n print \"Passport. Entered fillUser().\"\n print \"Passport. fillUser. foundUser = %s\" % foundUser\n print \"Passport. fillUser. profile = %s\" % profile\n for attr in profile:\n # \"provider\" is disregarded if part of mapping\n if attr != self.providerKey:\n values = profile[attr]\n print \"%s = %s\" % (attr, values)\n foundUser.setAttribute(attr, values)\n\n if attr == \"mail\":\n print \"Passport. fillUser. entered if attr == mail\"\n oxtrustMails = []\n for mail in values:\n oxtrustMails.append('{\"value\":\"%s\",\"primary\":false}' % mail)\n foundUser.setAttribute(\"oxTrustEmail\", oxtrustMails)\n\n# IDP-initiated flow routines\n\n def isInboundFlow(self, identity):\n print \"passport. entered isInboundFlow\"\n\n sessionId = identity.getSessionId()\n print \"passport. isInboundFlow. sessionId = %s\" % sessionId\n if sessionId == None:\n print \"passport. isInboundFlow. sessionId not found yet...\"\n # Detect mode if there is no session yet. It's needed for getPageForStep method\n facesContext = CdiUtil.bean(FacesContext)\n requestParameters = facesContext.getExternalContext().getRequestParameterMap()\n print \"passport. isInboundFlow. requestParameters = %s\" % requestParameters\n\n authz_state = requestParameters.get(AuthorizeRequestParam.STATE)\n print \"passport. isInboundFlow. authz_state = %s\" % authz_state\n else:\n authz_state = identity.getSessionId().getSessionAttributes().get(AuthorizeRequestParam.STATE)\n\n print \"passport. IsInboundFlow. authz_state = %s\" % authz_state\n\n # the replace above is workaround due a problem reported\n # on issue: https://github.com/GluuFederation/gluu-passport/issues/95\n # TODO: Remove after fixed on JSF side\n\n b64url_decoded_auth_state = base64.urlsafe_b64decode(str(authz_state+'=='))\n\n # print \"passport. IsInboundFlow. b64url_decoded_auth_state = %s\" % str(b64url_decoded_auth_state)\n print \"passport. IsInboundFlow. self.isInboundJwt() = %s\" % str(self.isInboundJwt(b64url_decoded_auth_state))\n if self.isInboundJwt(b64url_decoded_auth_state):\n return True\n\n return False\n\n\n def isInboundJwt(self, value):\n if value == None:\n return False\n\n try:\n\n print(\"passport.isInboundJwt. value = %s\" % value)\n # value = value.replace(\"_\", \".\")\n # print(\"passport.isInboundJwt. value = %s\" % value)\n\n jwt = Jwt.parse(value)\n print \"passport.isInboundJwt. jwt = %s\" % jwt\n\n # user_profile_json = jwt.getClaims().getClaimAsString(\"data\")\n\n user_profile_json = CdiUtil.bean(EncryptionService).decrypt(jwt.getClaims().getClaimAsString(\"data\"))\n print \"passport.isInboundJwt. user_profile_json = %s\" % user_profile_json\n if StringHelper.isEmpty(user_profile_json):\n return False\n except InvalidJwtException:\n return False\n\n except:\n print(\"Unexpected error:\", sys.exc_info()[0])\n return False\n\n return True\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "passport_saml", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "/etc/certs/passport-rp.jks", + "value1": "key_store_file" + }, + { + "hide": false, + "value2": "secret", + "value1": "key_store_password" + } + ], + "baseDn": "inum=D40C-1CA4,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 60, + "programmingLanguage": "PYTHON", + "description": "Super Gluu authentication module", + "locationType": "LDAP", + "dn": "inum=92F0-BF9E,ou=scripts,o=gluu", + "inum": "92F0-BF9E", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom com.google.android.gcm.server import Sender, Message\nfrom com.notnoop.apns import APNS\nfrom java.util import Arrays\nfrom org.apache.http.params import CoreConnectionPNames\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.model.config import ConfigurationFactory\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.fido.u2f import DeviceRegistrationService\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.util import StringHelper\nfrom org.gluu.oxauth.service.common import EncryptionService, UserService\nfrom org.gluu.service import MailService\nfrom org.gluu.oxauth.service.push.sns import PushPlatform, PushSnsService \nfrom org.gluu.oxnotify.client import NotifyClientFactory \nfrom java.util import Arrays, HashMap, IdentityHashMap, Date\nfrom java.time import ZonedDateTime\nfrom java.time.format import DateTimeFormatter\n\ntry:\n from org.gluu.oxd.license.client.js import Product\n from org.gluu.oxd.license.validator import LicenseValidator\n has_license_api = True\nexcept ImportError:\n print \"Super-Gluu. Load. Failed to load licensing API\"\n has_license_api = False\n\nimport datetime\nimport urllib\n\nimport sys\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Super-Gluu. Initialization\"\n\n if not configurationAttributes.containsKey(\"authentication_mode\"):\n print \"Super-Gluu. Initialization. Property authentication_mode is mandatory\"\n return False\n\n self.applicationId = None\n if configurationAttributes.containsKey(\"application_id\"):\n self.applicationId = configurationAttributes.get(\"application_id\").getValue2()\n\n self.registrationUri = None\n if configurationAttributes.containsKey(\"registration_uri\"):\n self.registrationUri = configurationAttributes.get(\"registration_uri\").getValue2()\n\n authentication_mode = configurationAttributes.get(\"authentication_mode\").getValue2()\n if StringHelper.isEmpty(authentication_mode):\n print \"Super-Gluu. Initialization. Failed to determine authentication_mode. authentication_mode configuration parameter is empty\"\n return False\n \n self.oneStep = StringHelper.equalsIgnoreCase(authentication_mode, \"one_step\")\n self.twoStep = StringHelper.equalsIgnoreCase(authentication_mode, \"two_step\")\n\n if not (self.oneStep or self.twoStep):\n print \"Super-Gluu. Initialization. Valid authentication_mode values are one_step and two_step\"\n return False\n \n self.enabledPushNotifications = self.initPushNotificationService(configurationAttributes)\n\n self.androidUrl = None\n if configurationAttributes.containsKey(\"supergluu_android_download_url\"):\n self.androidUrl = configurationAttributes.get(\"supergluu_android_download_url\").getValue2()\n\n self.IOSUrl = None\n if configurationAttributes.containsKey(\"supergluu_ios_download_url\"):\n self.IOSUrl = configurationAttributes.get(\"supergluu_ios_download_url\").getValue2()\n\n self.customLabel = None\n if configurationAttributes.containsKey(\"label\"):\n self.customLabel = configurationAttributes.get(\"label\").getValue2()\n\n self.customQrOptions = {}\n if configurationAttributes.containsKey(\"qr_options\"):\n self.customQrOptions = configurationAttributes.get(\"qr_options\").getValue2()\n\n self.use_super_gluu_group = False\n if configurationAttributes.containsKey(\"super_gluu_group\"):\n self.super_gluu_group = configurationAttributes.get(\"super_gluu_group\").getValue2()\n self.use_super_gluu_group = True\n print \"Super-Gluu. Initialization. Using super_gluu only if user belong to group: %s\" % self.super_gluu_group\n\n self.use_audit_group = False\n if configurationAttributes.containsKey(\"audit_group\"):\n self.audit_group = configurationAttributes.get(\"audit_group\").getValue2()\n\n if (not configurationAttributes.containsKey(\"audit_group_email\")):\n print \"Super-Gluu. Initialization. Property audit_group_email is not specified\"\n return False\n\n self.audit_email = configurationAttributes.get(\"audit_group_email\").getValue2()\n self.use_audit_group = True\n\n print \"Super-Gluu. Initialization. Using audit group: %s\" % self.audit_group\n \n if self.use_super_gluu_group or self.use_audit_group:\n if not configurationAttributes.containsKey(\"audit_attribute\"):\n print \"Super-Gluu. Initialization. Property audit_attribute is not specified\"\n return False\n else:\n self.audit_attribute = configurationAttributes.get(\"audit_attribute\").getValue2()\n\n self.valid_license = False\n # Removing or altering this block validation is against the terms of the license. \n if has_license_api and configurationAttributes.containsKey(\"license_file\"):\n license_file = configurationAttributes.get(\"license_file\").getValue2()\n\n # Load license from file\n f = open(license_file, 'r')\n try:\n license = json.loads(f.read())\n except:\n print \"Super-Gluu. Initialization. Failed to load license from file: %s\" % license_file\n return False\n finally:\n f.close()\n \n # Validate license\n try:\n self.license_content = LicenseValidator.validate(license[\"public_key\"], license[\"public_password\"], license[\"license_password\"], license[\"license\"],\n Product.SUPER_GLUU, Date())\n self.valid_license = self.license_content.isValid()\n except:\n print \"Super-Gluu. Initialization. Failed to validate license. Exception: \", sys.exc_info()[1]\n return False\n\n print \"Super-Gluu. Initialization. License status: '%s'. License metadata: '%s'\" % (self.valid_license, self.license_content.getMetadata())\n\n print \"Super-Gluu. Initialized successfully. oneStep: '%s', twoStep: '%s', pushNotifications: '%s', customLabel: '%s'\" % (self.oneStep, self.twoStep, self.enabledPushNotifications, self.customLabel)\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Super-Gluu. Destroy\"\n\n self.pushAndroidService = None\n self.pushAppleService = None\n\n print \"Super-Gluu. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n client_redirect_uri = self.getApplicationUri(session_attributes)\n if client_redirect_uri == None:\n print \"Super-Gluu. Authenticate. redirect_uri is not set\"\n return False\n\n self.setRequestScopedParameters(identity, step)\n\n # Validate form result code and initialize QR code regeneration if needed (retry_current_step = True)\n identity.setWorkingParameter(\"retry_current_step\", False)\n form_auth_result = ServerUtil.getFirstValue(requestParameters, \"auth_result\")\n if StringHelper.isNotEmpty(form_auth_result):\n print \"Super-Gluu. Authenticate for step %s. Get auth_result: '%s'\" % (step, form_auth_result)\n if form_auth_result in ['error']:\n return False\n\n if form_auth_result in ['timeout']:\n if ((step == 1) and self.oneStep) or ((step == 2) and self.twoStep): \n print \"Super-Gluu. Authenticate for step %s. Reinitializing current step\" % step\n identity.setWorkingParameter(\"retry_current_step\", True)\n return False\n\n userService = CdiUtil.bean(UserService)\n deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)\n if step == 1:\n print \"Super-Gluu. Authenticate for step 1\"\n\n user_name = credentials.getUsername()\n if self.oneStep:\n session_device_status = self.getSessionDeviceStatus(session_attributes, user_name)\n if session_device_status == None:\n return False\n\n u2f_device_id = session_device_status['device_id']\n\n validation_result = self.validateSessionDeviceStatus(client_redirect_uri, session_device_status)\n if validation_result:\n print \"Super-Gluu. Authenticate for step 1. User successfully authenticated with u2f_device '%s'\" % u2f_device_id\n else:\n return False\n \n if not session_device_status['one_step']:\n print \"Super-Gluu. Authenticate for step 1. u2f_device '%s' is not one step device\" % u2f_device_id\n return False\n \n # There are two steps only in enrollment mode\n if session_device_status['enroll']:\n return validation_result\n\n identity.setWorkingParameter(\"super_gluu_count_login_steps\", 1)\n\n user_inum = session_device_status['user_inum']\n\n u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id, \"oxId\")\n if u2f_device == None:\n print \"Super-Gluu. Authenticate for step 1. Failed to load u2f_device '%s'\" % u2f_device_id\n return False\n\n logged_in = authenticationService.authenticate(user_name)\n if not logged_in:\n print \"Super-Gluu. Authenticate for step 1. Failed to authenticate user '%s'\" % user_name\n return False\n\n print \"Super-Gluu. Authenticate for step 1. User '%s' successfully authenticated with u2f_device '%s'\" % (user_name, u2f_device_id)\n \n return True\n elif self.twoStep:\n authenticated_user = self.processBasicAuthentication(credentials)\n if authenticated_user == None:\n return False\n\n if (self.use_super_gluu_group):\n print \"Super-Gluu. Authenticate for step 1. Checking if user belong to super_gluu group\"\n is_member_super_gluu_group = self.isUserMemberOfGroup(authenticated_user, self.audit_attribute, self.super_gluu_group)\n if (is_member_super_gluu_group):\n print \"Super-Gluu. Authenticate for step 1. User '%s' member of super_gluu group\" % authenticated_user.getUserId()\n super_gluu_count_login_steps = 2\n else:\n if self.use_audit_group:\n self.processAuditGroup(authenticated_user, self.audit_attribute, self.audit_group)\n super_gluu_count_login_steps = 1\n \n identity.setWorkingParameter(\"super_gluu_count_login_steps\", super_gluu_count_login_steps)\n \n if super_gluu_count_login_steps == 1:\n return True\n \n auth_method = 'authenticate'\n enrollment_mode = ServerUtil.getFirstValue(requestParameters, \"loginForm:registerButton\")\n if StringHelper.isNotEmpty(enrollment_mode):\n auth_method = 'enroll'\n \n if auth_method == 'authenticate':\n user_inum = userService.getUserInum(authenticated_user)\n u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, \"oxId\")\n if u2f_devices_list.size() == 0:\n auth_method = 'enroll'\n print \"Super-Gluu. Authenticate for step 1. There is no U2F '%s' user devices associated with application '%s'. Changing auth_method to '%s'\" % (user_name, client_redirect_uri, auth_method)\n \n print \"Super-Gluu. Authenticate for step 1. auth_method: '%s'\" % auth_method\n \n identity.setWorkingParameter(\"super_gluu_auth_method\", auth_method)\n\n return True\n\n return False\n elif step == 2:\n print \"Super-Gluu. Authenticate for step 2\"\n\n user = authenticationService.getAuthenticatedUser()\n if (user == None):\n print \"Super-Gluu. Authenticate for step 2. Failed to determine user name\"\n return False\n user_name = user.getUserId()\n\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n session_device_status = self.getSessionDeviceStatus(session_attributes, user_name)\n if session_device_status == None:\n return False\n\n u2f_device_id = session_device_status['device_id']\n\n # There are two steps only in enrollment mode\n if self.oneStep and session_device_status['enroll']:\n authenticated_user = self.processBasicAuthentication(credentials)\n if authenticated_user == None:\n return False\n\n user_inum = userService.getUserInum(authenticated_user)\n \n attach_result = deviceRegistrationService.attachUserDeviceRegistration(user_inum, u2f_device_id)\n\n print \"Super-Gluu. Authenticate for step 2. Result after attaching u2f_device '%s' to user '%s': '%s'\" % (u2f_device_id, user_name, attach_result) \n\n return attach_result\n elif self.twoStep:\n if user_name == None:\n print \"Super-Gluu. Authenticate for step 2. Failed to determine user name\"\n return False\n\n validation_result = self.validateSessionDeviceStatus(client_redirect_uri, session_device_status, user_name)\n if validation_result:\n print \"Super-Gluu. Authenticate for step 2. User '%s' successfully authenticated with u2f_device '%s'\" % (user_name, u2f_device_id)\n else:\n return False\n \n super_gluu_request = json.loads(session_device_status['super_gluu_request'])\n auth_method = super_gluu_request['method']\n if auth_method in ['enroll', 'authenticate']:\n if validation_result and self.use_audit_group:\n user = authenticationService.getAuthenticatedUser()\n self.processAuditGroup(user, self.audit_attribute, self.audit_group)\n\n return validation_result\n\n print \"Super-Gluu. Authenticate for step 2. U2F auth_method is invalid\"\n\n return False\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n client_redirect_uri = self.getApplicationUri(session_attributes)\n if client_redirect_uri == None:\n print \"Super-Gluu. Prepare for step. redirect_uri is not set\"\n return False\n\n self.setRequestScopedParameters(identity, step)\n\n if step == 1:\n print \"Super-Gluu. Prepare for step 1\"\n if self.oneStep:\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"Super-Gluu. Prepare for step 2. Failed to determine session_id\"\n return False\n\n issuer = CdiUtil.bean(ConfigurationFactory).getConfiguration().getIssuer()\n super_gluu_request_dictionary = {'app': client_redirect_uri,\n 'issuer': issuer,\n 'state': session.getId(),\n 'licensed': self.valid_license,\n 'created': DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().withNano(0))}\n\n self.addGeolocationData(session_attributes, super_gluu_request_dictionary)\n\n super_gluu_request = json.dumps(super_gluu_request_dictionary, separators=(',',':'))\n print \"Super-Gluu. Prepare for step 1. Prepared super_gluu_request:\", super_gluu_request\n \n identity.setWorkingParameter(\"super_gluu_request\", super_gluu_request)\n elif self.twoStep:\n identity.setWorkingParameter(\"display_register_action\", True)\n\n return True\n elif step == 2:\n print \"Super-Gluu. Prepare for step 2\"\n if self.oneStep:\n return True\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"Super-Gluu. Prepare for step 2. Failed to determine user name\"\n return False\n\n if session_attributes.containsKey(\"super_gluu_request\"):\n super_gluu_request = session_attributes.get(\"super_gluu_request\")\n if not StringHelper.equalsIgnoreCase(super_gluu_request, \"timeout\"):\n print \"Super-Gluu. Prepare for step 2. Request was generated already\"\n return True\n \n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"Super-Gluu. Prepare for step 2. Failed to determine session_id\"\n return False\n\n auth_method = session_attributes.get(\"super_gluu_auth_method\")\n if StringHelper.isEmpty(auth_method):\n print \"Super-Gluu. Prepare for step 2. Failed to determine auth_method\"\n return False\n\n print \"Super-Gluu. Prepare for step 2. auth_method: '%s'\" % auth_method\n \n issuer = CdiUtil.bean(ConfigurationFactory).getAppConfiguration().getIssuer()\n super_gluu_request_dictionary = {'username': user.getUserId(),\n 'app': client_redirect_uri,\n 'issuer': issuer,\n 'method': auth_method,\n 'state': session.getId(),\n 'licensed': self.valid_license,\n 'created': DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().withNano(0))}\n\n self.addGeolocationData(session_attributes, super_gluu_request_dictionary)\n\n super_gluu_request = json.dumps(super_gluu_request_dictionary, separators=(',',':'))\n print \"Super-Gluu. Prepare for step 2. Prepared super_gluu_request:\", super_gluu_request\n\n identity.setWorkingParameter(\"super_gluu_request\", super_gluu_request)\n identity.setWorkingParameter(\"super_gluu_auth_method\", auth_method)\n\n if auth_method in ['authenticate']:\n self.sendPushNotification(client_redirect_uri, user, super_gluu_request)\n\n return True\n else:\n return False\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n # If user not pass current step change step to previous\n identity = CdiUtil.bean(Identity)\n retry_current_step = identity.getWorkingParameter(\"retry_current_step\")\n if retry_current_step:\n print \"Super-Gluu. Get next step. Retrying current step\"\n\n # Remove old QR code\n identity.setWorkingParameter(\"super_gluu_request\", \"timeout\")\n\n resultStep = step\n return resultStep\n\n return -1\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n if step == 1:\n if self.oneStep: \n return Arrays.asList(\"super_gluu_request\")\n elif self.twoStep:\n return Arrays.asList(\"display_register_action\")\n elif step == 2:\n return Arrays.asList(\"super_gluu_auth_method\", \"super_gluu_request\")\n \n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n identity = CdiUtil.bean(Identity)\n if identity.isSetWorkingParameter(\"super_gluu_count_login_steps\"):\n return identity.getWorkingParameter(\"super_gluu_count_login_steps\")\n else:\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 1:\n if self.oneStep: \n return \"/auth/super-gluu/login.xhtml\"\n elif step == 2:\n if self.oneStep:\n return \"/login.xhtml\"\n else:\n identity = CdiUtil.bean(Identity)\n authmethod = identity.getWorkingParameter(\"super_gluu_auth_method\")\n print \"Super-Gluu. authmethod '%s'\" % authmethod\n if authmethod == \"enroll\":\n return \"/auth/super-gluu/login.xhtml\"\n else:\n return \"/auth/super-gluu/login.xhtml\"\n\n return \"\"\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def processBasicAuthentication(self, credentials):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return None\n\n find_user_by_uid = authenticationService.getAuthenticatedUser()\n if find_user_by_uid == None:\n print \"Super-Gluu. Process basic authentication. Failed to find user '%s'\" % user_name\n return None\n \n return find_user_by_uid\n\n def validateSessionDeviceStatus(self, client_redirect_uri, session_device_status, user_name = None):\n userService = CdiUtil.bean(UserService)\n deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)\n\n u2f_device_id = session_device_status['device_id']\n\n u2f_device = None\n if session_device_status['enroll'] and session_device_status['one_step']:\n u2f_device = deviceRegistrationService.findOneStepUserDeviceRegistration(u2f_device_id)\n if u2f_device == None:\n print \"Super-Gluu. Validate session device status. There is no one step u2f_device '%s'\" % u2f_device_id\n return False\n else:\n # Validate if user has specified device_id enrollment\n user_inum = userService.getUserInum(user_name)\n\n if session_device_status['one_step']:\n user_inum = session_device_status['user_inum']\n \n u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id)\n if u2f_device == None:\n print \"Super-Gluu. Validate session device status. There is no u2f_device '%s' associated with user '%s'\" % (u2f_device_id, user_inum)\n return False\n\n if not StringHelper.equalsIgnoreCase(client_redirect_uri, u2f_device.application):\n print \"Super-Gluu. Validate session device status. u2f_device '%s' associated with other application '%s'\" % (u2f_device_id, u2f_device.application)\n return False\n \n return True\n\n def getSessionDeviceStatus(self, session_attributes, user_name):\n print \"Super-Gluu. Get session device status\"\n\n if not session_attributes.containsKey(\"super_gluu_request\"):\n print \"Super-Gluu. Get session device status. There is no Super-Gluu request in session attributes\"\n return None\n\n # Check session state extended\n if not session_attributes.containsKey(\"session_custom_state\"):\n print \"Super-Gluu. Get session device status. There is no session_custom_state in session attributes\"\n return None\n\n session_custom_state = session_attributes.get(\"session_custom_state\")\n if not StringHelper.equalsIgnoreCase(\"approved\", session_custom_state):\n print \"Super-Gluu. Get session device status. User '%s' not approve or not pass U2F authentication. session_custom_state: '%s'\" % (user_name, session_custom_state)\n return None\n\n # Try to find device_id in session attribute\n if not session_attributes.containsKey(\"oxpush2_u2f_device_id\"):\n print \"Super-Gluu. Get session device status. There is no u2f_device associated with this request\"\n return None\n\n # Try to find user_inum in session attribute\n if not session_attributes.containsKey(\"oxpush2_u2f_device_user_inum\"):\n print \"Super-Gluu. Get session device status. There is no user_inum associated with this request\"\n return None\n \n enroll = False\n if session_attributes.containsKey(\"oxpush2_u2f_device_enroll\"):\n enroll = StringHelper.equalsIgnoreCase(\"true\", session_attributes.get(\"oxpush2_u2f_device_enroll\"))\n\n one_step = False\n if session_attributes.containsKey(\"oxpush2_u2f_device_one_step\"):\n one_step = StringHelper.equalsIgnoreCase(\"true\", session_attributes.get(\"oxpush2_u2f_device_one_step\"))\n \n super_gluu_request = session_attributes.get(\"super_gluu_request\")\n u2f_device_id = session_attributes.get(\"oxpush2_u2f_device_id\")\n user_inum = session_attributes.get(\"oxpush2_u2f_device_user_inum\")\n\n session_device_status = {\"super_gluu_request\": super_gluu_request, \"device_id\": u2f_device_id, \"user_inum\" : user_inum, \"enroll\" : enroll, \"one_step\" : one_step}\n print \"Super-Gluu. Get session device status. session_device_status: '%s'\" % (session_device_status)\n \n return session_device_status\n\n def initPushNotificationService(self, configurationAttributes):\n print \"Super-Gluu. Initialize Native/SNS/Gluu notification services\"\n\n self.pushSnsMode = False\n self.pushGluuMode = False\n if configurationAttributes.containsKey(\"notification_service_mode\"):\n notificationServiceMode = configurationAttributes.get(\"notification_service_mode\").getValue2()\n if StringHelper.equalsIgnoreCase(notificationServiceMode, \"sns\"):\n return self.initSnsPushNotificationService(configurationAttributes)\n elif StringHelper.equalsIgnoreCase(notificationServiceMode, \"gluu\"):\n return self.initGluuPushNotificationService(configurationAttributes)\n\n return self.initNativePushNotificationService(configurationAttributes)\n\n def initNativePushNotificationService(self, configurationAttributes):\n print \"Super-Gluu. Initialize native notification services\"\n \n creds = self.loadPushNotificationCreds(configurationAttributes)\n if creds == None:\n return False\n \n try:\n android_creds = creds[\"android\"][\"gcm\"]\n ios_creds = creds[\"ios\"][\"apns\"]\n except:\n print \"Super-Gluu. Initialize native notification services. Invalid credentials file format\"\n return False\n \n self.pushAndroidService = None\n self.pushAppleService = None\n if android_creds[\"enabled\"]:\n self.pushAndroidService = Sender(android_creds[\"api_key\"]) \n print \"Super-Gluu. Initialize native notification services. Created Android notification service\"\n \n if ios_creds[\"enabled\"]:\n p12_file_path = ios_creds[\"p12_file_path\"]\n p12_password = ios_creds[\"p12_password\"]\n\n try:\n encryptionService = CdiUtil.bean(EncryptionService)\n p12_password = encryptionService.decrypt(p12_password)\n except:\n # Ignore exception. Password is not encrypted\n print \"Super-Gluu. Initialize native notification services. Assuming that 'p12_password' password in not encrypted\"\n\n apnsServiceBuilder = APNS.newService().withCert(p12_file_path, p12_password)\n if ios_creds[\"production\"]:\n self.pushAppleService = apnsServiceBuilder.withProductionDestination().build()\n else:\n self.pushAppleService = apnsServiceBuilder.withSandboxDestination().build()\n\n self.pushAppleServiceProduction = ios_creds[\"production\"]\n\n print \"Super-Gluu. Initialize native notification services. Created iOS notification service\"\n\n enabled = self.pushAndroidService != None or self.pushAppleService != None\n\n return enabled\n\n def initSnsPushNotificationService(self, configurationAttributes):\n print \"Super-Gluu. Initialize SNS notification services\"\n self.pushSnsMode = True\n\n creds = self.loadPushNotificationCreds(configurationAttributes)\n if creds == None:\n return False\n \n try:\n sns_creds = creds[\"sns\"]\n android_creds = creds[\"android\"][\"sns\"]\n ios_creds = creds[\"ios\"][\"sns\"]\n except:\n print \"Super-Gluu. Initialize SNS notification services. Invalid credentials file format\"\n return False\n \n self.pushAndroidService = None\n self.pushAppleService = None\n if not (android_creds[\"enabled\"] or ios_creds[\"enabled\"]):\n print \"Super-Gluu. Initialize SNS notification services. SNS disabled for all platforms\"\n return False\n\n sns_access_key = sns_creds[\"access_key\"]\n sns_secret_access_key = sns_creds[\"secret_access_key\"]\n sns_region = sns_creds[\"region\"]\n\n encryptionService = CdiUtil.bean(EncryptionService)\n\n try:\n sns_secret_access_key = encryptionService.decrypt(sns_secret_access_key)\n except:\n # Ignore exception. Password is not encrypted\n print \"Super-Gluu. Initialize SNS notification services. Assuming that 'sns_secret_access_key' in not encrypted\"\n \n pushSnsService = CdiUtil.bean(PushSnsService)\n pushClient = pushSnsService.createSnsClient(sns_access_key, sns_secret_access_key, sns_region)\n\n if android_creds[\"enabled\"]:\n self.pushAndroidService = pushClient\n self.pushAndroidPlatformArn = android_creds[\"platform_arn\"]\n print \"Super-Gluu. Initialize SNS notification services. Created Android notification service\"\n\n if ios_creds[\"enabled\"]:\n self.pushAppleService = pushClient \n self.pushApplePlatformArn = ios_creds[\"platform_arn\"]\n self.pushAppleServiceProduction = ios_creds[\"production\"]\n print \"Super-Gluu. Initialize SNS notification services. Created iOS notification service\"\n\n enabled = self.pushAndroidService != None or self.pushAppleService != None\n\n return enabled\n\n def initGluuPushNotificationService(self, configurationAttributes):\n print \"Super-Gluu. Initialize Gluu notification services\"\n\n self.pushGluuMode = True\n\n creds = self.loadPushNotificationCreds(configurationAttributes)\n if creds == None:\n return False\n \n try:\n gluu_conf = creds[\"gluu\"]\n android_creds = creds[\"android\"][\"gluu\"]\n ios_creds = creds[\"ios\"][\"gluu\"]\n except:\n print \"Super-Gluu. Initialize Gluu notification services. Invalid credentials file format\"\n return False\n \n self.pushAndroidService = None\n self.pushAppleService = None\n if not (android_creds[\"enabled\"] or ios_creds[\"enabled\"]):\n print \"Super-Gluu. Initialize Gluu notification services. Gluu disabled for all platforms\"\n return False\n\n gluu_server_uri = gluu_conf[\"server_uri\"]\n notifyClientFactory = NotifyClientFactory.instance()\n metadataConfiguration = None\n try:\n metadataConfiguration = notifyClientFactory.createMetaDataConfigurationService(gluu_server_uri).getMetadataConfiguration()\n except:\n print \"Super-Gluu. Initialize Gluu notification services. Failed to load metadata. Exception: \", sys.exc_info()[1]\n return False\n\n gluuClient = notifyClientFactory.createNotifyService(metadataConfiguration)\n encryptionService = CdiUtil.bean(EncryptionService)\n\n if android_creds[\"enabled\"]:\n gluu_access_key = android_creds[\"access_key\"]\n gluu_secret_access_key = android_creds[\"secret_access_key\"]\n \n try:\n gluu_secret_access_key = encryptionService.decrypt(gluu_secret_access_key)\n except:\n # Ignore exception. Password is not encrypted\n print \"Super-Gluu. Initialize Gluu notification services. Assuming that 'gluu_secret_access_key' in not encrypted\"\n \n self.pushAndroidService = gluuClient \n self.pushAndroidServiceAuth = notifyClientFactory.getAuthorization(gluu_access_key, gluu_secret_access_key);\n print \"Super-Gluu. Initialize Gluu notification services. Created Android notification service\"\n\n if ios_creds[\"enabled\"]:\n gluu_access_key = ios_creds[\"access_key\"]\n gluu_secret_access_key = ios_creds[\"secret_access_key\"]\n \n try:\n gluu_secret_access_key = encryptionService.decrypt(gluu_secret_access_key)\n except:\n # Ignore exception. Password is not encrypted\n print \"Super-Gluu. Initialize Gluu notification services. Assuming that 'gluu_secret_access_key' in not encrypted\"\n \n self.pushAppleService = gluuClient \n self.pushAppleServiceAuth = notifyClientFactory.getAuthorization(gluu_access_key, gluu_secret_access_key);\n print \"Super-Gluu. Initialize Gluu notification services. Created iOS notification service\"\n\n enabled = self.pushAndroidService != None or self.pushAppleService != None\n\n return enabled\n\n def loadPushNotificationCreds(self, configurationAttributes):\n print \"Super-Gluu. Initialize notification services\"\n if not configurationAttributes.containsKey(\"credentials_file\"):\n return None\n\n super_gluu_creds_file = configurationAttributes.get(\"credentials_file\").getValue2()\n\n # Load credentials from file\n f = open(super_gluu_creds_file, 'r')\n try:\n creds = json.loads(f.read())\n except:\n print \"Super-Gluu. Initialize notification services. Failed to load credentials from file:\", super_gluu_creds_file\n return None\n finally:\n f.close()\n\n return creds\n\n def sendPushNotification(self, client_redirect_uri, user, super_gluu_request):\n try:\n self.sendPushNotificationImpl(client_redirect_uri, user, super_gluu_request)\n except:\n print \"Super-Gluu. Send push notification. Failed to send push notification: \", sys.exc_info()[1]\n\n def sendPushNotificationImpl(self, client_redirect_uri, user, super_gluu_request):\n if not self.enabledPushNotifications:\n return\n\n user_name = user.getUserId()\n print \"Super-Gluu. Send push notification. Loading user '%s' devices\" % user_name\n\n send_notification = False\n send_notification_result = True\n\n userService = CdiUtil.bean(UserService)\n deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)\n\n user_inum = userService.getUserInum(user_name)\n\n send_android = 0\n send_ios = 0\n u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, \"oxId\", \"oxDeviceData\", \"oxDeviceNotificationConf\")\n if u2f_devices_list.size() > 0:\n for u2f_device in u2f_devices_list:\n device_data = u2f_device.getDeviceData()\n\n # Device data which Super-Gluu gets during enrollment\n if device_data == None:\n continue\n\n platform = device_data.getPlatform()\n push_token = device_data.getPushToken()\n debug = False\n\n if StringHelper.equalsIgnoreCase(platform, \"ios\") and StringHelper.isNotEmpty(push_token):\n # Sending notification to iOS user's device\n if self.pushAppleService == None:\n print \"Super-Gluu. Send push notification. Apple native push notification service is not enabled\"\n else:\n send_notification = True\n \n title = \"Super Gluu\"\n message = \"Confirm your sign in request to: %s\" % client_redirect_uri\n\n if self.pushSnsMode or self.pushGluuMode:\n pushSnsService = CdiUtil.bean(PushSnsService)\n targetEndpointArn = self.getTargetEndpointArn(deviceRegistrationService, pushSnsService, PushPlatform.APNS, user, u2f_device)\n if targetEndpointArn == None:\n \treturn\n\n send_notification = True\n \n sns_push_request_dictionary = { \"aps\": \n { \"badge\": 0,\n \"alert\" : {\"body\": message, \"title\" : title},\n \"category\": \"ACTIONABLE\",\n \"content-available\": \"1\",\n \"sound\": 'default'\n },\n \"request\" : super_gluu_request\n }\n push_message = json.dumps(sns_push_request_dictionary, separators=(',',':'))\n \n if self.pushSnsMode:\n apple_push_platform = PushPlatform.APNS\n if not self.pushAppleServiceProduction:\n apple_push_platform = PushPlatform.APNS_SANDBOX\n \n send_notification_result = pushSnsService.sendPushMessage(self.pushAppleService, apple_push_platform, targetEndpointArn, push_message, None)\n if debug:\n print \"Super-Gluu. Send iOS SNS push notification. token: '%s', message: '%s', send_notification_result: '%s', apple_push_platform: '%s'\" % (push_token, push_message, send_notification_result, apple_push_platform)\n elif self.pushGluuMode:\n send_notification_result = self.pushAppleService.sendNotification(self.pushAppleServiceAuth, targetEndpointArn, push_message)\n if debug:\n print \"Super-Gluu. Send iOS Gluu push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n else:\n additional_fields = { \"request\" : super_gluu_request }\n \n msgBuilder = APNS.newPayload().alertBody(message).alertTitle(title).sound(\"default\")\n msgBuilder.category('ACTIONABLE').badge(0)\n msgBuilder.forNewsstand()\n msgBuilder.customFields(additional_fields)\n push_message = msgBuilder.build()\n \n send_notification_result = self.pushAppleService.push(push_token, push_message)\n if debug:\n print \"Super-Gluu. Send iOS Native push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n send_ios = send_ios + 1\n\n if StringHelper.equalsIgnoreCase(platform, \"android\") and StringHelper.isNotEmpty(push_token):\n # Sending notification to Android user's device\n if self.pushAndroidService == None:\n print \"Super-Gluu. Send native push notification. Android native push notification service is not enabled\"\n else:\n send_notification = True\n\n title = \"Super-Gluu\"\n if self.pushSnsMode or self.pushGluuMode:\n pushSnsService = CdiUtil.bean(PushSnsService)\n targetEndpointArn = self.getTargetEndpointArn(deviceRegistrationService, pushSnsService, PushPlatform.GCM, user, u2f_device)\n if targetEndpointArn == None:\n \treturn\n\n send_notification = True\n \n sns_push_request_dictionary = { \"collapse_key\": \"single\",\n \"content_available\": True,\n \"time_to_live\": 60,\n \"data\": \n { \"message\" : super_gluu_request,\n \"title\" : title }\n }\n push_message = json.dumps(sns_push_request_dictionary, separators=(',',':'))\n \n if self.pushSnsMode:\n send_notification_result = pushSnsService.sendPushMessage(self.pushAndroidService, PushPlatform.GCM, targetEndpointArn, push_message, None)\n if debug:\n print \"Super-Gluu. Send Android SNS push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n elif self.pushGluuMode:\n send_notification_result = self.pushAndroidService.sendNotification(self.pushAndroidServiceAuth, targetEndpointArn, push_message)\n if debug:\n print \"Super-Gluu. Send Android Gluu push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n else:\n msgBuilder = Message.Builder().addData(\"message\", super_gluu_request).addData(\"title\", title).collapseKey(\"single\").contentAvailable(True)\n push_message = msgBuilder.build()\n \n send_notification_result = self.pushAndroidService.send(push_message, push_token, 3)\n if debug:\n print \"Super-Gluu. Send Android Native push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n send_android = send_android + 1\n\n print \"Super-Gluu. Send push notification. send_android: '%s', send_ios: '%s'\" % (send_android, send_ios)\n\n def getTargetEndpointArn(self, deviceRegistrationService, pushSnsService, platform, user, u2fDevice):\n targetEndpointArn = None\n \n # Return endpoint ARN if it created already\n notificationConf = u2fDevice.getDeviceNotificationConf()\n if StringHelper.isNotEmpty(notificationConf):\n notificationConfJson = json.loads(notificationConf)\n targetEndpointArn = notificationConfJson['sns_endpoint_arn']\n if StringHelper.isNotEmpty(targetEndpointArn):\n print \"Super-Gluu. Get target endpoint ARN. There is already created target endpoint ARN\"\n return targetEndpointArn\n\n # Create endpoint ARN \n pushClient = None\n pushClientAuth = None\n platformApplicationArn = None\n if platform == PushPlatform.GCM:\n pushClient = self.pushAndroidService\n if self.pushSnsMode:\n platformApplicationArn = self.pushAndroidPlatformArn\n if self.pushGluuMode:\n pushClientAuth = self.pushAndroidServiceAuth\n elif platform == PushPlatform.APNS:\n pushClient = self.pushAppleService\n if self.pushSnsMode:\n platformApplicationArn = self.pushApplePlatformArn\n if self.pushGluuMode:\n pushClientAuth = self.pushAppleServiceAuth\n else:\n return None\n\n deviceData = u2fDevice.getDeviceData()\n pushToken = deviceData.getPushToken()\n \n print \"Super-Gluu. Get target endpoint ARN. Attempting to create target endpoint ARN for user: '%s'\" % user.getUserId()\n if self.pushSnsMode:\n targetEndpointArn = pushSnsService.createPlatformArn(pushClient, platformApplicationArn, pushToken, user)\n else:\n customUserData = pushSnsService.getCustomUserData(user)\n registerDeviceResponse = pushClient.registerDevice(pushClientAuth, pushToken, customUserData);\n if registerDeviceResponse != None and registerDeviceResponse.getStatusCode() == 200:\n targetEndpointArn = registerDeviceResponse.getEndpointArn()\n \n if StringHelper.isEmpty(targetEndpointArn):\n\t print \"Super-Gluu. Failed to get endpoint ARN for user: '%s'\" % user.getUserId()\n \treturn None\n\n print \"Super-Gluu. Get target endpoint ARN. Create target endpoint ARN '%s' for user: '%s'\" % (targetEndpointArn, user.getUserId())\n \n # Store created endpoint ARN in device entry\n userInum = user.getAttribute(\"inum\")\n u2fDeviceUpdate = deviceRegistrationService.findUserDeviceRegistration(userInum, u2fDevice.getId())\n u2fDeviceUpdate.setDeviceNotificationConf('{\"sns_endpoint_arn\" : \"%s\"}' % targetEndpointArn)\n deviceRegistrationService.updateDeviceRegistration(userInum, u2fDeviceUpdate)\n\n return targetEndpointArn\n\n def getApplicationUri(self, session_attributes):\n if self.applicationId != None:\n return self.applicationId\n \n if not session_attributes.containsKey(\"redirect_uri\"):\n return None\n\n return session_attributes.get(\"redirect_uri\")\n\n def setRequestScopedParameters(self, identity, step):\n downloadMap = HashMap()\n if self.registrationUri != None:\n identity.setWorkingParameter(\"external_registration_uri\", self.registrationUri)\n\n if self.androidUrl!= None and step == 1:\n downloadMap.put(\"android\", self.androidUrl)\n\n if self.IOSUrl != None and step == 1:\n downloadMap.put(\"ios\", self.IOSUrl)\n \n if self.customLabel != None:\n identity.setWorkingParameter(\"super_gluu_label\", self.customLabel)\n \n identity.setWorkingParameter(\"download_url\", downloadMap)\n identity.setWorkingParameter(\"super_gluu_qr_options\", self.customQrOptions)\n\n def addGeolocationData(self, session_attributes, super_gluu_request_dictionary):\n if session_attributes.containsKey(\"remote_ip\"):\n remote_ip = session_attributes.get(\"remote_ip\")\n if StringHelper.isNotEmpty(remote_ip):\n print \"Super-Gluu. Prepare for step 2. Adding req_ip and req_loc to super_gluu_request\"\n super_gluu_request_dictionary['req_ip'] = remote_ip\n\n remote_loc_dic = self.determineGeolocationData(remote_ip)\n if remote_loc_dic == None:\n print \"Super-Gluu. Prepare for step 2. Failed to determine remote location by remote IP '%s'\" % remote_ip\n return\n\n remote_loc = \"%s, %s, %s\" % ( remote_loc_dic['country'], remote_loc_dic['regionName'], remote_loc_dic['city'] )\n remote_loc_encoded = urllib.quote(remote_loc.encode('utf-8'))\n super_gluu_request_dictionary['req_loc'] = remote_loc_encoded\n\n def determineGeolocationData(self, remote_ip):\n print \"Super-Gluu. Determine remote location. remote_ip: '%s'\" % remote_ip\n httpService = CdiUtil.bean(HttpService)\n\n http_client = httpService.getHttpsClient()\n http_client_params = http_client.getParams()\n http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000)\n \n geolocation_service_url = \"http://ip-api.com/json/%s?fields=49177\" % remote_ip\n geolocation_service_headers = { \"Accept\" : \"application/json\" }\n\n try:\n http_service_response = httpService.executeGet(http_client, geolocation_service_url, geolocation_service_headers)\n http_response = http_service_response.getHttpResponse()\n except:\n print \"Super-Gluu. Determine remote location. Exception: \", sys.exc_info()[1]\n return None\n\n try:\n if not httpService.isResponseStastusCodeOk(http_response):\n print \"Super-Gluu. Determine remote location. Get invalid response from validation server: \", str(http_response.getStatusLine().getStatusCode())\n httpService.consume(http_response)\n return None\n \n response_bytes = httpService.getResponseContent(http_response)\n response_string = httpService.convertEntityToString(response_bytes)\n httpService.consume(http_response)\n finally:\n http_service_response.closeConnection()\n\n if response_string == None:\n print \"Super-Gluu. Determine remote location. Get empty response from location server\"\n return None\n \n response = json.loads(response_string)\n \n if not StringHelper.equalsIgnoreCase(response['status'], \"success\"):\n print \"Super-Gluu. Determine remote location. Get response with status: '%s'\" % response['status']\n return None\n\n return response\n\n def isUserMemberOfGroup(self, user, attribute, group):\n is_member = False\n member_of_list = user.getAttributeValues(attribute)\n if (member_of_list != None):\n for member_of in member_of_list:\n if StringHelper.equalsIgnoreCase(group, member_of) or member_of.endswith(group):\n is_member = True\n break\n\n return is_member\n\n def processAuditGroup(self, user, attribute, group):\n is_member = self.isUserMemberOfGroup(user, attribute, group)\n if (is_member):\n print \"Super-Gluu. Authenticate for processAuditGroup. User '%s' member of audit group\" % user.getUserId()\n print \"Super-Gluu. Authenticate for processAuditGroup. Sending e-mail about user '%s' login to %s\" % (user.getUserId(), self.audit_email)\n \n # Send e-mail to administrator\n user_id = user.getUserId()\n mailService = CdiUtil.bean(MailService)\n subject = \"User log in: %s\" % user_id\n body = \"User log in: %s\" % user_id\n mailService.sendMail(self.audit_email, subject, body)\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + }, + { + "value2": "interactive", + "value1": "usage_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "super_gluu", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "{ size: 500, mSize: 0.05 }", + "value1": "qr_options" + }, + { + "hide": false, + "value2": "Super Gluu", + "value1": "label" + }, + { + "hide": false, + "value2": "https://pujavs4.2.gluu.server/identity/register", + "value1": "registration_uri" + }, + { + "hide": false, + "value2": "two_step", + "value1": "authentication_mode" + }, + { + "hide": false, + "value2": "gluu", + "value1": "notification_service_mode" + }, + { + "hide": false, + "value2": "/etc/certs/super_gluu_creds.json", + "value1": "credentials_file" + }, + { + "hide": false, + "value2": "https://play.google.com/store/apps/details?id=gluu.org.super.gluu&hl=en_US", + "value1": "supergluu_android_download_url" + }, + { + "hide": false, + "value2": "https://itunes.apple.com/us/app/super-gluu/id1093479646", + "value1": "supergluu_ios_download_url" + } + ], + "baseDn": "inum=92F0-BF9E,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 70, + "programmingLanguage": "PYTHON", + "description": "Fido2 authentication module", + "locationType": "LDAP", + "dn": "inum=8BAF-80D7,ou=scripts,o=gluu", + "inum": "8BAF-80D7", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2018, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom javax.ws.rs.core import Response\nfrom org.jboss.resteasy.client import ClientResponseFailure\nfrom org.jboss.resteasy.client.exception import ResteasyClientException\nfrom javax.ws.rs.core import Response\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.fido2.client import Fido2ClientFactory\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\n\nfrom java.util.concurrent.locks import ReentrantLock\n\nimport java\nimport sys\ntry:\n import json\nexcept ImportError:\n import simplejson as json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Fido2. Initialization\"\n\n if not configurationAttributes.containsKey(\"fido2_server_uri\"):\n print \"fido2_server_uri. Initialization. Property fido2_server_uri is not specified\"\n return False\n\n self.fido2_server_uri = configurationAttributes.get(\"fido2_server_uri\").getValue2()\n\n self.fido2_domain = None\n if configurationAttributes.containsKey(\"fido2_domain\"):\n self.fido2_domain = configurationAttributes.get(\"fido2_domain\").getValue2()\n\n self.metaDataLoaderLock = ReentrantLock()\n self.metaDataConfiguration = None\n \n print \"Fido2. Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"Fido2. Destroy\"\n print \"Fido2. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n user_name = credentials.getUsername()\n\n if step == 1:\n print \"Fido2. Authenticate for step 1\"\n\n user_password = credentials.getPassword()\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n userService = CdiUtil.bean(UserService)\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return False\n\n return True\n elif step == 2:\n print \"Fido2. Authenticate for step 2\"\n\n token_response = ServerUtil.getFirstValue(requestParameters, \"tokenResponse\")\n if token_response == None:\n print \"Fido2. Authenticate for step 2. tokenResponse is empty\"\n return False\n\n auth_method = ServerUtil.getFirstValue(requestParameters, \"authMethod\")\n if auth_method == None:\n print \"Fido2. Authenticate for step 2. authMethod is empty\"\n return False\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"Fido2. Prepare for step 2. Failed to determine user name\"\n return False\n\n if auth_method == 'authenticate':\n print \"Fido2. Prepare for step 2. Call Fido2 in order to finish authentication flow\"\n assertionService = Fido2ClientFactory.instance().createAssertionService(self.metaDataConfiguration)\n assertionStatus = assertionService.verify(token_response)\n authenticationStatusEntity = assertionStatus.readEntity(java.lang.String)\n\n if assertionStatus.getStatus() != Response.Status.OK.getStatusCode():\n print \"Fido2. Authenticate for step 2. Get invalid authentication status from Fido2 server\"\n return False\n\n return True\n elif auth_method == 'enroll':\n print \"Fido2. Prepare for step 2. Call Fido2 in order to finish registration flow\"\n attestationService = Fido2ClientFactory.instance().createAttestationService(self.metaDataConfiguration)\n attestationStatus = attestationService.verify(token_response)\n\n if attestationStatus.getStatus() != Response.Status.OK.getStatusCode():\n print \"Fido2. Authenticate for step 2. Get invalid registration status from Fido2 server\"\n return False\n\n return True\n else:\n print \"Fido2. Prepare for step 2. Authentication method is invalid\"\n return False\n\n return False\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n\n if step == 1:\n return True\n elif step == 2:\n print \"Fido2. Prepare for step 2\"\n\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"Fido2. Prepare for step 2. Failed to determine session_id\"\n return False\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"Fido2. Prepare for step 2. Failed to determine user name\"\n return False\n\n userName = user.getUserId()\n\n metaDataConfiguration = self.getMetaDataConfiguration()\n \n assertionResponse = None\n attestationResponse = None\n\n # Check if user have registered devices\n userService = CdiUtil.bean(UserService)\n countFido2Devices = userService.countFidoAndFido2Devices(userName, self.fido2_domain)\n if countFido2Devices > 0:\n print \"Fido2. Prepare for step 2. Call Fido2 endpoint in order to start assertion flow\"\n\n try:\n assertionService = Fido2ClientFactory.instance().createAssertionService(metaDataConfiguration)\n assertionRequest = json.dumps({'username': userName}, separators=(',', ':'))\n assertionResponse = assertionService.authenticate(assertionRequest).readEntity(java.lang.String)\n except ClientResponseFailure, ex:\n print \"Fido2. Prepare for step 2. Failed to start assertion flow. Exception:\", sys.exc_info()[1]\n return False\n else:\n print \"Fido2. Prepare for step 2. Call Fido2 endpoint in order to start attestation flow\"\n\n try:\n attestationService = Fido2ClientFactory.instance().createAttestationService(metaDataConfiguration)\n attestationRequest = json.dumps({'username': userName, 'displayName': userName, 'attestation' : 'direct'}, separators=(',', ':'))\n attestationResponse = attestationService.register(attestationRequest).readEntity(java.lang.String)\n except ClientResponseFailure, ex:\n print \"Fido2. Prepare for step 2. Failed to start attestation flow. Exception:\", sys.exc_info()[1]\n return False\n\n identity.setWorkingParameter(\"fido2_assertion_request\", ServerUtil.asJson(assertionResponse))\n identity.setWorkingParameter(\"fido2_attestation_request\", ServerUtil.asJson(attestationResponse))\n print \"Fido2. Prepare for step 2. Successfully start flow with next requests.\\nfido2_assertion_request: '%s'\\nfido2_attestation_request: '%s'\" % ( assertionResponse, attestationResponse )\n\n return True\n elif step == 3:\n print \"Fido2. Prepare for step 3\"\n\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 2\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 2:\n return \"/auth/fido2/login.xhtml\"\n\n return \"\"\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None \n \n \n def getMetaDataConfiguration(self):\n if self.metaDataConfiguration != None:\n return self.metaDataConfiguration\n \n self.metaDataLoaderLock.lock()\n # Make sure that another thread not loaded configuration already \n if self.metaDataConfiguration != None:\n return self.metaDataConfiguration\n\n try:\n print \"Fido2. Initialization. Downloading Fido2 metadata\"\n self.fido2_server_metadata_uri = self.fido2_server_uri + \"/.well-known/fido2-configuration\"\n #self.fido2_server_metadata_uri = self.fido2_server_uri + \"/fido2/restv1/fido2/configuration\"\n\n metaDataConfigurationService = Fido2ClientFactory.instance().createMetaDataConfigurationService(self.fido2_server_metadata_uri)\n \n max_attempts = 10\n for attempt in range(1, max_attempts + 1):\n try:\n self.metaDataConfiguration = metaDataConfigurationService.getMetadataConfiguration().readEntity(java.lang.String)\n return self.metaDataConfiguration\n except ClientResponseFailure, ex:\n # Detect if last try or we still get Service Unavailable HTTP error\n if (attempt == max_attempts) or (ex.getResponse().getResponseStatus() != Response.Status.SERVICE_UNAVAILABLE):\n raise ex\n \n java.lang.Thread.sleep(3000)\n print \"Attempting to load metadata: %d\" % attempt\n except ResteasyClientException, ex:\n # Detect if last try or we still get Service Unavailable HTTP error\n if attempt == max_attempts:\n raise ex\n \n java.lang.Thread.sleep(3000)\n print \"Attempting to load metadata: %d\" % attempt\n finally:\n self.metaDataLoaderLock.unlock()\n \n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "interactive", + "value1": "usage_type" + }, + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "fido2", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "https://pujavs4.2.gluu.server", + "value1": "fido2_server_uri" + } + ], + "baseDn": "inum=8BAF-80D7,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 70, + "programmingLanguage": "PYTHON", + "description": "UAF authentication module", + "locationType": "LDAP", + "dn": "inum=5018-AF9C,ou=scripts,o=gluu", + "inum": "5018-AF9C", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\n# Requires the following custom properties and values:\n# uaf_server_uri: \n#\n# These are non mandatory custom properties and values:\n# uaf_policy_name: default\n# send_push_notifaction: false\n# registration_uri: https:///identity/register\n# qr_options: { width: 400, height: 400 }\n\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.oxauth.model.config import Constants\nfrom javax.ws.rs.core import Response\nfrom java.util import Arrays\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.apache.http.params import CoreConnectionPNames\n\nimport sys\nimport java\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"UAF. Initialization\"\n\n if not configurationAttributes.containsKey(\"uaf_server_uri\"):\n print \"UAF. Initialization. Property uaf_server_uri is mandatory\"\n return False\n\n self.uaf_server_uri = configurationAttributes.get(\"uaf_server_uri\").getValue2()\n\n self.uaf_policy_name = \"default\"\n if configurationAttributes.containsKey(\"uaf_policy_name\"):\n self.uaf_policy_name = configurationAttributes.get(\"uaf_policy_name\").getValue2()\n\n self.send_push_notifaction = False\n if configurationAttributes.containsKey(\"send_push_notifaction\"):\n self.send_push_notifaction = StringHelper.toBoolean(configurationAttributes.get(\"send_push_notifaction\").getValue2(), False)\n\n self.registration_uri = None\n if configurationAttributes.containsKey(\"registration_uri\"):\n self.registration_uri = configurationAttributes.get(\"registration_uri\").getValue2()\n\n self.customQrOptions = {}\n if configurationAttributes.containsKey(\"qr_options\"):\n self.customQrOptions = configurationAttributes.get(\"qr_options\").getValue2()\n\n print \"UAF. Initializing HTTP client\"\n httpService = CdiUtil.bean(HttpService)\n self.http_client = httpService.getHttpsClient()\n http_client_params = self.http_client.getParams()\n http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000)\n\n print \"UAF. Initialized successfully. uaf_server_uri: '%s', uaf_policy_name: '%s', send_push_notifaction: '%s', registration_uri: '%s', qr_options: '%s'\" % (self.uaf_server_uri, self.uaf_policy_name, self.send_push_notifaction, self.registration_uri, self.customQrOptions)\n \n print \"UAF. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"UAF. Destroy\"\n print \"UAF. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n self.setRequestScopedParameters(identity)\n\n if (step == 1):\n print \"UAF. Authenticate for step 1\"\n\n user_name = credentials.getUsername()\n\n authenticated_user = self.processBasicAuthentication(credentials)\n if authenticated_user == None:\n return False\n\n uaf_auth_method = \"authenticate\"\n # Uncomment this block if you need to allow user second device registration\n #enrollment_mode = ServerUtil.getFirstValue(requestParameters, \"loginForm:registerButton\")\n #if StringHelper.isNotEmpty(enrollment_mode):\n # uaf_auth_method = \"enroll\"\n \n if uaf_auth_method == \"authenticate\":\n user_enrollments = self.findEnrollments(credentials)\n if len(user_enrollments) == 0:\n uaf_auth_method = \"enroll\"\n print \"UAF. Authenticate for step 1. There is no UAF enrollment for user '%s'. Changing uaf_auth_method to '%s'\" % (user_name, uaf_auth_method)\n\n print \"UAF. Authenticate for step 1. uaf_auth_method: '%s'\" % uaf_auth_method\n \n identity.setWorkingParameter(\"uaf_auth_method\", uaf_auth_method)\n\n return True\n elif (step == 2):\n print \"UAF. Authenticate for step 2\"\n\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"UAF. Prepare for step 2. Failed to determine session_id\"\n return False\n\n user = authenticationService.getAuthenticatedUser()\n if (user == None):\n print \"UAF. Authenticate for step 2. Failed to determine user name\"\n return False\n user_name = user.getUserId()\n\n uaf_auth_result = ServerUtil.getFirstValue(requestParameters, \"auth_result\")\n if uaf_auth_result != \"success\":\n print \"UAF. Authenticate for step 2. auth_result is '%s'\" % uaf_auth_result\n return False\n\n # Restore state from session\n uaf_auth_method = session_attributes.get(\"uaf_auth_method\")\n\n if not uaf_auth_method in ['enroll', 'authenticate']:\n print \"UAF. Authenticate for step 2. Failed to authenticate user. uaf_auth_method: '%s'\" % uaf_auth_method\n return False\n\n # Request STATUS_OBB\n if True:\n #TODO: Remove this condition\n # It's workaround becuase it's not possible to call STATUS_OBB 2 times. First time on browser and second ime on server\n uaf_user_device_handle = ServerUtil.getFirstValue(requestParameters, \"auth_handle\")\n else:\n uaf_obb_auth_method = session_attributes.get(\"uaf_obb_auth_method\")\n uaf_obb_server_uri = session_attributes.get(\"uaf_obb_server_uri\")\n uaf_obb_start_response = session_attributes.get(\"uaf_obb_start_response\")\n\n # Prepare STATUS_OBB\n uaf_obb_start_response_json = json.loads(uaf_obb_start_response)\n uaf_obb_status_request_dictionary = { \"operation\": \"STATUS_%s\" % uaf_obb_auth_method,\n \"userName\": user_name,\n \"needDetails\": 1,\n \"oobStatusHandle\": uaf_obb_start_response_json[\"oobStatusHandle\"],\n }\n \n uaf_obb_status_request = json.dumps(uaf_obb_status_request_dictionary, separators=(',',':'))\n print \"UAF. Authenticate for step 2. Prepared STATUS request: '%s' to send to '%s'\" % (uaf_obb_status_request, uaf_obb_server_uri)\n\n uaf_status_obb_response = self.executePost(uaf_obb_server_uri, uaf_obb_status_request)\n if uaf_status_obb_response == None:\n return False\n\n print \"UAF. Authenticate for step 2. Get STATUS response: '%s'\" % uaf_status_obb_response\n uaf_status_obb_response_json = json.loads(uaf_status_obb_response)\n \n if uaf_status_obb_response_json[\"statusCode\"] != 4000:\n print \"UAF. Authenticate for step 2. UAF operation status is invalid. statusCode: '%s'\" % uaf_status_obb_response_json[\"statusCode\"]\n return False\n\n uaf_user_device_handle = uaf_status_obb_response_json[\"additionalInfo\"][\"authenticatorsResult\"][\"handle\"]\n\n if StringHelper.isEmpty(uaf_user_device_handle):\n print \"UAF. Prepare for step 2. Failed to get UAF handle\"\n return False\n\n uaf_user_external_uid = \"uaf:%s\" % uaf_user_device_handle\n print \"UAF. Authenticate for step 2. UAF handle: '%s'\" % uaf_user_external_uid\n\n if uaf_auth_method == \"authenticate\":\n # Validate if user used device with same keYHandle\n user_enrollments = self.findEnrollments(credentials)\n if len(user_enrollments) == 0:\n uaf_auth_method = \"enroll\"\n print \"UAF. Authenticate for step 2. There is no UAF enrollment for user '%s'.\" % user_name\n return False\n \n for user_enrollment in user_enrollments:\n if StringHelper.equalsIgnoreCase(user_enrollment, uaf_user_device_handle):\n print \"UAF. Authenticate for step 2. There is UAF enrollment for user '%s'. User authenticated successfully\" % user_name\n return True\n else:\n userService = CdiUtil.bean(UserService)\n\n # Double check just to make sure. We did checking in previous step\n # Check if there is user which has uaf_user_external_uid\n # Avoid mapping user cert to more than one IDP account\n find_user_by_external_uid = userService.getUserByAttribute(\"oxExternalUid\", uaf_user_external_uid)\n if find_user_by_external_uid == None:\n # Add uaf_user_external_uid to user's external GUID list\n find_user_by_external_uid = userService.addUserAttribute(user_name, \"oxExternalUid\", uaf_user_external_uid)\n if find_user_by_external_uid == None:\n print \"UAF. Authenticate for step 2. Failed to update current user\"\n return False\n \n return True\n\n return False\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n self.setRequestScopedParameters(identity)\n\n if (step == 1):\n return True\n elif (step == 2):\n print \"UAF. Prepare for step 2\"\n\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"UAF. Prepare for step 2. Failed to determine session_id\"\n return False\n\n user = authenticationService.getAuthenticatedUser()\n if (user == None):\n print \"UAF. Prepare for step 2. Failed to determine user name\"\n return False\n\n uaf_auth_method = session_attributes.get(\"uaf_auth_method\")\n if StringHelper.isEmpty(uaf_auth_method):\n print \"UAF. Prepare for step 2. Failed to determine auth_method\"\n return False\n\n print \"UAF. Prepare for step 2. uaf_auth_method: '%s'\" % uaf_auth_method\n\n uaf_obb_auth_method = \"OOB_REG\"\n uaf_obb_server_uri = self.uaf_server_uri + \"/nnl/v2/reg\" \n if StringHelper.equalsIgnoreCase(uaf_auth_method, \"authenticate\"):\n uaf_obb_auth_method = \"OOB_AUTH\"\n uaf_obb_server_uri = self.uaf_server_uri + \"/nnl/v2/auth\" \n\n # Prepare START_OBB\n uaf_obb_start_request_dictionary = { \"operation\": \"START_%s\" % uaf_obb_auth_method,\n \"userName\": user.getUserId(),\n \"policyName\": \"default\",\n \"oobMode\":\n { \"qr\": \"true\", \"rawData\": \"false\", \"push\": \"false\" } \n }\n\n uaf_obb_start_request = json.dumps(uaf_obb_start_request_dictionary, separators=(',',':'))\n print \"UAF. Prepare for step 2. Prepared START request: '%s' to send to '%s'\" % (uaf_obb_start_request, uaf_obb_server_uri)\n\n # Request START_OBB\n uaf_obb_start_response = self.executePost(uaf_obb_server_uri, uaf_obb_start_request)\n if uaf_obb_start_response == None:\n return False\n\n print \"UAF. Prepare for step 2. Get START response: '%s'\" % uaf_obb_start_response\n uaf_obb_start_response_json = json.loads(uaf_obb_start_response)\n\n # Prepare STATUS_OBB\n #TODO: Remove needDetails parameter\n uaf_obb_status_request_dictionary = { \"operation\": \"STATUS_%s\" % uaf_obb_auth_method,\n \"userName\": user.getUserId(),\n \"needDetails\": 1,\n \"oobStatusHandle\": uaf_obb_start_response_json[\"oobStatusHandle\"],\n }\n\n uaf_obb_status_request = json.dumps(uaf_obb_status_request_dictionary, separators=(',',':'))\n print \"UAF. Prepare for step 2. Prepared STATUS request: '%s' to send to '%s'\" % (uaf_obb_status_request, uaf_obb_server_uri)\n\n identity.setWorkingParameter(\"uaf_obb_auth_method\", uaf_obb_auth_method)\n identity.setWorkingParameter(\"uaf_obb_server_uri\", uaf_obb_server_uri)\n identity.setWorkingParameter(\"uaf_obb_start_response\", uaf_obb_start_response)\n identity.setWorkingParameter(\"qr_image\", uaf_obb_start_response_json[\"modeResult\"][\"qrCode\"][\"qrImage\"])\n identity.setWorkingParameter(\"uaf_obb_status_request\", uaf_obb_status_request)\n\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return Arrays.asList(\"uaf_auth_method\", \"uaf_obb_auth_method\", \"uaf_obb_server_uri\", \"uaf_obb_start_response\")\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if (step == 2):\n return \"/auth/uaf/login.xhtml\"\n\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def setRequestScopedParameters(self, identity):\n if self.registration_uri != None:\n identity.setWorkingParameter(\"external_registration_uri\", self.registration_uri)\n identity.setWorkingParameter(\"qr_options\", self.customQrOptions)\n\n def processBasicAuthentication(self, credentials):\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return None\n\n find_user_by_uid = authenticationService.getAuthenticatedUser()\n if find_user_by_uid == None:\n print \"UAF. Process basic authentication. Failed to find user '%s'\" % user_name\n return None\n \n return find_user_by_uid\n\n def findEnrollments(self, credentials):\n result = []\n\n userService = CdiUtil.bean(UserService)\n user_name = credentials.getUsername()\n user = userService.getUser(user_name, \"oxExternalUid\")\n if user == None:\n print \"UAF. Find enrollments. Failed to find user\"\n return result\n \n user_custom_ext_attribute = userService.getCustomAttribute(user, \"oxExternalUid\")\n if user_custom_ext_attribute == None:\n return result\n \n uaf_prefix = \"uaf:\"\n uaf_prefix_length = len(uaf_prefix) \n for user_external_uid in user_custom_ext_attribute.getValues():\n index = user_external_uid.find(uaf_prefix)\n if index != -1:\n enrollment_uid = user_external_uid[uaf_prefix_length:]\n result.append(enrollment_uid)\n \n return result\n\n def executePost(self, request_uri, request_data):\n httpService = CdiUtil.bean(HttpService)\n\n request_headers = { \"Content-type\" : \"application/json; charset=UTF-8\", \"Accept\" : \"application/json\" }\n\n try:\n http_service_response = httpService.executePost(self.http_client, request_uri, None, request_headers, request_data)\n http_response = http_service_response.getHttpResponse()\n except:\n print \"UAF. Validate POST response. Exception: \", sys.exc_info()[1]\n return None\n\n try:\n if not httpService.isResponseStastusCodeOk(http_response):\n print \"UAF. Validate POST response. Get invalid response from server: %s\" % str(http_response.getStatusLine().getStatusCode())\n httpService.consume(http_response)\n return None\n \n response_bytes = httpService.getResponseContent(http_response)\n response_string = httpService.convertEntityToString(response_bytes)\n httpService.consume(http_response)\n \n return response_string\n finally:\n http_service_response.closeConnection()\n return None\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + }, + { + "value2": "interactive", + "value1": "usage_type" + } + ], + "scriptType": "PERSON_AUTHENTICATION", + "name": "uaf", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "https://pujavs4.2.gluu.server", + "value1": "uaf_server_uri" + }, + { + "hide": false, + "value2": "default", + "value1": "uaf_policy_name" + }, + { + "hide": false, + "value2": "{ width: 400, height: 400 }", + "value1": "qr_options" + }, + { + "hide": false, + "value2": "https://pujavs4.2.gluu.server/identity/register", + "value1": "registration_uri" + }, + { + "hide": false, + "value2": "false", + "value1": "send_push_notifaction" + } + ], + "baseDn": "inum=5018-AF9C,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Client authorization UMA RPT Policy for SCIM and Passport", + "locationType": "LDAP", + "dn": "inum=2DAF-F9A5,ou=scripts,o=gluu", + "inum": "2DAF-F9A5", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2017, Gluu\n#\n# Author: Jose Gonzalez\n# Adapted from previous 3.0.1 script of Yuriy Movchan\n#\n# oxConfigurationProperty required:\n# allowed_clients - comma separated list of dns of allowed clients\n# (i.e. the SCIM RP client)\n\nfrom org.gluu.oxauth.model.uma import UmaConstants\nfrom org.gluu.model.uma import ClaimDefinitionBuilder\nfrom org.gluu.model.custom.script.type.uma import UmaRptPolicyType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList, HashSet\nfrom java.lang import String\n\nclass UmaRptPolicy(UmaRptPolicyType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"RPT Policy. Initializing ...\"\n self.clientsSet = self.prepareClientsSet(configurationAttributes)\n print \"RPT Policy. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"RPT Policy. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def getRequiredClaims(self, context):\n json = \"\"\"[\n ]\"\"\"\n return ClaimDefinitionBuilder.build(json)\n\n def authorize(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\n print \"RPT Policy. Authorizing ...\"\n\n client_id=context.getClient().getClientId()\n print \"UmaRptPolicy. client_id = %s\" % client_id\n\n if (StringHelper.isEmpty(client_id)):\n return False\n \n if (self.clientsSet.contains(client_id)):\n print \"UmaRptPolicy. Authorizing client\"\n return True\n else:\n print \"UmaRptPolicy. Client isn't authorized\"\n return False\n\n def getClaimsGatheringScriptName(self, context):\n return UmaConstants.NO_SCRIPT\n\n def prepareClientsSet(self, configurationAttributes):\n clientsSet = HashSet()\n if (not configurationAttributes.containsKey(\"allowed_clients\")):\n return clientsSet\n\n allowedClientsList = configurationAttributes.get(\"allowed_clients\").getValue2()\n if (StringHelper.isEmpty(allowedClientsList)):\n print \"UmaRptPolicy. The property allowed_clients is empty\"\n return clientsSet \n\n allowedClientsListArray = StringHelper.split(allowedClientsList, \",\")\n if (ArrayHelper.isEmpty(allowedClientsListArray)):\n print \"UmaRptPolicy. No clients specified in allowed_clients property\"\n return clientsSet\n \n # Convert to HashSet to quick search\n i = 0\n count = len(allowedClientsListArray)\n while (i < count):\n client = allowedClientsListArray[i]\n clientsSet.add(client)\n i = i + 1\n\n return clientsSet\n", + "enabled": true, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "UMA_RPT_POLICY", + "name": "scim_access_policy", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "1202.f39fd3df-45b8-412b-a628-13ef5c38d453, None", + "value1": "allowed_clients" + } + ], + "baseDn": "inum=2DAF-F9A5,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Client authorization UMA RPT Policy for oxtrust api", + "locationType": "LDAP", + "dn": "inum=OO11-BAFE,ou=scripts,o=gluu", + "inum": "OO11-BAFE", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2017, Gluu\n#\n# Author: Jose Gonzalez\n# Adapted from previous 3.0.1 script of Yuriy Movchan\n#\n# oxConfigurationProperty required:\n# allowed_clients - comma separated list of dns of allowed clients\n# (i.e. the SCIM RP client)\n\nfrom org.gluu.oxauth.model.uma import UmaConstants\nfrom org.gluu.model.uma import ClaimDefinitionBuilder\nfrom org.gluu.model.custom.script.type.uma import UmaRptPolicyType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList, HashSet\nfrom java.lang import String\n\nclass UmaRptPolicy(UmaRptPolicyType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"RPT Policy. Initializing ...\"\n self.clientsSet = self.prepareClientsSet(configurationAttributes)\n print \"RPT Policy. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"RPT Policy. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def getRequiredClaims(self, context):\n json = \"\"\"[\n ]\"\"\"\n return ClaimDefinitionBuilder.build(json)\n\n def authorize(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\n print \"RPT Policy. Authorizing ...\"\n\n client_id=context.getClient().getClientId()\n print \"UmaRptPolicy. client_id = %s\" % client_id\n\n if (StringHelper.isEmpty(client_id)):\n return False\n \n if (self.clientsSet.contains(client_id)):\n print \"UmaRptPolicy. Authorizing client\"\n return True\n else:\n print \"UmaRptPolicy. Client isn't authorized\"\n return False\n\n def getClaimsGatheringScriptName(self, context):\n return UmaConstants.NO_SCRIPT\n\n def prepareClientsSet(self, configurationAttributes):\n clientsSet = HashSet()\n if (not configurationAttributes.containsKey(\"allowed_clients\")):\n return clientsSet\n\n allowedClientsList = configurationAttributes.get(\"allowed_clients\").getValue2()\n if (StringHelper.isEmpty(allowedClientsList)):\n print \"UmaRptPolicy. The property allowed_clients is empty\"\n return clientsSet \n\n allowedClientsListArray = StringHelper.split(allowedClientsList, \",\")\n if (ArrayHelper.isEmpty(allowedClientsListArray)):\n print \"UmaRptPolicy. No clients specified in allowed_clients property\"\n return clientsSet\n \n # Convert to HashSet to quick search\n i = 0\n count = len(allowedClientsListArray)\n while (i < count):\n client = allowedClientsListArray[i]\n clientsSet.add(client)\n i = i + 1\n\n return clientsSet\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "UMA_RPT_POLICY", + "name": "oxtrust_api_access_policy", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "1402.06d4bb9f-b830-44af-bbb2-6bc301448038", + "value1": "allowed_clients" + } + ], + "baseDn": "inum=OO11-BAFE,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Sample Dynamic Scope script for org_name", + "locationType": "LDAP", + "dn": "inum=031C-5621,ou=scripts,o=gluu", + "inum": "031C-5621", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2016, Gluu\r\n#\r\n# Author: Yuriy Movchan\r\n#\r\n\r\nfrom org.gluu.model.custom.script.type.scope import DynamicScopeType\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.util import StringHelper, ArrayHelper\r\nfrom java.util import Arrays, ArrayList\r\n\r\nimport java\r\n\r\nclass DynamicScope(DynamicScopeType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Dynamic scope. Initialization\"\r\n\r\n print \"Dynamic scope. Initialized successfully\"\r\n\r\n return True \r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Dynamic scope. Destroy\"\r\n print \"Dynamic scope. Destroyed successfully\"\r\n return True \r\n\r\n # Update Json Web token before signing/encrypring it\r\n # dynamicScopeContext is org.gluu.oxauth.service.external.context.DynamicScopeExternalContext\r\n # configurationAttributes is java.util.Map\r\n def update(self, dynamicScopeContext, configurationAttributes):\r\n print \"Dynamic scope. Update method\"\r\n\r\n dynamicScopes = dynamicScopeContext.getDynamicScopes()\r\n authorizationGrant = dynamicScopeContext.getAuthorizationGrant()\r\n user = dynamicScopeContext.getUser()\r\n jsonWebResponse = dynamicScopeContext.getJsonWebResponse()\r\n claims = jsonWebResponse.getClaims()\r\n\r\n # Add organization name if there is scope = org_name\r\n claims.setClaim(\"org_name\", \"Gluu, Inc.\")\r\n\r\n return True\r\n\r\n def getSupportedClaims(self, configurationAttributes):\r\n return Arrays.asList(\"org_name\")\r\n\r\n def getApiVersion(self):\r\n return 11\r\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "DYNAMIC_SCOPE", + "name": "org_name", + "modified": false, + "baseDn": "inum=031C-5621,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "locationType": "LDAP", + "dn": "inum=8AF7.D82A,ou=scripts,o=gluu", + "inum": "8AF7.D82A", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2020, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.model.custom.script.type.persistence import PersistenceType\nfrom org.gluu.util import StringHelper\nfrom org.gluu.persist.operation.auth import PasswordEncryptionHelper\nfrom org.gluu.persist.operation.auth import PasswordEncryptionMethod\n\nimport java\n\nclass PersistenceExtension(PersistenceType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Persistence extension. Initialization\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"Persistence extension. Destroy\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def onAfterCreate(self, context, configurationAttributes):\n print \"Persistence extension. Method: onAfterCreate\"\n\n def onAfterDestroy(self, context, configurationAttributes):\n print \"Persistence extension. Method: onAfterDestroy\"\n\n def createHashedPassword(self, credential):\n print \"Persistence extension. Method: createHashedPassword\"\n\n hashed_password= PasswordEncryptionHelper.createStoragePassword(credential, PasswordEncryptionMethod.HASH_METHOD_PKCS5S2)\n\n return hashed_password\n\n def compareHashedPasswords(self, credential, storedCredential):\n print \"Persistence extension. Method: compareHashedPasswords\"\n \n auth_result = PasswordEncryptionHelper.compareCredentials(credential, storedCredential)\n\n return auth_result \n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "PERSISTENCE_EXTENSION", + "name": "persistence_extension", + "modified": false, + "baseDn": "inum=8AF7.D82A,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Sample Cache Refresh script", + "locationType": "LDAP", + "dn": "inum=13D3-E7AD,ou=scripts,o=gluu", + "inum": "13D3-E7AD", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.user import CacheRefreshType\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList\nfrom org.gluu.oxtrust.model import GluuCustomAttribute\nfrom org.gluu.model.custom.script.model.bind import BindCredentials\n\nimport java\n\nclass CacheRefresh(CacheRefreshType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Cache refresh. Initialization\"\n print \"Cache refresh. Initialized successfully\"\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Cache refresh. Destroy\"\n print \"Cache refresh. Destroyed successfully\"\n return True\n\n # Check if this instance conform starting conditions \n # configurationAttributes is java.util.Map\n # return True/False\n def isStartProcess(self, configurationAttributes):\n print \"Cache refresh. Is start process method\"\n\n return False\n \n # Get bind credentials required to access source server \n # configId is the source server\n # configurationAttributes is java.util.Map\n # return None (use password from configuration) or org.gluu.model.custom.script.model.bind.BindCredentials\n def getBindCredentials(self, configId, configurationAttributes):\n print \"Cache refresh. GetBindCredentials method\"\n# if configId == \"source\":\n# return BindCredentials(\"cn=Directory Manager\", \"password\")\n\n return None\n\n # Update user entry before persist it\n # user is org.gluu.oxtrust.model.GluuCustomPerson\n # configurationAttributes is java.util.Map\n def updateUser(self, user, configurationAttributes):\n print \"Cache refresh. UpdateUser method\"\n\n attributes = user.getCustomAttributes()\n\n # Add new attribute preferredLanguage\n attrPrefferedLanguage = GluuCustomAttribute(\"preferredLanguage\", \"en-us\")\n attributes.add(attrPrefferedLanguage)\n\n # Add new attribute userPassword\n attrUserPassword = GluuCustomAttribute(\"userPassword\", \"test\")\n attributes.add(attrUserPassword)\n\n # Update givenName attribute\n for attribute in attributes:\n attrName = attribute.getName()\n if ((\"givenname\" == StringHelper.toLowerCase(attrName)) and StringHelper.isNotEmpty(attribute.getValue())):\n attribute.setValue(StringHelper.removeMultipleSpaces(attribute.getValue()) + \" (updated)\")\n\n return True\n\n def getApiVersion(self):\n return 11\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "CACHE_REFRESH", + "name": "cache_refresh", + "modified": false, + "baseDn": "inum=13D3-E7AD,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Sample Application Session script", + "locationType": "LDAP", + "dn": "inum=DAA9-B789,ou=scripts,o=gluu", + "inum": "DAA9-B789", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.session import ApplicationSessionType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.persist import PersistenceEntryManager\nfrom org.gluu.oxauth.model.config import StaticConfiguration\nfrom org.gluu.oxauth.model.ldap import TokenLdap\nfrom javax.faces.application import FacesMessage\nfrom org.gluu.jsf2.message import FacesMessages\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom org.gluu.oxauth.model.config import Constants\nfrom java.util import Arrays, ArrayList\nfrom org.gluu.oxauth.service.external.session import SessionEventType\n\nimport java\n\nclass ApplicationSession(ApplicationSessionType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Application session. Initialization\"\n\n self.entryManager = CdiUtil.bean(PersistenceEntryManager)\n self.staticConfiguration = CdiUtil.bean(StaticConfiguration)\n\n print \"Application session. Initialized successfully\"\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Application session. Destroy\"\n print \"Application session. Destroyed successfully\"\n return True \n\n def getApiVersion(self):\n return 11\n\n # Called each time specific session event occurs\n # event is org.gluu.oxauth.service.external.session.SessionEvent\n def onEvent(self, event):\n if event.getType() == SessionEventType.AUTHENTICATED:\n print \"Session is authenticated, session: \" + event.getSessionId().getId()\n return\n\n # Application calls it at start session request to allow notify 3rd part systems\n # httpRequest is javax.servlet.http.HttpServletRequest\n # sessionId is org.gluu.oxauth.model.common.SessionId\n # configurationAttributes is java.util.Map\n def startSession(self, httpRequest, sessionId, configurationAttributes):\n print \"Application session. Starting external session\"\n\n user_name = sessionId.getSessionAttributes().get(Constants.AUTHENTICATED_USER)\n\n first_session = self.isFirstSession(user_name)\n if not first_session:\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Please, end active session first!\")\n return False\n\n print \"Application session. External session started successfully\"\n return True\n\n # Application calls it at end session request to allow notify 3rd part systems\n # httpRequest is javax.servlet.http.HttpServletRequest\n # sessionId is org.gluu.oxauth.model.common.SessionId\n # configurationAttributes is java.util.Map\n def endSession(self, httpRequest, sessionId, configurationAttributes):\n print \"Application session. Starting external session end\"\n\n print \"Application session. External session ended successfully\"\n return True\n\n def isFirstSession(self, user_name):\n tokenLdap = TokenLdap()\n tokenLdap.setDn(self.staticConfiguration.getBaseDn().getClients())\n tokenLdap.setUserId(user_name)\n\n tokenLdapList = self.entryManager.findEntries(tokenLdap, 1)\n print \"Application session. isFirstSession. Get result: '%s'\" % tokenLdapList\n\n if (tokenLdapList != None) and (tokenLdapList.size() > 0):\n print \"Application session. isFirstSession: False\"\n return False\n\n print \"Application session. isFirstSession: True\"\n return True\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "APPLICATION_SESSION", + "name": "application_session", + "modified": false, + "baseDn": "inum=DAA9-B789,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Dynamic Scope Script for Super Gluu RO", + "locationType": "LDAP", + "dn": "inum=5866-4202,ou=scripts,o=gluu", + "inum": "5866-4202", + "script": "# Super Gluu Radius Dynamic Scope \n# Copyright (c) 2019 Gluu Inc.\n\nfrom org.gluu.model.custom.script.type.scope import DynamicScopeType\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.service.cdi.util import CdiUtil\n\nimport java\n\nclass DynamicScope(DynamicScopeType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Super-Gluu-DynScope init\"\n self.sessionIdClaimName = \"__session_id\"\n if configurationAttributes.containsKey(\"session_id_claim_name\"):\n self.sessionIdClaimName = configurationAttributes.get(\"session_id_claim_name\").getValue2()\n \n print \"Super-Gluu-DynScope init complete\"\n return True\n \n def destroy(self, configurationAttributes):\n print \"Super-Gluu-DynScope destroy\"\n print \"Super-Gluu-DynScope destroy complete\"\n return True\n \n def update(self, dynamicScopeContext, configurationAttributes):\n # Todo implement this\n print \"Super-Gluu-DynScope update\"\n updated = False\n identity = CdiUtil.bean(Identity)\n if (identity is not None) and (identity.getSessionId() is not None):\n session_id = identity.getSessionId().getId()\n jsonWebResponse = dynamicScopeContext.getJsonWebResponse()\n claims = jsonWebResponse.getClaims()\n claims.setClaim(self.sessionIdClaimName,session_id)\n updated = True\n else:\n print \"Super-Gluu-DynScope. No session id found. Skipping\"\n print \"Super-Gluu-DynScope update complete\"\n return updated\n \n def getApiVersion(self):\n return 11\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "DYNAMIC_SCOPE", + "name": "super_gluu_ro_session", + "modified": false, + "baseDn": "inum=5866-4202,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "locationType": "LDAP", + "dn": "inum=8AF7.D82B,ou=scripts,o=gluu", + "inum": "8AF7.D82B", + "script": "# oxShibboleth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2020, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.idp import IdpType\nfrom org.gluu.util import StringHelper\nfrom org.gluu.idp.externalauth import AuthenticatedNameTranslator\nfrom net.shibboleth.idp.authn.principal import UsernamePrincipal, IdPAttributePrincipal\nfrom net.shibboleth.idp.authn import ExternalAuthentication\nfrom net.shibboleth.idp.attribute import IdPAttribute, StringAttributeValue\nfrom net.shibboleth.idp.authn.context import AuthenticationContext, ExternalAuthenticationContext\nfrom net.shibboleth.idp.attribute.context import AttributeContext\nfrom javax.security.auth import Subject\nfrom java.util import Collections, HashSet, ArrayList, Arrays\n\nimport java\n\nclass IdpExtension(IdpType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Idp extension. Initialization\"\n \n self.defaultNameTranslator = AuthenticatedNameTranslator()\n \n return True\n\n def destroy(self, configurationAttributes):\n print \"Idp extension. Destroy\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Translate attributes from user profile\n # context is org.gluu.idp.externalauth.TranslateAttributesContext (https://github.com/GluuFederation/shib-oxauth-authn3/blob/master/src/main/java/org/gluu/idp/externalauth/TranslateAttributesContext.java)\n # configurationAttributes is java.util.Map\n def translateAttributes(self, context, configurationAttributes):\n print \"Idp extension. Method: translateAttributes\"\n \n # Return False to use default method\n #return False\n \n request = context.getRequest()\n userProfile = context.getUserProfile()\n principalAttributes = self.defaultNameTranslator.produceIdpAttributePrincipal(userProfile.getAttributes())\n print \"Idp extension. Converted user profile: '%s' to attribute principal: '%s'\" % (userProfile, principalAttributes)\n\n if not principalAttributes.isEmpty():\n print \"Idp extension. Found attributes from oxAuth. Processing...\"\n \n # Start: Custom part\n # Add givenName attribute\n givenNameAttribute = IdPAttribute(\"oxEnrollmentCode\")\n givenNameAttribute.setValues(ArrayList(Arrays.asList(StringAttributeValue(\"Dummy\"))))\n principalAttributes.add(IdPAttributePrincipal(givenNameAttribute))\n print \"Idp extension. Updated attribute principal: '%s'\" % principalAttributes\n # End: Custom part\n\n principals = HashSet()\n principals.addAll(principalAttributes)\n principals.add(UsernamePrincipal(userProfile.getId()))\n\n request.setAttribute(ExternalAuthentication.SUBJECT_KEY, Subject(False, Collections.singleton(principals),\n Collections.emptySet(), Collections.emptySet()))\n\n print \"Created an IdP subject instance with principals containing attributes for: '%s'\" % userProfile.getId()\n\n if False:\n idpAttributes = ArrayList()\n for principalAttribute in principalAttributes:\n idpAttributes.add(principalAttribute.getAttribute())\n \n request.setAttribute(ExternalAuthentication.ATTRIBUTES_KEY, idpAttributes)\n \n authenticationKey = context.getAuthenticationKey()\n profileRequestContext = ExternalAuthentication.getProfileRequestContext(authenticationKey, request)\n authContext = profileRequestContext.getSubcontext(AuthenticationContext)\n extContext = authContext.getSubcontext(ExternalAuthenticationContext)\n \n extContext.setSubject(Subject(False, Collections.singleton(principals), Collections.emptySet(), Collections.emptySet()));\n \n extContext.getSubcontext(AttributeContext, True).setUnfilteredIdPAttributes(idpAttributes)\n extContext.getSubcontext(AttributeContext).setIdPAttributes(idpAttributes)\n else:\n print \"No attributes released from oxAuth. Creating an IdP principal for: '%s'\" % userProfile.getId()\n request.setAttribute(ExternalAuthentication.PRINCIPAL_NAME_KEY, userProfile.getId())\n\n #Return True to specify that default method is not needed\n return False\n\n # Update attributes before releasing them\n # context is org.gluu.idp.consent.processor.PostProcessAttributesContext (https://github.com/GluuFederation/shib-oxauth-authn3/blob/master/src/main/java/org/gluu/idp/consent/processor/PostProcessAttributesContext.java)\n # configurationAttributes is java.util.Map\n def updateAttributes(self, context, configurationAttributes):\n print \"Idp extension. Method: updateAttributes\"\n return True\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "IDP", + "name": "idp", + "modified": false, + "baseDn": "inum=8AF7.D82B,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Permission Dynamic Scope script", + "locationType": "LDAP", + "dn": "inum=CB5B-3211,ou=scripts,o=gluu", + "inum": "CB5B-3211", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2016, Gluu\r\n#\r\n# Author: Yuriy Movchan\r\n#\r\n\r\nfrom org.gluu.model.custom.script.type.scope import DynamicScopeType\r\nfrom org.gluu.service.cdi.util import CdiUtil\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.util import StringHelper, ArrayHelper\r\nfrom java.util import Arrays, ArrayList\r\n\r\nimport java\r\n\r\nclass DynamicScope(DynamicScopeType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Permission dynamic scope. Initialization\"\r\n\r\n print \"Permission dynamic scope. Initialized successfully\"\r\n\r\n return True \r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Permission dynamic scope. Destroy\"\r\n print \"Permission dynamic scope. Destroyed successfully\"\r\n return True \r\n\r\n # Update Json Web token before signing/encrypring it\r\n # dynamicScopeContext is org.gluu.oxauth.service.external.context.DynamicScopeExternalContext\r\n # configurationAttributes is java.util.Map\r\n def update(self, dynamicScopeContext, configurationAttributes):\r\n print \"Permission dynamic scope scope. Update method\"\r\n\r\n authorizationGrant = dynamicScopeContext.getAuthorizationGrant()\r\n user = dynamicScopeContext.getUser()\r\n jsonWebResponse = dynamicScopeContext.getJsonWebResponse()\r\n claims = jsonWebResponse.getClaims()\r\n\r\n userService = CdiUtil.bean(UserService)\r\n roles = userService.getCustomAttribute(user, \"role\")\r\n if roles != None:\r\n claims.setClaim(\"role\", roles.getValues())\r\n\r\n return True\r\n\r\n def getSupportedClaims(self, configurationAttributes):\r\n return Arrays.asList(\"role\")\r\n\r\n def getApiVersion(self):\r\n return 11\r\n", + "enabled": true, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "DYNAMIC_SCOPE", + "name": "dynamic_permission", + "modified": false, + "baseDn": "inum=CB5B-3211,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Sample script for SCIM events", + "locationType": "LDAP", + "dn": "inum=A910-56AB,ou=scripts,o=gluu", + "inum": "A910-56AB", + "script": "# oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2014, Gluu\n#\n# Author: Jose Gonzalez\n#\nfrom org.gluu.model.custom.script.type.scim import ScimType\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList\nfrom org.gluu.oxtrust.ldap.service import PersonService\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxtrust.model import GluuCustomPerson\n\nimport java\n\nclass ScimEventHandler(ScimType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"ScimEventHandler (init): Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"ScimEventHandler (destroy): Destroyed successfully\"\n return True \n\n def getApiVersion(self):\n #return 2 if you want the post* scripts being executed\n return 11\n\n def createUser(self, user, configurationAttributes):\n\n print \"ScimEventHandler (createUser): Current id = \" + user.getUid()\n\n testProp1 = configurationAttributes.get(\"testProp1\").getValue2()\n testProp2 = configurationAttributes.get(\"testProp2\").getValue2()\n\n print \"ScimEventHandler (createUser): testProp1 = \" + testProp1\n print \"ScimEventHandler (createUser): testProp2 = \" + testProp2\n\n return True\n\n def updateUser(self, user, configurationAttributes):\n personService = CdiUtil.bean(PersonService)\n oldUser = personService.getPersonByUid(user.getUid())\n print \"ScimEventHandler (updateUser): Old displayName %s\" % oldUser.getDisplayName()\n print \"ScimEventHandler (updateUser): New displayName \" + user.getDisplayName()\n return True\n\n def deleteUser(self, user, configurationAttributes):\n print \"ScimEventHandler (deleteUser): Current id = \" + user.getUid()\n return True\n\n def createGroup(self, group, configurationAttributes):\n print \"ScimEventHandler (createGroup): Current displayName = \" + group.getDisplayName()\n return True\n\n def updateGroup(self, group, configurationAttributes):\n print \"ScimEventHandler (updateGroup): Current displayName = \" + group.getDisplayName()\n return True\n\n def deleteGroup(self, group, configurationAttributes):\n print \"ScimEventHandler (deleteGroup): Current displayName = \" + group.getDisplayName()\n return True\n \n def postCreateUser(self, user, configurationAttributes):\n return True\n\n def postUpdateUser(self, user, configurationAttributes):\n return True\n\n def postDeleteUser(self, user, configurationAttributes):\n return True\n\n def postUpdateGroup(self, group, configurationAttributes):\n return True\n\n def postCreateGroup(self, group, configurationAttributes):\n return True\n\n def postDeleteGroup(self, group, configurationAttributes):\n return True", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "SCIM", + "name": "scim_event_handler", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "Test value 1", + "value1": "testProp1" + }, + { + "hide": false, + "value2": "Test value 2", + "value1": "testProp2" + } + ], + "baseDn": "inum=A910-56AB,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Sample Id Generator script", + "locationType": "LDAP", + "dn": "inum=031C-4A65,ou=scripts,o=gluu", + "inum": "031C-4A65", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.id import IdGeneratorType\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList\n\nimport java\n\nclass IdGenerator(IdGeneratorType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Id generator. Initialization\"\n print \"Id generator. Initialized successfully\"\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Id generator. Destroy\"\n print \"Id generator. Destroyed successfully\"\n return True \n\n def getApiVersion(self):\n return 11\n\n # Id generator init method\n # appId is application Id\n # idType is Id Type\n # idPrefix is Id Prefix\n # user is org.gluu.oxtrust.model.GluuCustomPerson\n # configurationAttributes is java.util.Map\n def generateId(self, appId, idType, idPrefix, configurationAttributes):\n print \"Id generator. Generate Id\"\n print \"Id generator. Generate Id. AppId: '\", appId, \"', IdType: '\", idType, \"', IdPrefix: '\", idPrefix, \"'\"\n\n # Return None or empty string to trigger default Id generation method\n return None\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "ID_GENERATOR", + "name": "id_generator", + "modified": false, + "baseDn": "inum=031C-4A65,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Sample Client Registration script", + "locationType": "LDAP", + "dn": "inum=DAA9-B788,ou=scripts,o=gluu", + "inum": "DAA9-B788", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.client import ClientRegistrationType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.service import ScopeService\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList, HashSet\n\nimport java\n\nclass ClientRegistration(ClientRegistrationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Client registration. Initialization\"\n \n self.clientRedirectUrisSet = self.prepareClientRedirectUris(configurationAttributes)\n\n print \"Client registration. Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"Client registration. Destroy\"\n print \"Client registration. Destroyed successfully\"\n return True \n\n # Update client entry before persistent it\n # registerRequest is org.gluu.oxauth.client.RegisterRequest\n # client is org.gluu.oxauth.model.registration.Client\n # configurationAttributes is java.util.Map\n def createClient(self, registerRequest, client, configurationAttributes):\n print \"Client registration. CreateClient method\"\n\n redirectUris = client.getRedirectUris()\n print \"Client registration. Redirect Uris: %s\" % redirectUris\n\n addAddressScope = False\n for redirectUri in redirectUris:\n if (self.clientRedirectUrisSet.contains(redirectUri)):\n addAddressScope = True\n break\n \n print \"Client registration. Is add address scope: %s\" % addAddressScope\n\n if addAddressScope:\n currentScopes = client.getScopes()\n print \"Client registration. Current scopes: %s\" % currentScopes\n \n scopeService = CdiUtil.bean(ScopeService)\n addressScope = scopeService.getScopeByDisplayName(\"address\")\n newScopes = ArrayHelper.addItemToStringArray(currentScopes, addressScope.getDn())\n \n print \"Client registration. Result scopes: %s\" % newScopes\n client.setScopes(newScopes)\n\n return True\n\n # Update client entry before persistent it\n # registerRequest is org.gluu.oxauth.client.RegisterRequest\n # client is org.gluu.oxauth.model.registration.Client\n # configurationAttributes is java.util.Map\n def updateClient(self, registerRequest, client, configurationAttributes):\n print \"Client registration. UpdateClient method\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def prepareClientRedirectUris(self, configurationAttributes):\n clientRedirectUrisSet = HashSet()\n if not configurationAttributes.containsKey(\"client_redirect_uris\"):\n return clientRedirectUrisSet\n\n clientRedirectUrisList = configurationAttributes.get(\"client_redirect_uris\").getValue2()\n if StringHelper.isEmpty(clientRedirectUrisList):\n print \"Client registration. The property client_redirect_uris is empty\"\n return clientRedirectUrisSet \n\n clientRedirectUrisArray = StringHelper.split(clientRedirectUrisList, \",\")\n if ArrayHelper.isEmpty(clientRedirectUrisArray):\n print \"Client registration. No clients specified in client_redirect_uris property\"\n return clientRedirectUrisSet\n \n # Convert to HashSet to quick search\n i = 0\n count = len(clientRedirectUrisArray)\n while i < count:\n uris = clientRedirectUrisArray[i]\n clientRedirectUrisSet.add(uris)\n i = i + 1\n\n return clientRedirectUrisSet\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "CLIENT_REGISTRATION", + "name": "client_registration", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "https://client.example.com/example1, https://client.example.com/example2", + "value1": "client_redirect_uris" + } + ], + "baseDn": "inum=DAA9-B788,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Sample Dynamic Scope script for work_phone", + "locationType": "LDAP", + "dn": "inum=031C-5622,ou=scripts,o=gluu", + "inum": "031C-5622", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2016, Gluu\r\n#\r\n# Author: Yuriy Movchan\r\n#\r\n\r\nfrom org.gluu.model.custom.script.type.scope import DynamicScopeType\r\nfrom org.gluu.service.cdi.util import CdiUtil\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.util import StringHelper, ArrayHelper\r\nfrom java.util import Arrays, ArrayList\r\n\r\nimport java\r\n\r\nclass DynamicScope(DynamicScopeType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Dynamic scope. Initialization\"\r\n\r\n print \"Dynamic scope. Initialized successfully\"\r\n\r\n return True \r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Dynamic scope. Destroy\"\r\n print \"Dynamic scope. Destroyed successfully\"\r\n return True \r\n\r\n # Update Json Web token before signing/encrypring it\r\n # dynamicScopeContext is org.gluu.oxauth.service.external.context.DynamicScopeExternalContext\r\n # configurationAttributes is java.util.Map\r\n def update(self, dynamicScopeContext, configurationAttributes):\r\n print \"Dynamic scope. Update method\"\r\n\r\n dynamicScopes = dynamicScopeContext.getDynamicScopes()\r\n authorizationGrant = dynamicScopeContext.getAuthorizationGrant()\r\n user = dynamicScopeContext.getUser()\r\n jsonWebResponse = dynamicScopeContext.getJsonWebResponse()\r\n claims = jsonWebResponse.getClaims()\r\n\r\n # Add work phone if there is scope = work_phone\r\n userService = CdiUtil.bean(UserService)\r\n workPhone = userService.getCustomAttribute(user, \"telephoneNumber\")\r\n if workPhone != None:\r\n claims.setClaim(\"work_phone\", workPhone.getValues())\r\n\r\n return True\r\n\r\n def getSupportedClaims(self, configurationAttributes):\r\n return Arrays.asList(\"work_phone\")\r\n\r\n def getApiVersion(self):\r\n return 11\r\n", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "DYNAMIC_SCOPE", + "name": "work_phone", + "modified": false, + "baseDn": "inum=031C-5622,ou=scripts,o=gluu" + }, + { + "internal": false, + "level": 100, + "programmingLanguage": "PYTHON", + "description": "Sample UMA RPT Policy", + "locationType": "LDAP", + "dn": "inum=2DAF-F995,ou=scripts,o=gluu", + "inum": "2DAF-F995", + "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2017, Gluu\r\n#\r\n# Author: Yuriy Zabrovarnyy\r\n#\r\n# Call sequence\r\n# 1. First is call constructor of the Script __init__\r\n# 2. Next init() method\r\n# 3. Next getRequiredClaims() - method returns required claims, so UMA engine checks whether\r\n# in request RP provided all claims that are required. Pay attention that there can be\r\n# multiple scripts bound to the scopes, means that UMA engine will build set of required claims\r\n# from all scripts. If not all claims are provided need_info error is sent to RP.\r\n# During need_info construction getClaimsGatheringScriptName() method is called\r\n# 4. authorize() method is called if all required claims are provided.\r\n# 5. destroy()\r\n\r\nfrom org.gluu.model.custom.script.type.uma import UmaRptPolicyType\r\nfrom org.gluu.model.uma import ClaimDefinitionBuilder\r\nfrom java.lang import String\r\n\r\nclass UmaRptPolicy(UmaRptPolicyType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"RPT Policy. Initializing ...\"\r\n print \"RPT Policy. Initialized successfully\"\r\n\r\n return True\r\n\r\n def destroy(self, configurationAttributes):\r\n print \"RPT Policy. Destroying ...\"\r\n print \"RPT Policy. Destroyed successfully\"\r\n return True\r\n\r\n def getApiVersion(self):\r\n return 11\r\n\r\n # Returns required claims definitions.\r\n # This method must provide definition of all claims that is used in 'authorize' method.\r\n # Note : name in both places must match.\r\n # %1$s - placeholder for issuer. It uses standard Java Formatter, docs : https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html\r\n def getRequiredClaims(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\r\n json = \"\"\"[\r\n {\r\n \"issuer\" : [ \"%1$s\" ],\r\n \"name\" : \"country\",\r\n \"claim_token_format\" : [ \"http://openid.net/specs/openid-connect-core-1_0.html#IDToken\" ],\r\n \"claim_type\" : \"string\",\r\n \"friendly_name\" : \"country\"\r\n },\r\n {\r\n \"issuer\" : [ \"%1$s\" ],\r\n \"name\" : \"city\",\r\n \"claim_token_format\" : [ \"http://openid.net/specs/openid-connect-core-1_0.html#IDToken\" ],\r\n \"claim_type\" : \"string\",\r\n \"friendly_name\" : \"city\"\r\n }\r\n ]\"\"\"\r\n context.addRedirectUserParam(\"customUserParam1\", \"value1\") # pass some custom parameters to need_info uri. It can be removed if you don't need custom parameters.\r\n return ClaimDefinitionBuilder.build(String.format(json, context.getIssuer()))\r\n\r\n # Main authorization method. Must return True or False.\r\n def authorize(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\r\n print \"RPT Policy. Authorizing ...\"\r\n\r\n if context.getClaim(\"country\") == 'US' and context.getClaim(\"city\") == 'NY':\r\n print \"Authorized successfully!\"\r\n return True\r\n\r\n return False\r\n\r\n # Returns name of the Claims-Gathering script which will be invoked if need_info error is returned.\r\n def getClaimsGatheringScriptName(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\r\n context.addRedirectUserParam(\"customUserParam2\", \"value2\") # pass some custom parameters to need_info uri. It can be removed if you don't need custom parameters.\r\n return \"sampleClaimsGathering\"", + "enabled": false, + "revision": 1, + "moduleProperties": [ + { + "value2": "ldap", + "value1": "location_type" + } + ], + "scriptType": "UMA_RPT_POLICY", + "name": "uma_rpt_policy", + "modified": false, + "configurationProperties": [ + { + "hide": false, + "value2": "1202.f39fd3df-45b8-412b-a628-13ef5c38d453, None", + "value1": "allowed_clients" + } + ], + "baseDn": "inum=2DAF-F995,ou=scripts,o=gluu" + } +] \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/custom.feature b/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/custom.feature new file mode 100644 index 00000000000..2bee94d9729 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/custom.feature @@ -0,0 +1,103 @@ +Feature: Verify Custom Script configuration endpoint + + Background: + * def mainUrl = scriptsUrl + + + @scripts-get + Scenario: Retrieve Custom Script configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + + @scripts-get + Scenario: Retrieve Custom Script configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @scripts-get-custom-script-by-name + Scenario: Fetch all custom scripts by name + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.entries[0] + And print 'Script inum = '+response.entries[0].name + And assert response.entries[0].name != null + And print 'Script Name = '+response.entries[0].name + And print 'Fetching script by name' + '-' +response.entries[0].name + Given url mainUrl + '/name' + '/'+response.entries[0].name + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @scripts-get-person-custom-scripts + Scenario: Fetch all person custom script + Given url mainUrl + '/type' + And path 'person_authentication' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @scripts-get-introspection-custom-scripts + Scenario: Fetch all introspection scripts + Given url mainUrl + '/type' + And path 'introspection' + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + Scenario: Patch person custom script by inum + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + And print response.entries[0] + And print 'Script inum = '+response.entries[0].inum + And assert response.entries[0].inum != null + And print 'Script Type = '+response.entries[0].scriptType + And print 'Patching script ' + '-' +response.entries[0].scriptType + '-' +response.entries[0].inum + Given url mainUrl + '/'+response.entries[0].inum + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And def request_body = "[ {\"op\":\"replace\", \"path\": \"/enabled\", \"value\":"+response.entries[0].enabled+" } ]" + And print 'request_body ='+request_body + And request request_body + When method PATCH + Then status 200 + And print response + And assert response.length !=0 + + + Scenario: Post person custom script by inum + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request read('post-script.json') + When method POST + Then status 201 + And print response + And print response.inum + And print 'Delete newly created script' + Given url mainUrl + '/' +response.inum + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + And print response \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/post-script.json b/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/post-script.json new file mode 100644 index 00000000000..a4c0beea841 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/scripts/custom/generic/post-script.json @@ -0,0 +1,17 @@ +{ +"internal": false, +"level": 1, +"programmingLanguage": "PYTHON", +"description": "Introspection Custom Parameters Sample Script", +"enabled": false, +"revision": 1, +"moduleProperties": [ + { + "value2": "db", + "value1": "location_type" + } +], +"scriptType": "INTROSPECTION", +"name": "introspection_custom_params", +"modified": false +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/scripts/custom/persons/person-script.json b/jans-config-api/server/src/test/resources/json/config/scripts/custom/persons/person-script.json new file mode 100644 index 00000000000..72b3497b0e1 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/scripts/custom/persons/person-script.json @@ -0,0 +1,26 @@ +{ + "configurationProperties": [], + "description": "QAAdded Person Script description", + "enabled": false, + "internal": false, + "level": 30, + "locationType": "db", + "modified": false, + "moduleProperties": [ + { + "description": "", + "value1": "location_type", + "value2": "db" + }, + { + "description": "", + "value1": "usage_type", + "value2": "interactive" + } + ], + "name": "QAAddedPersonScript", + "programmingLanguage": "python", + "revision": 1, + "script": "QaAdded Person Script Content", + "scriptType": "person_authentication" +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/config/scripts/custom/persons/person-scripts.feature b/jans-config-api/server/src/test/resources/json/config/scripts/custom/persons/person-scripts.feature new file mode 100644 index 00000000000..47163507930 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/scripts/custom/persons/person-scripts.feature @@ -0,0 +1,122 @@ + +Feature: Person Custom Scripts + +Background: + * def mainUrl = scriptsUrl + +Scenario: Fetch all person custom scripts without bearer token +Given url mainUrl + '/type' +And path 'person_authentication' +When method GET +Then status 401 +And print response + + +Scenario: Fetch all person custom scripts +Given url mainUrl + '/type' +And header Authorization = 'Bearer ' + accessToken +And path 'person_authentication' +When method GET +Then status 200 +And print response +And assert response.length != null +And assert response.entries[0].scriptType == 'person_authentication' + + +Scenario: Fetch the first three person custom scripts +Given url mainUrl + '/type' +And header Authorization = 'Bearer ' + accessToken +And path 'person_authentication' +And params ({ limit: 3}) +When method GET +And print response +Then status 200 +And assert response.entries.length == 3 +And assert response.entries[0].scriptType == 'person_authentication' + + +Scenario: Search person custom scripts given a serach pattern +Given url mainUrl + '/type' +And header Authorization = 'Bearer ' + accessToken +And path 'person_authentication' +And params ({ limit: 3,pattern:'fido2'}) +When method GET +And print response +Then status 200 +And assert response.entries.length <= 3 +And assert response.entries[0].scriptType == 'person_authentication' + +@ignore +@CreateUpdateDelete +Scenario: Create new Person Script +Given url mainUrl + '/type' +And header Authorization = 'Bearer ' + accessToken +And path 'person_authentication' +When method GET +And print response +Then status 200 +And assert response.length != 0 +And assert response.entries[0].scriptType == 'person_authentication' +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And def testScript = response.entries[0] +And print "testScript before = "+testScript +And testScript.inum = null +And testScript.dn = null +And testScript.name = "Test_PERSON_AUTHENTICATION" +And testScript.description = "Test_PERSON_AUTHENTICATION_description" +And print "testScript after = "+testScript +And request testScript +When method POST +And print response +Then status 201 +Then def result = response +Then set result.name = 'UpdatedQAAddedPersonScript' +Then def inum_before = result.inum +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And request result +When method PUT +And print response +Then status 200 +And assert response.name == 'UpdatedQAAddedPersonScript' +And assert response.inum == inum_before +Given url mainUrl + '/' +response.inum +And header Authorization = 'Bearer ' + accessToken +And print response +When method DELETE +Then status 204 + + +Scenario: Delete a non-existing person custom script by inum +Given url mainUrl + '/1402.66633-8675-473e-a749' +And header Authorization = 'Bearer ' + accessToken +When method DELETE +And print response +Then status 404 + + +Scenario: Get a person custom script by inum(unexisting person script) +#Given url mainUrl + '/53553532727272772' +Given url mainUrl + '/inum/53553532727272772' +And header Authorization = 'Bearer ' + accessToken +When method GET +And print response +Then status 404 + + +Scenario: Get a person custom script by inum +Given url mainUrl + '/type' +And header Authorization = 'Bearer ' + accessToken +And path 'person_authentication' +When method GET +And print response +Then status 200 +And print response.entries[0].inum +Given url mainUrl + '/inum/'+response.entries[0].inum +And header Authorization = 'Bearer ' + accessToken +And print request +When method GET +And print response +Then status 200 +And assert response.scriptType == 'person_authentication' diff --git a/jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.feature b/jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.feature new file mode 100644 index 00000000000..28ecbbed44a --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.feature @@ -0,0 +1,59 @@ + +Feature: Verify Default ACRS configuration endpoint + + Background: + * def mainUrl = acrsUrl + + @acrs-get-error + Scenario: Retrieve ACRS configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + @acrs-get + Scenario: Retrieve Default ACRS configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + @ignore + @acrs-put + Scenario: Update Default ACRS configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def first_response = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 200 + And print response + And assert response.length != null + + @ignore + @acrs-error + Scenario: Default Authentication Mode configuration cannot be null or blank + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def result = response + Then set result.defaultAcr = null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 400 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.json b/jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.json new file mode 100644 index 00000000000..44b246679fd --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.json @@ -0,0 +1,3 @@ +{ + "defaultAcr": "simple_password_auth" +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/health/auth-server-health.feature b/jans-config-api/server/src/test/resources/json/health/auth-server-health.feature new file mode 100644 index 00000000000..4e993f3ce1e --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/health/auth-server-health.feature @@ -0,0 +1,13 @@ + +Feature: Verify API HealthCheck + +Background: +* def mainUrl = auth_health_url + + Scenario: Verify all stats of the health + Given url mainUrl + When method GET + Then status 200 + And print response + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/health/config-api-health.feature b/jans-config-api/server/src/test/resources/json/health/config-api-health.feature new file mode 100644 index 00000000000..66e3e5cc1ea --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/health/config-api-health.feature @@ -0,0 +1,32 @@ + +Feature: Verify API HealthCheck + +Background: + * def mainUrl = healthUrl + * def health_schema = { name: '#string', status: '#string' } + * def status_str = 'UP' + * def response_str = [{"name": "jans-config-api liveness","status": "UP"},{"name": "jans-config-api readiness","status": "UP"}] + * def live_str = [{"name": "jans-config-api liveness","status": "UP"}] + * def ready_str = [{"name": "jans-config-api readiness","status": "UP"}] + + Scenario: Verify all stats of the health + Given url mainUrl + When method GET + Then status 200 + And print response + + + Scenario: Verify liveness status of API + Given url mainUrl + '/live/' + When method GET + Then status 200 + And print response + + Scenario: Verify readiness status of API + Given url mainUrl + '/ready/' + When method GET + Then status 200 + And print response + + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/health/server-health.feature b/jans-config-api/server/src/test/resources/json/health/server-health.feature new file mode 100644 index 00000000000..4b7d44306a7 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/health/server-health.feature @@ -0,0 +1,14 @@ + +Feature: Verify Server stats + +Background: + * def mainUrl = healthUrl + "/server-stat" + + Scenario: Verify Underlying server stats + Given url mainUrl + When method GET + Then status 200 + And print response + + + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/logging/logging.feature b/jans-config-api/server/src/test/resources/json/logging/logging.feature new file mode 100644 index 00000000000..74ab57b7431 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/logging/logging.feature @@ -0,0 +1,37 @@ + +Feature: Logging connection configuration + + Background: + * def mainUrl = logging_url + + + Scenario: Retrieve logging configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + + Scenario: Retrieve logging configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + Scenario: Update logging configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Then def first_response = response + And header Authorization = 'Bearer ' + accessToken + And request first_response + When method PUT + Then status 200 + And print response + \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/plugins/plugin-all.json b/jans-config-api/server/src/test/resources/json/plugins/plugin-all.json new file mode 100644 index 00000000000..d2055ab6f4b --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/plugins/plugin-all.json @@ -0,0 +1,14 @@ +[ + { + "name": "fido2", + "description": "fido2 plugin" + }, + { + "name": "scim", + "description": "scim plugin" + }, + { + "name": "user-management", + "description": "user-management plugin" + } +] \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/plugins/plugin.feature b/jans-config-api/server/src/test/resources/json/plugins/plugin.feature new file mode 100644 index 00000000000..42d9c06ec02 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/plugins/plugin.feature @@ -0,0 +1,30 @@ + +Feature: Plugins + +Background: +* def mainUrl = plugin_url + +Scenario: Fetch all plugin without bearer token +Given url mainUrl +When method GET +Then status 401 + + +Scenario: Fetch all plugin_url +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +And print response +And assert response.length != null + + +Scenario: Fetch plugin based on name +Given url mainUrl + '/fido2' +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +And print response + + + diff --git a/jans-config-api/server/src/test/resources/json/session/session.feature b/jans-config-api/server/src/test/resources/json/session/session.feature new file mode 100644 index 00000000000..12b7e4bfaa0 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/session/session.feature @@ -0,0 +1,52 @@ + +Feature: Session flow + +Background: +* def mainUrl = session_url + +Scenario: Fetch all session + Given url mainUrl + When method GET + Then status 401 + And print response + +@ignore +Scenario: Fetch all session + Given url mainUrl + And print 'accessToken = '+accessToken + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + +@ignore +Scenario: Fetch all session +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +Given url mainUrl + '/search' +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +And print response + + +@ignore +Scenario: Revoke user session + Given url mainUrl + And print 'accessToken = '+accessToken + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + Then def result = response[0] + And print result + And def userDn = result.userDn + Given url mainUrl + '/' +userDn + And header Authorization = 'Bearer ' + accessToken + And request {} + When method POST + Then status 200 + And print response + diff --git a/jans-config-api/server/src/test/resources/json/smtp/smtp.feature b/jans-config-api/server/src/test/resources/json/smtp/smtp.feature new file mode 100644 index 00000000000..477d5ad7478 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/smtp/smtp.feature @@ -0,0 +1,54 @@ + +Feature: Configure SMTP server + + Background: + * def mainUrl = smtp_url + + @get-smtp-config + Scenario: Get SMTP server details + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @CreateGetUpdateDelete + Scenario: Setup SMTP configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And def smtpConf = (response.length != null ? response : read('smtp.json')) + And print smtpConf + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request smtpConf + When method POST + Then status 201 + And print response + Then def result = response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request result + When method PUT + Then status 200 + And print response + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method DELETE + Then status 204 + And print response + + @ignore + @test-smtp-config + Scenario: Get SMTP server details + Given url mainUrl +'/test' + And header Authorization = 'Bearer ' + accessToken + And request read('smtp.json') + When method POST + Then status 200 + And print response + And assert response.length != null diff --git a/jans-config-api/server/src/test/resources/json/smtp/smtp.json b/jans-config-api/server/src/test/resources/json/smtp/smtp.json new file mode 100644 index 00000000000..2977149bb78 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/smtp/smtp.json @@ -0,0 +1,12 @@ +{ + "fromEmailAddress": "test@gmail.com", + "fromName": "QA-TESTER", + "host": "smtp.gmail.com", + "password": "password", + "port": 587, + "requiresAuthentication": true, + "requiresSsl": true, + "serverTrust": true, + "userName": "test@gmail.com", + "valid": true +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/stat/stat.feature b/jans-config-api/server/src/test/resources/json/stat/stat.feature new file mode 100644 index 00000000000..ccbeaeba473 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/stat/stat.feature @@ -0,0 +1,24 @@ +@ignore + +Feature: Statistics + +Background: +* def mainUrl = statUrl + +Scenario: Fetch all statistics without bearer token + Given url mainUrl + And param month = '202107' + When method GET + Then status 401 + +Scenario: Fetch user statistics + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And param month = '202107' + #And param format = 'openmetrics' + When method GET + Then status 200 + And print response + + + diff --git a/jans-config-api/server/src/test/resources/json/token/client-token.feature b/jans-config-api/server/src/test/resources/json/token/client-token.feature new file mode 100644 index 00000000000..edb945da958 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/token/client-token.feature @@ -0,0 +1,27 @@ + +Feature: Token flow + +Background: +* def mainUrl = token_url + + +Scenario: Fetch all client token +Given url mainUrl +When method GET +Then status 401 +And print response + +@ignore +Scenario: Fetch all token +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +Given url mainUrl + '/search' +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +And print response + + + diff --git a/jans-config-api/server/src/test/resources/json/uma/resource/resources.feature b/jans-config-api/server/src/test/resources/json/uma/resource/resources.feature new file mode 100644 index 00000000000..183feb743cd --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/uma/resource/resources.feature @@ -0,0 +1,107 @@ + +Feature: Uma Resource + + Background: + * def mainUrl = umaresources_url + +Scenario: Fetch all uma resources without bearer token +Given url mainUrl +When method GET +Then status 401 + + +Scenario: Fetch all uma resources +Given url mainUrl +And print accessToken +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +And print response +#And assert response.length != null + + +Scenario: Fetch the first two uma resources +Given url mainUrl +And print accessToken +And header Authorization = 'Bearer ' + accessToken +And param limit = 2 +When method GET +Then status 200 +Then print response +#And assert response.length == 2 + + +Scenario: Search uma resources given a search pattern +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And param pattern = 'Passport Resource' +When method GET +Then status 200 +#And assert response.length == 1 + + +@CreateUpdateDelete +Scenario: Create new Uma Resource +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And request read('uma-resource.json') +When method POST +Then status 201 +And print response +Then def result = response +Then set result.name = 'UpdatedQAAddedResource' +Then def id_before = result.id +Given url mainUrl + '/' +response.id +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +And print response +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And request result +When method PUT +Then status 200 +And print response +And assert response.name == 'UpdatedQAAddedResource' +And assert response.id == id_before +Given url mainUrl + '/' +response.id +And header Authorization = 'Bearer ' + accessToken +And header Content-Type = 'application/json-patch+json' +And header Accept = 'application/json' +And def newName = response.name +And print " newName = "+newName +And request "[ {\"op\":\"replace\", \"path\": \"/description\", \"value\":\""+newName+"\"} ]" +When method PATCH +Then status 200 +And print response +And assert response.length !=0 +Given url mainUrl + '/' +response.id +And header Authorization = 'Bearer ' + accessToken +When method DELETE +Then status 204 + + +Scenario: Delete a non-existion uma resource by id +Given url mainUrl + '/1402.66633-8675-473e-a749' +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 404 + + +Scenario: Get an uma resource by id(unexisting resource) +Given url mainUrl + '/53553532727272772' +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 404 + + +@ignore +Scenario: Get an uma resource by id +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 +Given url mainUrl + '/' +response[0].id +And header Authorization = 'Bearer ' + accessToken +When method GET +Then status 200 diff --git a/jans-config-api/server/src/test/resources/json/uma/resource/uma-resource.json b/jans-config-api/server/src/test/resources/json/uma/resource/uma-resource.json new file mode 100644 index 00000000000..39a5a98bb35 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/uma/resource/uma-resource.json @@ -0,0 +1,16 @@ + { + "clients": [ + ], + "deletable": false, + "expired": false, + "iconUri": "http://www.qa.org/qa_logo.png", + "name": "QAAddedResource", + "description": "QAAdded Resource", + "resources": [ + "https://gluu.gasmyr.com/identity/restv1/passport/config" + ], + "rev": "0", + "scopes": [ + "inum=8CAD-B06E,ou=scopes,o=gluu" + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/uma/scopes/uma-scope.json b/jans-config-api/server/src/test/resources/json/uma/scopes/uma-scope.json new file mode 100644 index 00000000000..c3baf346f20 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/uma/scopes/uma-scope.json @@ -0,0 +1,10 @@ +{ + "attributes": { + "notShowInDiscovery": true + }, + "displayName": "QAAddedUmaScope", + "id": "https://gluu.qa.com/jans-auth/restv1/uma/scopes/qa-scope", + "scopeType": "UMA", + "umaAuthorizationPolicies": [], + "umaType": true +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/uma/scopes/umascopes.feature b/jans-config-api/server/src/test/resources/json/uma/scopes/umascopes.feature new file mode 100644 index 00000000000..5abf737aa07 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/uma/scopes/umascopes.feature @@ -0,0 +1,118 @@ + +Feature: Uma Scopes + +Background: +* def mainUrl = scopes_url + + +Scenario: Fetch all uma scopes without bearer token +Given url mainUrl +When method GET +Then status 401 + + +Scenario: Fetch all uma scopes +Given url mainUrl +And print accessToken +And header Authorization = 'Bearer ' + accessToken +And param type = 'uma' +When method GET +Then status 200 +And print response +And assert response.length != null + + +Scenario: Fetch the first three uma scopes +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And param type = 'uma' +And param limit = 3 +When method GET +Then status 200 +And print response +#And assert response.length <= 3 + + +Scenario: Search uma scopes given a search pattern +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And param type = 'uma' +And param pattern = 'SCIM Access' +When method GET +Then status 200 +And print response +#And assert response.length == 1 + + +@CreateUpdateDelete +Scenario: Create new Uma Scope +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And request read('uma-scope.json') +When method POST +Then status 201 +And print response +Then def result = response +Then set result.displayName = 'UpdatedQAAddedUmaScope' +Then def inum_before = result.inum +Given url mainUrl + '/' +result.inum +And header Authorization = 'Bearer ' + accessToken +And param type = 'uma' +When method GET +Then status 200 +And print response +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And request result +When method PUT +Then status 200 +And print response +And assert response.displayName == 'UpdatedQAAddedUmaScope' +And assert response.inum == inum_before +Given url mainUrl + '/' +response.inum +And header Authorization = 'Bearer ' + accessToken +And header Content-Type = 'application/json-patch+json' +And header Accept = 'application/json' +And def newDisplayName = response.displayName +And print " newDisplayName = "+newDisplayName +And request "[ {\"op\":\"replace\", \"path\": \"/displayName\", \"value\":\""+newDisplayName+"\"} ]" +When method PATCH +Then status 200 +And print response +And assert response.length !=0 +Given url mainUrl + '/' +response.inum +And header Authorization = 'Bearer ' + accessToken +When method DELETE +Then status 204 + + +Scenario: Delete a non-existion uma scope by inum +Given url mainUrl + '/1402.66633-8675-473e-a749' +And header Authorization = 'Bearer ' + accessToken +And param type = 'uma' +When method GET +Then status 404 + + +Scenario: Get an uma scope by inum(unexisting scope) +Given url mainUrl + '/53553532727272772' +And header Authorization = 'Bearer ' + accessToken +And param type = 'uma' +When method GET +Then status 404 +And print response + + +@ignore +Scenario: Get an uma scope by inum +Given url mainUrl +And header Authorization = 'Bearer ' + accessToken +And param type = 'uma' +When method GET +Then status 200 +Given url mainUrl + '/' +response[0].inum +And header Authorization = 'Bearer ' + accessToken +And param type = 'uma' +When method GET +Then status 200 + From de95b62963b65d5fee3e9c721e039c774e182100 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 14 Nov 2024 20:55:42 +0530 Subject: [PATCH 11/44] feat(config-api): testng framework Signed-off-by: pujavs --- .../rest/resource/ConfigResourceTest.java | 26 +++---------- .../{rest => test}/health/ApiHealthTest.java | 2 +- .../{rest => test}/resource/AcrsTest.java | 2 +- .../resource/ClientResourceTest.java | 2 +- .../test/resource/ConfigResourceTest.java | 37 +++++++++++++++++++ .../DatabaseConnectionHealthTest.java | 2 +- 6 files changed, 47 insertions(+), 24 deletions(-) rename jans-config-api/server/src/test/java/io/jans/configapi/{rest => test}/health/ApiHealthTest.java (98%) rename jans-config-api/server/src/test/java/io/jans/configapi/{rest => test}/resource/AcrsTest.java (97%) rename jans-config-api/server/src/test/java/io/jans/configapi/{rest => test}/resource/ClientResourceTest.java (97%) create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ConfigResourceTest.java rename jans-config-api/server/src/test/java/io/jans/configapi/{rest => test}/resource/DatabaseConnectionHealthTest.java (98%) diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java index 6c45e3da4a2..34e4b478b39 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java @@ -6,34 +6,20 @@ package io.jans.configapi.rest.resource; -import static io.restassured.RestAssured.given; -import io.jans.configapi.BaseTest; +import org.junit.jupiter.api.Test; import jakarta.ws.rs.core.MediaType; - -import org.testng.annotations.Test; -import org.testng.annotations.Parameters; +import static io.restassured.RestAssured.given; /** * @author Yuriy Zabrovarnyy */ -public class ConfigResourceTest extends BaseTest{ +public class ConfigResourceTest { - @Parameters({"issuer", "authConfigurationUrl"}) - @Test - public void getAuthAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { - log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) - .get(issuer+authConfigurationUrl).then().statusCode(200); - } - - @Parameters({"issuer", "authConfigurationUrl"}) @Test - public void patchAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { - log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); + public void patchAppConfigurationProperty() { given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", "Bearer 0ea2ce99-b741-4f5a-8fd7-26f52d057c19", null) .body("[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]") - .patch(issuer+authConfigurationUrl).then().statusCode(200); + .patch("/jans-config-api/api/v1/jans-auth-server/config").then().statusCode(200); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/health/ApiHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java similarity index 98% rename from jans-config-api/server/src/test/java/io/jans/configapi/rest/health/ApiHealthTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java index 49d978cb09d..0184dffca90 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/health/ApiHealthTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.test; +package io.jans.configapi.test.health; import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/AcrsTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/AcrsTest.java similarity index 97% rename from jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/AcrsTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/resource/AcrsTest.java index dacefd78cdd..b5cc619b4cb 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/AcrsTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/AcrsTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.test; +package io.jans.configapi.test.resource; import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ClientResourceTest.java similarity index 97% rename from jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ClientResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ClientResourceTest.java index 6f9e0843d2e..731f3c50bd5 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ClientResourceTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.rest.resource; +package io.jans.configapi.test.resource; import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ConfigResourceTest.java new file mode 100644 index 00000000000..0c570ce3f41 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ConfigResourceTest.java @@ -0,0 +1,37 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test.resource; + +import static io.restassured.RestAssured.given; +import io.jans.configapi.BaseTest; +import jakarta.ws.rs.core.MediaType; + +import org.testng.annotations.Test; +import org.testng.annotations.Parameters; + + +public class ConfigResourceTest extends BaseTest{ + + @Parameters({"issuer", "authConfigurationUrl"}) + @Test + public void getAuthAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { + log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+authConfigurationUrl).then().statusCode(200); + } + + @Parameters({"issuer", "authConfigurationUrl"}) + @Test + public void patchAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { + log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .body("[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]") + .patch(issuer+authConfigurationUrl).then().statusCode(200); + } +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/DatabaseConnectionHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/DatabaseConnectionHealthTest.java similarity index 98% rename from jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/DatabaseConnectionHealthTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/resource/DatabaseConnectionHealthTest.java index 49d978cb09d..7ee7b3fbbd9 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/DatabaseConnectionHealthTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/DatabaseConnectionHealthTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.test; +package io.jans.configapi.test.resource; import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; From db7d4eb9db03aa709ec5bfbaa7e4de0f43ff2ce0 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 14 Nov 2024 20:57:52 +0530 Subject: [PATCH 12/44] feat(config-api): testng framework Signed-off-by: pujavs --- .../io/jans/configapi/test/{resource => auth}/AcrsTest.java | 2 +- .../configapi/test/{resource => auth}/ClientResourceTest.java | 2 +- .../configapi/test/{resource => auth}/ConfigResourceTest.java | 2 +- .../test/{resource => auth}/DatabaseConnectionHealthTest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename jans-config-api/server/src/test/java/io/jans/configapi/test/{resource => auth}/AcrsTest.java (97%) rename jans-config-api/server/src/test/java/io/jans/configapi/test/{resource => auth}/ClientResourceTest.java (97%) rename jans-config-api/server/src/test/java/io/jans/configapi/test/{resource => auth}/ConfigResourceTest.java (97%) rename jans-config-api/server/src/test/java/io/jans/configapi/test/{resource => auth}/DatabaseConnectionHealthTest.java (98%) diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/AcrsTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsTest.java similarity index 97% rename from jans-config-api/server/src/test/java/io/jans/configapi/test/resource/AcrsTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsTest.java index b5cc619b4cb..96db0327d9e 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/AcrsTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.test.resource; +package io.jans.configapi.test.auth; import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java similarity index 97% rename from jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ClientResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index 731f3c50bd5..cc750f37daa 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.test.resource; +package io.jans.configapi.test.auth; import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java similarity index 97% rename from jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ConfigResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java index 0c570ce3f41..c5939694b28 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.test.resource; +package io.jans.configapi.test.auth; import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/DatabaseConnectionHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/DatabaseConnectionHealthTest.java similarity index 98% rename from jans-config-api/server/src/test/java/io/jans/configapi/test/resource/DatabaseConnectionHealthTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/DatabaseConnectionHealthTest.java index 7ee7b3fbbd9..e57da6a1d95 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/resource/DatabaseConnectionHealthTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/DatabaseConnectionHealthTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.test.resource; +package io.jans.configapi.test.auth; import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; From e73b5a0e875622138fda17a2fe79675b89a6db32 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 14 Nov 2024 21:24:26 +0530 Subject: [PATCH 13/44] feat(config-api): testng framework Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 12 ++--- .../{AcrsTest.java => AcrsResourceTest.java} | 2 +- .../auth/AgamaDeploymentsResourceTest.java | 29 ++++++++++ ...eTest.java => AuthConfigResourceTest.java} | 2 +- .../auth/DatabaseConnectionHealthTest.java | 54 ------------------- .../server/src/test/resources/testng.xml | 25 +++++++-- 6 files changed, 59 insertions(+), 65 deletions(-) rename jans-config-api/server/src/test/java/io/jans/configapi/test/auth/{AcrsTest.java => AcrsResourceTest.java} (96%) create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java rename jans-config-api/server/src/test/java/io/jans/configapi/test/auth/{ConfigResourceTest.java => AuthConfigResourceTest.java} (96%) delete mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/test/auth/DatabaseConnectionHealthTest.java diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 5baec642f59..1dd13dc1060 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,18 +9267,18 @@ components: type: string selected: type: boolean - userCanEdit: + adminCanView: type: boolean adminCanEdit: type: boolean - adminCanView: - type: boolean userCanView: type: boolean - adminCanAccess: + userCanEdit: type: boolean userCanAccess: type: boolean + adminCanAccess: + type: boolean whitePagesCanView: type: boolean baseDn: @@ -11246,14 +11246,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java similarity index 96% rename from jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java index 96db0327d9e..a00e33d9200 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java @@ -13,7 +13,7 @@ import org.testng.annotations.Test; import org.testng.annotations.Parameters; -public class AcrsTest extends BaseTest{ +public class AcrsResourceTest extends BaseTest{ @Parameters({"issuer", "acrsUrl"}) @Test diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java new file mode 100644 index 00000000000..3eba3c60170 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java @@ -0,0 +1,29 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test.auth; + +import static io.restassured.RestAssured.given; +import io.jans.configapi.BaseTest; +import jakarta.ws.rs.core.MediaType; + +import org.testng.annotations.Test; +import org.testng.annotations.Parameters; + +public class AgamaDeploymentsResourceTest extends BaseTest{ + + @Parameters({"issuer", "agamaDeploymentUrl"}) + @Test + public void getDeployments(final String issuer, final String agamaDeploymentUrl) { + log.error("accessToken:{}, issuer:{}, agamaDeploymentUrl:{}", accessToken, issuer, agamaDeploymentUrl); + given().when().contentType(MediaType.APPLICATION_JSON) + .header("Authorization", accessToken, null) + .get(issuer+agamaDeploymentUrl).then().statusCode(200); + } + + + +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java similarity index 96% rename from jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java index c5939694b28..9c0ca300753 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java @@ -14,7 +14,7 @@ import org.testng.annotations.Parameters; -public class ConfigResourceTest extends BaseTest{ +public class AuhConfigResourceTest extends BaseTest{ @Parameters({"issuer", "authConfigurationUrl"}) @Test diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/DatabaseConnectionHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/DatabaseConnectionHealthTest.java deleted file mode 100644 index e57da6a1d95..00000000000 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/DatabaseConnectionHealthTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi.test.auth; - -import static io.restassured.RestAssured.given; -import io.jans.configapi.BaseTest; -import jakarta.ws.rs.core.MediaType; - -import org.testng.annotations.Test; -import org.testng.annotations.Parameters; - -public class ApiHealthTest extends BaseTest{ - - @Parameters({"issuer", "healthUrl"}) - @Test - public void getHealthResponse(final String issuer, final String healthUrl) { - log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) - .get(issuer+healthUrl).then().statusCode(200); - } - - - @Parameters({"issuer", "healthUrl"}) - @Test - public void getServerStat(final String issuer, final String healthUrl) { - log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) - .get(issuer+healthUrl+"/server-stat").then().statusCode(200); - } - - @Parameters({"issuer", "healthUrl"}) - @Test - public void getApplicationVersion(final String issuer, final String healthUrl) { - log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) - .get(issuer+healthUrl+"/app-version").then().statusCode(200); - } - - @Parameters({"issuer", "healthUrl"}) - @Test - public void getServiceStatus(final String issuer, final String healthUrl) { - log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) - .get(issuer+healthUrl+"/service-status").then().statusCode(200); - } -} diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index 773651b5f94..d04de3670d4 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -4,16 +4,35 @@ + + + + + + + + + + + + - + - + + + + + + + + - + From 3a75cd15d518e3cea16f1f0846002cb30839fe38 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 14 Nov 2024 21:34:29 +0530 Subject: [PATCH 14/44] feat(config-api): testng framework Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 22 +++++++++---------- .../rest/resource/ConfigResourceTest.java | 2 +- .../configapi/test/auth/AcrsResourceTest.java | 4 ++-- ...ceTest.java => AuhConfigResourceTest.java} | 0 .../server/src/test/resources/testng.xml | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) rename jans-config-api/server/src/test/java/io/jans/configapi/test/auth/{AuthConfigResourceTest.java => AuhConfigResourceTest.java} (100%) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 1dd13dc1060..937fb0db797 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,19 +9267,19 @@ components: type: string selected: type: boolean - adminCanView: + whitePagesCanView: + type: boolean + userCanView: type: boolean adminCanEdit: type: boolean - userCanView: + adminCanView: type: boolean userCanEdit: type: boolean - userCanAccess: - type: boolean adminCanAccess: type: boolean - whitePagesCanView: + userCanAccess: type: boolean baseDn: type: string @@ -10128,8 +10128,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10139,6 +10137,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -11246,14 +11246,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: @@ -11682,10 +11682,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java index 34e4b478b39..3ce07f1e0e8 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java @@ -6,7 +6,7 @@ package io.jans.configapi.rest.resource; -import org.junit.jupiter.api.Test; +import org.testng.annotations.Test; import jakarta.ws.rs.core.MediaType; import static io.restassured.RestAssured.given; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java index a00e33d9200..c77491a6849 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java @@ -27,8 +27,8 @@ public void getDefaultAuthenticationMethod(final String issuer, final String acr @Parameters({"issuer", "acrsUrl", "default_acr1"}) @Test - public void postClient(final String issuer, final String openidClientsUrl, final String json) { - log.error("accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); + public void postClient(final String issuer, final String acrsUrl, final String json) { + log.error("accessToken:{}, issuer:{}, acrsUrl:{}, json:{}", accessToken, issuer, acrsUrl, json); log.info("Creating client using json string"); given().when().contentType(MediaType.APPLICATION_JSON) diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuhConfigResourceTest.java similarity index 100% rename from jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuhConfigResourceTest.java diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index d04de3670d4..97a2fe06e41 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -13,7 +13,7 @@ - + From 71826b6e53c8e5f838ec6b6f192a371b112d4026 Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 15 Nov 2024 18:32:15 +0530 Subject: [PATCH 15/44] feat(config-api): testng framework - wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 16 ++++++++-------- jans-config-api/plugins/fido2-plugin/pom.xml | 6 ------ jans-config-api/plugins/jans-link-plugin/pom.xml | 6 ------ jans-config-api/plugins/kc-link-plugin/pom.xml | 3 --- jans-config-api/plugins/kc-saml-plugin/pom.xml | 3 --- jans-config-api/plugins/lock-plugin/pom.xml | 3 --- jans-config-api/plugins/scim-plugin/pom.xml | 3 --- jans-config-api/plugins/user-mgt-plugin/pom.xml | 3 --- .../test/java/io/jans/configapi/BaseTest.java | 10 ++++++---- ...urceTest.java => AuthConfigResourceTest.java} | 2 +- 10 files changed, 15 insertions(+), 40 deletions(-) rename jans-config-api/server/src/test/java/io/jans/configapi/test/auth/{AuhConfigResourceTest.java => AuthConfigResourceTest.java} (96%) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 937fb0db797..81b7f4ce7da 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,19 +9267,19 @@ components: type: string selected: type: boolean - whitePagesCanView: - type: boolean - userCanView: + adminCanAccess: type: boolean - adminCanEdit: + userCanAccess: type: boolean adminCanView: type: boolean + userCanView: + type: boolean userCanEdit: type: boolean - adminCanAccess: + adminCanEdit: type: boolean - userCanAccess: + whitePagesCanView: type: boolean baseDn: type: string @@ -11682,10 +11682,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/fido2-plugin/pom.xml b/jans-config-api/plugins/fido2-plugin/pom.xml index e49c60b71f7..abaec4ba596 100644 --- a/jans-config-api/plugins/fido2-plugin/pom.xml +++ b/jans-config-api/plugins/fido2-plugin/pom.xml @@ -134,12 +134,6 @@ src/test/resources true - - karate.properties - karate_jenkins.properties - test.properties - *.* - diff --git a/jans-config-api/plugins/jans-link-plugin/pom.xml b/jans-config-api/plugins/jans-link-plugin/pom.xml index 1abfa9e538f..268c4c5aafd 100644 --- a/jans-config-api/plugins/jans-link-plugin/pom.xml +++ b/jans-config-api/plugins/jans-link-plugin/pom.xml @@ -134,12 +134,6 @@ src/test/resources true - - karate.properties - karate_jenkins.properties - test.properties - *.* - diff --git a/jans-config-api/plugins/kc-link-plugin/pom.xml b/jans-config-api/plugins/kc-link-plugin/pom.xml index ce427837f74..e288ac2b466 100644 --- a/jans-config-api/plugins/kc-link-plugin/pom.xml +++ b/jans-config-api/plugins/kc-link-plugin/pom.xml @@ -174,9 +174,6 @@ src/test/resources true - karate.properties - karate_jenkins.properties - test.properties *.* diff --git a/jans-config-api/plugins/kc-saml-plugin/pom.xml b/jans-config-api/plugins/kc-saml-plugin/pom.xml index 257dc952f7f..3aa9ab7cbfa 100644 --- a/jans-config-api/plugins/kc-saml-plugin/pom.xml +++ b/jans-config-api/plugins/kc-saml-plugin/pom.xml @@ -194,9 +194,6 @@ src/test/resources true - karate.properties - karate_jenkins.properties - test.properties *.* diff --git a/jans-config-api/plugins/lock-plugin/pom.xml b/jans-config-api/plugins/lock-plugin/pom.xml index 6189a6d0e00..e3475e7c4ef 100644 --- a/jans-config-api/plugins/lock-plugin/pom.xml +++ b/jans-config-api/plugins/lock-plugin/pom.xml @@ -163,9 +163,6 @@ src/test/resources true - karate.properties - karate_jenkins.properties - test.properties *.* diff --git a/jans-config-api/plugins/scim-plugin/pom.xml b/jans-config-api/plugins/scim-plugin/pom.xml index 38e8fb19e71..42059c50869 100644 --- a/jans-config-api/plugins/scim-plugin/pom.xml +++ b/jans-config-api/plugins/scim-plugin/pom.xml @@ -137,9 +137,6 @@ src/test/resources true - karate.properties - karate_jenkins.properties - test.properties *.* diff --git a/jans-config-api/plugins/user-mgt-plugin/pom.xml b/jans-config-api/plugins/user-mgt-plugin/pom.xml index 930e80f2391..115d6a384e5 100644 --- a/jans-config-api/plugins/user-mgt-plugin/pom.xml +++ b/jans-config-api/plugins/user-mgt-plugin/pom.xml @@ -133,9 +133,6 @@ src/test/resources true - karate.properties - karate_jenkins.properties - test.properties *.* diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index 6f4ecbfc400..2e208d73608 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -42,6 +42,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.Serializable; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.security.*; @@ -102,7 +103,7 @@ public class BaseTest { private static final String CONTENT_TYPE = "Content-Type"; private static final String AUTHORIZATION = "Authorization"; - private static final long serialVersionUID = -2398422090669045605L; + protected Logger log = LogManager.getLogger(getClass()); private Base64 base64; private static Map propertiesMap = null; @@ -116,7 +117,7 @@ public void initTestSuite(ITestContext context) throws Exception { resteasyService = new ResteasyService(); httpService = new HttpService(); - log.info("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); + log.error("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); Properties prop = new Properties(); prop.load(Files.newBufferedReader(Paths.get(propertiesFile), UTF_8)); @@ -125,7 +126,7 @@ public void initTestSuite(ITestContext context) throws Exception { prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); context.getSuite().getXmlSuite().setParameters(propertiesMap); - //accessToken + log.error("End initTestSuite propertiesMap: {}", propertiesMap); } @@ -138,6 +139,7 @@ public void finalize() { @BeforeTest public void getAccessToken() throws Exception { + log.error("getAccessToken - propertiesMap:{}", propertiesMap); String tokenUrl = propertiesMap.get("token.endpoint"); String strGrantType = propertiesMap.get("token.grant.type"); String clientId = propertiesMap.get("test.client.id"); @@ -148,7 +150,7 @@ public void getAccessToken() throws Exception { String token = new String(Base64.decodeBase64(authStr), StandardCharsets.UTF_8); String encodedScopes = URLDecoder.decode(scopes, "UTF-8"); GrantType grantType = GrantType.fromString(strGrantType); - accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); + accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, encodedScopes); log.error("accessToken:{}", accessToken); } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuhConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java similarity index 96% rename from jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuhConfigResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java index 9c0ca300753..ebbd3e575a8 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuhConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java @@ -14,7 +14,7 @@ import org.testng.annotations.Parameters; -public class AuhConfigResourceTest extends BaseTest{ +public class AuthConfigResourceTest extends BaseTest{ @Parameters({"issuer", "authConfigurationUrl"}) @Test From 8321a24824bc7e0111ad5220ebd2a6df6de755d0 Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 15 Nov 2024 20:12:47 +0530 Subject: [PATCH 16/44] feat(config-api): testng framework - wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 22 +++--- .../test/java/io/jans/configapi/BaseTest.java | 19 ++--- .../configapi/service/ResteasyService.java | 76 +------------------ .../test/resources/config-api-test.properties | 50 ++++++------ 4 files changed, 49 insertions(+), 118 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 81b7f4ce7da..8149b72c219 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9267,19 +9267,19 @@ components: type: string selected: type: boolean - adminCanAccess: - type: boolean - userCanAccess: + whitePagesCanView: type: boolean - adminCanView: + userCanEdit: type: boolean userCanView: type: boolean - userCanEdit: - type: boolean adminCanEdit: type: boolean - whitePagesCanView: + adminCanView: + type: boolean + adminCanAccess: + type: boolean + userCanAccess: type: boolean baseDn: type: string @@ -10128,6 +10128,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10137,8 +10139,6 @@ components: - code - token - id_token - fapi: - type: boolean AuthenticationFilter: required: - baseDn @@ -11682,10 +11682,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index 2e208d73608..b9e360f6a07 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -140,17 +140,18 @@ public void finalize() { @BeforeTest public void getAccessToken() throws Exception { log.error("getAccessToken - propertiesMap:{}", propertiesMap); - String tokenUrl = propertiesMap.get("token.endpoint"); - String strGrantType = propertiesMap.get("token.grant.type"); - String clientId = propertiesMap.get("test.client.id"); - String clientSecret = propertiesMap.get("test.client.secret"); - String scopes = propertiesMap.get("test.scopes"); + + //accessToken = "ad00f5cc-3221-4d31-8318-aa3642f5ed00"; + + String tokenUrl = propertiesMap.get("tokenEndpoint"); + String strGrantType = propertiesMap.get("tokenGrantType"); + String clientId = propertiesMap.get("clientId"); + String clientSecret = propertiesMap.get("clientSecret"); + String scopes = propertiesMap.get("scopes"); String authStr = clientId + ':' + clientSecret; - String token = new String(Base64.decodeBase64(authStr), StandardCharsets.UTF_8); - String encodedScopes = URLDecoder.decode(scopes, "UTF-8"); - GrantType grantType = GrantType.fromString(strGrantType); - accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, encodedScopes); + GrantType grantType = GrantType.fromString(strGrantType); + accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); log.error("accessToken:{}", accessToken); } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java b/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java index 07beb1c1c44..40e035264a8 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java @@ -6,99 +6,29 @@ package io.jans.configapi.service; -import java.io.File; -import java.io.IOException; import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.Charset; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.util.Map; -import java.util.Map.Entry; -import javax.net.ssl.SSLContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.codec.binary.Base64; -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.conn.routing.HttpRoutePlanner; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.DefaultProxyRoutePlanner; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.ssl.SSLContexts; -import org.apache.http.ssl.TrustStrategy; -import org.apache.http.util.EntityUtils; +import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.Invocation.Builder; -import jakarta.ws.rs.client.ClientBuilder; -import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; -import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; -import org.json.JSONObject; -import io.jans.model.net.HttpServiceResponse; -import io.jans.util.StringHelper; -import io.jans.util.Util; -import jakarta.annotation.PostConstruct; -import jakarta.inject.Inject; -import jakarta.servlet.http.HttpServletRequest; public class ResteasyService implements Serializable { + private static final long serialVersionUID = 1L; protected Logger logger = LogManager.getLogger(getClass()); - public ResteasyClient newClient(ClientHttpEngine engine) { - return ((ResteasyClientBuilder) ClientBuilder.newBuilder()).httpEngine(engine).build(); - } public Builder getClientBuilder(String url) { return ClientBuilder.newClient().target(url).request(); } - public ApacheHttpClient43Engine createEngine() { - return createEngine(false); - } - - public ApacheHttpClient43Engine createEngine(boolean followRedirects) { - return createEngine(200, 20, CookieSpecs.STANDARD, followRedirects); - } - - public ApacheHttpClient43Engine createEngine(int maxTotal, int defaultMaxPerRoute, String cookieSpec, - boolean followRedirects) { - PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); - CloseableHttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(cookieSpec).build()) - .setConnectionManager(cm).build(); - cm.setMaxTotal(maxTotal); - cm.setDefaultMaxPerRoute(defaultMaxPerRoute); - final ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(httpClient); - engine.setFollowRedirects(followRedirects); - return engine; - } + } diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties index 5e49eb48541..50e70af5a86 100644 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -8,31 +8,31 @@ clientSecret=k7gDCUKv1IMo issuer=https://pujavs-amazed-rat.gluu.info -statUrl= "/jans-config-api/api/v1/stat" -healthUrl="/jans-config-api/api/v1/health" -acrsUrl="/jans-config-api/api/v1/acrs" -authConfigurationUrl="/jans-config-api/api/v1/jans-auth-server/config" -scriptsUrl="/jans-config-api/api/v1/config/scripts" -cacheUrl="/jans-config-api/api/v1/config/cache" -messageUrl="/jans-config-api/api/v1/config/message" -jwksUrl="/jans-config-api/api/v1/config/jwks" -ldapUrl="/jans-config-api/api/v1/config/database/ldap" -openidClientsUrl="/jans-config-api/api/v1/openid/clients" -scopesUrl="/jans-config-api/api/v1/scopes" -umaresourcesUrl="/jans-config-api/api/v1/uma/resources" -attributesUrl="/jans-config-api/api/v1/attributes" -smtpUrl="/jans-config-api/api/v1/config/smtp" -loggingUrl="/jans-config-api/api/v1/logging" -authHealthUrl="/jans-config-api/api/v1/jans-auth-server/health" -orgConfigurationUrl="/jans-config-api/api/v1/org" -userUrl="/jans-config-api/api/v1/user" -agamaUrl="/jans-config-api/api/v1/agama" -sessionUrl="/jans-config-api/api/v1/jans-auth-server/session" -pluginUrl="/jans-config-api/api/v1/plugin" -apiConfigUrl="/jans-config-api/api/v1/api-config" -agamaDeploymentUrl="/jans-config-api/api/v1/agama-deployment" -clientsAuthorizationsUrl="/jans-config-api/api/v1/clients/authorizations" -tokenUrl="/jans-config-api/api/v1/token" +statUrl=/jans-config-api/api/v1/stat +healthUrl=/jans-config-api/api/v1/health +acrsUrl=/jans-config-api/api/v1/acrs +authConfigurationUrl=/jans-config-api/api/v1/jans-auth-server/config +scriptsUrl=/jans-config-api/api/v1/config/scripts +cacheUrl=/jans-config-api/api/v1/config/cache +messageUrl=/jans-config-api/api/v1/config/message +jwksUrl=/jans-config-api/api/v1/config/jwks +ldapUrl=/jans-config-api/api/v1/config/database/ldap +openidClientsUrl=/jans-config-api/api/v1/openid/clients +scopesUrl=/jans-config-api/api/v1/scopes +umaresourcesUrl=/jans-config-api/api/v1/uma/resources +attributesUrl=/jans-config-api/api/v1/attributes +smtpUrl=/jans-config-api/api/v1/config/smtp +loggingUrl=/jans-config-api/api/v1/logging +authHealthUrl=/jans-config-api/api/v1/jans-auth-server/health +orgConfigurationUrl=/jans-config-api/api/v1/org +userUrl=/jans-config-api/api/v1/user +agamaUrl=/jans-config-api/api/v1/agama +sessionUrl=/jans-config-api/api/v1/jans-auth-server/session +pluginUrl=/jans-config-api/api/v1/plugin +apiConfigUrl=/jans-config-api/api/v1/api-config +agamaDeploymentUrl=/jans-config-api/api/v1/agama-deployment +clientsAuthorizationsUrl=/jans-config-api/api/v1/clients/authorizations +tokenUrl=/jans-config-api/api/v1/token #defaultAcr From e643f0f48c126660b5f8ad1da53753e6f08bf772 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 19 Nov 2024 20:08:45 +0530 Subject: [PATCH 17/44] feat(config-api): testing framework change wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 18 +- .../test/java/io/jans/configapi/BaseTest.java | 50 ++- .../jans/configapi/service/HttpService.java | 18 +- .../configapi/test/auth/AcrsResourceTest.java | 4 +- .../auth/AgamaDeploymentsResourceTest.java | 2 +- .../test/auth/AuthConfigResourceTest.java | 4 +- .../test/auth/ClientResourceTest.java | 36 +- .../configapi/test/health/ApiHealthTest.java | 8 +- .../test/resources/config-api-test.properties | 1 + .../openid/clients/openid-client-post.json | 55 +++ .../json/openid/clients/openid-client.json | 8 +- .../src/test/resources/testng - Copy.xml | 41 +++ .../server/src/test/resources/testng.xml | 28 +- .../Default suite/Default test.html | 215 +++++++++++ .../Default suite/Default test.xml | 46 +++ .../Default suite/testng-failed.xml | 19 + .../server/test-output/bullet_point.png | Bin 0 -> 356 bytes .../server/test-output/emailable-report.html | 71 ++++ jans-config-api/server/test-output/failed.png | Bin 0 -> 977 bytes jans-config-api/server/test-output/index.html | 280 ++++++++++++++ .../server/test-output/jquery-3.6.0.min.js | 2 + ...configapi.test.auth.ClientResourceTest.xml | 37 ++ .../server/test-output/navigator-bullet.png | Bin 0 -> 352 bytes .../old/Default suite/Default test.properties | 1 + .../old/Default suite/classes.html | 40 ++ .../test-output/old/Default suite/groups.html | 1 + .../test-output/old/Default suite/index.html | 6 + .../test-output/old/Default suite/main.html | 2 + .../Default suite/methods-alphabetical.html | 6 + .../old/Default suite/methods-not-run.html | 4 + .../old/Default suite/methods.html | 6 + .../old/Default suite/reporter-output.html | 1 + .../old/Default suite/testng.xml.html | 1 + .../test-output/old/Default suite/toc.html | 30 ++ .../server/test-output/old/index.html | 9 + jans-config-api/server/test-output/passed.png | Bin 0 -> 1019 bytes .../server/test-output/skipped.png | Bin 0 -> 967 bytes .../server/test-output/testng-failed.xml | 19 + .../server/test-output/testng-reports.css | 326 +++++++++++++++++ .../server/test-output/testng-reports.js | 122 +++++++ .../server/test-output/testng-reports1.css | 344 ++++++++++++++++++ .../server/test-output/testng-reports2.js | 76 ++++ .../server/test-output/testng-results.xml | 113 ++++++ jans-config-api/server/test-output/testng.css | 9 + 44 files changed, 1981 insertions(+), 78 deletions(-) create mode 100644 jans-config-api/server/src/test/resources/json/openid/clients/openid-client-post.json create mode 100644 jans-config-api/server/src/test/resources/testng - Copy.xml create mode 100644 jans-config-api/server/test-output/Default suite/Default test.html create mode 100644 jans-config-api/server/test-output/Default suite/Default test.xml create mode 100644 jans-config-api/server/test-output/Default suite/testng-failed.xml create mode 100644 jans-config-api/server/test-output/bullet_point.png create mode 100644 jans-config-api/server/test-output/emailable-report.html create mode 100644 jans-config-api/server/test-output/failed.png create mode 100644 jans-config-api/server/test-output/index.html create mode 100644 jans-config-api/server/test-output/jquery-3.6.0.min.js create mode 100644 jans-config-api/server/test-output/junitreports/TEST-io.jans.configapi.test.auth.ClientResourceTest.xml create mode 100644 jans-config-api/server/test-output/navigator-bullet.png create mode 100644 jans-config-api/server/test-output/old/Default suite/Default test.properties create mode 100644 jans-config-api/server/test-output/old/Default suite/classes.html create mode 100644 jans-config-api/server/test-output/old/Default suite/groups.html create mode 100644 jans-config-api/server/test-output/old/Default suite/index.html create mode 100644 jans-config-api/server/test-output/old/Default suite/main.html create mode 100644 jans-config-api/server/test-output/old/Default suite/methods-alphabetical.html create mode 100644 jans-config-api/server/test-output/old/Default suite/methods-not-run.html create mode 100644 jans-config-api/server/test-output/old/Default suite/methods.html create mode 100644 jans-config-api/server/test-output/old/Default suite/reporter-output.html create mode 100644 jans-config-api/server/test-output/old/Default suite/testng.xml.html create mode 100644 jans-config-api/server/test-output/old/Default suite/toc.html create mode 100644 jans-config-api/server/test-output/old/index.html create mode 100644 jans-config-api/server/test-output/passed.png create mode 100644 jans-config-api/server/test-output/skipped.png create mode 100644 jans-config-api/server/test-output/testng-failed.xml create mode 100644 jans-config-api/server/test-output/testng-reports.css create mode 100644 jans-config-api/server/test-output/testng-reports.js create mode 100644 jans-config-api/server/test-output/testng-reports1.css create mode 100644 jans-config-api/server/test-output/testng-reports2.js create mode 100644 jans-config-api/server/test-output/testng-results.xml create mode 100644 jans-config-api/server/test-output/testng.css diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 41e209bdf96..d4214945bc4 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9270,14 +9270,14 @@ components: type: string selected: type: boolean - userCanView: - type: boolean userCanEdit: type: boolean - adminCanEdit: + userCanView: type: boolean adminCanView: type: boolean + adminCanEdit: + type: boolean adminCanAccess: type: boolean userCanAccess: @@ -10131,8 +10131,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10142,6 +10140,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -11249,14 +11249,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: @@ -11685,10 +11685,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index b9e360f6a07..3e6b70d3b0f 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -86,6 +86,7 @@ import org.testng.ITestContext; import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeSuite; import org.testng.annotations.BeforeTest; @@ -101,22 +102,20 @@ public class BaseTest { - private static final String CONTENT_TYPE = "Content-Type"; - private static final String AUTHORIZATION = "Authorization"; - + protected static final String CONTENT_TYPE = "Content-Type"; + protected static final String AUTHORIZATION = "Authorization"; + protected static final String AUTHORIZATION_TYPE = "Bearer"; protected Logger log = LogManager.getLogger(getClass()); - private Base64 base64; - private static Map propertiesMap = null; - private ResteasyService resteasyService; - private HttpService httpService; + protected Base64 base64; + protected static Map propertiesMap = null; + protected ResteasyService resteasyService = new ResteasyService();; + protected HttpService httpService = new HttpService(); protected String accessToken; @BeforeSuite public void initTestSuite(ITestContext context) throws Exception { - resteasyService = new ResteasyService(); - httpService = new HttpService(); - + log.error("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); Properties prop = new Properties(); @@ -137,11 +136,9 @@ public void finalize() { log.info("After Suite finalize'"); } - @BeforeTest + @BeforeMethod public void getAccessToken() throws Exception { log.error("getAccessToken - propertiesMap:{}", propertiesMap); - - //accessToken = "ad00f5cc-3221-4d31-8318-aa3642f5ed00"; String tokenUrl = propertiesMap.get("tokenEndpoint"); String strGrantType = propertiesMap.get("tokenGrantType"); @@ -151,7 +148,7 @@ public void getAccessToken() throws Exception { String authStr = clientId + ':' + clientSecret; GrantType grantType = GrantType.fromString(strGrantType); - accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); + this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); log.error("accessToken:{}", accessToken); } @@ -213,5 +210,30 @@ protected ResteasyService getResteasyService() { return this.resteasyService; } + protected String getCredentials(final String clientId, final String clientSecret) throws UnsupportedEncodingException { + return URLEncoder.encode(clientId, Util.UTF8_STRING_ENCODING) + + ":" + + URLEncoder.encode(clientSecret, Util.UTF8_STRING_ENCODING); + } + + /** + * Returns the client credentials encoded using base64. + * + * @return The encoded client credentials. + */ + protected String getEncodedCredentials() { + try { + String clientId = propertiesMap.get("clientId"); + String clientSecret = propertiesMap.get("clientSecret"); + if (StringUtils.isNotBlank(clientId) && StringUtils.isNotBlank(clientSecret)) { + return Base64.encodeBase64String(Util.getBytes(getCredentials(clientId, clientSecret))); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + return null; + } + } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java index 17be894d8ba..fdf54712fc3 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java @@ -147,7 +147,7 @@ public CloseableHttpClient getHttpsClient(String trustStoreType, String trustSto .setConnectionManager(connectionManager).build(); } - public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authCode, Map headers, String postData, ContentType contentType, String authType) { HttpPost httpPost = new HttpPost(uri); @@ -157,8 +157,8 @@ public HttpServiceResponse executePost(HttpClient httpClient, String uri, String } else { authType = authType + " "; } - if (StringHelper.isNotEmpty(authData)) { - httpPost.setHeader("Authorization", authType + authData); + if (StringHelper.isNotEmpty(authCode)) { + httpPost.setHeader("Authorization", authType + authCode); } if(contentType==null) { @@ -185,19 +185,19 @@ public HttpServiceResponse executePost(HttpClient httpClient, String uri, String return null; } - public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authCode, Map headers, String postData) { - return executePost(httpClient, uri, authData, headers, postData, null, null); + return executePost(httpClient, uri, authCode, headers, postData, null, null); } - public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authData, String postData, + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authCode, String postData, ContentType contentType) { - return executePost(httpClient, uri, authData, null, postData, contentType, null); + return executePost(httpClient, uri, authCode, null, postData, contentType, null); } - public HttpServiceResponse executePost(String uri, String authData, Map headers, String postData, + public HttpServiceResponse executePost(String uri, String authCode, Map headers, String postData, ContentType contentType, String authType) { - return executePost(this.getHttpsClient(), uri, authData, null, postData, contentType, authType); + return executePost(this.getHttpsClient(), uri, authCode, null, postData, contentType, authType); } public String encodeBase64(String value) { diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java index c77491a6849..3f8c5984469 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java @@ -20,7 +20,7 @@ public class AcrsResourceTest extends BaseTest{ public void getDefaultAuthenticationMethod(final String issuer, final String acrsUrl) { log.error("accessToken:{}, issuer:{}, acrsUrl:{}", accessToken, issuer, acrsUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization",AUTHORIZATION_TYPE + " "+ accessToken, null) .get(issuer+acrsUrl).then().statusCode(200); } @@ -32,7 +32,7 @@ public void postClient(final String issuer, final String acrsUrl, final String j log.info("Creating client using json string"); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) .body(json) .put(issuer+acrsUrl).then().statusCode(200); } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java index 3eba3c60170..806aab7aa02 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java @@ -20,7 +20,7 @@ public class AgamaDeploymentsResourceTest extends BaseTest{ public void getDeployments(final String issuer, final String agamaDeploymentUrl) { log.error("accessToken:{}, issuer:{}, agamaDeploymentUrl:{}", accessToken, issuer, agamaDeploymentUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) .get(issuer+agamaDeploymentUrl).then().statusCode(200); } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java index ebbd3e575a8..dee270cf970 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java @@ -21,7 +21,7 @@ public class AuthConfigResourceTest extends BaseTest{ public void getAuthAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) .get(issuer+authConfigurationUrl).then().statusCode(200); } @@ -30,7 +30,7 @@ public void getAuthAppConfigurationProperty(final String issuer, final String au public void patchAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) .body("[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]") .patch(issuer+authConfigurationUrl).then().statusCode(200); } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index cc750f37daa..c2041a7206d 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -9,6 +9,8 @@ import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; import io.jans.model.net.HttpServiceResponse; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import static org.testng.Assert.*; @@ -32,24 +34,46 @@ public class ClientResourceTest extends BaseTest{ public void getClients(final String issuer, final String openidClientsUrl) { log.error("accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " " + accessToken, null) .get(issuer+openidClientsUrl).then().statusCode(200); } @Parameters({"issuer", "openidClientsUrl", "openid_client1"}) - @Test + //@Test public void postClient(final String issuer, final String openidClientsUrl, final String json) { log.error("accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); - log.info("Creating client using json string"); + log.error("Creating client using json string - getHttpService():{}, this.accessToken:{}", getHttpService(), this.accessToken); - HttpServiceResponse httpServiceResponse = getHttpService().executePost(issuer+openidClientsUrl, "Basic ", null, json, - ContentType.APPLICATION_JSON, null); + HttpServiceResponse httpServiceResponse = getHttpService().executePost(issuer+openidClientsUrl, this.accessToken, null, json, + ContentType.APPLICATION_JSON, AUTHORIZATION_TYPE); assertFalse(httpServiceResponse==null); int statusCode = httpServiceResponse.getHttpResponse().getStatusLine().getStatusCode(); Status status = Status.fromStatusCode(statusCode); + log.error("postClient - using json string - status():{} ", status); + assertEquals(status, Status.CREATED.getStatusCode()); + } + + @Parameters({"issuer", "openidClientsUrl", "openid_client2"}) + //@Test + public void postClient2(final String issuer, final String openidClientsUrl, final String json) { + log.error("postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); + log.error("postClient2 client using json string - getHttpService():{}, this.accessToken:{}", getHttpService(), this.accessToken); + + Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + + Response response = request.post(Entity.json(json)); + log.trace("Response for Access Token - response:{}", response); + + if (response.getStatus() == 201) { + log.trace("Response for Access Token - response.getEntity():{}, response.getClass():{}", response.getEntity(), response.getClass()); + } + + - assertEquals(status, Status.OK.getStatusCode()); + assertEquals(response.getStatus(), Status.CREATED.getStatusCode()); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java index 0184dffca90..1ba26ae56be 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java @@ -20,7 +20,7 @@ public class ApiHealthTest extends BaseTest{ public void getHealthResponse(final String issuer, final String healthUrl) { log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) .get(issuer+healthUrl).then().statusCode(200); } @@ -30,7 +30,7 @@ public void getHealthResponse(final String issuer, final String healthUrl) { public void getServerStat(final String issuer, final String healthUrl) { log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) .get(issuer+healthUrl+"/server-stat").then().statusCode(200); } @@ -39,7 +39,7 @@ public void getServerStat(final String issuer, final String healthUrl) { public void getApplicationVersion(final String issuer, final String healthUrl) { log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) .get(issuer+healthUrl+"/app-version").then().statusCode(200); } @@ -48,7 +48,7 @@ public void getApplicationVersion(final String issuer, final String healthUrl) { public void getServiceStatus(final String issuer, final String healthUrl) { log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", accessToken, null) + .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) .get(issuer+healthUrl+"/service-status").then().statusCode(200); } } diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties index 50e70af5a86..c7ec06fcaf6 100644 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -40,6 +40,7 @@ default_acr1=file:target/test-classes/json/acr/defaultAcr.json #openid-client openid_client1=file:target/test-classes/json/openid/clients/client.json +openid_client2=file:target/test-classes/json/openid/clients/openid-client-post.json #openid-scopes openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json diff --git a/jans-config-api/server/src/test/resources/json/openid/clients/openid-client-post.json b/jans-config-api/server/src/test/resources/json/openid/clients/openid-client-post.json new file mode 100644 index 00000000000..300d87d7dd2 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/openid/clients/openid-client-post.json @@ -0,0 +1,55 @@ +{ + "applicationType": "web", + "description":"Description for test client 2", + "customObjectClasses":["top"], + "accessTokenAsJwt": false, + "claimRedirectUris": [ + ], + "deletable": false, + "disabled": false, + "requireAuthTime": false, + "clientName": "test-client-2", + "clientSecret": "test1234", + "exp": "2130-09-28T23:00:00Z[UTC]", + "grantTypes": [ + "authorization_code", + "implicit", + "refresh_token", + "client_credentials", + "password" + ], + "responseTypes": ["code"], + "idTokenSignedResponseAlg": "RS256", + "accessTokenSigningAlg": "RS256", + "attributes": { + "tlsClientAuthSubjectDn":"", + "runIntrospectionScriptBeforeJwtCreation":false, + "keepClientAuthorizationAfterExpiration":false, + "allowSpontaneousScopes":false, + "spontaneousScopes":[],"spontaneousScopeScriptDns":[], + "backchannelLogoutUri":[],"backchannelLogoutSessionRequired":false, + "additionalAudience":[],"postAuthnScripts":[],"consentGatheringScripts":[], + "introspectionScripts":[],"rptClaimsScripts":[] + }, + "frontChannelLogoutSessionRequired": false, + "logoutUri": [ + ], + "persistClientAuthorizations": true, + "postLogoutRedirectUris": [ + ], + "redirectUris": [ + "http://localhost:8080" + ], + "scopes": [ + ], + "trustedClient": false, + "includeClaimsInIdToken": false, + "rptAsJwt": false, + "subjectType": "pairwise", + "tokenEndpointAuthMethod": "client_secret_basic", + "dynamicRegistrationCustomObjectClass": "MyDynamicRegistrationCustomObject", + "dynamicRegistrationCustomAttributes": [ + "jansTrustedClnt", + "myAttr1" + ] +} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/json/openid/clients/openid-client.json b/jans-config-api/server/src/test/resources/json/openid/clients/openid-client.json index 24da86ddd1f..5a05c79e704 100644 --- a/jans-config-api/server/src/test/resources/json/openid/clients/openid-client.json +++ b/jans-config-api/server/src/test/resources/json/openid/clients/openid-client.json @@ -15,7 +15,7 @@ "spontaneousScopes": [] }, "claimRedirectURI": [ - "https://gluu.gasmyr.com/jans-auth/restv1/uma/gather_claims" + "https://gluu.server.com/jans-auth/restv1/uma/gather_claims" ], "deletable": false, "disabled": false, @@ -29,15 +29,15 @@ "idTokenSignedResponseAlg": "HS256", "logoutSessionRequired": true, "logoutUri": [ - "https://gluu.gasmyr.com/identity/ssologout.htm" + "https://gluu.server.com/identity/ssologout.htm" ], "jansAppTyp": "WEB", "jansPersistClntAuthzs": false, "jansPostLogoutRedirectURI": [ - "https://gluu.gasmyr.com/identity/finishlogout.htm" + "https://gluu.server.com/identity/finishlogout.htm" ], "jansRedirectURI": [ - "https://gluu.gasmyr.com/identity/uri1" + "https://gluu.server.com/identity/uri1" ], "jansScope": [ "inum=F0C4,ou=scopes,o=gluu" diff --git a/jans-config-api/server/src/test/resources/testng - Copy.xml b/jans-config-api/server/src/test/resources/testng - Copy.xml new file mode 100644 index 00000000000..97a2fe06e41 --- /dev/null +++ b/jans-config-api/server/src/test/resources/testng - Copy.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index 97a2fe06e41..45db2d7808f 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -3,33 +3,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/jans-config-api/server/test-output/Default suite/Default test.html b/jans-config-api/server/test-output/Default suite/Default test.html new file mode 100644 index 00000000000..0e9ca400b42 --- /dev/null +++ b/jans-config-api/server/test-output/Default suite/Default test.html @@ -0,0 +1,215 @@ + + +TestNG: Default test + + + + + + + + +

Default test

+ + + + + + + + + + + +
Tests passed/Failed/Skipped:0/0/1
Started on:Tue Nov 19 17:09:20 IST 2024
Total time:0 seconds (49 ms)
Included groups:
Excluded groups:

+(Hover the method name to see the test class name)

+ + + + + + + + + + + + + +
FAILED CONFIGURATIONS
Test methodAttribute(s)ExceptionTime (seconds)Instance
initTestSuite
Test class: io.jans.configapi.test.auth.ClientResourceTest
Parameters: org.testng.TestRunner@74518890
java.lang.NullPointerException
+	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
+	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
+	at java.base/java.nio.file.Path.of(Path.java:147)
+	at java.base/java.nio.file.Paths.get(Paths.java:69)
+	at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
+	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
+	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
+	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
+	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
+	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
+	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382)
+	at org.testng.SuiteRunner.run(SuiteRunner.java:336)
+	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
+	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
+	at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
+	at org.testng.TestNG.runSuites(TestNG.java:1114)
+	at org.testng.TestNG.run(TestNG.java:1082)
+	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
+	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
+	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)
+
Click to show all stack frames +
java.lang.NullPointerException
+	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
+	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
+	at java.base/java.nio.file.Path.of(Path.java:147)
+	at java.base/java.nio.file.Paths.get(Paths.java:69)
+	at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
+	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
+	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
+	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
+	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
+	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
+	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382)
+	at org.testng.SuiteRunner.run(SuiteRunner.java:336)
+	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
+	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
+	at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
+	at org.testng.TestNG.runSuites(TestNG.java:1114)
+	at org.testng.TestNG.run(TestNG.java:1082)
+	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
+	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
+	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)
+
0io.jans.configapi.test.auth.ClientResourceTest@3e2fc448

+ + + + + + + + + + + + + +
SKIPPED CONFIGURATIONS
Test methodAttribute(s)ExceptionTime (seconds)Instance
getAccessToken
Test class: io.jans.configapi.test.auth.ClientResourceTest
0io.jans.configapi.test.auth.ClientResourceTest@3e2fc448

+ + + + + + + + + + + + + +
SKIPPED TESTS
Test methodAttribute(s)ExceptionTime (seconds)Instance
postClient2
Test class: io.jans.configapi.test.auth.ClientResourceTest
Parameters: param-val-not-found, param-val-not-found, param-val-not-found
java.lang.NullPointerException
+	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
+	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
+	at java.base/java.nio.file.Path.of(Path.java:147)
+	at java.base/java.nio.file.Paths.get(Paths.java:69)
+	at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
+	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
+	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
+	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
+	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
+	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
+	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382)
+	at org.testng.SuiteRunner.run(SuiteRunner.java:336)
+	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
+	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
+	at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
+	at org.testng.TestNG.runSuites(TestNG.java:1114)
+	at org.testng.TestNG.run(TestNG.java:1082)
+	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
+	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
+	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)
+
Click to show all stack frames +
java.lang.NullPointerException
+	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
+	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
+	at java.base/java.nio.file.Path.of(Path.java:147)
+	at java.base/java.nio.file.Paths.get(Paths.java:69)
+	at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
+	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
+	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
+	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
+	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
+	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
+	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382)
+	at org.testng.SuiteRunner.run(SuiteRunner.java:336)
+	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
+	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
+	at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
+	at org.testng.TestNG.runSuites(TestNG.java:1114)
+	at org.testng.TestNG.run(TestNG.java:1082)
+	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
+	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
+	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)
+
0io.jans.configapi.test.auth.ClientResourceTest@3e2fc448

+ + \ No newline at end of file diff --git a/jans-config-api/server/test-output/Default suite/Default test.xml b/jans-config-api/server/test-output/Default suite/Default test.xml new file mode 100644 index 00000000000..bd4a13d62ca --- /dev/null +++ b/jans-config-api/server/test-output/Default suite/Default test.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/server/test-output/Default suite/testng-failed.xml b/jans-config-api/server/test-output/Default suite/testng-failed.xml new file mode 100644 index 00000000000..c7b78234715 --- /dev/null +++ b/jans-config-api/server/test-output/Default suite/testng-failed.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/server/test-output/bullet_point.png b/jans-config-api/server/test-output/bullet_point.png new file mode 100644 index 0000000000000000000000000000000000000000..176e6d5b3d64d032e76c493e5811a1cf839220b5 GIT binary patch literal 356 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqoCO|{#S9GG!XV7ZFl&wkP>?0v z(btiIVPjv-@4(4GzCyA`kS_y6l_~>6Lo)-z&;LOBB?CjL0RzLU1O^7H84L{K`IF+0 zx&hVR@^o z&n}1RKn7{ + + + +TestNG Report + + + + + + + +
Test# Passed# Skipped# Retried# FailedTime (ms)Included GroupsExcluded Groups
Default suite
Default test010049
+ +
ClassMethodStartTime (ms)
Default suite
Default test — failed (configuration methods)
io.jans.configapi.test.auth.ClientResourceTestinitTestSuite173201636014436
Default test — skipped (configuration methods)
io.jans.configapi.test.auth.ClientResourceTestfinalize17320163602760
getAccessToken17320163602280
Default test — skipped
io.jans.configapi.test.auth.ClientResourceTestpostClient217320163602320
+

Default test

io.jans.configapi.test.auth.ClientResourceTest#initTestSuite

Parameter #1
org.testng.TestRunner@74518890
Exception
java.lang.NullPointerException + at java.base/java.util.Objects.requireNonNull(Objects.java:208) + at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216) + at java.base/java.nio.file.Path.of(Path.java:147) + at java.base/java.nio.file.Paths.get(Paths.java:69) + at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139) + at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69) + at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390) + at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325) + at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382) + at org.testng.SuiteRunner.run(SuiteRunner.java:336) + at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) + at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95) + at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280) + at org.testng.TestNG.runSuitesLocally(TestNG.java:1200) + at org.testng.TestNG.runSuites(TestNG.java:1114) + at org.testng.TestNG.run(TestNG.java:1082) + at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) + at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293) + at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91) +

back to summary

+

io.jans.configapi.test.auth.ClientResourceTest#finalize

back to summary

+

io.jans.configapi.test.auth.ClientResourceTest#getAccessToken

back to summary

+

io.jans.configapi.test.auth.ClientResourceTest#postClient2

Parameter #1Parameter #2Parameter #3
param-val-not-foundparam-val-not-foundparam-val-not-found
Exception
java.lang.NullPointerException + at java.base/java.util.Objects.requireNonNull(Objects.java:208) + at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216) + at java.base/java.nio.file.Path.of(Path.java:147) + at java.base/java.nio.file.Paths.get(Paths.java:69) + at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139) + at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69) + at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390) + at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325) + at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382) + at org.testng.SuiteRunner.run(SuiteRunner.java:336) + at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) + at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95) + at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280) + at org.testng.TestNG.runSuitesLocally(TestNG.java:1200) + at org.testng.TestNG.runSuites(TestNG.java:1114) + at org.testng.TestNG.run(TestNG.java:1082) + at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) + at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293) + at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91) +

back to summary

+ + diff --git a/jans-config-api/server/test-output/failed.png b/jans-config-api/server/test-output/failed.png new file mode 100644 index 0000000000000000000000000000000000000000..c117be59a9ecd1da15ebf48f6b7f53496302a7cd GIT binary patch literal 977 zcmV;?11|iDP)4Tx0C)j~RNrgUP!#^!Wu36$i#lf!2|j3%Ze&w*L!7p2SGvtw>Nd9_NSmf@ zT$;ut?S8Na*^6&F#dq-sKKTa>*@JI;k`2ZbVfd_wB24xov!0tYO(#d#()tZ$I5%3%!zLYh@BH>w}XODA7?mkV}ap}jU$$3 zG&Mk)3Bm`(LOM&hKscCb;PVaG&Vdx+MpZJHTQ(R_;DA31$+jOGBoLXk_De?ey1m!ik&_4G zH9n^))_*|$z4!HUisgBd@awc5jn(v9k~&t~+vLrrBg4dZQ9lDnLV}JQWGLW~LJVP= zW5lZXOcog;N~F?hbX0k=IMzETla}oqM|jC!4!B+x^;@#I_Tc-T-6hwKycLDTx1-om z?X`jFy0R0R8-I0SrK4`)H@W4T8*Qr#2vPou<*`U!Wy(*2QP*`g=8#jD{B;Y@GL-Hm zb`n?&x~%YC_$q7)PlXr4m%r4=&fcvN%Ybn#KC7Nn&Bp8{(oE9pWVpYI^+LuN`H(R~ zTAjWmO`M83^4d@fCkA(d>*nHIFV_d2yUbnT`nd?LE^;G|!WZ>Ld?E0@Grm4ww{M7H zr`x{MWb30bTI;*hk-DO>dX$gbC-yy#suLNqvA(f>RtPJ!qGM`Gvvf}Y10`)vm-7Xa z?-7Ixe2A_siI1ydSCCID3U8SVUY86>uSnT0use_K1GZDvUFKY)t}F* z)!pahe+zh{{06Bb3f97*Uorpy0B%V{K~yLeW4y>F|DS;bz(j&tuu`}Ny`K+o>P41= zYq-R&z$-w|z14sZ}6S`uM8b)lMhS`K{GDtB9px6Kr!cSsofH?!*c`##8 zG{6+YB(Z6NYd}|wOA}U4!xUqq;Wl8C#3lv+hIuOk>aOmJ00000NkvXXu0mjfn+D0# literal 0 HcmV?d00001 diff --git a/jans-config-api/server/test-output/index.html b/jans-config-api/server/test-output/index.html new file mode 100644 index 00000000000..2dc98a6ad3a --- /dev/null +++ b/jans-config-api/server/test-output/index.html @@ -0,0 +1,280 @@ + + + + + + TestNG reports + + + + + + + + + + +
+ Test results + +
+ 1 suite +
+ +
+
+
+
+
+ + io.jans.configapi.test.auth.ClientResourceTest +
+
+
+
+ + + postClient2 + (param-val-not-found,param-val-not-found,param-val-not-found) +
java.lang.NullPointerException + at java.base/java.util.Objects.requireNonNull(Objects.java:208) + at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216) + at java.base/java.nio.file.Path.of(Path.java:147) + at java.base/java.nio.file.Paths.get(Paths.java:69) + at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139) + at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69) + at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390) + at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325) + at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382) + at org.testng.SuiteRunner.run(SuiteRunner.java:336) + at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) + at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95) + at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280) + at org.testng.TestNG.runSuitesLocally(TestNG.java:1200) + at org.testng.TestNG.runSuites(TestNG.java:1114) + at org.testng.TestNG.run(TestNG.java:1082) + at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) + at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293) + at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91) + +
+
+
+
+
+
+
+
+ C:\Users\pujavs\AppData\Local\Temp\testng-eclipse-1646905561\testng-customsuite.xml +
+
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
+<suite name="Default suite" guice-stage="DEVELOPMENT">
+  <parameter name="openid_client2" value="param-val-not-found"/>
+  <parameter name="issuer" value="param-val-not-found"/>
+  <parameter name="openidClientsUrl" value="param-val-not-found"/>
+  <test thread-count="5" name="Default test" verbose="2">
+    <classes>
+      <class name="io.jans.configapi.test.auth.ClientResourceTest">
+        <methods>
+          <include name="postClient2"/>
+        </methods>
+      </class> <!-- io.jans.configapi.test.auth.ClientResourceTest -->
+    </classes>
+  </test> <!-- Default test -->
+</suite> <!-- Default suite -->
+            
+
+
+
+
+ Tests for Default suite +
+
+
    +
  • + Default test (1 class) +
  • +
+
+
+
+
+ Groups for Default suite +
+
+
+
+
+
+ Times for Default suite +
+
+
+ + Total running time: 0 ms +
+
+
+
+
+
+
+ Reporter output for Default suite +
+
+
+
+
+
+ 2 ignored methods +
+
+
+ io.jans.configapi.test.auth.ClientResourceTest +
+ postClient +
+ getClients +
+
+
+
+
+
+
+ Methods in chronological order +
+
+
+
io.jans.configapi.test.auth.ClientResourceTest
+
+ + + initTestSuite(org.testng.TestRunner@74518890) + 0 ms +
+
+
+
+
+ + + diff --git a/jans-config-api/server/test-output/jquery-3.6.0.min.js b/jans-config-api/server/test-output/jquery-3.6.0.min.js new file mode 100644 index 00000000000..c4c6022f298 --- /dev/null +++ b/jans-config-api/server/test-output/jquery-3.6.0.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 + + + + + + + + + + + diff --git a/jans-config-api/server/test-output/navigator-bullet.png b/jans-config-api/server/test-output/navigator-bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..36d90d395c51912e718b89dd88b4a3fb53aa1d85 GIT binary patch literal 352 zcmV-m0iXVfP)G5@hw44>$jtc^drBsEhr7 z^X9?-KzfCWMC0vWtek#CBxB+XG+nX0$0e)!py)g%*!C9F3xb^$q9zV zJJ-RS;)J3Q3>X<0IJnsvq?E-OUUR%-Sh{}$*!>`a1>MbzjEoGd?5qriD%uRz5+)#_ z=~xvqF)}e2@@p|@3aYFDDdOf=+lQf0fP;_0P2842gi~-LkXsB?^cOvN)>U@o{(tlO y5-4a&(SrsYdr*b0AjKdWn<5ZqBsQ)A0t^5xc9&6bK}yU30000 + +Class name +Method name +Groups + +io.jans.configapi.test.auth.ClientResourceTest +   + +@Test + + +  +getClients +  + +  +postClient2 +  + +  +postClient +  + +@BeforeClass + + +@BeforeMethod + + +  +getAccessToken +  + +@AfterMethod + + +@AfterClass + + diff --git a/jans-config-api/server/test-output/old/Default suite/groups.html b/jans-config-api/server/test-output/old/Default suite/groups.html new file mode 100644 index 00000000000..199cb3f1188 --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/groups.html @@ -0,0 +1 @@ +

Groups used for this test run

\ No newline at end of file diff --git a/jans-config-api/server/test-output/old/Default suite/index.html b/jans-config-api/server/test-output/old/Default suite/index.html new file mode 100644 index 00000000000..8ed202c3be3 --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/index.html @@ -0,0 +1,6 @@ +Results for Default suite + + + + + diff --git a/jans-config-api/server/test-output/old/Default suite/main.html b/jans-config-api/server/test-output/old/Default suite/main.html new file mode 100644 index 00000000000..5888ae0744d --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/main.html @@ -0,0 +1,2 @@ +Results for Default suite +Select a result on the left-hand pane. diff --git a/jans-config-api/server/test-output/old/Default suite/methods-alphabetical.html b/jans-config-api/server/test-output/old/Default suite/methods-alphabetical.html new file mode 100644 index 00000000000..115a3fab23e --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/methods-alphabetical.html @@ -0,0 +1,6 @@ +

Methods run, sorted chronologically

>> means before, << means after


Default suite

(Hover the method name to see the test class name)

+ + + + +
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
24/11/19 17:09:20 0 >>initTestSuite      main@651235118
diff --git a/jans-config-api/server/test-output/old/Default suite/methods-not-run.html b/jans-config-api/server/test-output/old/Default suite/methods-not-run.html new file mode 100644 index 00000000000..df2dbaa2f45 --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/methods-not-run.html @@ -0,0 +1,4 @@ +

Methods that were not run

+ + +
io.jans.configapi.test.auth.ClientResourceTest.postClient
io.jans.configapi.test.auth.ClientResourceTest.getClients
\ No newline at end of file diff --git a/jans-config-api/server/test-output/old/Default suite/methods.html b/jans-config-api/server/test-output/old/Default suite/methods.html new file mode 100644 index 00000000000..115a3fab23e --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/methods.html @@ -0,0 +1,6 @@ +

Methods run, sorted chronologically

>> means before, << means after


Default suite

(Hover the method name to see the test class name)

+ + + + +
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
24/11/19 17:09:20 0 >>initTestSuite      main@651235118
diff --git a/jans-config-api/server/test-output/old/Default suite/reporter-output.html b/jans-config-api/server/test-output/old/Default suite/reporter-output.html new file mode 100644 index 00000000000..063bc2e96fd --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/reporter-output.html @@ -0,0 +1 @@ +

Reporter output

\ No newline at end of file diff --git a/jans-config-api/server/test-output/old/Default suite/testng.xml.html b/jans-config-api/server/test-output/old/Default suite/testng.xml.html new file mode 100644 index 00000000000..9f47c3a20ba --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/testng.xml.html @@ -0,0 +1 @@ +testng.xml for Default suite<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Default suite" guice-stage="DEVELOPMENT">
  <parameter name="openid_client2" value="param-val-not-found"/>
  <parameter name="issuer" value="param-val-not-found"/>
  <parameter name="openidClientsUrl" value="param-val-not-found"/>
  <test thread-count="5" name="Default test" verbose="2">
    <classes>
      <class name="io.jans.configapi.test.auth.ClientResourceTest">
        <methods>
          <include name="postClient2"/>
        </methods>
      </class> <!-- io.jans.configapi.test.auth.ClientResourceTest -->
    </classes>
  </test> <!-- Default test -->
</suite> <!-- Default suite -->
\ No newline at end of file diff --git a/jans-config-api/server/test-output/old/Default suite/toc.html b/jans-config-api/server/test-output/old/Default suite/toc.html new file mode 100644 index 00000000000..1bd1225486a --- /dev/null +++ b/jans-config-api/server/test-output/old/Default suite/toc.html @@ -0,0 +1,30 @@ + + +Results for Default suite + + + + +

Results for
Default suite

+ + + + + + + + + + +
1 test1 class1 method:
+  chronological
+  alphabetical
+  not run (2)
0 groupreporter outputtestng.xml
+ +

+

+
Default test (0/0/1) + Results +
+
+ \ No newline at end of file diff --git a/jans-config-api/server/test-output/old/index.html b/jans-config-api/server/test-output/old/index.html new file mode 100644 index 00000000000..1335d5818da --- /dev/null +++ b/jans-config-api/server/test-output/old/index.html @@ -0,0 +1,9 @@ + + + + +

Test results

+ + + +
SuitePassedFailedSkippedtestng.xml
Total001 
Default suite001Link
diff --git a/jans-config-api/server/test-output/passed.png b/jans-config-api/server/test-output/passed.png new file mode 100644 index 0000000000000000000000000000000000000000..45e85bbfd0f5e85def14b896cfd4331675be2759 GIT binary patch literal 1019 zcmV4Tx0C)j~RNrgUP!#^!Wu36$i#lf!2|j3%Ze&w*L!7p2SGvtw>Nd9_NSmf@ zT$;ut?S8Na*^6&F#dq-sKKTa>*@JI;k`2ZbVfd_wB24xov!0tYO(#d#()tZ$I5%3%!zLYh@BH>w}XODA7?mkV}ap}jU$$3 zG&Mk)3Bm`(LOM&hKscCb;PVaG&Vdx+MpZJHTQ(R_;DA31$+jOGBoLXk_De?ey1m!ik&_4G zH9n^))_*|$z4!HUisgBd@awc5jn(v9k~&t~+vLrrBg4dZQ9lDnLV}JQWGLW~LJVP= zW5lZXOcog;N~F?hbX0k=IMzETla}oqM|jC!4!B+x^;@#I_Tc-T-6hwKycLDTx1-om z?X`jFy0R0R8-I0SrK4`)H@W4T8*Qr#2vPou<*`U!Wy(*2QP*`g=8#jD{B;Y@GL-Hm zb`n?&x~%YC_$q7)PlXr4m%r4=&fcvN%Ybn#KC7Nn&Bp8{(oE9pWVpYI^+LuN`H(R~ zTAjWmO`M83^4d@fCkA(d>*nHIFV_d2yUbnT`nd?LE^;G|!WZ>Ld?E0@Grm4ww{M7H zr`x{MWb30bTI;*hk-DO>dX$gbC-yy#suLNqvA(f>RtPJ!qGM`Gvvf}Y10`)vm-7Xa z?-7Ixe2A_siI1ydSCCID3U8SVUY86>uSnT0use_K1GZDvUFKY)t}F* z)!pahe+zh{{06Bb3f97*Uorpy0GLTcK~yLeW0ahz`=5aXz(j&tuu_sWu%O#uE8~VD zl&lrR;HF{4AT>#kuni$fu3*LaYg^!kpg8GS-X(?~-@n6gsDV2}@4opAtDmldYd~=l z$fS+YQyErY*vatm`)9DCL(k8^6@wTk8o(y4Wnh>XTmx2AyLA%7m+#+DG@v*MBy;8c pT?UXs5IFYyJeWo%7zba(0RWt9G$oT4y{G^H002ovPDHLkV1nS74Tx0C)j~RNrgUP!#^!Wu36$i#lf!2|j3%Ze&w*L!7p2SGvtw>Nd9_NSmf@ zT$;ut?S8Na*^6&F#dq-sKKTa>*@JI;k`2ZbVfd_wB24xov!0tYO(#d#()tZ$I5%3%!zLYh@BH>w}XODA7?mkV}ap}jU$$3 zG&Mk)3Bm`(LOM&hKscCb;PVaG&Vdx+MpZJHTQ(R_;DA31$+jOGBoLXk_De?ey1m!ik&_4G zH9n^))_*|$z4!HUisgBd@awc5jn(v9k~&t~+vLrrBg4dZQ9lDnLV}JQWGLW~LJVP= zW5lZXOcog;N~F?hbX0k=IMzETla}oqM|jC!4!B+x^;@#I_Tc-T-6hwKycLDTx1-om z?X`jFy0R0R8-I0SrK4`)H@W4T8*Qr#2vPou<*`U!Wy(*2QP*`g=8#jD{B;Y@GL-Hm zb`n?&x~%YC_$q7)PlXr4m%r4=&fcvN%Ybn#KC7Nn&Bp8{(oE9pWVpYI^+LuN`H(R~ zTAjWmO`M83^4d@fCkA(d>*nHIFV_d2yUbnT`nd?LE^;G|!WZ>Ld?E0@Grm4ww{M7H zr`x{MWb30bTI;*hk-DO>dX$gbC-yy#suLNqvA(f>RtPJ!qGM`Gvvf}Y10`)vm-7Xa z?-7Ixe2A_siI1ydSCCID3U8SVUY86>uSnT0use_K1GZDvUFKY)t}F* z)!pahe+zh{{06Bb3f97*Uorpy0Axu-K~yLeV|;sz;XeZjfQbaPV5M*kLYBBKLY9MT zcz2wU0a*fOGe`_12Lo^oAOUnu=!!vVSU?0aK-Pq8GE5DM4KP7`G=>J4GmvdUHULEf pOfgIWHcfC1=!$V^Vx)OY0{~v*D#slo71{s*002ovPDHLkV1jLYy!8M8 literal 0 HcmV?d00001 diff --git a/jans-config-api/server/test-output/testng-failed.xml b/jans-config-api/server/test-output/testng-failed.xml new file mode 100644 index 00000000000..c7b78234715 --- /dev/null +++ b/jans-config-api/server/test-output/testng-failed.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/server/test-output/testng-reports.css b/jans-config-api/server/test-output/testng-reports.css new file mode 100644 index 00000000000..d7b75c40478 --- /dev/null +++ b/jans-config-api/server/test-output/testng-reports.css @@ -0,0 +1,326 @@ +body { + margin: 0 0 5px 5px; +} + +ul { + margin: 0; +} + +li { + list-style-type: none; +} + +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +.navigator-selected { + background: #ffa500; +} + +.wrapper { + position: absolute; + top: 60px; + bottom: 0; + left: 400px; + right: 0; + overflow: auto; +} + +.navigator-root { + position: absolute; + top: 60px; + bottom: 0; + left: 0; + width: 400px; + overflow-y: auto; +} + +.suite { + margin: 0 10px 10px 0; + background-color: #fff8dc; +} + +.suite-name { + padding-left: 10px; + font-size: 25px; + font-family: Times, sans-serif; +} + +.main-panel-header { + padding: 5px; + background-color: #9FB4D9; /*afeeee*/; + font-family: monospace; + font-size: 18px; +} + +.main-panel-content { + padding: 5px; + margin-bottom: 10px; + background-color: #DEE8FC; /*d0ffff*/; +} + +.rounded-window { + border-radius: 10px; + border-style: solid; + border-width: 1px; +} + +.rounded-window-top { + border-top-right-radius: 10px 10px; + border-top-left-radius: 10px 10px; + border-style: solid; + border-width: 1px; + overflow: auto; +} + +.light-rounded-window-top { + border-top-right-radius: 10px 10px; + border-top-left-radius: 10px 10px; +} + +.rounded-window-bottom { + border-style: solid; + border-width: 0 1px 1px 1px; + border-bottom-right-radius: 10px 10px; + border-bottom-left-radius: 10px 10px; + overflow: auto; +} + +.method-name { + font-size: 12px; + font-family: monospace; +} + +.method-content { + border-style: solid; + border-width: 0 0 1px 0; + margin-bottom: 10px; + padding-bottom: 5px; + width: 80%; +} + +.parameters { + font-size: 14px; + font-family: monospace; +} + +.stack-trace { + white-space: pre; + font-family: monospace; + font-size: 12px; + font-weight: bold; + margin-top: 0; + margin-left: 20px; +} + +.testng-xml { + font-family: monospace; +} + +.method-list-content { + margin-left: 10px; +} + +.navigator-suite-content { + margin-left: 10px; + font: 12px 'Lucida Grande'; +} + +.suite-section-title { + margin-top: 10px; + width: 80%; + border-style: solid; + border-width: 1px 0 0 0; + font-family: Times, sans-serif; + font-size: 18px; + font-weight: bold; +} + +.suite-section-content { + list-style-image: url(bullet_point.png); +} + +.top-banner-root { + position: absolute; + top: 0; + height: 45px; + left: 0; + right: 0; + padding: 5px; + margin: 0 0 5px 0; + background-color: #0066ff; + font-family: Times, sans-serif; + color: #fff; + text-align: center; +} +.button{ + position: absolute; + margin-left:500px; + margin-top:8px; + background-color: white; + color:#0066ff; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight:bold; + border-color:#0066ff ; + border-radius:25px; + cursor: pointer; + height:30px; + width:150px; + outline:none; + +} + +.top-banner-title-font { + font-size: 25px; +} + +.test-name { + font-family: 'Lucida Grande', sans-serif; + font-size: 16px; +} + +.suite-icon { + padding: 5px; + float: right; + height: 20px; +} + +.test-group { + font: 20px 'Lucida Grande'; + margin: 5px 5px 10px 5px; + border-width: 0 0 1px 0; + border-style: solid; + padding: 5px; +} + +.test-group-name { + font-weight: bold; +} + +.method-in-group { + font-size: 16px; + margin-left: 80px; +} + +table.google-visualization-table-table { + width: 100%; +} + +.reporter-method-name { + font-size: 14px; + font-family: monospace; +} + +.reporter-method-output-div { + padding: 5px; + margin: 0 0 5px 20px; + font-size: 12px; + font-family: monospace; + border-width: 0 0 0 1px; + border-style: solid; +} + +.ignored-class-div { + font-size: 14px; + font-family: monospace; +} + +.ignored-methods-div { + padding: 5px; + margin: 0 0 5px 20px; + font-size: 12px; + font-family: monospace; + border-width: 0 0 0 1px; + border-style: solid; +} + +.border-failed { + border-top-left-radius: 10px 10px; + border-bottom-left-radius: 10px 10px; + border-style: solid; + border-width: 0 0 0 10px; + border-color: #f00; +} + +.border-skipped { + border-top-left-radius: 10px 10px; + border-bottom-left-radius: 10px 10px; + border-style: solid; + border-width: 0 0 0 10px; + border-color: #edc600; +} + +.border-passed { + border-top-left-radius: 10px 10px; + border-bottom-left-radius: 10px 10px; + border-style: solid; + border-width: 0 0 0 10px; + border-color: #19f52d; +} + +.times-div { + text-align: center; + padding: 5px; +} + +.suite-total-time { + font: 16px 'Lucida Grande'; +} + +.configuration-suite { + margin-left: 20px; +} + +.configuration-test { + margin-left: 40px; +} + +.configuration-class { + margin-left: 60px; +} + +.configuration-method { + margin-left: 80px; +} + +.test-method { + margin-left: 100px; +} + +.chronological-class { + background-color: skyblue; + border-style: solid; + border-width: 0 0 1px 1px; +} + +.method-start { + float: right; +} + +.chronological-class-name { + padding: 0 0 0 5px; + color: #008; +} + +.after, .before, .test-method { + font-family: monospace; + font-size: 14px; +} + +.navigator-suite-header { + font-size: 22px; + margin: 0 10px 5px 0; + background-color: #deb887; + text-align: center; +} + +.collapse-all-icon { + padding: 5px; + float: right; +} +/*retro Theme*/ diff --git a/jans-config-api/server/test-output/testng-reports.js b/jans-config-api/server/test-output/testng-reports.js new file mode 100644 index 00000000000..c1a84a35d45 --- /dev/null +++ b/jans-config-api/server/test-output/testng-reports.js @@ -0,0 +1,122 @@ +$(document).ready(function() { + $('a.navigator-link').on("click", function() { + // Extract the panel for this link + var panel = getPanelName($(this)); + + // Mark this link as currently selected + $('.navigator-link').parent().removeClass('navigator-selected'); + $(this).parent().addClass('navigator-selected'); + + showPanel(panel); + }); + + installMethodHandlers('failed'); + installMethodHandlers('skipped'); + installMethodHandlers('passed', true); // hide passed methods by default + + $('a.method').on("click", function() { + showMethod($(this)); + return false; + }); + + // Hide all the panels and display the first one (do this last + // to make sure the click() will invoke the listeners) + $('.panel').hide(); + $('.navigator-link').first().trigger("click"); + + // Collapse/expand the suites + $('a.collapse-all-link').on("click", function() { + var contents = $('.navigator-suite-content'); + if (contents.css('display') == 'none') { + contents.show(); + } else { + contents.hide(); + } + }); +}); + +// The handlers that take care of showing/hiding the methods +function installMethodHandlers(name, hide) { + function getContent(t) { + return $('.method-list-content.' + name + "." + t.attr('panel-name')); + } + + function getHideLink(t, name) { + var s = 'a.hide-methods.' + name + "." + t.attr('panel-name'); + return $(s); + } + + function getShowLink(t, name) { + return $('a.show-methods.' + name + "." + t.attr('panel-name')); + } + + function getMethodPanelClassSel(element, name) { + var panelName = getPanelName(element); + var sel = '.' + panelName + "-class-" + name; + return $(sel); + } + + $('a.hide-methods.' + name).on("click", function() { + var w = getContent($(this)); + w.hide(); + getHideLink($(this), name).hide(); + getShowLink($(this), name).show(); + getMethodPanelClassSel($(this), name).hide(); + }); + + $('a.show-methods.' + name).on("click", function() { + var w = getContent($(this)); + w.show(); + getHideLink($(this), name).show(); + getShowLink($(this), name).hide(); + showPanel(getPanelName($(this))); + getMethodPanelClassSel($(this), name).show(); + }); + + if (hide) { + $('a.hide-methods.' + name).trigger("click"); + } else { + $('a.show-methods.' + name).trigger("click"); + } +} + +function getHashForMethod(element) { + return element.attr('hash-for-method'); +} + +function getPanelName(element) { + return element.attr('panel-name'); +} + +function showPanel(panelName) { + $('.panel').hide(); + var panel = $('.panel[panel-name="' + panelName + '"]'); + panel.show(); +} + +function showMethod(element) { + var hashTag = getHashForMethod(element); + var panelName = getPanelName(element); + showPanel(panelName); + var current = document.location.href; + var base = current.substring(0, current.indexOf('#')) + document.location.href = base + '#' + hashTag; + var newPosition = $(document).scrollTop() - 65; + $(document).scrollTop(newPosition); +} + +function drawTable() { + for (var i = 0; i < suiteTableInitFunctions.length; i++) { + window[suiteTableInitFunctions[i]](); + } + + for (var k in window.suiteTableData) { + var v = window.suiteTableData[k]; + var div = v.tableDiv; + var data = v.tableData + var table = new google.visualization.Table(document.getElementById(div)); + table.draw(data, { + showRowNumber : false + }); + } +} diff --git a/jans-config-api/server/test-output/testng-reports1.css b/jans-config-api/server/test-output/testng-reports1.css new file mode 100644 index 00000000000..570323ffb8f --- /dev/null +++ b/jans-config-api/server/test-output/testng-reports1.css @@ -0,0 +1,344 @@ +body { + background-color: whitesmoke; + margin: 0 0 5px 5px; +} +ul { + margin-top: 10px; + margin-left:-10px; +} + li { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + padding:5px 5px; + } + a { + text-decoration: none; + color: black; + font-size: 14px; + } + + a:hover { + color:black ; + text-decoration: underline; + } + + .navigator-selected { + /* #ffa500; Mouse hover color after click Orange.*/ + background:#027368 + } + + .wrapper { + position: absolute; + top: 60px; + bottom: 0; + left: 400px; + right: 0; + margin-right:9px; + overflow: auto;/*imortant*/ + } + + .navigator-root { + position: absolute; + top: 60px; + bottom: 0; + left: 0; + width: 400px; + overflow-y: auto;/*important*/ + } + + .suite { + margin: -5px 10px 10px 5px; + background-color: whitesmoke ;/*Colour of the left bside box*/ + } + + .suite-name { + font-size: 24px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;/*All TEST SUITE*/ + color: white; + } + + .main-panel-header { + padding: 5px; + background-color: #027368; /*afeeee*/; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + color:white; + font-size: 18px; + } + + .main-panel-content { + padding: 5px; + margin-bottom: 10px; + background-color: #CCD0D1; /*d0ffff*/; /*Belongs to backGround of rightSide boxes*/ + } + + .rounded-window { + border-style: dotted; + border-width: 1px;/*Border of left Side box*/ + background-color: whitesmoke; + border-radius: 10px; + } + + .rounded-window-top { + border-top-right-radius: 10px 10px; + border-top-left-radius: 10px 10px; + border-style: solid; + border-width: 1px; + overflow: auto;/*Top of RightSide box*/ + } + + .light-rounded-window-top { + background-color: #027368; + padding-left:120px; + border-radius: 10px; + + } + + .rounded-window-bottom { + border-bottom-right-radius: 10px 10px; + border-bottom-left-radius: 10px 10px; + overflow: auto;/*Bottom of rightSide box*/ + } + + .method-name { + font-size: 14px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: bold; + } + + .method-content { + border-style: solid; + border-width: 0 0 1px 0; + margin-bottom: 10px; + padding-bottom: 5px; + width: 100%; + } + + .parameters { + font-size: 14px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + } + + .stack-trace { + white-space: pre; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-weight: bold; + margin-top: 0; + margin-left: 20px; /*Error Stack Trace Message*/ + } + + .testng-xml { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + } + + .method-list-content { + margin-left: 10px; + } + + .navigator-suite-content { + margin-left: 10px; + font: 12px 'Lucida Grande'; + } + + .suite-section-title { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-weight:bold; + background-color: #8C8887; + margin-left: -10px; + margin-top:10px; + padding:6px; + } + + .suite-section-content { + list-style-image: url(bullet_point.png); + background-color: whitesmoke; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + overflow: hidden; + } + + .top-banner-root { + position: absolute; + top: 0; + height: 45px; + left: 0; + right: 0; + padding: 5px; + margin: 0 0 5px 0; + background-color: #027368; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 18px; + color: #fff; + text-align: center;/*Belongs to the Top of Report*//*Status: - Completed*/ + } + + .top-banner-title-font { + font-size: 25px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + padding: 3px; + float: right; + } + + .test-name { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 16px; + } + + .suite-icon { + padding: 5px; + float: right; + height: 20px; + } + + .test-group { + font: 20px 'Lucida Grande'; + margin: 5px 5px 10px 5px; + border-width: 0 0 1px 0; + border-style: solid; + padding: 5px; + } + + .test-group-name { + font-weight: bold; + } + + .method-in-group { + font-size: 16px; + margin-left: 80px; + } + + table.google-visualization-table-table { + width: 100%; + } + + .reporter-method-name { + font-size: 14px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + } + + .reporter-method-output-div { + padding: 5px; + margin: 0 0 5px 20px; + font-size: 12px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + border-width: 0 0 0 1px; + border-style: solid; + } + + .ignored-class-div { + font-size: 14px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + } + + .ignored-methods-div { + padding: 5px; + margin: 0 0 5px 20px; + font-size: 12px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + border-width: 0 0 0 1px; + border-style: solid; + } + + .border-failed { + border-radius:2px; + border-style: solid; + border-width: 0 0 0 10px; + border-color: #F20505; + } + + .border-skipped { + border-radius:2px; + border-style: solid; + border-width: 0 0 0 10px; + border-color: #F2BE22; + } + + .border-passed { + border-radius:2px; + border-style: solid; + border-width: 0 0 0 10px; + border-color: #038C73; + } + + .times-div { + text-align: center; + padding: 5px; + } + + .suite-total-time { + font: 16px 'Lucida Grande'; + } + + .configuration-suite { + margin-left: 20px; + } + + .configuration-test { + margin-left: 40px; + } + + .configuration-class { + margin-left: 60px; + } + + .configuration-method { + margin-left: 80px; + } + + .test-method { + margin-left: 100px; + } + + .chronological-class { + background-color: #CCD0D1; + border-width: 0 0 1px 1px;/*Chronological*/ + } + + .method-start { + float: right; + } + + .chronological-class-name { + padding: 0 0 0 5px; + margin-top:5px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #008; + } + + .after, .before, .test-method { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + margin-top:5px; + } + + .navigator-suite-header { + font-size: 18px; + margin: 0px 10px 10px 5px; + padding: 5px; + border-radius: 10px; + background-color: #027368; + color: white; + font-weight:bold; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + text-align: center; /*All Suites on top of left box*//*Status: -Completed*/ + } + + .collapse-all-icon { + padding: 3px; + float: right; + } + .button{ + position: absolute; + margin-left:500px; + margin-top:8px; + background-color: white; + color:#027368; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight:bold; + border-color:#027368; + border-radius:25px; + cursor: pointer; + height:30px; + width:150px; + outline: none; +} +/*Author: - Akhil Gullapalli*/ \ No newline at end of file diff --git a/jans-config-api/server/test-output/testng-reports2.js b/jans-config-api/server/test-output/testng-reports2.js new file mode 100644 index 00000000000..5342859fa4d --- /dev/null +++ b/jans-config-api/server/test-output/testng-reports2.js @@ -0,0 +1,76 @@ +window.onload = function () { + let cookies = document.cookie; + let cookieValue = cookies.split('='); + if (cookieValue[1] === 'null' || localStorage.getItem('Theme') === 'null') { + document.getElementById('retro').setAttribute('disabled', 'false'); + } else if (cookieValue[1] === 'Switch Ultra Theme' || + localStorage.getItem('Theme') === 'Switch Ultra Theme') { + document.getElementById('button').innerText = "Switch Retro Theme"; + document.getElementById('retro').setAttribute('disabled', 'false'); + + } else if (cookieValue[1] === 'Switch Retro Theme' || + localStorage.getItem('Theme') === 'Switch Retro Theme') { + if (cookieValue[1] === 'Switch Ultra Theme' || + localStorage.getItem('Theme') === 'Switch Ultra Theme') { + document.getElementById('button').innerText = "Switch Retro Theme"; + document.getElementById('retro').setAttribute('disabled', 'false'); + + document.getElementById('button').innerText = "Switch Ultra Theme"; + document.getElementById('retro').removeAttribute('disabled'); + document.getElementById('ultra').setAttribute('disabled', 'false'); + localStorage.setItem('Theme', select); + + } else if (select === 'Switch Ultra Theme') { + document.getElementById('button').innerText = "Switch Retro Theme"; + document.getElementById('ultra').removeAttribute('disabled'); + document.getElementById('retro').setAttribute('disabled', 'false'); + localStorage.setItem('Theme', select); + } + } else if (cookieValue[1] === 'Switch Retro Theme' || + localStorage.getItem('Theme') === 'Switch Retro Theme') { + document.getElementById('button').innerText = "Switch Ultra Theme"; + document.getElementById('ultra').setAttribute('disabled', 'false'); + } +} +document.getElementById('button').onclick = function () { + let select = document.getElementById('button').innerText; + if (select === 'Switch Retro Theme') { + let d = new Date(); + days = 365; + d.setTime(+d + (days * 86400000)); //24 * 60 * 60 * 1000 + document.cookie = "Theme =" + select + "; expires=" + d.toGMTString() + ";"; + document.getElementById('button').innerText = "Switch Ultra Theme"; + document.getElementById('retro').removeAttribute('disabled'); + document.getElementById('ultra').setAttribute('disabled', 'false'); + localStorage.setItem('Theme', select); + + } else if (select === 'Switch Ultra Theme') { + let d = new Date(); + days = 365; + d.setTime(+d + (days * 86400000)); //24 * 60 * 60 * 1000 + document.cookie = "Theme =" + select + "; expires=" + d.toGMTString() + ";"; + document.getElementById('button').innerText = "Switch Retro Theme"; + document.getElementById('ultra').removeAttribute('disabled'); + document.getElementById('retro').setAttribute('disabled', 'false'); + localStorage.setItem('Theme', select); + } +} +//Function to mouse hovering affect. +document.getElementById('button').onmouseover = function () { + document.getElementById('button').style.borderRadius = "25px"; + document.getElementById('button').style.width = "180px"; + document.getElementById('button').style.height = "45px"; + document.getElementById('button').style.marginTop = "1px"; + +} +//Function to mouse out affect +document.getElementById('button').onmouseout = function () { + document.getElementById('button').style.borderRadius = "25px"; + document.getElementById('button').style.width = "150px"; + document.getElementById('button').style.height = "30px"; + document.getElementById('button').style.marginTop = "8px"; + +} + +//This is the file where we handle the switching of the Themes. +/*Author:- Akhil Gullapalli*/ diff --git a/jans-config-api/server/test-output/testng-results.xml b/jans-config-api/server/test-output/testng-results.xml new file mode 100644 index 00000000000..1d5bef92530 --- /dev/null +++ b/jans-config-api/server/test-output/testng-results.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/server/test-output/testng.css b/jans-config-api/server/test-output/testng.css new file mode 100644 index 00000000000..5124ba863b3 --- /dev/null +++ b/jans-config-api/server/test-output/testng.css @@ -0,0 +1,9 @@ +.invocation-failed, .test-failed { background-color: #DD0000; } +.invocation-percent, .test-percent { background-color: #006600; } +.invocation-passed, .test-passed { background-color: #00AA00; } +.invocation-skipped, .test-skipped { background-color: #CCCC00; } + +.main-page { + font-size: x-large; +} + From 9fe748f5c1b26066e1731e9ad6f5bcc1b4e51b84 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 19 Nov 2024 21:05:05 +0530 Subject: [PATCH 18/44] feat(config-api): testing framework change wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 10 +++---- .../test/auth/ClientResourceTest.java | 29 +++++++++---------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index d4214945bc4..6f665989f95 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9270,20 +9270,20 @@ components: type: string selected: type: boolean - userCanEdit: + whitePagesCanView: type: boolean userCanView: type: boolean adminCanView: type: boolean + userCanEdit: + type: boolean adminCanEdit: type: boolean adminCanAccess: type: boolean userCanAccess: type: boolean - whitePagesCanView: - type: boolean baseDn: type: string PatchRequest: @@ -11685,10 +11685,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index c2041a7206d..1e232d5496e 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -38,25 +38,21 @@ public void getClients(final String issuer, final String openidClientsUrl) { .get(issuer+openidClientsUrl).then().statusCode(200); } - @Parameters({"issuer", "openidClientsUrl", "openid_client1"}) - //@Test - public void postClient(final String issuer, final String openidClientsUrl, final String json) { - log.error("accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); - log.error("Creating client using json string - getHttpService():{}, this.accessToken:{}", getHttpService(), this.accessToken); - - HttpServiceResponse httpServiceResponse = getHttpService().executePost(issuer+openidClientsUrl, this.accessToken, null, json, - ContentType.APPLICATION_JSON, AUTHORIZATION_TYPE); - assertFalse(httpServiceResponse==null); + @Parameters({"issuer", "openidClientsUrl"}) + @Test + public void getAllClient(final String issuer, final String openidClientsUrl) { + log.error("getAllClient() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); + Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - int statusCode = httpServiceResponse.getHttpResponse().getStatusLine().getStatusCode(); + Response response = request.get(); + log.error("Response for Access Token - response:{}", response); - Status status = Status.fromStatusCode(statusCode); - log.error("postClient - using json string - status():{} ", status); - assertEquals(status, Status.CREATED.getStatusCode()); } - + @Parameters({"issuer", "openidClientsUrl", "openid_client2"}) - //@Test + @Test public void postClient2(final String issuer, final String openidClientsUrl, final String json) { log.error("postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); log.error("postClient2 client using json string - getHttpService():{}, this.accessToken:{}", getHttpService(), this.accessToken); @@ -65,7 +61,8 @@ public void postClient2(final String issuer, final String openidClientsUrl, fina request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - Response response = request.post(Entity.json(json)); + //Response response = request.post(Entity.json(json)); + Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); log.trace("Response for Access Token - response:{}", response); if (response.getStatus() == 201) { From 7d841266ce959ccb74d1c141b22300ec7ea15746 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 21 Nov 2024 20:31:02 +0530 Subject: [PATCH 19/44] feat(config-api): testmg framework change wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 20 ++--- .../test/java/io/jans/configapi/BaseTest.java | 89 ++++++++++++------- .../listener/AlterSuiteListener.java | 83 +++++++++++++++++ .../configapi/listener/PersistenceType.java | 16 ++++ .../io/jans/configapi/listener/SkipTest.java | 18 ++++ .../configapi/listener/SkipTestsListener.java | 42 +++++++++ .../test/auth/ClientResourceTest.java | 23 ++--- .../server/src/test/resources/testng.xml | 5 ++ 8 files changed, 238 insertions(+), 58 deletions(-) create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/listener/AlterSuiteListener.java create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/listener/PersistenceType.java create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTest.java create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTestsListener.java diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 6f665989f95..2690e0a71c0 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9272,17 +9272,17 @@ components: type: boolean whitePagesCanView: type: boolean - userCanView: - type: boolean - adminCanView: + userCanAccess: type: boolean - userCanEdit: + adminCanAccess: type: boolean adminCanEdit: type: boolean - adminCanAccess: + userCanView: type: boolean - userCanAccess: + adminCanView: + type: boolean + userCanEdit: type: boolean baseDn: type: string @@ -11249,14 +11249,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: @@ -11685,10 +11685,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index 3e6b70d3b0f..e4d1df5d1d8 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -9,19 +9,12 @@ import io.jans.as.client.TokenRequest; import io.jans.as.client.TokenResponse; import io.jans.as.model.common.GrantType; -import io.jans.as.model.common.ScopeType; -import io.jans.as.model.uma.wrapper.Token; import io.jans.as.model.util.Util; +import io.jans.configapi.core.util.Jackson; import io.jans.configapi.service.HttpService; import io.jans.configapi.service.ResteasyService; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - -import io.jans.model.net.HttpServiceResponse; - import static java.nio.charset.StandardCharsets.UTF_8; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyManagementException; @@ -34,16 +27,17 @@ import java.util.Properties; import java.net.URLEncoder; import java.io.UnsupportedEncodingException; - -import jakarta.servlet.http.HttpServletRequest; - import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; +import java.io.BufferedReader; +import java.io.InputStreamReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.net.URLDecoder; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.cert.CertificateException; @@ -52,6 +46,8 @@ import java.util.*; import java.util.Map.Entry; +import jakarta.servlet.http.HttpServletRequest; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -84,6 +80,8 @@ import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; +import org.json.JSONObject; +import org.json.JSONException; import org.testng.ITestContext; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeMethod; @@ -102,6 +100,10 @@ public class BaseTest { + private static final String FILE_PREFIX = "file:"; + private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + private static final String NEW_LINE = System.getProperty("line.separator"); + protected static final String CONTENT_TYPE = "Content-Type"; protected static final String AUTHORIZATION = "Authorization"; protected static final String AUTHORIZATION_TYPE = "Bearer"; @@ -110,23 +112,23 @@ public class BaseTest { protected static Map propertiesMap = null; protected ResteasyService resteasyService = new ResteasyService();; protected HttpService httpService = new HttpService(); - protected String accessToken; + protected String accessToken; @BeforeSuite public void initTestSuite(ITestContext context) throws Exception { - log.error("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); + log.error("Invoked initTestSuite propertiesFile '{}'", propertiesFile); + Properties prop = new Properties(); prop.load(Files.newBufferedReader(Paths.get(propertiesFile), UTF_8)); propertiesMap = new Hashtable<>(); prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); context.getSuite().getXmlSuite().setParameters(propertiesMap); - + log.error("End initTestSuite propertiesMap: {}", propertiesMap); - } @@ -139,7 +141,7 @@ public void finalize() { @BeforeMethod public void getAccessToken() throws Exception { log.error("getAccessToken - propertiesMap:{}", propertiesMap); - + String tokenUrl = propertiesMap.get("tokenEndpoint"); String strGrantType = propertiesMap.get("tokenGrantType"); String clientId = propertiesMap.get("clientId"); @@ -147,19 +149,20 @@ public void getAccessToken() throws Exception { String scopes = propertiesMap.get("scopes"); String authStr = clientId + ':' + clientSecret; - GrantType grantType = GrantType.fromString(strGrantType); - this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); + GrantType grantType = GrantType.fromString(strGrantType); + this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); log.error("accessToken:{}", accessToken); } - - public String getToken(final String tokenUrl, final String clientId, final String clientSecret, - GrantType grantType, final String scopes) { - log.info("Request for token tokenUrl:{}, clientId:{}, grantType:{}, scopes:{}", tokenUrl, clientId, grantType, scopes); + + public String getToken(final String tokenUrl, final String clientId, final String clientSecret, GrantType grantType, + final String scopes) { + log.info("Request for token tokenUrl:{}, clientId:{}, grantType:{}, scopes:{}", tokenUrl, clientId, grantType, + scopes); String accessToken = null; TokenResponse tokenResponse = this.requestAccessToken(tokenUrl, clientId, clientSecret, grantType, scopes); if (tokenResponse != null) { accessToken = tokenResponse.getAccessToken(); - log.trace("accessToken:{}, ", accessToken); + log.trace("accessToken:{}, ", accessToken); } return accessToken; @@ -170,7 +173,7 @@ public TokenResponse requestAccessToken(final String tokenUrl, final String clie log.info("Request for access token tokenUrl:{}, clientId:{},scope:{}", tokenUrl, clientId, scope); Response response = null; try { - if (grantType==null) { + if (grantType == null) { grantType = GrantType.CLIENT_CREDENTIALS; } TokenRequest tokenRequest = new TokenRequest(grantType); @@ -199,23 +202,21 @@ public TokenResponse requestAccessToken(final String tokenUrl, final String clie } return null; } - - + protected HttpService getHttpService() { return this.httpService; } - - + protected ResteasyService getResteasyService() { return this.resteasyService; } - - protected String getCredentials(final String clientId, final String clientSecret) throws UnsupportedEncodingException { - return URLEncoder.encode(clientId, Util.UTF8_STRING_ENCODING) - + ":" + + protected String getCredentials(final String clientId, final String clientSecret) + throws UnsupportedEncodingException { + return URLEncoder.encode(clientId, Util.UTF8_STRING_ENCODING) + ":" + URLEncoder.encode(clientSecret, Util.UTF8_STRING_ENCODING); } - + /** * Returns the client credentials encoded using base64. * @@ -234,6 +235,26 @@ protected String getEncodedCredentials() { return null; } - + protected String decodeFileValue(String value) { + log.error("\n\n decodeFileValue"); + String decoded = value; + if (value.startsWith(FILE_PREFIX)) { + value = value.substring(FILE_PREFIX.length()); // remove the prefix + + try (BufferedReader bfr = Files.newBufferedReader(Paths.get(value), DEFAULT_CHARSET)) { // create reader + // appends every line after another + decoded = bfr.lines().reduce("", (partial, next) -> partial + NEW_LINE + next); + if (decoded.length() == 0) + log.warn("Key '{}' is empty", value); + } catch (IOException e) { + log.error(e.getMessage(), e); + decoded = null; + } + } + + log.error("\n\n decodeFileValue - decoded:{}", decoded); + return decoded; + + } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/AlterSuiteListener.java b/jans-config-api/server/src/test/java/io/jans/configapi/listener/AlterSuiteListener.java new file mode 100644 index 00000000000..3cf2280980f --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/listener/AlterSuiteListener.java @@ -0,0 +1,83 @@ +package io.jans.configapi.listener; + +import io.jans.util.StringHelper; +import io.jans.util.security.SecurityProviderUtility; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.testng.IAlterSuiteListener; +import org.testng.xml.XmlSuite; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Hashtable; +import java.util.Map; +import java.util.List; +import java.util.Properties; + +public class AlterSuiteListener implements IAlterSuiteListener { + + static PersistenceType persistenceType; + + private static final String FILE_PREFIX = "file:"; + private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + private static final String NEW_LINE = System.getProperty("line.separator"); + + private Logger logger = LogManager.getLogger(getClass()); + + public void alter(List suites) { + + try { + SecurityProviderUtility.installBCProvider(); + logger.error("\n\n Parsing XML suite"); + XmlSuite suite = suites.get(0); + + //Properties with the file: preffix will point to real .json files stored under src/test/resources folder + String propertiesFile = suite.getParameter("propertiesFile"); + + + Properties prop = new Properties(); + prop.load(Files.newBufferedReader(Paths.get(propertiesFile), DEFAULT_CHARSET)); //do not bother about IO issues here + + persistenceType = PersistenceType.fromString(prop.getProperty("persistenceType")); + logger.error("Using persistence type = {}", persistenceType); + + Map parameters = new Hashtable<>(); + //do not bother about empty keys... but + //If a value is found null, this will throw a NPE since we are using a Hashtable + prop.forEach((Object key, Object value) -> parameters.put(key.toString(), decodeFileValue(value.toString()))); + // Override test parameters + suite.setParameters(parameters); + + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + } + + private String decodeFileValue(String value) { + logger.error("\n\n decodeFileValue"); + String decoded = value; + if (value.startsWith(FILE_PREFIX)) { + value = value.substring(FILE_PREFIX.length()); //remove the prefix + + try (BufferedReader bfr = Files.newBufferedReader(Paths.get(value), DEFAULT_CHARSET)) { //create reader + //appends every line after another + decoded = bfr.lines().reduce("", (partial, next) -> partial + NEW_LINE + next); + if (decoded.length() == 0) + logger.warn("Key '{}' is empty", value); + } catch (IOException e) { + logger.error(e.getMessage(), e); + decoded = null; + } + } + + logger.error("\n\n decodeFileValue - decoded:{}",decoded); + return decoded; + + } + +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/PersistenceType.java b/jans-config-api/server/src/test/java/io/jans/configapi/listener/PersistenceType.java new file mode 100644 index 00000000000..a1bd7afb960 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/listener/PersistenceType.java @@ -0,0 +1,16 @@ +package io.jans.configapi.listener; + +import io.jans.util.StringHelper; + +import java.util.stream.Stream; + +public enum PersistenceType { + LDAP, COUCHBASE, SPANNER, SQL; + + public static PersistenceType fromString(String from) { + return Stream.of(PersistenceType.values()) + .filter(bt -> StringHelper.equalsIgnoreCase(bt.name(), from)) + .findFirst().orElse(null); + } + +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTest.java new file mode 100644 index 00000000000..ff8d923f410 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTest.java @@ -0,0 +1,18 @@ +package io.jans.configapi.listener; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface SkipTest { + + /** + * See valid values for databases in enum {@link PersistenceType} + */ + String[] databases() default {}; + +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTestsListener.java b/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTestsListener.java new file mode 100644 index 00000000000..fad58e05fd5 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTestsListener.java @@ -0,0 +1,42 @@ +package io.jans.configapi.listener; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.stream.Stream; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.testng.IAnnotationTransformer; +import org.testng.annotations.ITestAnnotation; + +public class SkipTestsListener implements IAnnotationTransformer { + + private Logger logger = LogManager.getLogger(getClass()); + + public void transform(ITestAnnotation annotation, Class testClass, + Constructor testConstructor, Method testMethod) { + + if (testMethod != null) { + // Try to find SkipTest annotation at method level or at class level + SkipTest skipper = testMethod.getAnnotation(SkipTest.class); + + if (skipper == null) { + skipper = testMethod.getDeclaringClass().getAnnotation(SkipTest.class); + } + + if (skipper != null) { + // Search for a match with value of BaseTest.persistenceType (it's computed before suite) + boolean disable = Stream.of(skipper.databases()) + .map(PersistenceType::fromString).anyMatch(AlterSuiteListener.persistenceType::equals); + + if (disable) { + logger.warn("Disabling test method {}", testMethod.getName()); + annotation.setEnabled(false); + } + } + } + + } + +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index 1e232d5496e..5d454d3e75b 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -6,6 +6,8 @@ package io.jans.configapi.test.auth; +import io.jans.as.common.model.registration.Client; + import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; import io.jans.model.net.HttpServiceResponse; @@ -13,11 +15,13 @@ import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; +import org.json.JSONObject; import static org.testng.Assert.*; import java.util.Map; import org.apache.http.entity.ContentType; +import org.json.JSONObject; import org.testng.annotations.Parameters; import org.testng.annotations.Test; @@ -29,14 +33,6 @@ public class ClientResourceTest extends BaseTest{ private String clientId; - @Parameters({"issuer", "openidClientsUrl"}) - @Test - public void getClients(final String issuer, final String openidClientsUrl) { - log.error("accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " " + accessToken, null) - .get(issuer+openidClientsUrl).then().statusCode(200); - } @Parameters({"issuer", "openidClientsUrl"}) @Test @@ -54,16 +50,15 @@ public void getAllClient(final String issuer, final String openidClientsUrl) { @Parameters({"issuer", "openidClientsUrl", "openid_client2"}) @Test public void postClient2(final String issuer, final String openidClientsUrl, final String json) { - log.error("postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); - log.error("postClient2 client using json string - getHttpService():{}, this.accessToken:{}", getHttpService(), this.accessToken); + log.error("\n\n\n postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - - //Response response = request.post(Entity.json(json)); - Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); - log.trace("Response for Access Token - response:{}", response); + String jsonStr = decodeFileValue(json); + log.error("\n\n\n postClient2 - jsonStr:{}", jsonStr); + Response response = request.post(Entity.entity(jsonStr, MediaType.APPLICATION_JSON)); + log.error("post client - response:{}", response); if (response.getStatus() == 201) { log.trace("Response for Access Token - response.getEntity():{}, response.getClass():{}", response.getEntity(), response.getClass()); diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index 45db2d7808f..634768b8efc 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -3,6 +3,11 @@ + + + + + From 74b78d6ebd5a214dc9b0288ef5919489aa34d357 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 21 Nov 2024 20:45:28 +0530 Subject: [PATCH 20/44] feat(config-api): testmg framework change wip Signed-off-by: pujavs --- jans-config-api/docs/jans-config-api-swagger.yaml | 12 ++++++------ .../src/test/java/io/jans/configapi/BaseTest.java | 12 ++++++------ .../jans/configapi/test/auth/ClientResourceTest.java | 6 +++--- .../src/test/resources/config-api-test.properties | 6 +++--- jans-config-api/server/src/test/resources/testng.xml | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 2690e0a71c0..99b20c045b0 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9272,10 +9272,6 @@ components: type: boolean whitePagesCanView: type: boolean - userCanAccess: - type: boolean - adminCanAccess: - type: boolean adminCanEdit: type: boolean userCanView: @@ -9284,6 +9280,10 @@ components: type: boolean userCanEdit: type: boolean + adminCanAccess: + type: boolean + userCanAccess: + type: boolean baseDn: type: string PatchRequest: @@ -11249,14 +11249,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java index e4d1df5d1d8..8173d00331b 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java @@ -117,16 +117,16 @@ public class BaseTest { @BeforeSuite public void initTestSuite(ITestContext context) throws Exception { - log.error("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); + //log.error("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); log.error("Invoked initTestSuite propertiesFile '{}'", propertiesFile); - Properties prop = new Properties(); - prop.load(Files.newBufferedReader(Paths.get(propertiesFile), UTF_8)); + //Properties prop = new Properties(); + // prop.load(Files.newBufferedReader(Paths.get(propertiesFile), UTF_8)); - propertiesMap = new Hashtable<>(); - prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); - context.getSuite().getXmlSuite().setParameters(propertiesMap); + propertiesMap = context.getSuite().getXmlSuite().getParameters(); + //prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); + //context.getSuite().getXmlSuite().setParameters(propertiesMap); log.error("End initTestSuite propertiesMap: {}", propertiesMap); diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index 5d454d3e75b..eeb8e276bbf 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -55,9 +55,9 @@ public void postClient2(final String issuer, final String openidClientsUrl, fina Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - String jsonStr = decodeFileValue(json); - log.error("\n\n\n postClient2 - jsonStr:{}", jsonStr); - Response response = request.post(Entity.entity(jsonStr, MediaType.APPLICATION_JSON)); + //String jsonStr = decodeFileValue(json); + //log.error("\n\n\n postClient2 - jsonStr:{}", jsonStr); + Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); log.error("post client - response:{}", response); if (response.getStatus() == 201) { diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties index c7ec06fcaf6..a2222461bed 100644 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -36,12 +36,12 @@ tokenUrl=/jans-config-api/api/v1/token #defaultAcr -default_acr1=file:target/test-classes/json/acr/defaultAcr.json +#default_acr1=file:target/test-classes/json/acr/defaultAcr.json #openid-client -openid_client1=file:target/test-classes/json/openid/clients/client.json +#openid_client1=file:target/test-classes/json/openid/clients/client.json openid_client2=file:target/test-classes/json/openid/clients/openid-client-post.json #openid-scopes -openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json +#openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index 634768b8efc..4878788b305 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -5,7 +5,7 @@ - + From 27ea40f984a4992c73794b5e693e28b82f44691b Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 21 Nov 2024 21:16:38 +0530 Subject: [PATCH 21/44] feat(config-api): testmg framework change wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 99b20c045b0..a549115455f 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9270,19 +9270,19 @@ components: type: string selected: type: boolean - whitePagesCanView: - type: boolean adminCanEdit: type: boolean - userCanView: - type: boolean adminCanView: type: boolean + userCanView: + type: boolean userCanEdit: type: boolean + userCanAccess: + type: boolean adminCanAccess: type: boolean - userCanAccess: + whitePagesCanView: type: boolean baseDn: type: string @@ -10131,6 +10131,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10140,8 +10142,6 @@ components: - code - token - id_token - fapi: - type: boolean AuthenticationFilter: required: - baseDn @@ -11685,10 +11685,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: From c32843593337aec8cb4ad8de3fdd582e42e21458 Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 25 Nov 2024 19:11:11 +0530 Subject: [PATCH 22/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 16 +-- .../plugins/admin-ui-plugin/pom.xml | 22 ++-- .../ca/plugin/adminui/AdminUIBaseTest.java | 104 ++++++++++++++++++ .../ca/plugin/adminui/KarateTestRunner.java | 19 ---- .../TestAdminUIPluginJenkinsRunner.java | 43 -------- .../adminui/test/ClientResourceTest.java | 71 ++++++++++++ .../test/resources/config-api-test.properties | 50 +++++++++ .../resources/json/auth/auditLogging.feature | 15 +++ .../test/resources/json/auth/license.feature | 10 ++ .../test/resources/json/auth/oauth2.feature | 26 +++++ .../src/test/resources/testng.xml | 20 ++++ .../plugins/docs/user-mgt-plugin-swagger.yaml | 4 +- jans-config-api/pom.xml | 1 - jans-config-api/server/pom.xml | 4 +- .../jans/configapi/ConfigServerBaseTest.java | 104 ++++++++++++++++++ .../configapi/test/auth/AcrsResourceTest.java | 4 +- .../auth/AgamaDeploymentsResourceTest.java | 4 +- .../test/auth/AuthConfigResourceTest.java | 4 +- .../test/auth/ClientResourceTest.java | 4 +- jans-config-api/shared/pom.xml | 10 ++ .../jans/configapi/core/test}/BaseTest.java | 6 +- .../test}/listener/AlterSuiteListener.java | 2 +- .../test}/listener/ApiUnitTestListener.java | 2 +- .../core/test}/listener/PersistenceType.java | 2 +- .../core/test}/listener/SkipTest.java | 2 +- .../test}/listener/SkipTestsListener.java | 2 +- .../core/test}/service/HttpService.java | 2 +- .../core/test}/service/ResteasyService.java | 2 +- 28 files changed, 452 insertions(+), 103 deletions(-) create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java delete mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/KarateTestRunner.java delete mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/TestAdminUIPluginJenkinsRunner.java create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/ClientResourceTest.java create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/auditLogging.feature create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/license.feature create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/oauth2.feature create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml create mode 100644 jans-config-api/server/src/test/java/io/jans/configapi/ConfigServerBaseTest.java rename jans-config-api/{server/src/test/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core/test}/BaseTest.java (98%) rename jans-config-api/{server/src/test/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core/test}/listener/AlterSuiteListener.java (98%) rename jans-config-api/{server/src/test/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core/test}/listener/ApiUnitTestListener.java (97%) rename jans-config-api/{server/src/test/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core/test}/listener/PersistenceType.java (88%) rename jans-config-api/{server/src/test/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core/test}/listener/SkipTest.java (89%) rename jans-config-api/{server/src/test/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core/test}/listener/SkipTestsListener.java (96%) rename jans-config-api/{server/src/test/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core/test}/service/HttpService.java (99%) rename jans-config-api/{server/src/test/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core/test}/service/ResteasyService.java (93%) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 9dc96231226..e23deb79907 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9271,19 +9271,19 @@ components: type: string selected: type: boolean - adminCanAccess: - type: boolean - adminCanView: + whitePagesCanView: type: boolean adminCanEdit: type: boolean - userCanAccess: + userCanEdit: type: boolean userCanView: type: boolean - whitePagesCanView: + adminCanView: type: boolean - userCanEdit: + adminCanAccess: + type: boolean + userCanAccess: type: boolean baseDn: type: string @@ -10914,10 +10914,10 @@ components: type: array items: type: object - displayValue: - type: string value: type: object + displayValue: + type: string LocalizedString: type: object properties: diff --git a/jans-config-api/plugins/admin-ui-plugin/pom.xml b/jans-config-api/plugins/admin-ui-plugin/pom.xml index c47467970a1..dfd1622af32 100644 --- a/jans-config-api/plugins/admin-ui-plugin/pom.xml +++ b/jans-config-api/plugins/admin-ui-plugin/pom.xml @@ -37,7 +37,12 @@ rest-assured test - + + org.testng + testng + test + + jakarta.xml.bind @@ -119,14 +124,11 @@ maven-surefire-plugin - - - - integration - - --tags ~@ignore - - + + + target/test-classes/testng.xml + + integration-tests diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java new file mode 100644 index 00000000000..741571b0f4f --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -0,0 +1,104 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.core.test; + +import io.jans.as.client.TokenRequest; +import io.jans.as.client.TokenResponse; +import io.jans.as.model.common.GrantType; +import io.jans.as.model.util.Util; +import io.jans.configapi.core.util.Jackson; +import io.jans.configapi.core.test.BaseTest; + + +import static java.nio.charset.StandardCharsets.UTF_8; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; + +import java.util.Hashtable; +import java.util.Map; +import java.util.Properties; +import java.net.URLEncoder; +import java.io.UnsupportedEncodingException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URLDecoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.util.*; +import java.util.Map.Entry; + +import jakarta.servlet.http.HttpServletRequest; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CookieStore; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.entity.ContentType; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.SSLContexts; + +import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; +import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; +import org.jboss.resteasy.client.jaxrs.ResteasyClient; +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; +import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; + +import org.json.JSONObject; +import org.json.JSONException; +import org.testng.ITestContext; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.BeforeTest; + +import jakarta.annotation.PostConstruct; +import jakarta.ws.rs.core.UriBuilder; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedHashMap; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +public class AdminUIBaseTest extends BaseTest{ + + //AdminUI specific code +} diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/KarateTestRunner.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/KarateTestRunner.java deleted file mode 100644 index a9d07255f2f..00000000000 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/KarateTestRunner.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.ca.plugin.adminui; - -import com.intuit.karate.junit5.Karate; -import org.junit.jupiter.api.Test; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/TestAdminUIPluginJenkinsRunner.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/TestAdminUIPluginJenkinsRunner.java deleted file mode 100644 index 466e942a336..00000000000 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/TestAdminUIPluginJenkinsRunner.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.ca.plugin.adminui; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * @author Yuriy Zabrovarnyy - */ -public class TestAdminUIPluginJenkinsRunner { - - @Test - void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/ClientResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/ClientResourceTest.java new file mode 100644 index 00000000000..21d4b9f9620 --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/ClientResourceTest.java @@ -0,0 +1,71 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test.auth; + +import io.jans.as.common.model.registration.Client; + +import static io.restassured.RestAssured.given; +import io.jans.configapi.ConfigServerBaseTest; +import io.jans.model.net.HttpServiceResponse; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; + +import org.json.JSONObject; +import static org.testng.Assert.*; + +import java.util.Map; + +import org.apache.http.entity.ContentType; +import org.json.JSONObject; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + + +public class ClientResourceTest extends ConfigServerBaseTest{ + + private String clientId; + + + @Parameters({"issuer", "openidClientsUrl"}) + @Test + public void getAllClient(final String issuer, final String openidClientsUrl) { + log.error("getAllClient() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); + Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + + Response response = request.get(); + log.error("Response for Access Token - response:{}", response); + + } + + @Parameters({"issuer", "openidClientsUrl", "openid_client2"}) + @Test + public void postClient2(final String issuer, final String openidClientsUrl, final String json) { + log.error("\n\n\n postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); + + Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + //String jsonStr = decodeFileValue(json); + //log.error("\n\n\n postClient2 - jsonStr:{}", jsonStr); + Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); + log.error("post client - response:{}", response); + + if (response.getStatus() == 201) { + log.trace("Response for Access Token - response.getEntity():{}, response.getClass():{}", response.getEntity(), response.getClass()); + } + + + + assertEquals(response.getStatus(), Status.CREATED.getStatusCode()); + } +} diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties new file mode 100644 index 00000000000..5863e6d3395 --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties @@ -0,0 +1,50 @@ +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete + +# Test env Setting +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +test.authzurl=https://admin-ui-test.gluu.org/jans-auth/authorize.htm + + +statUrl=/jans-config-api/api/v1/stat +healthUrl=/jans-config-api/api/v1/health +acrsUrl=/jans-config-api/api/v1/acrs +authConfigurationUrl=/jans-config-api/api/v1/jans-auth-server/config +scriptsUrl=/jans-config-api/api/v1/config/scripts +cacheUrl=/jans-config-api/api/v1/config/cache +messageUrl=/jans-config-api/api/v1/config/message +jwksUrl=/jans-config-api/api/v1/config/jwks +ldapUrl=/jans-config-api/api/v1/config/database/ldap +openidClientsUrl=/jans-config-api/api/v1/openid/clients +scopesUrl=/jans-config-api/api/v1/scopes +umaresourcesUrl=/jans-config-api/api/v1/uma/resources +attributesUrl=/jans-config-api/api/v1/attributes +smtpUrl=/jans-config-api/api/v1/config/smtp +loggingUrl=/jans-config-api/api/v1/logging +authHealthUrl=/jans-config-api/api/v1/jans-auth-server/health +orgConfigurationUrl=/jans-config-api/api/v1/org +userUrl=/jans-config-api/api/v1/user +agamaUrl=/jans-config-api/api/v1/agama +sessionUrl=/jans-config-api/api/v1/jans-auth-server/session +pluginUrl=/jans-config-api/api/v1/plugin +apiConfigUrl=/jans-config-api/api/v1/api-config +agamaDeploymentUrl=/jans-config-api/api/v1/agama-deployment +clientsAuthorizationsUrl=/jans-config-api/api/v1/clients/authorizations +tokenUrl=/jans-config-api/api/v1/token + + +#defaultAcr +#default_acr1=file:target/test-classes/json/acr/defaultAcr.json + +#openid-client +#openid_client1=file:target/test-classes/json/openid/clients/client.json +openid_client2=file:target/test-classes/json/openid/clients/openid-client-post.json + +#openid-scopes +#openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json + diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/auditLogging.feature b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/auditLogging.feature new file mode 100644 index 00000000000..788f8d35ac3 --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/auditLogging.feature @@ -0,0 +1,15 @@ +# new feature +# Tags: optional + +Feature: Test License endpoints of admin-ui + + Scenario Outline: Testing 'auditLogging' POST endpoint + Given url + And header = + And request + When method + Then status + And print + Examples: + | expression | name | values | body | method | status | exps | + | getAuditLoggingURL | Accept | 'application/json' | {\"message\": {\"childMsg\": \"Testing audit logging.\"}} | POST | 200 | response | \ No newline at end of file diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/license.feature b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/license.feature new file mode 100644 index 00000000000..8dc9e510f17 --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/license.feature @@ -0,0 +1,10 @@ +# new feature +# Tags: optional + +Feature: Test Audit logging endpoints of admin-ui + + Scenario: Testing 'checkLicense' GET endpoint + Given url checkLicenseURL + When method GET + Then status 200 + And print response diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/oauth2.feature b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/oauth2.feature new file mode 100644 index 00000000000..ee60ee8de24 --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/auth/oauth2.feature @@ -0,0 +1,26 @@ +Feature: Oauth2 + + Background: + * def ujwt = 'eyJraWQiOiI2NmQ1ODk4Ny03NjQ0LTRkYjEtOWU2YS04ZmFiNWFjYWVhNjVfc2lnX3JzMjU2IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJndFZ2cDJCMGlwdFN5bXFSTEpzc2ZZOWZNbjliWVZRNF8xVTBHSFlFWFRJIiwiYXVkIjoiMjA3M2M4ZTctMTA2MC00YzA5LWIwZjYtN2Q0NmZiNmZmOGY1IiwibmFtZSI6IkRlZmF1bHQgQWRtaW4gVXNlciIsIm5pY2tuYW1lIjoiQWRtaW4iLCJpc3MiOiJodHRwczovL2FkbWluLXVpLXRlc3QuZ2x1dS5vcmciLCJnaXZlbl9uYW1lIjoiQWRtaW4iLCJtaWRkbGVfbmFtZSI6IkFkbWluIiwiZmFtaWx5X25hbWUiOiJVc2VyIiwiamFuc0FkbWluVUlSb2xlIjpbImFwaS1hZG1pbiJdfQ.losuUsBib2YvB2t995iT0HJvE-q7uZT8zHrTJsWN8_rxB_-kawFNI6weWiH4hpAaIAIaw6Bnq5AczSW3OS6sn5fZDrBxuftrurCa7PK7uAeYim8Zozg0NHNQQ9FDe6MYg8FLtKI3eiusvgC3P4CClIFf1AMGVxREyBra87r_J8j2IyV86Ktjv_rVZLNm2mChOrbM5sIjaski4saKtZTMiVZoK7WMC4FJmS8ttysfG2w7-t8MoI9kiM890RhxSoUba9nQIVxKmpdJOzam8_FqNfQmC9fzI2XKjgRu16SoAoJxCNeTy8HHBCN4H_BwxgU2seSbDTMgU11GiApd4D2xaw' + + Scenario: Testing oauth2 GET configuration endpoint + Given url adminUIConfigURL + And header Accept = 'application/json' + When method GET + Then status 200 + And print response + + Scenario: Testing api-protection-token GET endpoint + Given url apiProtectionTokenURL + And header Accept = 'application/json' + Given param ujwt = ujwt + When method GET + Then status 200 + And print response + + +#Scenario: Testing access-token GET endpoint + #Given url https://admin-ui-test.gluu.org/jans-config-api/admin-ui/oauth2/access-token + #When method GET + #Then status 200 + #And print response \ No newline at end of file diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml new file mode 100644 index 00000000000..4878788b305 --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml index 9113a738b01..a23d9c4e828 100644 --- a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml @@ -863,10 +863,10 @@ components: type: array items: type: object - displayValue: - type: string value: type: object + displayValue: + type: string CustomUser: type: object properties: diff --git a/jans-config-api/pom.xml b/jans-config-api/pom.xml index a2aa5ce1085..eacd0e0c372 100644 --- a/jans-config-api/pom.xml +++ b/jans-config-api/pom.xml @@ -333,7 +333,6 @@ org.testng testng ${testng.version} - test diff --git a/jans-config-api/server/pom.xml b/jans-config-api/server/pom.xml index 0b5fde4d4bc..e4aeb64d3ac 100644 --- a/jans-config-api/server/pom.xml +++ b/jans-config-api/server/pom.xml @@ -220,12 +220,12 @@ org.junit.jupiter junit-jupiter-engine test - --> + net.masterthought cucumber-reporting test - + --> diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/ConfigServerBaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/ConfigServerBaseTest.java new file mode 100644 index 00000000000..7ca1932ca39 --- /dev/null +++ b/jans-config-api/server/src/test/java/io/jans/configapi/ConfigServerBaseTest.java @@ -0,0 +1,104 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.core.test; + +import io.jans.as.client.TokenRequest; +import io.jans.as.client.TokenResponse; +import io.jans.as.model.common.GrantType; +import io.jans.as.model.util.Util; +import io.jans.configapi.core.util.Jackson; +import io.jans.configapi.core.test.BaseTest; + + +import static java.nio.charset.StandardCharsets.UTF_8; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; + +import java.util.Hashtable; +import java.util.Map; +import java.util.Properties; +import java.net.URLEncoder; +import java.io.UnsupportedEncodingException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URLDecoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.util.*; +import java.util.Map.Entry; + +import jakarta.servlet.http.HttpServletRequest; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CookieStore; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.entity.ContentType; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.SSLContexts; + +import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; +import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; +import org.jboss.resteasy.client.jaxrs.ResteasyClient; +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; +import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; + +import org.json.JSONObject; +import org.json.JSONException; +import org.testng.ITestContext; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.BeforeTest; + +import jakarta.annotation.PostConstruct; +import jakarta.ws.rs.core.UriBuilder; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedHashMap; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +public class ConfigServerBaseTest extends BaseTest{ + + //server specific code +} diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java index 3f8c5984469..a65046dd676 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java @@ -7,13 +7,13 @@ package io.jans.configapi.test.auth; import static io.restassured.RestAssured.given; -import io.jans.configapi.BaseTest; +import io.jans.configapi.ConfigServerBaseTest; import jakarta.ws.rs.core.MediaType; import org.testng.annotations.Test; import org.testng.annotations.Parameters; -public class AcrsResourceTest extends BaseTest{ +public class AcrsResourceTest extends ConfigServerBaseTest{ @Parameters({"issuer", "acrsUrl"}) @Test diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java index 806aab7aa02..e903f3d61fe 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java @@ -7,13 +7,13 @@ package io.jans.configapi.test.auth; import static io.restassured.RestAssured.given; -import io.jans.configapi.BaseTest; +import io.jans.configapi.ConfigServerBaseTest; import jakarta.ws.rs.core.MediaType; import org.testng.annotations.Test; import org.testng.annotations.Parameters; -public class AgamaDeploymentsResourceTest extends BaseTest{ +public class AgamaDeploymentsResourceTest extends ConfigServerBaseTest{ @Parameters({"issuer", "agamaDeploymentUrl"}) @Test diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java index dee270cf970..23398696689 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java @@ -7,14 +7,14 @@ package io.jans.configapi.test.auth; import static io.restassured.RestAssured.given; -import io.jans.configapi.BaseTest; +import io.jans.configapi.ConfigServerBaseTest; import jakarta.ws.rs.core.MediaType; import org.testng.annotations.Test; import org.testng.annotations.Parameters; -public class AuthConfigResourceTest extends BaseTest{ +public class AuthConfigResourceTest extends ConfigServerBaseTest{ @Parameters({"issuer", "authConfigurationUrl"}) @Test diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index eeb8e276bbf..21d4b9f9620 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -9,7 +9,7 @@ import io.jans.as.common.model.registration.Client; import static io.restassured.RestAssured.given; -import io.jans.configapi.BaseTest; +import io.jans.configapi.ConfigServerBaseTest; import io.jans.model.net.HttpServiceResponse; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; @@ -29,7 +29,7 @@ import jakarta.ws.rs.core.Response.Status; -public class ClientResourceTest extends BaseTest{ +public class ClientResourceTest extends ConfigServerBaseTest{ private String clientId; diff --git a/jans-config-api/shared/pom.xml b/jans-config-api/shared/pom.xml index 15efc9f1800..8ed902e773a 100644 --- a/jans-config-api/shared/pom.xml +++ b/jans-config-api/shared/pom.xml @@ -13,6 +13,10 @@ + + io.jans + jans-auth-client + io.jans jans-auth-common @@ -54,6 +58,12 @@ org.apache.commons commons-collections4 + + + + org.testng + testng + diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java similarity index 98% rename from jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java index 8173d00331b..17c17debbb7 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/BaseTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java @@ -4,15 +4,15 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi; +package io.jans.configapi.core.test; import io.jans.as.client.TokenRequest; import io.jans.as.client.TokenResponse; import io.jans.as.model.common.GrantType; import io.jans.as.model.util.Util; import io.jans.configapi.core.util.Jackson; -import io.jans.configapi.service.HttpService; -import io.jans.configapi.service.ResteasyService; +import io.jans.configapi.core.test.service.HttpService; +import io.jans.configapi.core.test.service.ResteasyService; import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.file.Files; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/AlterSuiteListener.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/AlterSuiteListener.java similarity index 98% rename from jans-config-api/server/src/test/java/io/jans/configapi/listener/AlterSuiteListener.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/AlterSuiteListener.java index 3cf2280980f..583b3c8efc2 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/listener/AlterSuiteListener.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/AlterSuiteListener.java @@ -1,4 +1,4 @@ -package io.jans.configapi.listener; +package io.jans.configapi.core.test.listener; import io.jans.util.StringHelper; import io.jans.util.security.SecurityProviderUtility; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/ApiUnitTestListener.java similarity index 97% rename from jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/ApiUnitTestListener.java index bd68a087d1f..cb95b62d3ca 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/listener/ApiUnitTestListener.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/ApiUnitTestListener.java @@ -3,7 +3,7 @@ * * Copyright (c) 2021, Janssen Project */ -package io.jans.configapi.listener; +package io.jans.configapi.core.test.listener; import org.testng.ITestContext; import org.testng.ITestListener; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/PersistenceType.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/PersistenceType.java similarity index 88% rename from jans-config-api/server/src/test/java/io/jans/configapi/listener/PersistenceType.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/PersistenceType.java index a1bd7afb960..d6f57caa828 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/listener/PersistenceType.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/PersistenceType.java @@ -1,4 +1,4 @@ -package io.jans.configapi.listener; +package io.jans.configapi.core.test.listener; import io.jans.util.StringHelper; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTest.java similarity index 89% rename from jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTest.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTest.java index ff8d923f410..20571b1816c 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTest.java @@ -1,4 +1,4 @@ -package io.jans.configapi.listener; +package io.jans.configapi.core.test.listener; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTestsListener.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTestsListener.java similarity index 96% rename from jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTestsListener.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTestsListener.java index fad58e05fd5..3d6f46c734e 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/listener/SkipTestsListener.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTestsListener.java @@ -1,4 +1,4 @@ -package io.jans.configapi.listener; +package io.jans.configapi.core.test.listener; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java similarity index 99% rename from jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java index fdf54712fc3..348ad66ff5f 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/service/HttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.service; +package io.jans.configapi.core.test.service; import java.io.File; import java.io.IOException; diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/ResteasyService.java similarity index 93% rename from jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/ResteasyService.java index 40e035264a8..e21bdfa8d41 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/service/ResteasyService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/ResteasyService.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.service; +package io.jans.configapi.core.test.service; import java.io.Serializable; From 804ee590c77049fd1cd0503045e5ccb55b8c4920 Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 25 Nov 2024 22:14:28 +0530 Subject: [PATCH 23/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../rest/resource/ConfigResourceTest.java | 29 +++++++- .../test/auth/ClientResourceTest.java | 36 +++++----- .../configapi/test/health/ApiHealthTest.java | 67 +++++++++++++------ .../test/resources/config-api-test.properties | 4 ++ .../json/config/api/api-config-patch.json | 5 ++ 5 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 jans-config-api/server/src/test/resources/json/config/api/api-config-patch.json diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java index 3ce07f1e0e8..b8ae7f99e52 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java @@ -6,8 +6,17 @@ package io.jans.configapi.rest.resource; +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; import org.testng.annotations.Test; + +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + import static io.restassured.RestAssured.given; /** @@ -15,11 +24,29 @@ */ public class ConfigResourceTest { + @Parameters({ "issuer", "apiConfigtionUrl" }) + @Test + public void getApiConfigtion(final String issuer, final String apiConfigtionUrl) { + log.error("getApiConfigtion() - accessToken:{}, issuer:{}, apiConfigtionUrl:{}", accessToken, issuer, + apiConfigtionUrl); + Builder request = getResteasyService().getClientBuilder(issuer + apiConfigtionUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getApiConfigtion - response:{}", response); + + } + + @Parameters({"issuer", "apiConfigtionUrl", "api_config-patch"}) @Test - public void patchAppConfigurationProperty() { + public void patchgetApiConfigtion(final String issuer, final String apiConfigtionUrl) { given().when().contentType(MediaType.APPLICATION_JSON) .header("Authorization", "Bearer 0ea2ce99-b741-4f5a-8fd7-26f52d057c19", null) .body("[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]") .patch("/jans-config-api/api/v1/jans-auth-server/config").then().statusCode(200); + + } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index 21d4b9f9620..5b68c645395 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -28,44 +28,44 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; - -public class ClientResourceTest extends ConfigServerBaseTest{ +public class ClientResourceTest extends ConfigServerBaseTest { private String clientId; - - - @Parameters({"issuer", "openidClientsUrl"}) + + @Parameters({ "issuer", "openidClientsUrl" }) @Test public void getAllClient(final String issuer, final String openidClientsUrl) { - log.error("getAllClient() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); - Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); + log.error("getAllClient() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, + openidClientsUrl); + Builder request = getResteasyService().getClientBuilder(issuer + openidClientsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - + Response response = request.get(); - log.error("Response for Access Token - response:{}", response); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getAllClient - response:{}", response); } - @Parameters({"issuer", "openidClientsUrl", "openid_client2"}) + @Parameters({ "issuer", "openidClientsUrl", "openid_client2" }) @Test - public void postClient2(final String issuer, final String openidClientsUrl, final String json) { - log.error("\n\n\n postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); + public void postClient(final String issuer, final String openidClientsUrl, final String json) { + log.error("\n\n\n postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, + openidClientsUrl, json); - Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); + Builder request = getResteasyService().getClientBuilder(issuer + openidClientsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - //String jsonStr = decodeFileValue(json); - //log.error("\n\n\n postClient2 - jsonStr:{}", jsonStr); + // String jsonStr = decodeFileValue(json); + // log.error("\n\n\n postClient2 - jsonStr:{}", jsonStr); Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); log.error("post client - response:{}", response); if (response.getStatus() == 201) { - log.trace("Response for Access Token - response.getEntity():{}, response.getClass():{}", response.getEntity(), response.getClass()); + log.trace("Response for postClient - response.getEntity():{}, response.getClass():{}", + response.getEntity(), response.getClass()); } - - assertEquals(response.getStatus(), Status.CREATED.getStatusCode()); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java index 1ba26ae56be..904d0de4efe 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java @@ -8,47 +8,72 @@ import static io.restassured.RestAssured.given; import io.jans.configapi.BaseTest; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + import org.testng.annotations.Parameters; -public class ApiHealthTest extends BaseTest{ +public class ApiHealthTest extends ConfigServerBaseTest { - @Parameters({"issuer", "healthUrl"}) + @Parameters({ "issuer", "healthUrl" }) @Test public void getHealthResponse(final String issuer, final String healthUrl) { log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) - .get(issuer+healthUrl).then().statusCode(200); + + Builder request = getResteasyService().getClientBuilder(issuer + healthUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getHealthResponse - response:{}", response); } - - - @Parameters({"issuer", "healthUrl"}) + + @Parameters({ "issuer", "healthUrl" }) @Test public void getServerStat(final String issuer, final String healthUrl) { log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) - .get(issuer+healthUrl+"/server-stat").then().statusCode(200); + + Builder request = getResteasyService().getClientBuilder(issuer + healthUrl + "/server-stat"); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getServerStat - response:{}", response); } - - @Parameters({"issuer", "healthUrl"}) + + @Parameters({ "issuer", "healthUrl" }) @Test public void getApplicationVersion(final String issuer, final String healthUrl) { log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) - .get(issuer+healthUrl+"/app-version").then().statusCode(200); + + Builder request = getResteasyService().getClientBuilder(issuer + healthUrl + "/app-version"); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getApplicationVersion - response:{}", response); } - - @Parameters({"issuer", "healthUrl"}) + + @Parameters({ "issuer", "healthUrl" }) @Test public void getServiceStatus(final String issuer, final String healthUrl) { log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) - .get(issuer+healthUrl+"/service-status").then().statusCode(200); + + Builder request = getResteasyService().getClientBuilder(issuer + healthUrl + "/service-status"); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getServiceStatus - response:{}", response); } } diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties index a2222461bed..26b62354db0 100644 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -11,6 +11,7 @@ issuer=https://pujavs-amazed-rat.gluu.info statUrl=/jans-config-api/api/v1/stat healthUrl=/jans-config-api/api/v1/health acrsUrl=/jans-config-api/api/v1/acrs +apiConfigtionUrl=/jans-config-api/api/v1/api-config authConfigurationUrl=/jans-config-api/api/v1/jans-auth-server/config scriptsUrl=/jans-config-api/api/v1/config/scripts cacheUrl=/jans-config-api/api/v1/config/cache @@ -35,6 +36,9 @@ clientsAuthorizationsUrl=/jans-config-api/api/v1/clients/authorizations tokenUrl=/jans-config-api/api/v1/token +#apiConfigtion +api_config-patch=file:target/test-classes/json/config/api/api-config-patch.json + #defaultAcr #default_acr1=file:target/test-classes/json/acr/defaultAcr.json diff --git a/jans-config-api/server/src/test/resources/json/config/api/api-config-patch.json b/jans-config-api/server/src/test/resources/json/config/api/api-config-patch.json new file mode 100644 index 00000000000..e01cb359f03 --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/api/api-config-patch.json @@ -0,0 +1,5 @@ +[{ + "op": "add", + "path": "/loggingLevel", + "value": "DEBUG" +}] From 1477ea64a1c848cc0c8c3f88a475a09cd3beb276 Mon Sep 17 00:00:00 2001 From: pujavs Date: Wed, 27 Nov 2024 13:34:15 +0530 Subject: [PATCH 24/44] feat(config-api): testng framework --- .../docs/jans-config-api-swagger.yaml | 8 +- ...ourceTest.java => Oauth2ResourceTest.java} | 24 +---- .../jans/configapi/ConfigServerBaseTest.java | 93 +------------------ .../rest/resource/ConfigResourceTest.java | 32 +++++-- .../configapi/test/auth/AcrsResourceTest.java | 34 +++++-- .../auth/AgamaDeploymentsResourceTest.java | 27 ++++-- .../test/auth/AuthConfigResourceTest.java | 41 +++++--- .../test/auth/ClientResourceTest.java | 16 +--- .../configapi/test/health/ApiHealthTest.java | 3 +- .../test/resources/config-api-test.properties | 14 ++- .../{defaultAcr => acr}/defaultAcr.feature | 0 .../json/{defaultAcr => acr}/defaultAcr.json | 0 .../json/config/api/api-config-patch.json | 2 +- .../json/config/auth/auth-config-patch.json | 5 + .../server/src/test/resources/testng.xml | 4 +- 15 files changed, 125 insertions(+), 178 deletions(-) rename jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/{ClientResourceTest.java => Oauth2ResourceTest.java} (56%) rename jans-config-api/server/src/test/resources/json/{defaultAcr => acr}/defaultAcr.feature (100%) rename jans-config-api/server/src/test/resources/json/{defaultAcr => acr}/defaultAcr.json (100%) create mode 100644 jans-config-api/server/src/test/resources/json/config/auth/auth-config-patch.json diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index e23deb79907..3b8a6f15bd2 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9273,18 +9273,18 @@ components: type: boolean whitePagesCanView: type: boolean - adminCanEdit: - type: boolean userCanEdit: type: boolean - userCanView: + adminCanEdit: type: boolean adminCanView: type: boolean - adminCanAccess: + userCanView: type: boolean userCanAccess: type: boolean + adminCanAccess: + type: boolean baseDn: type: string PatchRequest: diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/ClientResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java similarity index 56% rename from jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/ClientResourceTest.java rename to jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java index 21d4b9f9620..468c595f834 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/ClientResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java @@ -29,7 +29,7 @@ import jakarta.ws.rs.core.Response.Status; -public class ClientResourceTest extends ConfigServerBaseTest{ +public class Oauth2ResourceTest extends ConfigServerBaseTest{ private String clientId; @@ -47,25 +47,5 @@ public void getAllClient(final String issuer, final String openidClientsUrl) { } - @Parameters({"issuer", "openidClientsUrl", "openid_client2"}) - @Test - public void postClient2(final String issuer, final String openidClientsUrl, final String json) { - log.error("\n\n\n postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); - - Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); - request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); - request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - //String jsonStr = decodeFileValue(json); - //log.error("\n\n\n postClient2 - jsonStr:{}", jsonStr); - Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); - log.error("post client - response:{}", response); - - if (response.getStatus() == 201) { - log.trace("Response for Access Token - response.getEntity():{}, response.getClass():{}", response.getEntity(), response.getClass()); - } - - - - assertEquals(response.getStatus(), Status.CREATED.getStatusCode()); - } + } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/ConfigServerBaseTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/ConfigServerBaseTest.java index 7ca1932ca39..e487705f1dc 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/ConfigServerBaseTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/ConfigServerBaseTest.java @@ -4,99 +4,10 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.core.test; +package io.jans.configapi; -import io.jans.as.client.TokenRequest; -import io.jans.as.client.TokenResponse; -import io.jans.as.model.common.GrantType; -import io.jans.as.model.util.Util; -import io.jans.configapi.core.util.Jackson; -import io.jans.configapi.core.test.BaseTest; - - -import static java.nio.charset.StandardCharsets.UTF_8; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; - -import java.util.Hashtable; -import java.util.Map; -import java.util.Properties; -import java.net.URLEncoder; -import java.io.UnsupportedEncodingException; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.net.URLDecoder; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.*; -import java.util.Map.Entry; - -import jakarta.servlet.http.HttpServletRequest; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang.StringUtils; - -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CookieStore; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.routing.HttpRoutePlanner; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.entity.ContentType; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.conn.ssl.TrustStrategy; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.client.LaxRedirectStrategy; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.http.ssl.SSLContexts; - -import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; -import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; - -import org.json.JSONObject; -import org.json.JSONException; -import org.testng.ITestContext; -import org.testng.annotations.AfterSuite; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeSuite; -import org.testng.annotations.BeforeTest; - -import jakarta.annotation.PostConstruct; -import jakarta.ws.rs.core.UriBuilder; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.client.Invocation.Builder; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; +import io.jans.configapi.core.test.BaseTest; public class ConfigServerBaseTest extends BaseTest{ diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java index b8ae7f99e52..924c8a88b1c 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java @@ -8,11 +8,14 @@ import static org.testng.Assert.assertEquals; +import io.jans.configapi.ConfigServerBaseTest; import org.testng.annotations.Parameters; import org.testng.annotations.Test; +import jakarta.ws.rs.HttpMethod; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; + import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; @@ -22,7 +25,7 @@ /** * @author Yuriy Zabrovarnyy */ -public class ConfigResourceTest { +public class ConfigResourceTest extends ConfigServerBaseTest { @Parameters({ "issuer", "apiConfigtionUrl" }) @Test @@ -38,15 +41,30 @@ public void getApiConfigtion(final String issuer, final String apiConfigtionUrl) log.error("Response for getApiConfigtion - response:{}", response); } - - @Parameters({"issuer", "apiConfigtionUrl", "api_config-patch"}) - @Test - public void patchgetApiConfigtion(final String issuer, final String apiConfigtionUrl) { + + @Parameters({ "issuer", "apiConfigtionUrl", "api_config-patch" }) + // @Test + public void patchgetApiConfigtion1(final String issuer, final String apiConfigtionUrl) { given().when().contentType(MediaType.APPLICATION_JSON) .header("Authorization", "Bearer 0ea2ce99-b741-4f5a-8fd7-26f52d057c19", null) .body("[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]") .patch("/jans-config-api/api/v1/jans-auth-server/config").then().statusCode(200); - - + + } + + @Parameters({ "issuer", "apiConfigtionUrl", "api_config_patch_1" }) + @Test + public void patchgetApiConfigtion(final String issuer, final String apiConfigtionUrl, final String json) { + log.error("getApiConfigtion() - accessToken:{}, issuer:{}, apiConfigtionUrl:{}, json:{}", accessToken, issuer, + apiConfigtionUrl, json); + Builder request = getResteasyService().getClientBuilder(issuer + apiConfigtionUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_PATCH_JSON); + + Response response = request.method(HttpMethod.PATCH, Entity.entity(json, MediaType.APPLICATION_JSON)); + + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getApiConfigtion - response:{}", response); + } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java index a65046dd676..12ec0f8a53f 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java @@ -6,11 +6,17 @@ package io.jans.configapi.test.auth; -import static io.restassured.RestAssured.given; import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + import org.testng.annotations.Parameters; public class AcrsResourceTest extends ConfigServerBaseTest{ @@ -19,21 +25,29 @@ public class AcrsResourceTest extends ConfigServerBaseTest{ @Test public void getDefaultAuthenticationMethod(final String issuer, final String acrsUrl) { log.error("accessToken:{}, issuer:{}, acrsUrl:{}", accessToken, issuer, acrsUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization",AUTHORIZATION_TYPE + " "+ accessToken, null) - .get(issuer+acrsUrl).then().statusCode(200); + Builder request = getResteasyService().getClientBuilder(issuer + acrsUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getDefaultAuthenticationMethod - response:{}", response); } - @Parameters({"issuer", "acrsUrl", "default_acr1"}) + @Parameters({"issuer", "acrsUrl", "default_acr_1"}) @Test public void postClient(final String issuer, final String acrsUrl, final String json) { log.error("accessToken:{}, issuer:{}, acrsUrl:{}, json:{}", accessToken, issuer, acrsUrl, json); - log.info("Creating client using json string"); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) - .body(json) - .put(issuer+acrsUrl).then().statusCode(200); + Builder request = getResteasyService().getClientBuilder(issuer + acrsUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); + + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getApiConfigtion - response:{}", response); + } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java index e903f3d61fe..6ee3e9b1b2e 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java @@ -6,24 +6,33 @@ package io.jans.configapi.test.auth; -import static io.restassured.RestAssured.given; import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + import org.testng.annotations.Parameters; -public class AgamaDeploymentsResourceTest extends ConfigServerBaseTest{ +public class AgamaDeploymentsResourceTest extends ConfigServerBaseTest { - @Parameters({"issuer", "agamaDeploymentUrl"}) + @Parameters({ "issuer", "agamaDeploymentUrl" }) @Test public void getDeployments(final String issuer, final String agamaDeploymentUrl) { log.error("accessToken:{}, issuer:{}, agamaDeploymentUrl:{}", accessToken, issuer, agamaDeploymentUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) - .get(issuer+agamaDeploymentUrl).then().statusCode(200); + + Builder request = getResteasyService().getClientBuilder(issuer + agamaDeploymentUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getDefaultAuthenticationMethod - response:{}", response); + } - - - + } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java index 23398696689..0eec29da2b5 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java @@ -6,11 +6,18 @@ package io.jans.configapi.test.auth; -import static io.restassured.RestAssured.given; +import jakarta.ws.rs.HttpMethod; import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + import org.testng.annotations.Parameters; @@ -18,20 +25,30 @@ public class AuthConfigResourceTest extends ConfigServerBaseTest{ @Parameters({"issuer", "authConfigurationUrl"}) @Test - public void getAuthAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { + public void getAuthConfigurationProperty(final String issuer, final String authConfigurationUrl) { log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) - .get(issuer+authConfigurationUrl).then().statusCode(200); + + Builder request = getResteasyService().getClientBuilder(issuer + authConfigurationUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getDefaultAuthenticationMethod - response:{}", response); } - @Parameters({"issuer", "authConfigurationUrl"}) + @Parameters({"issuer", "authConfigurationUrl", "auth_config_patch_1"}) @Test - public void patchAppConfigurationProperty(final String issuer, final String authConfigurationUrl) { - log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", AUTHORIZATION_TYPE + " "+ accessToken, null) - .body("[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]") - .patch(issuer+authConfigurationUrl).then().statusCode(200); + public void patchAuthConfigurationProperty(final String issuer, final String authConfigurationUrl, final String json) { + log.error("getApiConfigtion() - accessToken:{}, issuer:{}, authConfigurationUrl:{}, json:{}", accessToken, issuer, + authConfigurationUrl, json); + Builder request = getResteasyService().getClientBuilder(issuer + authConfigurationUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_PATCH_JSON); + + Response response = request.method(HttpMethod.PATCH, Entity.entity(json, MediaType.APPLICATION_JSON)); + + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getApiConfigtion - response:{}", response); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index 5b68c645395..dbabfc037c7 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -6,29 +6,20 @@ package io.jans.configapi.test.auth; -import io.jans.as.common.model.registration.Client; - -import static io.restassured.RestAssured.given; import io.jans.configapi.ConfigServerBaseTest; -import io.jans.model.net.HttpServiceResponse; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; -import org.json.JSONObject; import static org.testng.Assert.*; -import java.util.Map; - -import org.apache.http.entity.ContentType; -import org.json.JSONObject; import org.testng.annotations.Parameters; import org.testng.annotations.Test; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -public class ClientResourceTest extends ConfigServerBaseTest { +public class ClientResourceTest extends BaseTest { private String clientId; @@ -39,15 +30,14 @@ public void getAllClient(final String issuer, final String openidClientsUrl) { openidClientsUrl); Builder request = getResteasyService().getClientBuilder(issuer + openidClientsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); - request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); log.error("Response for getAllClient - response:{}", response); - } - @Parameters({ "issuer", "openidClientsUrl", "openid_client2" }) + @Parameters({ "issuer", "openidClientsUrl", "openid_client_1" }) @Test public void postClient(final String issuer, final String openidClientsUrl, final String json) { log.error("\n\n\n postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java index 904d0de4efe..0883bf2ec1e 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java @@ -6,8 +6,7 @@ package io.jans.configapi.test.health; -import static io.restassured.RestAssured.given; -import io.jans.configapi.BaseTest; +import io.jans.configapi.ConfigServerBaseTest; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties index 26b62354db0..460a2e643f9 100644 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ b/jans-config-api/server/src/test/resources/config-api-test.properties @@ -37,15 +37,19 @@ tokenUrl=/jans-config-api/api/v1/token #apiConfigtion -api_config-patch=file:target/test-classes/json/config/api/api-config-patch.json +api_config_patch_1=file:target/test-classes/json/config/api/api-config-patch.json + +#apiConfigtion +auth_config_patch_1=file:target/test-classes/json/config/auth/auth-config-patch.json #defaultAcr -#default_acr1=file:target/test-classes/json/acr/defaultAcr.json +default_acr_1=file:target/test-classes/json/acr/defaultAcr.json #openid-client -#openid_client1=file:target/test-classes/json/openid/clients/client.json -openid_client2=file:target/test-classes/json/openid/clients/openid-client-post.json +openid_client_1=file:target/test-classes/json/openid/clients/openid-client-post.json +openid_client_2=file:target/test-classes/json/openid/clients/client.json + #openid-scopes -#openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json +openid_scopes_1=file:target/test-classes/json/openid/scopes/scope.json diff --git a/jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.feature b/jans-config-api/server/src/test/resources/json/acr/defaultAcr.feature similarity index 100% rename from jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.feature rename to jans-config-api/server/src/test/resources/json/acr/defaultAcr.feature diff --git a/jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.json b/jans-config-api/server/src/test/resources/json/acr/defaultAcr.json similarity index 100% rename from jans-config-api/server/src/test/resources/json/defaultAcr/defaultAcr.json rename to jans-config-api/server/src/test/resources/json/acr/defaultAcr.json diff --git a/jans-config-api/server/src/test/resources/json/config/api/api-config-patch.json b/jans-config-api/server/src/test/resources/json/config/api/api-config-patch.json index e01cb359f03..d44e2e1292a 100644 --- a/jans-config-api/server/src/test/resources/json/config/api/api-config-patch.json +++ b/jans-config-api/server/src/test/resources/json/config/api/api-config-patch.json @@ -1,5 +1,5 @@ [{ - "op": "add", + "op": "replace", "path": "/loggingLevel", "value": "DEBUG" }] diff --git a/jans-config-api/server/src/test/resources/json/config/auth/auth-config-patch.json b/jans-config-api/server/src/test/resources/json/config/auth/auth-config-patch.json new file mode 100644 index 00000000000..d44e2e1292a --- /dev/null +++ b/jans-config-api/server/src/test/resources/json/config/auth/auth-config-patch.json @@ -0,0 +1,5 @@ +[{ + "op": "replace", + "path": "/loggingLevel", + "value": "DEBUG" +}] diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index 4878788b305..8aade5da3a0 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -5,8 +5,8 @@ - - + + From c89fc370cf206bc6d7ec888c23f56d5760fc0974 Mon Sep 17 00:00:00 2001 From: pujavs Date: Wed, 27 Nov 2024 19:14:38 +0530 Subject: [PATCH 25/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 18 +++--- .../ca/plugin/adminui/AdminUIBaseTest.java | 18 ++++++ .../adminui/test/Oauth2ResourceTest.java | 8 +-- .../test/resources/config-api-test.properties | 55 ++++--------------- .../test/auth/ClientResourceTest.java | 2 +- .../io/jans/configapi/core/test/BaseTest.java | 1 + 6 files changed, 45 insertions(+), 57 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 3b8a6f15bd2..54f337e216e 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9273,18 +9273,18 @@ components: type: boolean whitePagesCanView: type: boolean - userCanEdit: - type: boolean - adminCanEdit: - type: boolean adminCanView: type: boolean userCanView: type: boolean - userCanAccess: + userCanEdit: + type: boolean + adminCanEdit: type: boolean adminCanAccess: type: boolean + userCanAccess: + type: boolean baseDn: type: string PatchRequest: @@ -10137,8 +10137,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10148,6 +10146,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -11256,14 +11256,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java index 741571b0f4f..a0160c044da 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -101,4 +101,22 @@ public class AdminUIBaseTest extends BaseTest{ //AdminUI specific code + + @BeforeMethod + public void getAccessToken() throws Exception { + log.error("getAccessToken - propertiesMap:{}", propertiesMap); + + String tokenUrl = propertiesMap.get("authzurl"); + String strGrantType = propertiesMap.get("tokenGrantType"); + String clientId = propertiesMap.get("clientId"); + String clientSecret = propertiesMap.get("clientSecret"); + String scopes = propertiesMap.get("test.scopes"); + String authStr = clientId + ':' + clientSecret; + + GrantType grantType = GrantType.fromString(strGrantType); + this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); + log.error("accessToken:{}", accessToken); + } + + } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java index 468c595f834..f4a7442c589 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java @@ -29,21 +29,21 @@ import jakarta.ws.rs.core.Response.Status; -public class Oauth2ResourceTest extends ConfigServerBaseTest{ +public class OAuth2ResourceTest extends ConfigServerBaseTest{ private String clientId; @Parameters({"issuer", "openidClientsUrl"}) @Test - public void getAllClient(final String issuer, final String openidClientsUrl) { - log.error("getAllClient() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); + public void getOAuth2Data(final String issuer, final String openidClientsUrl) { + log.error("getOAuth2Data() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); Response response = request.get(); - log.error("Response for Access Token - response:{}", response); + log.error("Response for getOAuth2Data - response:{}", response); } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties index 5863e6d3395..145a0fc28ea 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties @@ -1,50 +1,19 @@ -scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete - -# Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token -tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info - - +test.scopes=openid profile email user_name +test.grant.type=authorization_code +test.client.id=2073c8e7-1060-4c09-b0f6-7d46fb6ff8f5 +test.client.secret=92bc4d8e-2f4c-4a4d-80ae-1e4eb1f5f463 +test.issuer=https://admin-ui-test.gluu.org test.authzurl=https://admin-ui-test.gluu.org/jans-auth/authorize.htm - -statUrl=/jans-config-api/api/v1/stat -healthUrl=/jans-config-api/api/v1/health -acrsUrl=/jans-config-api/api/v1/acrs -authConfigurationUrl=/jans-config-api/api/v1/jans-auth-server/config -scriptsUrl=/jans-config-api/api/v1/config/scripts -cacheUrl=/jans-config-api/api/v1/config/cache -messageUrl=/jans-config-api/api/v1/config/message -jwksUrl=/jans-config-api/api/v1/config/jwks -ldapUrl=/jans-config-api/api/v1/config/database/ldap -openidClientsUrl=/jans-config-api/api/v1/openid/clients -scopesUrl=/jans-config-api/api/v1/scopes -umaresourcesUrl=/jans-config-api/api/v1/uma/resources -attributesUrl=/jans-config-api/api/v1/attributes -smtpUrl=/jans-config-api/api/v1/config/smtp -loggingUrl=/jans-config-api/api/v1/logging -authHealthUrl=/jans-config-api/api/v1/jans-auth-server/health -orgConfigurationUrl=/jans-config-api/api/v1/org -userUrl=/jans-config-api/api/v1/user -agamaUrl=/jans-config-api/api/v1/agama -sessionUrl=/jans-config-api/api/v1/jans-auth-server/session -pluginUrl=/jans-config-api/api/v1/plugin -apiConfigUrl=/jans-config-api/api/v1/api-config -agamaDeploymentUrl=/jans-config-api/api/v1/agama-deployment -clientsAuthorizationsUrl=/jans-config-api/api/v1/clients/authorizations -tokenUrl=/jans-config-api/api/v1/token +ujwt=eyJraWQiOiI2NmQ1ODk4Ny03NjQ0LTRkYjEtOWU2YS04ZmFiNWFjYWVhNjVfc2lnX3JzMjU2IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJndFZ2cDJCMGlwdFN5bXFSTEpzc2ZZOWZNbjliWVZRNF8xVTBHSFlFWFRJIiwiYXVkIjoiMjA3M2M4ZTctMTA2MC00YzA5LWIwZjYtN2Q0NmZiNmZmOGY1IiwibmFtZSI6IkRlZmF1bHQgQWRtaW4gVXNlciIsIm5pY2tuYW1lIjoiQWRtaW4iLCJpc3MiOiJodHRwczovL2FkbWluLXVpLXRlc3QuZ2x1dS5vcmciLCJnaXZlbl9uYW1lIjoiQWRtaW4iLCJtaWRkbGVfbmFtZSI6IkFkbWluIiwiZmFtaWx5X25hbWUiOiJVc2VyIiwiamFuc0FkbWluVUlSb2xlIjpbImFwaS1hZG1pbiJdfQ.losuUsBib2YvB2t995iT0HJvE-q7uZT8zHrTJsWN8_rxB_-kawFNI6weWiH4hpAaIAIaw6Bnq5AczSW3OS6sn5fZDrBxuftrurCa7PK7uAeYim8Zozg0NHNQQ9FDe6MYg8FLtKI3eiusvgC3P4CClIFf1AMGVxREyBra87r_J8j2IyV86Ktjv_rVZLNm2mChOrbM5sIjaski4saKtZTMiVZoK7WMC4FJmS8ttysfG2w7-t8MoI9kiM890RhxSoUba9nQIVxKmpdJOzam8_FqNfQmC9fzI2XKjgRu16SoAoJxCNeTy8HHBCN4H_BwxgU2seSbDTMgU11GiApd4D2xaw +authzurl=/jans-auth/authorize.htm +adminUIConfigURL=/jans-config-api/admin-ui/oauth2/config +apiProtectionTokenURL=/jans-config-api/admin-ui/oauth2/api-protection-token +checkLicenseURL=/jans-config-api/admin-ui/license/checkLicense +getLicenseDetailsURL=/jans-config-api/admin-ui/license/getLicenseDetails +getAuditLoggingURL=/jans-config-api/admin-ui/logging/audit -#defaultAcr -#default_acr1=file:target/test-classes/json/acr/defaultAcr.json -#openid-client -#openid_client1=file:target/test-classes/json/openid/clients/client.json -openid_client2=file:target/test-classes/json/openid/clients/openid-client-post.json -#openid-scopes -#openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index dbabfc037c7..f204ca9a22b 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -19,7 +19,7 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -public class ClientResourceTest extends BaseTest { +public class ClientResourceTest extends ConfigServerBaseTest { private String clientId; diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java index 17c17debbb7..f30ee422bf9 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java @@ -203,6 +203,7 @@ public TokenResponse requestAccessToken(final String tokenUrl, final String clie return null; } + //TO-DO - check if needed protected HttpService getHttpService() { return this.httpService; } From 006ce4c5a6edeab6e89c5144891df6c2ba526ec5 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 28 Nov 2024 00:04:42 +0530 Subject: [PATCH 26/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 8 ++--- .../ca/plugin/adminui/AdminUIBaseTest.java | 2 +- ...ourceTest.java => OAuth2ResourceTest.java} | 34 ++++++++++++++----- 3 files changed, 30 insertions(+), 14 deletions(-) rename jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/{Oauth2ResourceTest.java => OAuth2ResourceTest.java} (56%) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 54f337e216e..9ecaba080e6 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9273,12 +9273,12 @@ components: type: boolean whitePagesCanView: type: boolean - adminCanView: - type: boolean userCanView: type: boolean userCanEdit: type: boolean + adminCanView: + type: boolean adminCanEdit: type: boolean adminCanAccess: @@ -11256,14 +11256,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java index a0160c044da..27967dfe949 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.core.test; +package io.jans.ca.plugin.adminui; import io.jans.as.client.TokenRequest; import io.jans.as.client.TokenResponse; diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java similarity index 56% rename from jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java rename to jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java index f4a7442c589..6d588bc1e0c 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/Oauth2ResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.test.auth; +package io.jans.ca.plugin.adminui.test; import io.jans.as.common.model.registration.Client; @@ -31,20 +31,36 @@ public class OAuth2ResourceTest extends ConfigServerBaseTest{ - private String clientId; - - - @Parameters({"issuer", "openidClientsUrl"}) + + /** + * Testing oauth2 GET configuration endpoint + */ + @Parameters({"issuer", "adminUIConfigURL"}) @Test - public void getOAuth2Data(final String issuer, final String openidClientsUrl) { - log.error("getOAuth2Data() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); - Builder request = getResteasyService().getClientBuilder(issuer+openidClientsUrl); + public void getOAuth2Data(final String issuer, final String adminUIConfigURL) { + log.error("getOAuth2Data() - accessToken:{}, issuer:{}, adminUIConfigURL:{}", accessToken, issuer, adminUIConfigURL); + Builder request = getResteasyService().getClientBuilder(issuer+adminUIConfigURL); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); Response response = request.get(); log.error("Response for getOAuth2Data - response:{}", response); - + } + + + /** + * Testing api-protection-token GET endpoint + */ + @Parameters({"issuer", "apiProtectionTokenURL"}) + @Test + public void getOAuth2Data(final String issuer, final String apiProtectionTokenURL, final String ujwt) { + log.error("getOAuth2Data() - accessToken:{}, issuer:{}, apiProtectionTokenURL:{}, ujwt:{}", accessToken, issuer, apiProtectionTokenURL, ujwt); + Builder request = getResteasyService().getClientBuilder(issuer+apiProtectionTokenURL); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + request.param("ujwt", ujwt); + Response response = request.get(); + log.error("Response for getOAuth2Data - response:{}", response); } From 26b7eee451c346198ccf1f1773146cc97049353e Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 28 Nov 2024 17:59:05 +0530 Subject: [PATCH 27/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 14 +++--- .../plugins/admin-ui-plugin/pom.xml | 3 -- .../test/AuditLoggingResourceTest.java | 49 +++++++++++++++++++ .../adminui/test/LicenseResourceTest.java | 47 ++++++++++++++++++ .../adminui/test/OAuth2ResourceTest.java | 31 +++++------- .../test/resources/config-api-test.properties | 7 +-- .../resources/json/logging/logging-post.json | 5 ++ .../src/test/resources/testng.xml | 21 ++++++-- .../configapi/test/auth/AcrsResourceTest.java | 4 +- .../test/auth/AuthConfigResourceTest.java | 30 ++++++++---- .../test/auth/ClientResourceTest.java | 7 ++- .../auth}/ConfigResourceTest.java | 6 +-- .../server/src/test/resources/testng.xml | 23 +++++++++ 13 files changed, 194 insertions(+), 53 deletions(-) create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java create mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/logging/logging-post.json rename jans-config-api/server/src/test/java/io/jans/configapi/{rest/resource => test/auth}/ConfigResourceTest.java (94%) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 9ecaba080e6..3a5b2887d7c 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9273,17 +9273,17 @@ components: type: boolean whitePagesCanView: type: boolean - userCanView: + adminCanAccess: type: boolean - userCanEdit: + userCanAccess: type: boolean - adminCanView: + userCanEdit: type: boolean adminCanEdit: type: boolean - adminCanAccess: + userCanView: type: boolean - userCanAccess: + adminCanView: type: boolean baseDn: type: string @@ -11692,10 +11692,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/admin-ui-plugin/pom.xml b/jans-config-api/plugins/admin-ui-plugin/pom.xml index dfd1622af32..704a8592bc8 100644 --- a/jans-config-api/plugins/admin-ui-plugin/pom.xml +++ b/jans-config-api/plugins/admin-ui-plugin/pom.xml @@ -99,9 +99,6 @@ src/test/resources true - - *.* - diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java new file mode 100644 index 00000000000..66a133a4653 --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java @@ -0,0 +1,49 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.ca.plugin.adminui.test; + +import io.jans.as.common.model.registration.Client; + +import static io.restassured.RestAssured.given; +import io.jans.ca.plugin.adminui.AdminUIBaseTest; +import io.jans.model.net.HttpServiceResponse; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import java.util.Map; + +import org.apache.http.entity.ContentType; +import static org.testng.Assert.*; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; + +public class AuditLoggingResourceTest extends AdminUIBaseTest{ + + + /** + * Testing Audit Logging endpoint + */ + @Parameters({"issuer", "auditLoggingURL", "audit_post_1"}) + @Test + public void postAuditLoggingData(final String issuer, final String auditLoggingURL, final String json) { + log.error("postAuditLoggingData() - accessToken:{}, issuer:{}, auditLoggingURL:{}, json:{}", accessToken, issuer, auditLoggingURL, json); + Builder request = getResteasyService().getClientBuilder(issuer+auditLoggingURL); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + + Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for assertEquals(response.getStatus(), Status.OK.getStatusCode()); - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java new file mode 100644 index 00000000000..dbabfb1659f --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java @@ -0,0 +1,47 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.ca.plugin.adminui.test; + +import io.jans.as.common.model.registration.Client; + +import static io.restassured.RestAssured.given; +import io.jans.ca.plugin.adminui.AdminUIBaseTest; +import io.jans.model.net.HttpServiceResponse; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; + +import java.util.Map; + +import org.apache.http.entity.ContentType; +import org.testng.annotations.Parameters; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +public class LicenseResourceTest extends AdminUIBaseTest { + + /** + * Test License Details + */ + @Parameters({ "issuer", "licenseDetailsURL" }) + @Test + public void getLicenseDetails(final String issuer, final String licenseDetailsURL) { + log.error("getLicenseDetails() - accessToken:{}, issuer:{}, licenseDetailsURL:{}", accessToken, issuer, + licenseDetailsURL); + Builder request = getResteasyService().getClientBuilder(issuer + licenseDetailsURL); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getLicenseDetails - response:{}", response); + } + +} diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java index 6d588bc1e0c..8819c972864 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java @@ -9,27 +9,22 @@ import io.jans.as.common.model.registration.Client; import static io.restassured.RestAssured.given; -import io.jans.configapi.ConfigServerBaseTest; +import io.jans.ca.plugin.adminui.AdminUIBaseTest; import io.jans.model.net.HttpServiceResponse; + +import java.util.Map; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; -import org.json.JSONObject; -import static org.testng.Assert.*; - -import java.util.Map; - import org.apache.http.entity.ContentType; -import org.json.JSONObject; +import static org.testng.Assert.*; import org.testng.annotations.Parameters; import org.testng.annotations.Test; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; - - -public class OAuth2ResourceTest extends ConfigServerBaseTest{ +public class OAuth2ResourceTest extends AdminUIBaseTest{ /** @@ -41,10 +36,10 @@ public void getOAuth2Data(final String issuer, final String adminUIConfigURL) { log.error("getOAuth2Data() - accessToken:{}, issuer:{}, adminUIConfigURL:{}", accessToken, issuer, adminUIConfigURL); Builder request = getResteasyService().getClientBuilder(issuer+adminUIConfigURL); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); - request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); - log.error("Response for getOAuth2Data - response:{}", response); + log.error("Response for getOAuth2Data() - response:{}", response); } @@ -53,14 +48,14 @@ public void getOAuth2Data(final String issuer, final String adminUIConfigURL) { */ @Parameters({"issuer", "apiProtectionTokenURL"}) @Test - public void getOAuth2Data(final String issuer, final String apiProtectionTokenURL, final String ujwt) { - log.error("getOAuth2Data() - accessToken:{}, issuer:{}, apiProtectionTokenURL:{}, ujwt:{}", accessToken, issuer, apiProtectionTokenURL, ujwt); + public void getApiProtectionTokenData(final String issuer, final String apiProtectionTokenURL, final String ujwt) { + log.error("getApiProtectionTokenData() - accessToken:{}, issuer:{}, apiProtectionTokenURL:{}, ujwt:{}", accessToken, issuer, apiProtectionTokenURL, ujwt); Builder request = getResteasyService().getClientBuilder(issuer+apiProtectionTokenURL); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - request.param("ujwt", ujwt); + request.property("ujwt", ujwt); Response response = request.get(); - log.error("Response for getOAuth2Data - response:{}", response); + log.error("Response for getApiProtectionTokenData() - response:{}", response); } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties index 145a0fc28ea..8bc6d4d2261 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties @@ -10,10 +10,11 @@ authzurl=/jans-auth/authorize.htm adminUIConfigURL=/jans-config-api/admin-ui/oauth2/config apiProtectionTokenURL=/jans-config-api/admin-ui/oauth2/api-protection-token checkLicenseURL=/jans-config-api/admin-ui/license/checkLicense -getLicenseDetailsURL=/jans-config-api/admin-ui/license/getLicenseDetails -getAuditLoggingURL=/jans-config-api/admin-ui/logging/audit - +licenseDetailsURL=/jans-config-api/admin-ui/license/getLicenseDetails +auditLoggingURL=/jans-config-api/admin-ui/logging/audit +#logging +audit_post_1=file:target/test-classes/json/logging/logging-post.json diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/logging/logging-post.json b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/logging/logging-post.json new file mode 100644 index 00000000000..9558aee3a09 --- /dev/null +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/json/logging/logging-post.json @@ -0,0 +1,5 @@ +{ + "message":{ + "childMsg":"Testing audit logging." + } +} \ No newline at end of file diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml index 4878788b305..4920639aa7b 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml @@ -5,13 +5,26 @@ - - + + + + + + + + + - + + + + + + + - + diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java index 12ec0f8a53f..5b2e24d08d6 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java @@ -27,7 +27,7 @@ public void getDefaultAuthenticationMethod(final String issuer, final String acr log.error("accessToken:{}, issuer:{}, acrsUrl:{}", accessToken, issuer, acrsUrl); Builder request = getResteasyService().getClientBuilder(issuer + acrsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); - request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); @@ -44,7 +44,7 @@ public void postClient(final String issuer, final String acrsUrl, final String j request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); + Response response = request.put(Entity.entity(json, MediaType.APPLICATION_JSON)); assertEquals(response.getStatus(), Status.OK.getStatusCode()); log.error("Response for getApiConfigtion - response:{}", response); diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java index 0eec29da2b5..ce33e0f5f6f 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java @@ -14,11 +14,9 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import org.testng.annotations.Test; - -import static org.testng.Assert.assertEquals; - +import static org.testng.Assert.*; import org.testng.annotations.Parameters; +import org.testng.annotations.Test; public class AuthConfigResourceTest extends ConfigServerBaseTest{ @@ -26,7 +24,7 @@ public class AuthConfigResourceTest extends ConfigServerBaseTest{ @Parameters({"issuer", "authConfigurationUrl"}) @Test public void getAuthConfigurationProperty(final String issuer, final String authConfigurationUrl) { - log.error("accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); + log.error("getAuthConfigurationProperty() - accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); Builder request = getResteasyService().getClientBuilder(issuer + authConfigurationUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -34,21 +32,35 @@ public void getAuthConfigurationProperty(final String issuer, final String authC Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getDefaultAuthenticationMethod - response:{}", response); + log.error("Response for getAuthConfigurationProperty() - response:{}", response); + } + + @Parameters({"issuer", "authConfigurationUrl"}) + @Test + public void getPersistenceDetails(final String issuer, final String authConfigurationUrl) { + log.error("getPersistenceDetails() - accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); + + Builder request = getResteasyService().getClientBuilder(issuer + authConfigurationUrl + "/persistence"); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getPersistenceDetails() - response:{}", response); } @Parameters({"issuer", "authConfigurationUrl", "auth_config_patch_1"}) @Test public void patchAuthConfigurationProperty(final String issuer, final String authConfigurationUrl, final String json) { - log.error("getApiConfigtion() - accessToken:{}, issuer:{}, authConfigurationUrl:{}, json:{}", accessToken, issuer, + log.error("patchAuthConfigurationProperty() - getApiConfigtion() - accessToken:{}, issuer:{}, authConfigurationUrl:{}, json:{}", accessToken, issuer, authConfigurationUrl, json); Builder request = getResteasyService().getClientBuilder(issuer + authConfigurationUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_PATCH_JSON); - Response response = request.method(HttpMethod.PATCH, Entity.entity(json, MediaType.APPLICATION_JSON)); + Response response = request.method(HttpMethod.PATCH, Entity.entity(json, MediaType.APPLICATION_JSON_PATCH_JSON)); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getApiConfigtion - response:{}", response); + log.error("Response patchAuthConfigurationProperty() - response:{}", response); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index f204ca9a22b..d13eafbeb94 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -10,14 +10,13 @@ import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; - +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; import static org.testng.Assert.*; - import org.testng.annotations.Parameters; import org.testng.annotations.Test; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; + public class ClientResourceTest extends ConfigServerBaseTest { diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java similarity index 94% rename from jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java rename to jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java index 924c8a88b1c..9a32484830b 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/rest/resource/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.rest.resource; +package io.jans.configapi.test.auth; import static org.testng.Assert.assertEquals; @@ -34,7 +34,7 @@ public void getApiConfigtion(final String issuer, final String apiConfigtionUrl) apiConfigtionUrl); Builder request = getResteasyService().getClientBuilder(issuer + apiConfigtionUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); - request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); @@ -61,7 +61,7 @@ public void patchgetApiConfigtion(final String issuer, final String apiConfigtio request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_PATCH_JSON); - Response response = request.method(HttpMethod.PATCH, Entity.entity(json, MediaType.APPLICATION_JSON)); + Response response = request.method(HttpMethod.PATCH, Entity.entity(json, MediaType.APPLICATION_JSON_PATCH_JSON)); assertEquals(response.getStatus(), Status.OK.getStatusCode()); log.error("Response for getApiConfigtion - response:{}", response); diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index 8aade5da3a0..127fa7cb56e 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -9,12 +9,35 @@ + + + + + + + + + + + + + + + + + + + + + + + From e9b64664904385cdb8c8eac08f4334c582a13c30 Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 29 Nov 2024 14:16:55 +0530 Subject: [PATCH 28/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 14 +- .../ca/plugin/adminui/AdminUIBaseTest.java | 15 -- .../test/AuditLoggingResourceTest.java | 4 +- .../adminui/test/LicenseResourceTest.java | 4 +- .../adminui/test/OAuth2ResourceTest.java | 6 +- .../test/resources/config-api-test.properties | 20 --- .../src/test/resources/test.properties | 24 +++ .../src/test/resources/testng.xml | 4 +- .../io/jans/configapi/KarateTestRunner.java | 18 --- .../io/jans/configapi/TestJenkinsRunner.java | 44 ----- .../configapi/test/Fido2ResourceTest.java | 39 +++++ .../test/resources/karate-config-jenkins.js | 58 ------- .../src/test/resources/karate.properties | 5 - .../test/resources/karate_jenkins.properties | 2 - .../src/test/resources/test.properties | 15 +- .../src/test/resources/testClient.feature | 13 -- .../src/test/resources/testng.xml | 19 +++ .../src/test/resources/token.feature | 45 ------ .../configapi/test/Fido2ResourceTest.java | 39 +++++ .../test/resources/karate-config-jenkins.js | 58 ------- .../src/test/resources/karate.properties | 5 - .../test/resources/karate_jenkins.properties | 2 - .../src/test/resources/test.properties | 15 +- .../src/test/resources/testClient.feature | 13 -- .../src/test/resources/testng.xml | 19 +++ .../src/test/resources/token.feature | 45 ------ .../config-api-test - Copy.properties | 43 ----- .../test/resources/config-api-test.properties | 55 ------- .../test/resources/karate-config-jenkins.js | 82 ---------- .../src/test/resources/karate.properties | 5 - .../test/resources/karate_jenkins.properties | 2 - .../server/src/test/resources/test.properties | 59 ++++++- .../src/test/resources/testClient.feature | 13 -- .../src/test/resources/testng - Copy.xml | 41 ----- .../server/src/test/resources/testng.xml | 8 +- .../server/src/test/resources/token.feature | 45 ------ .../io/jans/configapi/core/test/BaseTest.java | 61 ++----- .../core/test/service/TokenService.java | 151 ++++++++++++++++++ 38 files changed, 393 insertions(+), 717 deletions(-) delete mode 100644 jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties delete mode 100644 jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java delete mode 100644 jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java create mode 100644 jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java delete mode 100644 jans-config-api/plugins/fido2-plugin/src/test/resources/karate-config-jenkins.js delete mode 100644 jans-config-api/plugins/fido2-plugin/src/test/resources/karate.properties delete mode 100644 jans-config-api/plugins/fido2-plugin/src/test/resources/karate_jenkins.properties delete mode 100644 jans-config-api/plugins/fido2-plugin/src/test/resources/testClient.feature create mode 100644 jans-config-api/plugins/fido2-plugin/src/test/resources/testng.xml delete mode 100644 jans-config-api/plugins/fido2-plugin/src/test/resources/token.feature create mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java delete mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/resources/karate-config-jenkins.js delete mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/resources/karate.properties delete mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/resources/karate_jenkins.properties delete mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/resources/testClient.feature create mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/resources/testng.xml delete mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/resources/token.feature delete mode 100644 jans-config-api/server/src/test/resources/config-api-test - Copy.properties delete mode 100644 jans-config-api/server/src/test/resources/config-api-test.properties delete mode 100644 jans-config-api/server/src/test/resources/karate-config-jenkins.js delete mode 100644 jans-config-api/server/src/test/resources/karate.properties delete mode 100644 jans-config-api/server/src/test/resources/karate_jenkins.properties delete mode 100644 jans-config-api/server/src/test/resources/testClient.feature delete mode 100644 jans-config-api/server/src/test/resources/testng - Copy.xml delete mode 100644 jans-config-api/server/src/test/resources/token.feature create mode 100644 jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/TokenService.java diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 3a5b2887d7c..f2257ca9acd 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9273,17 +9273,17 @@ components: type: boolean whitePagesCanView: type: boolean - adminCanAccess: + adminCanEdit: type: boolean - userCanAccess: + adminCanView: type: boolean userCanEdit: type: boolean - adminCanEdit: - type: boolean userCanView: type: boolean - adminCanView: + adminCanAccess: + type: boolean + userCanAccess: type: boolean baseDn: type: string @@ -10137,6 +10137,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10146,8 +10148,6 @@ components: - code - token - id_token - fapi: - type: boolean AuthenticationFilter: required: - baseDn diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java index 27967dfe949..ec9bd0556e8 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -102,21 +102,6 @@ public class AdminUIBaseTest extends BaseTest{ //AdminUI specific code - @BeforeMethod - public void getAccessToken() throws Exception { - log.error("getAccessToken - propertiesMap:{}", propertiesMap); - - String tokenUrl = propertiesMap.get("authzurl"); - String strGrantType = propertiesMap.get("tokenGrantType"); - String clientId = propertiesMap.get("clientId"); - String clientSecret = propertiesMap.get("clientSecret"); - String scopes = propertiesMap.get("test.scopes"); - String authStr = clientId + ':' + clientSecret; - - GrantType grantType = GrantType.fromString(strGrantType); - this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); - log.error("accessToken:{}", accessToken); - } } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java index 66a133a4653..730b2ebf4fb 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java @@ -30,8 +30,8 @@ public class AuditLoggingResourceTest extends AdminUIBaseTest{ /** * Testing Audit Logging endpoint */ - @Parameters({"issuer", "auditLoggingURL", "audit_post_1"}) - @Test + @Parameters({"test.issuer", "auditLoggingURL", "audit_post_1"}) + // @Test public void postAuditLoggingData(final String issuer, final String auditLoggingURL, final String json) { log.error("postAuditLoggingData() - accessToken:{}, issuer:{}, auditLoggingURL:{}, json:{}", accessToken, issuer, auditLoggingURL, json); Builder request = getResteasyService().getClientBuilder(issuer+auditLoggingURL); diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java index dbabfb1659f..594c67ae942 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java @@ -30,8 +30,8 @@ public class LicenseResourceTest extends AdminUIBaseTest { /** * Test License Details */ - @Parameters({ "issuer", "licenseDetailsURL" }) - @Test + @Parameters({ "test.issuer", "licenseDetailsURL" }) + // @Test public void getLicenseDetails(final String issuer, final String licenseDetailsURL) { log.error("getLicenseDetails() - accessToken:{}, issuer:{}, licenseDetailsURL:{}", accessToken, issuer, licenseDetailsURL); diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java index 8819c972864..daaa257e5f5 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java @@ -30,8 +30,8 @@ public class OAuth2ResourceTest extends AdminUIBaseTest{ /** * Testing oauth2 GET configuration endpoint */ - @Parameters({"issuer", "adminUIConfigURL"}) - @Test + @Parameters({"test.issuer", "adminUIConfigURL"}) + @Test public void getOAuth2Data(final String issuer, final String adminUIConfigURL) { log.error("getOAuth2Data() - accessToken:{}, issuer:{}, adminUIConfigURL:{}", accessToken, issuer, adminUIConfigURL); Builder request = getResteasyService().getClientBuilder(issuer+adminUIConfigURL); @@ -46,7 +46,7 @@ public void getOAuth2Data(final String issuer, final String adminUIConfigURL) { /** * Testing api-protection-token GET endpoint */ - @Parameters({"issuer", "apiProtectionTokenURL"}) + @Parameters({"test.issuer", "apiProtectionTokenURL", "ujwt"}) @Test public void getApiProtectionTokenData(final String issuer, final String apiProtectionTokenURL, final String ujwt) { log.error("getApiProtectionTokenData() - accessToken:{}, issuer:{}, apiProtectionTokenURL:{}, ujwt:{}", accessToken, issuer, apiProtectionTokenURL, ujwt); diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties deleted file mode 100644 index 8bc6d4d2261..00000000000 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/config-api-test.properties +++ /dev/null @@ -1,20 +0,0 @@ -test.scopes=openid profile email user_name -test.grant.type=authorization_code -test.client.id=2073c8e7-1060-4c09-b0f6-7d46fb6ff8f5 -test.client.secret=92bc4d8e-2f4c-4a4d-80ae-1e4eb1f5f463 -test.issuer=https://admin-ui-test.gluu.org -test.authzurl=https://admin-ui-test.gluu.org/jans-auth/authorize.htm - -ujwt=eyJraWQiOiI2NmQ1ODk4Ny03NjQ0LTRkYjEtOWU2YS04ZmFiNWFjYWVhNjVfc2lnX3JzMjU2IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJndFZ2cDJCMGlwdFN5bXFSTEpzc2ZZOWZNbjliWVZRNF8xVTBHSFlFWFRJIiwiYXVkIjoiMjA3M2M4ZTctMTA2MC00YzA5LWIwZjYtN2Q0NmZiNmZmOGY1IiwibmFtZSI6IkRlZmF1bHQgQWRtaW4gVXNlciIsIm5pY2tuYW1lIjoiQWRtaW4iLCJpc3MiOiJodHRwczovL2FkbWluLXVpLXRlc3QuZ2x1dS5vcmciLCJnaXZlbl9uYW1lIjoiQWRtaW4iLCJtaWRkbGVfbmFtZSI6IkFkbWluIiwiZmFtaWx5X25hbWUiOiJVc2VyIiwiamFuc0FkbWluVUlSb2xlIjpbImFwaS1hZG1pbiJdfQ.losuUsBib2YvB2t995iT0HJvE-q7uZT8zHrTJsWN8_rxB_-kawFNI6weWiH4hpAaIAIaw6Bnq5AczSW3OS6sn5fZDrBxuftrurCa7PK7uAeYim8Zozg0NHNQQ9FDe6MYg8FLtKI3eiusvgC3P4CClIFf1AMGVxREyBra87r_J8j2IyV86Ktjv_rVZLNm2mChOrbM5sIjaski4saKtZTMiVZoK7WMC4FJmS8ttysfG2w7-t8MoI9kiM890RhxSoUba9nQIVxKmpdJOzam8_FqNfQmC9fzI2XKjgRu16SoAoJxCNeTy8HHBCN4H_BwxgU2seSbDTMgU11GiApd4D2xaw -authzurl=/jans-auth/authorize.htm -adminUIConfigURL=/jans-config-api/admin-ui/oauth2/config -apiProtectionTokenURL=/jans-config-api/admin-ui/oauth2/api-protection-token -checkLicenseURL=/jans-config-api/admin-ui/license/checkLicense -licenseDetailsURL=/jans-config-api/admin-ui/license/getLicenseDetails -auditLoggingURL=/jans-config-api/admin-ui/logging/audit - - - -#logging -audit_post_1=file:target/test-classes/json/logging/logging-post.json - diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties index a327ce4a05b..af4f0266193 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties @@ -1,6 +1,30 @@ +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete + +# Test env Setting +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + test.scopes=openid profile email user_name test.grant.type=authorization_code test.client.id=2073c8e7-1060-4c09-b0f6-7d46fb6ff8f5 test.client.secret=92bc4d8e-2f4c-4a4d-80ae-1e4eb1f5f463 test.issuer=https://admin-ui-test.gluu.org test.authzurl=https://admin-ui-test.gluu.org/jans-auth/authorize.htm + +ujwt=eyJraWQiOiI2NmQ1ODk4Ny03NjQ0LTRkYjEtOWU2YS04ZmFiNWFjYWVhNjVfc2lnX3JzMjU2IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJndFZ2cDJCMGlwdFN5bXFSTEpzc2ZZOWZNbjliWVZRNF8xVTBHSFlFWFRJIiwiYXVkIjoiMjA3M2M4ZTctMTA2MC00YzA5LWIwZjYtN2Q0NmZiNmZmOGY1IiwibmFtZSI6IkRlZmF1bHQgQWRtaW4gVXNlciIsIm5pY2tuYW1lIjoiQWRtaW4iLCJpc3MiOiJodHRwczovL2FkbWluLXVpLXRlc3QuZ2x1dS5vcmciLCJnaXZlbl9uYW1lIjoiQWRtaW4iLCJtaWRkbGVfbmFtZSI6IkFkbWluIiwiZmFtaWx5X25hbWUiOiJVc2VyIiwiamFuc0FkbWluVUlSb2xlIjpbImFwaS1hZG1pbiJdfQ.losuUsBib2YvB2t995iT0HJvE-q7uZT8zHrTJsWN8_rxB_-kawFNI6weWiH4hpAaIAIaw6Bnq5AczSW3OS6sn5fZDrBxuftrurCa7PK7uAeYim8Zozg0NHNQQ9FDe6MYg8FLtKI3eiusvgC3P4CClIFf1AMGVxREyBra87r_J8j2IyV86Ktjv_rVZLNm2mChOrbM5sIjaski4saKtZTMiVZoK7WMC4FJmS8ttysfG2w7-t8MoI9kiM890RhxSoUba9nQIVxKmpdJOzam8_FqNfQmC9fzI2XKjgRu16SoAoJxCNeTy8HHBCN4H_BwxgU2seSbDTMgU11GiApd4D2xaw +authzurl=/jans-auth/authorize.htm +adminUIConfigURL=/jans-config-api/admin-ui/oauth2/config +apiProtectionTokenURL=/jans-config-api/admin-ui/oauth2/api-protection-token +checkLicenseURL=/jans-config-api/admin-ui/license/checkLicense +licenseDetailsURL=/jans-config-api/admin-ui/license/getLicenseDetails +auditLoggingURL=/jans-config-api/admin-ui/logging/audit + + + +#logging +audit_post_1=file:target/test-classes/json/logging/logging-post.json + diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml index 4920639aa7b..a3a46e5b796 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/testng.xml @@ -2,14 +2,14 @@ - + - + diff --git a/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java deleted file mode 100644 index 34da4586ef9..00000000000 --- a/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.junit5.Karate; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java b/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java deleted file mode 100644 index a7f7d2d80c2..00000000000 --- a/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; - -import io.jans.as.common.model.registration.Client; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class TestJenkinsRunner { - - @Test - void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java b/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java new file mode 100644 index 00000000000..6710c8a5985 --- /dev/null +++ b/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class Fido2ResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "fido2Url"}) + @Test + public void getFido2Configuration(final String issuer, final String fido2Url) { + log.error("getFido2Configuration() - accessToken:{}, issuer:{}, fido2Url:{}", accessToken, issuer, fido2Url); + Builder request = getResteasyService().getClientBuilder(issuer + fido2Url); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("getFido2Configuration() - Response for getDefaultAuthenticationMethod - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/fido2-plugin/src/test/resources/karate-config-jenkins.js deleted file mode 100644 index 35a4a9bb3c1..00000000000 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/karate-config-jenkins.js +++ /dev/null @@ -1,58 +0,0 @@ -function() { - - var stream = read('classpath:karate_jenkins.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate_jenkins env :', env); - karate.log('karate_jenkins url :', url); - karate.log('karate_jenkins port :', port); - karate.log('karate_jenkins baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - fido2Url: baseUrl + '/jans-config-api/fido2/fido2-config', - - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/fido2-plugin/src/test/resources/karate.properties deleted file mode 100644 index 41c0d369aff..00000000000 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/karate.properties +++ /dev/null @@ -1,5 +0,0 @@ -#karate.test.url=http://localhost -#karate.test.port=8080 -#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api -#karate.test.port=443 -karate.test.url=${test.server} diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/fido2-plugin/src/test/resources/karate_jenkins.properties deleted file mode 100644 index 0b44a8d7b13..00000000000 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/karate_jenkins.properties +++ /dev/null @@ -1,2 +0,0 @@ -karate.test.url=${test.server} -#karate.test.port=443 diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/test.properties b/jans-config-api/plugins/fido2-plugin/src/test/resources/test.properties index 4257f297907..a552226de85 100644 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/fido2-plugin/src/test/resources/test.properties @@ -1,8 +1,11 @@ -test.scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +fido2Url=/jans-config-api/fido2/fido2-config \ No newline at end of file diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/fido2-plugin/src/test/resources/testClient.feature deleted file mode 100644 index 34cfdffc438..00000000000 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/testClient.feature +++ /dev/null @@ -1,13 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - -Background: -* def mainUrl = test_url - -Scenario: Get Token -Given url mainUrl -And print url -And request '' -When method POST -Then status 204 -And print response diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/fido2-plugin/src/test/resources/testng.xml new file mode 100644 index 00000000000..4a441f68680 --- /dev/null +++ b/jans-config-api/plugins/fido2-plugin/src/test/resources/testng.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/token.feature b/jans-config-api/plugins/fido2-plugin/src/test/resources/token.feature deleted file mode 100644 index ef0ad0d262d..00000000000 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/token.feature +++ /dev/null @@ -1,45 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - Do not remove ignore tag - -Background: -* def mainUrl = testProps.get('token.endpoint'); -* def grantType = testProps.get('token.grant.type'); -* def clientId = testProps.get('test.client.id'); -* def clientSecret = testProps.get('test.client.secret'); -* def scopes = testProps.get('test.scopes'); -* def authStr = clientId+':'+clientSecret -* def Base64 = Java.type('java.util.Base64') -* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) -* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') - - -Scenario: Get Token -Given url mainUrl -And print 'mainUrl = '+mainUrl -And print 'grantType = '+grantType -And print 'clientId = '+clientId -And print 'clientSecret = '+clientSecret -And print 'scopes = '+scopes -And print 'authStr = '+authStr -And print 'encodedAuth = '+encodedAuth -And print 'encodedScopes = '+encodedScopes -And header Accept = 'application/json' -And header Authorization = 'Basic '+encodedAuth -And form field grant_type = grantType -And form field scope = scopes -When method POST -Then status 200 -And print 'token response = '+response - - - - -#Scenario: Get Token -#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' -#And header Accept = 'application/json' -#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' -#And form field grant_type = 'client_credentials' -#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' -#When method POST -#Then status 200 -#And print 'token response = '+response diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java b/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java new file mode 100644 index 00000000000..6710c8a5985 --- /dev/null +++ b/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class Fido2ResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "fido2Url"}) + @Test + public void getFido2Configuration(final String issuer, final String fido2Url) { + log.error("getFido2Configuration() - accessToken:{}, issuer:{}, fido2Url:{}", accessToken, issuer, fido2Url); + Builder request = getResteasyService().getClientBuilder(issuer + fido2Url); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("getFido2Configuration() - Response for getDefaultAuthenticationMethod - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate-config-jenkins.js deleted file mode 100644 index e8db40cc61c..00000000000 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate-config-jenkins.js +++ /dev/null @@ -1,58 +0,0 @@ -function() { - - var stream = read('classpath:karate_jenkins.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate_jenkins env :', env); - karate.log('karate_jenkins url :', url); - karate.log('karate_jenkins port :', port); - karate.log('karate_jenkins baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - jansLinkUrl: baseUrl + '/jans-config-api/jans-link/link-config', - - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate.properties deleted file mode 100644 index 41c0d369aff..00000000000 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate.properties +++ /dev/null @@ -1,5 +0,0 @@ -#karate.test.url=http://localhost -#karate.test.port=8080 -#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api -#karate.test.port=443 -karate.test.url=${test.server} diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate_jenkins.properties deleted file mode 100644 index 0b44a8d7b13..00000000000 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate_jenkins.properties +++ /dev/null @@ -1,2 +0,0 @@ -karate.test.url=${test.server} -#karate.test.port=443 diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties b/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties index 4257f297907..a552226de85 100644 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties @@ -1,8 +1,11 @@ -test.scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +fido2Url=/jans-config-api/fido2/fido2-config \ No newline at end of file diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/jans-link-plugin/src/test/resources/testClient.feature deleted file mode 100644 index 34cfdffc438..00000000000 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/testClient.feature +++ /dev/null @@ -1,13 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - -Background: -* def mainUrl = test_url - -Scenario: Get Token -Given url mainUrl -And print url -And request '' -When method POST -Then status 204 -And print response diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/jans-link-plugin/src/test/resources/testng.xml new file mode 100644 index 00000000000..4a441f68680 --- /dev/null +++ b/jans-config-api/plugins/jans-link-plugin/src/test/resources/testng.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/token.feature b/jans-config-api/plugins/jans-link-plugin/src/test/resources/token.feature deleted file mode 100644 index ef0ad0d262d..00000000000 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/token.feature +++ /dev/null @@ -1,45 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - Do not remove ignore tag - -Background: -* def mainUrl = testProps.get('token.endpoint'); -* def grantType = testProps.get('token.grant.type'); -* def clientId = testProps.get('test.client.id'); -* def clientSecret = testProps.get('test.client.secret'); -* def scopes = testProps.get('test.scopes'); -* def authStr = clientId+':'+clientSecret -* def Base64 = Java.type('java.util.Base64') -* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) -* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') - - -Scenario: Get Token -Given url mainUrl -And print 'mainUrl = '+mainUrl -And print 'grantType = '+grantType -And print 'clientId = '+clientId -And print 'clientSecret = '+clientSecret -And print 'scopes = '+scopes -And print 'authStr = '+authStr -And print 'encodedAuth = '+encodedAuth -And print 'encodedScopes = '+encodedScopes -And header Accept = 'application/json' -And header Authorization = 'Basic '+encodedAuth -And form field grant_type = grantType -And form field scope = scopes -When method POST -Then status 200 -And print 'token response = '+response - - - - -#Scenario: Get Token -#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' -#And header Accept = 'application/json' -#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' -#And form field grant_type = 'client_credentials' -#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' -#When method POST -#Then status 200 -#And print 'token response = '+response diff --git a/jans-config-api/server/src/test/resources/config-api-test - Copy.properties b/jans-config-api/server/src/test/resources/config-api-test - Copy.properties deleted file mode 100644 index 5892a12bea4..00000000000 --- a/jans-config-api/server/src/test/resources/config-api-test - Copy.properties +++ /dev/null @@ -1,43 +0,0 @@ -scopes=${test.scopes} - -# Test env Setting -tokenEndpoint=${token.endpoint} -tokenGrantType=${token.grant.type} -clientId=${test.client.id} -clientSecret=${test.client.secret} -issuer=${test.issuer} - - -statUrl= "/jans-config-api/api/v1/stat" -healthUrl="/jans-config-api/api/v1/health" -acrsUrl="/jans-config-api/api/v1/acrs" -authConfigurationUrl="/jans-config-api/api/v1/jans-auth-server/config" -scriptsUrl="/jans-config-api/api/v1/config/scripts" -cacheUrl="/jans-config-api/api/v1/config/cache" -messageUrl="/jans-config-api/api/v1/config/message" -jwksUrl="/jans-config-api/api/v1/config/jwks" -ldapUrl="/jans-config-api/api/v1/config/database/ldap" -openidClientsUrl="/jans-config-api/api/v1/openid/clients" -scopesUrl="/jans-config-api/api/v1/scopes" -umaresourcesUrl="/jans-config-api/api/v1/uma/resources" -attributesUrl="/jans-config-api/api/v1/attributes" -smtpUrl="/jans-config-api/api/v1/config/smtp" -loggingUrl="/jans-config-api/api/v1/logging" -authHealthUrl="/jans-config-api/api/v1/jans-auth-server/health" -orgConfigurationUrl="/jans-config-api/api/v1/org" -userUrl="/jans-config-api/api/v1/user" -agamaUrl="/jans-config-api/api/v1/agama" -sessionUrl="/jans-config-api/api/v1/jans-auth-server/session" -pluginUrl="/jans-config-api/api/v1/plugin" -apiConfigUrl="/jans-config-api/api/v1/api-config" -agamaDeploymentUrl="/jans-config-api/api/v1/agama-deployment" -clientsAuthorizationsUrl="/jans-config-api/api/v1/clients/authorizations" -tokenUrl="/jans-config-api/api/v1/token" - - -#openid-client -openid_client1=file:target/test-classes/json/openid/clients/client.json - -#openid-scopes -openid_scopes1=file:target/test-classes/json/openid/scopes/scope.json - diff --git a/jans-config-api/server/src/test/resources/config-api-test.properties b/jans-config-api/server/src/test/resources/config-api-test.properties deleted file mode 100644 index 460a2e643f9..00000000000 --- a/jans-config-api/server/src/test/resources/config-api-test.properties +++ /dev/null @@ -1,55 +0,0 @@ -scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete - -# Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token -tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info - - -statUrl=/jans-config-api/api/v1/stat -healthUrl=/jans-config-api/api/v1/health -acrsUrl=/jans-config-api/api/v1/acrs -apiConfigtionUrl=/jans-config-api/api/v1/api-config -authConfigurationUrl=/jans-config-api/api/v1/jans-auth-server/config -scriptsUrl=/jans-config-api/api/v1/config/scripts -cacheUrl=/jans-config-api/api/v1/config/cache -messageUrl=/jans-config-api/api/v1/config/message -jwksUrl=/jans-config-api/api/v1/config/jwks -ldapUrl=/jans-config-api/api/v1/config/database/ldap -openidClientsUrl=/jans-config-api/api/v1/openid/clients -scopesUrl=/jans-config-api/api/v1/scopes -umaresourcesUrl=/jans-config-api/api/v1/uma/resources -attributesUrl=/jans-config-api/api/v1/attributes -smtpUrl=/jans-config-api/api/v1/config/smtp -loggingUrl=/jans-config-api/api/v1/logging -authHealthUrl=/jans-config-api/api/v1/jans-auth-server/health -orgConfigurationUrl=/jans-config-api/api/v1/org -userUrl=/jans-config-api/api/v1/user -agamaUrl=/jans-config-api/api/v1/agama -sessionUrl=/jans-config-api/api/v1/jans-auth-server/session -pluginUrl=/jans-config-api/api/v1/plugin -apiConfigUrl=/jans-config-api/api/v1/api-config -agamaDeploymentUrl=/jans-config-api/api/v1/agama-deployment -clientsAuthorizationsUrl=/jans-config-api/api/v1/clients/authorizations -tokenUrl=/jans-config-api/api/v1/token - - -#apiConfigtion -api_config_patch_1=file:target/test-classes/json/config/api/api-config-patch.json - -#apiConfigtion -auth_config_patch_1=file:target/test-classes/json/config/auth/auth-config-patch.json - -#defaultAcr -default_acr_1=file:target/test-classes/json/acr/defaultAcr.json - -#openid-client -openid_client_1=file:target/test-classes/json/openid/clients/openid-client-post.json -openid_client_2=file:target/test-classes/json/openid/clients/client.json - - -#openid-scopes -openid_scopes_1=file:target/test-classes/json/openid/scopes/scope.json - diff --git a/jans-config-api/server/src/test/resources/karate-config-jenkins.js b/jans-config-api/server/src/test/resources/karate-config-jenkins.js deleted file mode 100644 index 33999c8bcf8..00000000000 --- a/jans-config-api/server/src/test/resources/karate-config-jenkins.js +++ /dev/null @@ -1,82 +0,0 @@ -function() { - - var stream = read('classpath:karate_jenkins.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate_jenkins env :', env); - karate.log('karate_jenkins url :', url); - karate.log('karate_jenkins port :', port); - karate.log('karate_jenkins baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - statUrl: baseUrl + '/jans-config-api/api/v1/stat', - healthUrl: baseUrl + '/jans-config-api/api/v1/health', - acrsUrl: baseUrl + '/jans-config-api/api/v1/acrs', - authConfigurationUrl: baseUrl + '/jans-config-api/api/v1/jans-auth-server/config', - scriptsUrl: baseUrl + '/jans-config-api/api/v1/config/scripts', - cacheUrl: baseUrl + '/jans-config-api/api/v1/config/cache', - messageUrl: baseUrl + '/jans-config-api/api/v1/config/message', - jwksUrl: baseUrl + '/jans-config-api/api/v1/config/jwks', - ldapUrl: baseUrl + '/jans-config-api/api/v1/config/database/ldap', - openidclients_url: baseUrl + '/jans-config-api/api/v1/openid/clients', - scopes_url: baseUrl + '/jans-config-api/api/v1/scopes', - umaresources_url: baseUrl + '/jans-config-api/api/v1/uma/resources', - attributes_url: baseUrl + '/jans-config-api/api/v1/attributes', - smtp_url: baseUrl + '/jans-config-api/api/v1/config/smtp', - logging_url: baseUrl + '/jans-config-api/api/v1/logging', - auth_health_url: baseUrl + '/jans-config-api/api/v1/jans-auth-server/health', - org_configuration_url: baseUrl + '/jans-config-api/api/v1/org', - user_url: baseUrl + '/jans-config-api/api/v1/user', - agama_url: baseUrl + '/jans-config-api/api/v1/agama', - session_url: baseUrl + '/jans-config-api/api/v1/jans-auth-server/session', - plugin_url: baseUrl + '/jans-config-api/api/v1/plugin', - api_config_url: baseUrl + '/jans-config-api/api/v1/api-config', - agama_deployment_url: baseUrl + '/jans-config-api/api/v1/agama-deployment', - clients_authorizations_url: baseUrl + '/jans-config-api/api/v1/clients/authorizations', - token_url: baseUrl + '/jans-config-api/api/v1/token', - - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/karate.properties b/jans-config-api/server/src/test/resources/karate.properties deleted file mode 100644 index 41c0d369aff..00000000000 --- a/jans-config-api/server/src/test/resources/karate.properties +++ /dev/null @@ -1,5 +0,0 @@ -#karate.test.url=http://localhost -#karate.test.port=8080 -#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api -#karate.test.port=443 -karate.test.url=${test.server} diff --git a/jans-config-api/server/src/test/resources/karate_jenkins.properties b/jans-config-api/server/src/test/resources/karate_jenkins.properties deleted file mode 100644 index 0b44a8d7b13..00000000000 --- a/jans-config-api/server/src/test/resources/karate_jenkins.properties +++ /dev/null @@ -1,2 +0,0 @@ -karate.test.url=${test.server} -#karate.test.port=443 diff --git a/jans-config-api/server/src/test/resources/test.properties b/jans-config-api/server/src/test/resources/test.properties index 4257f297907..460a2e643f9 100644 --- a/jans-config-api/server/src/test/resources/test.properties +++ b/jans-config-api/server/src/test/resources/test.properties @@ -1,8 +1,55 @@ -test.scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +statUrl=/jans-config-api/api/v1/stat +healthUrl=/jans-config-api/api/v1/health +acrsUrl=/jans-config-api/api/v1/acrs +apiConfigtionUrl=/jans-config-api/api/v1/api-config +authConfigurationUrl=/jans-config-api/api/v1/jans-auth-server/config +scriptsUrl=/jans-config-api/api/v1/config/scripts +cacheUrl=/jans-config-api/api/v1/config/cache +messageUrl=/jans-config-api/api/v1/config/message +jwksUrl=/jans-config-api/api/v1/config/jwks +ldapUrl=/jans-config-api/api/v1/config/database/ldap +openidClientsUrl=/jans-config-api/api/v1/openid/clients +scopesUrl=/jans-config-api/api/v1/scopes +umaresourcesUrl=/jans-config-api/api/v1/uma/resources +attributesUrl=/jans-config-api/api/v1/attributes +smtpUrl=/jans-config-api/api/v1/config/smtp +loggingUrl=/jans-config-api/api/v1/logging +authHealthUrl=/jans-config-api/api/v1/jans-auth-server/health +orgConfigurationUrl=/jans-config-api/api/v1/org +userUrl=/jans-config-api/api/v1/user +agamaUrl=/jans-config-api/api/v1/agama +sessionUrl=/jans-config-api/api/v1/jans-auth-server/session +pluginUrl=/jans-config-api/api/v1/plugin +apiConfigUrl=/jans-config-api/api/v1/api-config +agamaDeploymentUrl=/jans-config-api/api/v1/agama-deployment +clientsAuthorizationsUrl=/jans-config-api/api/v1/clients/authorizations +tokenUrl=/jans-config-api/api/v1/token + + +#apiConfigtion +api_config_patch_1=file:target/test-classes/json/config/api/api-config-patch.json + +#apiConfigtion +auth_config_patch_1=file:target/test-classes/json/config/auth/auth-config-patch.json + +#defaultAcr +default_acr_1=file:target/test-classes/json/acr/defaultAcr.json + +#openid-client +openid_client_1=file:target/test-classes/json/openid/clients/openid-client-post.json +openid_client_2=file:target/test-classes/json/openid/clients/client.json + + +#openid-scopes +openid_scopes_1=file:target/test-classes/json/openid/scopes/scope.json + diff --git a/jans-config-api/server/src/test/resources/testClient.feature b/jans-config-api/server/src/test/resources/testClient.feature deleted file mode 100644 index 34cfdffc438..00000000000 --- a/jans-config-api/server/src/test/resources/testClient.feature +++ /dev/null @@ -1,13 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - -Background: -* def mainUrl = test_url - -Scenario: Get Token -Given url mainUrl -And print url -And request '' -When method POST -Then status 204 -And print response diff --git a/jans-config-api/server/src/test/resources/testng - Copy.xml b/jans-config-api/server/src/test/resources/testng - Copy.xml deleted file mode 100644 index 97a2fe06e41..00000000000 --- a/jans-config-api/server/src/test/resources/testng - Copy.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index 127fa7cb56e..ff0a012a9bb 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -2,20 +2,20 @@ - + - + - + @@ -33,7 +33,7 @@ - + diff --git a/jans-config-api/server/src/test/resources/token.feature b/jans-config-api/server/src/test/resources/token.feature deleted file mode 100644 index ef0ad0d262d..00000000000 --- a/jans-config-api/server/src/test/resources/token.feature +++ /dev/null @@ -1,45 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - Do not remove ignore tag - -Background: -* def mainUrl = testProps.get('token.endpoint'); -* def grantType = testProps.get('token.grant.type'); -* def clientId = testProps.get('test.client.id'); -* def clientSecret = testProps.get('test.client.secret'); -* def scopes = testProps.get('test.scopes'); -* def authStr = clientId+':'+clientSecret -* def Base64 = Java.type('java.util.Base64') -* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) -* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') - - -Scenario: Get Token -Given url mainUrl -And print 'mainUrl = '+mainUrl -And print 'grantType = '+grantType -And print 'clientId = '+clientId -And print 'clientSecret = '+clientSecret -And print 'scopes = '+scopes -And print 'authStr = '+authStr -And print 'encodedAuth = '+encodedAuth -And print 'encodedScopes = '+encodedScopes -And header Accept = 'application/json' -And header Authorization = 'Basic '+encodedAuth -And form field grant_type = grantType -And form field scope = scopes -When method POST -Then status 200 -And print 'token response = '+response - - - - -#Scenario: Get Token -#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' -#And header Accept = 'application/json' -#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' -#And form field grant_type = 'client_credentials' -#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' -#When method POST -#Then status 200 -#And print 'token response = '+response diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java index f30ee422bf9..a43a3043853 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java @@ -13,6 +13,7 @@ import io.jans.configapi.core.util.Jackson; import io.jans.configapi.core.test.service.HttpService; import io.jans.configapi.core.test.service.ResteasyService; +import io.jans.configapi.core.test.service.TokenService; import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.file.Files; @@ -103,15 +104,16 @@ public class BaseTest { private static final String FILE_PREFIX = "file:"; private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private static final String NEW_LINE = System.getProperty("line.separator"); - protected static final String CONTENT_TYPE = "Content-Type"; protected static final String AUTHORIZATION = "Authorization"; protected static final String AUTHORIZATION_TYPE = "Bearer"; + protected Logger log = LogManager.getLogger(getClass()); protected Base64 base64; protected static Map propertiesMap = null; protected ResteasyService resteasyService = new ResteasyService();; protected HttpService httpService = new HttpService(); + protected TokenService tokenService = new TokenService(); protected String accessToken; @BeforeSuite @@ -153,57 +155,12 @@ public void getAccessToken() throws Exception { this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); log.error("accessToken:{}", accessToken); } - - public String getToken(final String tokenUrl, final String clientId, final String clientSecret, GrantType grantType, + + protected String getToken(final String tokenUrl, final String clientId, final String clientSecret, GrantType grantType, final String scopes) { - log.info("Request for token tokenUrl:{}, clientId:{}, grantType:{}, scopes:{}", tokenUrl, clientId, grantType, - scopes); - String accessToken = null; - TokenResponse tokenResponse = this.requestAccessToken(tokenUrl, clientId, clientSecret, grantType, scopes); - if (tokenResponse != null) { - accessToken = tokenResponse.getAccessToken(); - log.trace("accessToken:{}, ", accessToken); - } - - return accessToken; - } - - public TokenResponse requestAccessToken(final String tokenUrl, final String clientId, final String clientSecret, - GrantType grantType, final String scope) { - log.info("Request for access token tokenUrl:{}, clientId:{},scope:{}", tokenUrl, clientId, scope); - Response response = null; - try { - if (grantType == null) { - grantType = GrantType.CLIENT_CREDENTIALS; - } - TokenRequest tokenRequest = new TokenRequest(grantType); - tokenRequest.setScope(scope); - tokenRequest.setAuthUsername(clientId); - tokenRequest.setAuthPassword(clientSecret); - Builder request = resteasyService.getClientBuilder(tokenUrl); - request.header(AUTHORIZATION, "Basic " + tokenRequest.getEncodedCredentials()); - request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - final MultivaluedHashMap multivaluedHashMap = new MultivaluedHashMap<>( - tokenRequest.getParameters()); - response = request.post(Entity.form(multivaluedHashMap)); - log.trace("Response for Access Token - response:{}", response); - if (response.getStatus() == 200) { - String entity = response.readEntity(String.class); - TokenResponse tokenResponse = new TokenResponse(); - tokenResponse.setEntity(entity); - tokenResponse.injectDataFromJson(entity); - return tokenResponse; - } - } finally { - - if (response != null) { - response.close(); - } - } - return null; + return getTokenService().getToken(tokenUrl, clientId, clientSecret, grantType, scopes); } - - //TO-DO - check if needed + protected HttpService getHttpService() { return this.httpService; } @@ -211,6 +168,10 @@ protected HttpService getHttpService() { protected ResteasyService getResteasyService() { return this.resteasyService; } + + protected TokenService getTokenService() { + return this.tokenService; + } protected String getCredentials(final String clientId, final String clientSecret) throws UnsupportedEncodingException { diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/TokenService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/TokenService.java new file mode 100644 index 00000000000..5a243cadc42 --- /dev/null +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/TokenService.java @@ -0,0 +1,151 @@ +/* + * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.core.test.service; + +import io.jans.as.client.TokenRequest; +import io.jans.as.client.TokenResponse; +import io.jans.as.model.common.GrantType; +import io.jans.as.model.util.Util; +import io.jans.configapi.core.util.Jackson; +import io.jans.configapi.core.test.service.HttpService; +import io.jans.configapi.core.test.service.ResteasyService; +import io.jans.configapi.core.test.service.TokenService; + +import static java.nio.charset.StandardCharsets.UTF_8; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; + +import java.util.Hashtable; +import java.util.Map; +import java.util.Properties; +import java.net.URLEncoder; +import java.io.UnsupportedEncodingException; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URLDecoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.util.*; +import java.util.Map.Entry; + +import jakarta.servlet.http.HttpServletRequest; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CookieStore; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.entity.ContentType; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.SSLContexts; + +import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; +import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; +import org.jboss.resteasy.client.jaxrs.ResteasyClient; +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; +import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; + +import jakarta.annotation.PostConstruct; +import jakarta.ws.rs.core.UriBuilder; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedHashMap; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +public class TokenService implements Serializable { + + private static final long serialVersionUID = 1L; + private Logger log = LogManager.getLogger(getClass()); + private static final String CONTENT_TYPE = "Content-Type"; + private static final String AUTHORIZATION = "Authorization"; + private static final String AUTHORIZATION_TYPE = "Bearer"; + + public String getToken(final String tokenUrl, final String clientId, final String clientSecret, GrantType grantType, + final String scopes) { + log.info("Request for token tokenUrl:{}, clientId:{}, grantType:{}, scopes:{}", tokenUrl, clientId, grantType, + scopes); + String accessToken = null; + TokenResponse tokenResponse = this.requestAccessToken(tokenUrl, clientId, clientSecret, grantType, scopes); + if (tokenResponse != null) { + accessToken = tokenResponse.getAccessToken(); + log.trace("accessToken:{}, ", accessToken); + } + + return accessToken; + } + + public TokenResponse requestAccessToken(final String tokenUrl, final String clientId, final String clientSecret, + GrantType grantType, final String scope) { + log.info("Request for access token tokenUrl:{}, clientId:{},scope:{}", tokenUrl, clientId, scope); + Response response = null; + try { + if (grantType == null) { + grantType = GrantType.CLIENT_CREDENTIALS; + } + TokenRequest tokenRequest = new TokenRequest(grantType); + tokenRequest.setScope(scope); + tokenRequest.setAuthUsername(clientId); + tokenRequest.setAuthPassword(clientSecret); + Builder request = new ResteasyService().getClientBuilder(tokenUrl); + request.header(AUTHORIZATION, "Basic " + tokenRequest.getEncodedCredentials()); + request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); + final MultivaluedHashMap multivaluedHashMap = new MultivaluedHashMap<>( + tokenRequest.getParameters()); + response = request.post(Entity.form(multivaluedHashMap)); + log.trace("Response for Access Token - response:{}", response); + if (response.getStatus() == 200) { + String entity = response.readEntity(String.class); + TokenResponse tokenResponse = new TokenResponse(); + tokenResponse.setEntity(entity); + tokenResponse.injectDataFromJson(entity); + return tokenResponse; + } + } finally { + + if (response != null) { + response.close(); + } + } + return null; + } + +} From f6029f4b83500f9f30818c28e42624976e97b027 Mon Sep 17 00:00:00 2001 From: pujavs Date: Wed, 4 Dec 2024 13:39:14 +0530 Subject: [PATCH 29/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 20 +++++++++---------- .../plugins/admin-ui-plugin/pom.xml | 2 ++ .../test/AuditLoggingResourceTest.java | 4 ++-- .../adminui/test/LicenseResourceTest.java | 12 +++++------ .../src/test/resources/test.properties | 2 +- .../server/src/test/resources/testng.xml | 4 ++-- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index f2257ca9acd..9ccb55bcd7d 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9275,16 +9275,16 @@ components: type: boolean adminCanEdit: type: boolean - adminCanView: + userCanView: type: boolean userCanEdit: type: boolean - userCanView: - type: boolean - adminCanAccess: + adminCanView: type: boolean userCanAccess: type: boolean + adminCanAccess: + type: boolean baseDn: type: string PatchRequest: @@ -10137,8 +10137,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10148,6 +10146,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -11256,14 +11256,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: @@ -11692,10 +11692,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/admin-ui-plugin/pom.xml b/jans-config-api/plugins/admin-ui-plugin/pom.xml index 704a8592bc8..03b0ef004c0 100644 --- a/jans-config-api/plugins/admin-ui-plugin/pom.xml +++ b/jans-config-api/plugins/admin-ui-plugin/pom.xml @@ -95,12 +95,14 @@ admin-ui-plugin + src/test/resources true + org.apache.maven.plugins diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java index 730b2ebf4fb..bed59a000f9 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java @@ -31,11 +31,11 @@ public class AuditLoggingResourceTest extends AdminUIBaseTest{ * Testing Audit Logging endpoint */ @Parameters({"test.issuer", "auditLoggingURL", "audit_post_1"}) - // @Test + @Test public void postAuditLoggingData(final String issuer, final String auditLoggingURL, final String json) { log.error("postAuditLoggingData() - accessToken:{}, issuer:{}, auditLoggingURL:{}, json:{}", accessToken, issuer, auditLoggingURL, json); Builder request = getResteasyService().getClientBuilder(issuer+auditLoggingURL); - request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + //request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java index 594c67ae942..a729fce2876 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java @@ -30,12 +30,12 @@ public class LicenseResourceTest extends AdminUIBaseTest { /** * Test License Details */ - @Parameters({ "test.issuer", "licenseDetailsURL" }) - // @Test - public void getLicenseDetails(final String issuer, final String licenseDetailsURL) { - log.error("getLicenseDetails() - accessToken:{}, issuer:{}, licenseDetailsURL:{}", accessToken, issuer, - licenseDetailsURL); - Builder request = getResteasyService().getClientBuilder(issuer + licenseDetailsURL); + @Parameters({ "test.issuer", "checkActiveLicenseURL" }) + @Test + public void getLicenseDetails(final String issuer, final String checkActiveLicenseURL) { + log.error("getLicenseDetails() - accessToken:{}, issuer:{}, checkActiveLicenseURL:{}", accessToken, issuer, + checkActiveLicenseURL); + Builder request = getResteasyService().getClientBuilder(issuer + checkActiveLicenseURL); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties index af4f0266193..667f61ea2ca 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties @@ -19,7 +19,7 @@ ujwt=eyJraWQiOiI2NmQ1ODk4Ny03NjQ0LTRkYjEtOWU2YS04ZmFiNWFjYWVhNjVfc2lnX3JzMjU2Iiw authzurl=/jans-auth/authorize.htm adminUIConfigURL=/jans-config-api/admin-ui/oauth2/config apiProtectionTokenURL=/jans-config-api/admin-ui/oauth2/api-protection-token -checkLicenseURL=/jans-config-api/admin-ui/license/checkLicense +checkActiveLicenseURL=/jans-config-api/admin-ui/license/isActive licenseDetailsURL=/jans-config-api/admin-ui/license/getLicenseDetails auditLoggingURL=/jans-config-api/admin-ui/logging/audit diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index ff0a012a9bb..77c72d62114 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -15,7 +15,7 @@ - + From 55c3706be6d7ad7b61d0be9b010fa3c526a839a2 Mon Sep 17 00:00:00 2001 From: pujavs Date: Wed, 4 Dec 2024 23:51:07 +0530 Subject: [PATCH 30/44] feat(config-api): testng framework changes - wip Signed-off-by: pujavs --- .../plugins/admin-ui-plugin/pom.xml | 36 +++----------- .../ca/plugin/adminui/AdminUIBaseTest.java | 16 +++++++ .../test/AuditLoggingResourceTest.java | 4 +- .../adminui/test/LicenseResourceTest.java | 4 +- .../adminui/test/OAuth2ResourceTest.java | 4 +- jans-config-api/plugins/fido2-plugin/pom.xml | 47 +++++------------- .../src/test/resources/testng.xml | 2 +- .../plugins/jans-link-plugin/pom.xml | 45 +++++------------ .../io/jans/configapi/KarateTestRunner.java | 18 ------- .../io/jans/configapi/TestJenkinsRunner.java | 44 ----------------- ...t.java => JansLinkConfigResourceTest.java} | 12 ++--- .../src/test/resources/test.properties | 2 +- .../src/test/resources/testng.xml | 6 +-- .../plugins/kc-link-plugin/pom.xml | 48 +++++-------------- .../io/jans/configapi/KarateTestRunner.java | 18 ------- .../io/jans/configapi/TestJenkinsRunner.java | 44 ----------------- .../test/JansKcLinkConfigResourceTest.java | 39 +++++++++++++++ .../src/test/resources/test.properties | 15 +++--- .../src/test/resources/testng.xml | 19 ++++++++ .../plugins/kc-saml-plugin/pom.xml | 48 +++++-------------- .../io/jans/configapi/KarateTestRunner.java | 18 ------- .../io/jans/configapi/TestJenkinsRunner.java | 44 ----------------- .../configapi/test/JansIdpResourceTest.java | 38 +++++++++++++++ .../test/JansKcSAMLConfigResourceTest.java | 39 +++++++++++++++ .../test/JansKcSAMLTrustRelationshipTest.java | 39 +++++++++++++++ .../src/test/resources/test.properties | 17 ++++--- .../src/test/resources/testng.xml | 21 ++++++++ jans-config-api/plugins/lock-plugin/pom.xml | 48 +++++-------------- .../io/jans/configapi/KarateTestRunner.java | 18 ------- .../io/jans/configapi/TestJenkinsRunner.java | 44 ----------------- .../configapi/test/LockAuditResourceTest.java | 38 +++++++++++++++ .../test/LockConfigResourceTest.java | 39 +++++++++++++++ .../src/test/resources/test.properties | 16 ++++--- .../lock-plugin/src/test/resources/testng.xml | 20 ++++++++ jans-config-api/plugins/scim-plugin/pom.xml | 48 +++++-------------- .../io/jans/configapi/JenkinsTestRunner.java | 47 ------------------ .../io/jans/configapi/KarateTestRunner.java | 18 ------- .../test/ScimConfigResourceTest.java | 39 +++++++++++++++ .../src/test/resources/test.properties | 15 +++--- .../scim-plugin/src/test/resources/testng.xml | 19 ++++++++ .../plugins/user-mgt-plugin/pom.xml | 48 +++++-------------- .../io/jans/configapi/JenkinsTestRunner.java | 47 ------------------ .../io/jans/configapi/KarateTestRunner.java | 18 ------- .../jans/configapi/test/UserResourceTest.java | 39 +++++++++++++++ .../src/test/resources/test.properties | 15 +++--- .../src/test/resources/testng.xml | 19 ++++++++ jans-config-api/server/pom.xml | 27 ----------- .../rest/resource/auth/AgamaResource.java | 1 - 48 files changed, 573 insertions(+), 737 deletions(-) delete mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java delete mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java rename jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/{Fido2ResourceTest.java => JansLinkConfigResourceTest.java} (67%) delete mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java delete mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java create mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java create mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/resources/testng.xml delete mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java delete mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java create mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java create mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java create mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java create mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/resources/testng.xml delete mode 100644 jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java delete mode 100644 jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java create mode 100644 jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java create mode 100644 jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java create mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/testng.xml delete mode 100644 jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java delete mode 100644 jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java create mode 100644 jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java create mode 100644 jans-config-api/plugins/scim-plugin/src/test/resources/testng.xml delete mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java delete mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java create mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java create mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/resources/testng.xml diff --git a/jans-config-api/plugins/admin-ui-plugin/pom.xml b/jans-config-api/plugins/admin-ui-plugin/pom.xml index 03b0ef004c0..dd12c01d1df 100644 --- a/jans-config-api/plugins/admin-ui-plugin/pom.xml +++ b/jans-config-api/plugins/admin-ui-plugin/pom.xml @@ -31,6 +31,7 @@ commons-collections 3.2.2 + io.rest-assured @@ -42,36 +43,6 @@ testng test - - jakarta.xml.bind jakarta.xml.bind-api @@ -95,6 +66,11 @@ admin-ui-plugin + + + ../../profiles/${cfg}/config-build.properties + ../../profiles/${cfg}/config-api-test.properties + diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java index ec9bd0556e8..a3f767aa1c1 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -102,6 +102,22 @@ public class AdminUIBaseTest extends BaseTest{ //AdminUI specific code + @BeforeMethod + @Override + public void getAccessToken() throws Exception { + log.error("AdminUI - getAccessToken - propertiesMap:{}", propertiesMap); + + String tokenUrl = propertiesMap.get("test.authzurl"); + String strGrantType = propertiesMap.get("test.grant.type"); + String clientId = propertiesMap.get("test.client.id"); + String clientSecret = propertiesMap.get("test.client.secret"); + String scopes = propertiesMap.get("test.scopes"); + String authStr = clientId + ':' + clientSecret; + + GrantType grantType = GrantType.fromString(strGrantType); + this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); + log.error("\n\n\n\n AdminUI- accessToken:{}", accessToken); + } } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java index bed59a000f9..259a950bddb 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java @@ -40,8 +40,8 @@ public void postAuditLoggingData(final String issuer, final String auditLoggingU Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); - assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for assertEquals(response.getStatus(), Status.OK.getStatusCode()); - response:{}", response); + // assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("\n\n Response for postAuditLoggingData - response:{}", response); } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java index a729fce2876..5d4a12362ea 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java @@ -40,8 +40,8 @@ public void getLicenseDetails(final String issuer, final String checkActiveLicen request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); - assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getLicenseDetails - response:{}", response); + //assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("\n\n Response for getLicenseDetails - response:{}", response); } } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java index daaa257e5f5..4bb2f7c2b04 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java @@ -49,13 +49,13 @@ public void getOAuth2Data(final String issuer, final String adminUIConfigURL) { @Parameters({"test.issuer", "apiProtectionTokenURL", "ujwt"}) @Test public void getApiProtectionTokenData(final String issuer, final String apiProtectionTokenURL, final String ujwt) { - log.error("getApiProtectionTokenData() - accessToken:{}, issuer:{}, apiProtectionTokenURL:{}, ujwt:{}", accessToken, issuer, apiProtectionTokenURL, ujwt); + log.error("\n\n getApiProtectionTokenData() - accessToken:{}, issuer:{}, apiProtectionTokenURL:{}, ujwt:{}", accessToken, issuer, apiProtectionTokenURL, ujwt); Builder request = getResteasyService().getClientBuilder(issuer+apiProtectionTokenURL); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); request.property("ujwt", ujwt); Response response = request.get(); - log.error("Response for getApiProtectionTokenData() - response:{}", response); + log.error("\n\n Response for getApiProtectionTokenData() - response:{}", response); } diff --git a/jans-config-api/plugins/fido2-plugin/pom.xml b/jans-config-api/plugins/fido2-plugin/pom.xml index 1d396d3037d..e8135018fb2 100644 --- a/jans-config-api/plugins/fido2-plugin/pom.xml +++ b/jans-config-api/plugins/fido2-plugin/pom.xml @@ -90,29 +90,9 @@ test - com.intuit.karate - karate-junit5 - test - - - com.intuit.karate - karate-apache - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - net.masterthought - cucumber-reporting - test + org.testng + testng + test @@ -130,12 +110,12 @@ ../../profiles/${cfg}/config-api-test.properties - - - src/test/resources - true - - + + + src/test/resources + true + + @@ -173,12 +153,9 @@ maven-surefire-plugin - - - integration - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/fido2-plugin/src/test/resources/testng.xml index 4a441f68680..6c1f8fdeef9 100644 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/testng.xml +++ b/jans-config-api/plugins/fido2-plugin/src/test/resources/testng.xml @@ -1,6 +1,6 @@ - + diff --git a/jans-config-api/plugins/jans-link-plugin/pom.xml b/jans-config-api/plugins/jans-link-plugin/pom.xml index dc1d818a6df..a8dc6b68f36 100644 --- a/jans-config-api/plugins/jans-link-plugin/pom.xml +++ b/jans-config-api/plugins/jans-link-plugin/pom.xml @@ -84,35 +84,15 @@ + + io.rest-assured + rest-assured + test + - io.rest-assured - rest-assured - test - - - com.intuit.karate - karate-junit5 - test - - - com.intuit.karate - karate-apache - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - net.masterthought - cucumber-reporting - test + org.testng + testng + test @@ -173,12 +153,9 @@ maven-surefire-plugin - - - integration - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java deleted file mode 100644 index 34da4586ef9..00000000000 --- a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.junit5.Karate; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java b/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java deleted file mode 100644 index a7f7d2d80c2..00000000000 --- a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; - -import io.jans.as.common.model.registration.Client; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class TestJenkinsRunner { - - @Test - void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java b/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/JansLinkConfigResourceTest.java similarity index 67% rename from jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java rename to jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/JansLinkConfigResourceTest.java index 6710c8a5985..d4e59657ccc 100644 --- a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java +++ b/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/JansLinkConfigResourceTest.java @@ -19,19 +19,19 @@ import org.testng.annotations.Parameters; -public class Fido2ResourceTest extends ConfigServerBaseTest{ +public class JansLinkConfigResourceTest extends ConfigServerBaseTest{ - @Parameters({"issuer", "fido2Url"}) + @Parameters({"issuer", "linkConfigUrl"}) @Test - public void getFido2Configuration(final String issuer, final String fido2Url) { - log.error("getFido2Configuration() - accessToken:{}, issuer:{}, fido2Url:{}", accessToken, issuer, fido2Url); - Builder request = getResteasyService().getClientBuilder(issuer + fido2Url); + public void getLinkConfiguration(final String issuer, final String linkConfigUrl) { + log.error("getLinkConfiguration() - accessToken:{}, issuer:{}, linkConfigUrl:{}", accessToken, issuer, linkConfigUrl); + Builder request = getResteasyService().getClientBuilder(issuer + linkConfigUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("getFido2Configuration() - Response for getDefaultAuthenticationMethod - response:{}", response); + log.error("Response for getLinkConfiguration - response:{}", response); } diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties b/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties index a552226de85..cec57a86794 100644 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties @@ -8,4 +8,4 @@ clientSecret=k7gDCUKv1IMo issuer=https://pujavs-amazed-rat.gluu.info -fido2Url=/jans-config-api/fido2/fido2-config \ No newline at end of file +linkConfigUrl=/jans-config-api/jans-link/link-config \ No newline at end of file diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/jans-link-plugin/src/test/resources/testng.xml index 4a441f68680..e37cc5e1b5f 100644 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/testng.xml +++ b/jans-config-api/plugins/jans-link-plugin/src/test/resources/testng.xml @@ -1,6 +1,6 @@ - + @@ -9,9 +9,9 @@ - + - + diff --git a/jans-config-api/plugins/kc-link-plugin/pom.xml b/jans-config-api/plugins/kc-link-plugin/pom.xml index 90e5bc09813..71f2e34df77 100644 --- a/jans-config-api/plugins/kc-link-plugin/pom.xml +++ b/jans-config-api/plugins/kc-link-plugin/pom.xml @@ -122,35 +122,15 @@ + + io.rest-assured + rest-assured + test + - io.rest-assured - rest-assured - test - - - com.intuit.karate - karate-junit5 - test - - - com.intuit.karate - karate-apache - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - net.masterthought - cucumber-reporting - test + org.testng + testng + test @@ -173,9 +153,6 @@ src/test/resources true - - *.* - @@ -215,12 +192,9 @@ maven-surefire-plugin - - - integration - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java deleted file mode 100644 index 34da4586ef9..00000000000 --- a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.junit5.Karate; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java deleted file mode 100644 index a7f7d2d80c2..00000000000 --- a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; - -import io.jans.as.common.model.registration.Client; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class TestJenkinsRunner { - - @Test - void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java new file mode 100644 index 00000000000..42b888fd526 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class JansKcLinkConfigResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "kcLinkConfigUrl"}) + @Test + public void getKcLinkConfiguration(final String issuer, final String kcLinkConfigUrl) { + log.error("getKcLinkConfiguration() - accessToken:{}, issuer:{}, kcLinkConfigUrl:{}", accessToken, issuer, kcLinkConfigUrl); + Builder request = getResteasyService().getClientBuilder(issuer + kcLinkConfigUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getKcLinkConfiguration - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties b/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties index 4257f297907..e2d5977cfa7 100644 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties @@ -1,8 +1,11 @@ -test.scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +kcLinkConfigUrl=/jans-config-api/kc-link/kc-link-config \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/kc-link-plugin/src/test/resources/testng.xml new file mode 100644 index 00000000000..f1b7dbb7db0 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/testng.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/plugins/kc-saml-plugin/pom.xml b/jans-config-api/plugins/kc-saml-plugin/pom.xml index baaa0cfaf6a..cb7c36c3821 100644 --- a/jans-config-api/plugins/kc-saml-plugin/pom.xml +++ b/jans-config-api/plugins/kc-saml-plugin/pom.xml @@ -142,35 +142,15 @@ + + io.rest-assured + rest-assured + test + - io.rest-assured - rest-assured - test - - - com.intuit.karate - karate-junit5 - test - - - com.intuit.karate - karate-apache - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - net.masterthought - cucumber-reporting - test + org.testng + testng + test @@ -193,9 +173,6 @@ src/test/resources true - - *.* - @@ -235,12 +212,9 @@ maven-surefire-plugin - - - integration - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java deleted file mode 100644 index 34da4586ef9..00000000000 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.junit5.Karate; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java deleted file mode 100644 index a7f7d2d80c2..00000000000 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; - -import io.jans.as.common.model.registration.Client; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class TestJenkinsRunner { - - @Test - void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java new file mode 100644 index 00000000000..7675faae318 --- /dev/null +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java @@ -0,0 +1,38 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class JansIdpResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "samlIdpUrl"}) + @Test + public void getKcSAMLIdp(final String issuer, final String samlIdpUrl) { + log.error("getKcSAMLIdp() - accessToken:{}, issuer:{}, samlIdpUrl:{}", accessToken, issuer, samlIdpUrl); + Builder request = getResteasyService().getClientBuilder(issuer + samlIdpUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getKcSAMLIdp - response:{}", response); + } + + +} diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java new file mode 100644 index 00000000000..ec472fe2829 --- /dev/null +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class JansKcSAMLConfigResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "samlConfigUrl"}) + @Test + public void getKcSAMLConfiguration(final String issuer, final String samlConfigUrl) { + log.error("getKcSAMLConfiguration() - accessToken:{}, issuer:{}, samlConfigUrl:{}", accessToken, issuer, samlConfigUrl); + Builder request = getResteasyService().getClientBuilder(issuer + samlConfigUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getKcSAMLConfiguration - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java new file mode 100644 index 00000000000..bb790a89623 --- /dev/null +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class JansKcSAMLTrustRelationshipTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "samlTrustRelationshipUrl"}) + @Test + public void getKcSAMLTrustRelationship(final String issuer, final String samlTrustRelationshipUrl) { + log.error("getKcSAMLTrustRelationship() - accessToken:{}, issuer:{}, samlTrustRelationshipUrl:{}", accessToken, issuer, samlTrustRelationshipUrl); + Builder request = getResteasyService().getClientBuilder(issuer + samlTrustRelationshipUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getKcSAMLTrustRelationship - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties index 4257f297907..aea02eb5735 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties @@ -1,8 +1,13 @@ -test.scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +samlConfigUrl=/jans-config-api/saml/samlConfig +samlTrustRelationshipUrl=/jans-config-api/saml/trust-relationship +samlIdpUrl=/jans-config-api/saml/idp \ No newline at end of file diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testng.xml new file mode 100644 index 00000000000..5ecb09ce227 --- /dev/null +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testng.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/plugins/lock-plugin/pom.xml b/jans-config-api/plugins/lock-plugin/pom.xml index a9a0469410f..053428ac213 100644 --- a/jans-config-api/plugins/lock-plugin/pom.xml +++ b/jans-config-api/plugins/lock-plugin/pom.xml @@ -111,35 +111,15 @@ + + io.rest-assured + rest-assured + test + - io.rest-assured - rest-assured - test - - - com.intuit.karate - karate-junit5 - test - - - com.intuit.karate - karate-apache - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - net.masterthought - cucumber-reporting - test + org.testng + testng + test @@ -162,9 +142,6 @@ src/test/resources true - - *.* - @@ -204,12 +181,9 @@ maven-surefire-plugin - - - integration - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java deleted file mode 100644 index 34da4586ef9..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.junit5.Karate; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java deleted file mode 100644 index a7f7d2d80c2..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; - -import io.jans.as.common.model.registration.Client; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class TestJenkinsRunner { - - @Test - void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java new file mode 100644 index 00000000000..fc09ebae30c --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java @@ -0,0 +1,38 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class LockAuditResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "lockAuditUrl"}) + @Test + public void getLockAuditData(final String issuer, final String lockAuditUrl) { + log.error("getLockAuditData() - accessToken:{}, issuer:{}, lockAuditUrl:{}", accessToken, issuer, lockAuditUrl); + Builder request = getResteasyService().getClientBuilder(issuer + lockAuditUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getLockAuditData - response:{}", response); + } + + +} diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java new file mode 100644 index 00000000000..934e0695539 --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class LockConfigResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "lockConfigUrl"}) + @Test + public void getLockConfigUrlData(final String issuer, final String lockConfigUrl) { + log.error("getLockConfigUrlData() - accessToken:{}, issuer:{}, lockConfigUrl:{}", accessToken, issuer, lockConfigUrl); + Builder request = getResteasyService().getClientBuilder(issuer + lockConfigUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getLockConfigUrlData - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/test.properties b/jans-config-api/plugins/lock-plugin/src/test/resources/test.properties index 4257f297907..a0ddd308549 100644 --- a/jans-config-api/plugins/lock-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/lock-plugin/src/test/resources/test.properties @@ -1,8 +1,12 @@ -test.scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +lockAuditUrl=/jans-config-api/lock/audit +lockConfigUrl=/jans-config-api/lock/lockConfig \ No newline at end of file diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/lock-plugin/src/test/resources/testng.xml new file mode 100644 index 00000000000..ffa29f7c848 --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/test/resources/testng.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/plugins/scim-plugin/pom.xml b/jans-config-api/plugins/scim-plugin/pom.xml index 091c00c5cc3..dc16e44d7f7 100644 --- a/jans-config-api/plugins/scim-plugin/pom.xml +++ b/jans-config-api/plugins/scim-plugin/pom.xml @@ -86,35 +86,15 @@ + + io.rest-assured + rest-assured + test + - io.rest-assured - rest-assured - test - - - com.intuit.karate - karate-junit5 - test - - - com.intuit.karate - karate-apache - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - net.masterthought - cucumber-reporting - test + org.testng + testng + test @@ -136,9 +116,6 @@ src/test/resources true - - *.* - @@ -178,12 +155,9 @@ maven-surefire-plugin - - - integration - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java b/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java deleted file mode 100644 index d039e1f2040..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; - -import io.jans.as.common.model.registration.Client; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * @author Yuriy Zabrovarnyy - */ -public class JenkinsTestRunner { - - @Test - public void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java deleted file mode 100644 index 34da4586ef9..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.junit5.Karate; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java b/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java new file mode 100644 index 00000000000..1b23c5ae35a --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class ScimConfigResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "scimConfigUrl"}) + @Test + public void getScimConfigData(final String issuer, final String scimConfigUrl) { + log.error("getScimConfigData() - accessToken:{}, issuer:{}, scimConfigUrl:{}", accessToken, issuer, scimConfigUrl); + Builder request = getResteasyService().getClientBuilder(issuer + scimConfigUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getScimConfigData - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/test.properties b/jans-config-api/plugins/scim-plugin/src/test/resources/test.properties index 4257f297907..ad5e990ed00 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/test.properties @@ -1,8 +1,11 @@ -test.scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +scimConfigUrl=/jans-config-api/scim/scim-config \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/scim-plugin/src/test/resources/testng.xml new file mode 100644 index 00000000000..4c9045e4208 --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/testng.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/plugins/user-mgt-plugin/pom.xml b/jans-config-api/plugins/user-mgt-plugin/pom.xml index a7e7991758a..0142c8706bb 100644 --- a/jans-config-api/plugins/user-mgt-plugin/pom.xml +++ b/jans-config-api/plugins/user-mgt-plugin/pom.xml @@ -82,35 +82,15 @@ + + io.rest-assured + rest-assured + test + - io.rest-assured - rest-assured - test - - - com.intuit.karate - karate-junit5 - test - - - com.intuit.karate - karate-apache - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - net.masterthought - cucumber-reporting - test + org.testng + testng + test @@ -132,9 +112,6 @@ src/test/resources true - - *.* - @@ -174,12 +151,9 @@ maven-surefire-plugin - - - integration - - --tags ~@ignore - + + target/test-classes/testng.xml + diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java deleted file mode 100644 index d039e1f2040..00000000000 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.Results; -import com.intuit.karate.Runner; - -import io.jans.as.common.model.registration.Client; -import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ReportBuilder; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * @author Yuriy Zabrovarnyy - */ -public class JenkinsTestRunner { - - @Test - public void testParallel() { - System.setProperty("karate.env", "jenkins"); - Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); - generateReport(results.getReportDir()); - Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); - } - - public static void generateReport(String karateOutputPath) { - Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); - List jsonPaths = new ArrayList(jsonFiles.size()); - jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); - Configuration config = new Configuration(new File("target"), "karateTesting"); - ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); - reportBuilder.generateReports(); - } -} diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java deleted file mode 100644 index 34da4586ef9..00000000000 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi; - -import com.intuit.karate.junit5.Karate; - -public class KarateTestRunner { - - @Karate.Test - Karate testFullPath() throws Exception { - return Karate.run("src/test/resources/feature"); - } - -} diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java new file mode 100644 index 00000000000..1066e21aad9 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java @@ -0,0 +1,39 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.test; + +import io.jans.configapi.ConfigServerBaseTest; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Parameters; + +public class UserResourceTest extends ConfigServerBaseTest{ + + @Parameters({"issuer", "userUrl"}) + @Test + public void getUserResourceData(final String issuer, final String userUrl) { + log.error("getUserResourceData() - accessToken:{}, issuer:{}, userUrl:{}", accessToken, issuer, userUrl); + Builder request = getResteasyService().getClientBuilder(issuer + userUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.get(); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getUserResourceData() - response:{}", response); + } + + + +} diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties index 4257f297907..77953be1675 100644 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties @@ -1,8 +1,11 @@ -test.scopes=${test.scopes} +scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -token.endpoint=${token.endpoint} -token.grant.type=${token.grant.type} -test.client.id=${test.client.id} -test.client.secret=${test.client.secret} -test.issuer=${test.issuer} \ No newline at end of file +tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenGrantType=client_credentials +clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d +clientSecret=k7gDCUKv1IMo +issuer=https://pujavs-amazed-rat.gluu.info + + +userUrl=/jans-config-api/mgt/configuser \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testng.xml new file mode 100644 index 00000000000..e346fbf279d --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testng.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jans-config-api/server/pom.xml b/jans-config-api/server/pom.xml index e4aeb64d3ac..aae964a284c 100644 --- a/jans-config-api/server/pom.xml +++ b/jans-config-api/server/pom.xml @@ -200,33 +200,6 @@ test - - - commons-beanutils diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AgamaResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AgamaResource.java index 5f24bdead8b..dd5b41dcf87 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AgamaResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AgamaResource.java @@ -55,7 +55,6 @@ public Response doSyntaxCheck(@Parameter(description = "Agama Flow name") @PathP } e.setStackTrace(new StackTraceElement[0]); return Response.ok().entity(e).build(); - } } From f35d31b6b18cde720c81dea05737a7cf64e69a61 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 5 Dec 2024 23:18:38 +0530 Subject: [PATCH 31/44] feat(config-api): testng framework chnages wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 18 ++++++++++-------- .../ca/plugin/adminui/AdminUIBaseTest.java | 2 +- .../jans/configapi/test/Fido2ResourceTest.java | 5 ++--- .../test/JansLinkConfigResourceTest.java | 5 ++--- .../test/JansKcLinkConfigResourceTest.java | 5 ++--- .../configapi/test/JansIdpResourceTest.java | 4 ++-- .../test/JansKcSAMLConfigResourceTest.java | 4 ++-- .../test/JansKcSAMLTrustRelationshipTest.java | 5 ++--- .../configapi/test/ScimConfigResourceTest.java | 5 ++--- .../jans/configapi/test/UserResourceTest.java | 11 +++++------ .../io/jans/configapi/core/test/BaseTest.java | 2 +- .../core/test/service/HttpService.java | 2 +- .../core/test/service/TokenService.java | 2 +- 13 files changed, 33 insertions(+), 37 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 9ccb55bcd7d..88a09fa1aef 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9269,22 +9269,22 @@ components: $ref: '#/components/schemas/AttributeValidation' tooltip: type: string - selected: - type: boolean whitePagesCanView: type: boolean adminCanEdit: type: boolean + adminCanView: + type: boolean userCanView: type: boolean userCanEdit: type: boolean - adminCanView: - type: boolean userCanAccess: type: boolean adminCanAccess: type: boolean + selected: + type: boolean baseDn: type: string PatchRequest: @@ -9820,6 +9820,8 @@ components: type: string shareSubjectIdBetweenClientsWithSameSectorId: type: boolean + useOpenidSubAttributeValueForPairwiseLocalAccountId: + type: boolean webKeysStorage: type: string enum: @@ -11256,14 +11258,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: @@ -11692,10 +11694,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java index a3f767aa1c1..81b2b3d4ba8 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -52,7 +52,7 @@ import org.apache.logging.log4j.Logger; import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; diff --git a/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java b/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java index 6710c8a5985..8fc67c8698d 100644 --- a/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java +++ b/jans-config-api/plugins/fido2-plugin/src/test/java/io/jans/configapi/test/Fido2ResourceTest.java @@ -6,8 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; -import jakarta.ws.rs.client.Entity; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -19,7 +18,7 @@ import org.testng.annotations.Parameters; -public class Fido2ResourceTest extends ConfigServerBaseTest{ +public class Fido2ResourceTest extends BaseTest { @Parameters({"issuer", "fido2Url"}) @Test diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/JansLinkConfigResourceTest.java b/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/JansLinkConfigResourceTest.java index d4e59657ccc..d8bcfaf5678 100644 --- a/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/JansLinkConfigResourceTest.java +++ b/jans-config-api/plugins/jans-link-plugin/src/test/java/io/jans/configapi/test/JansLinkConfigResourceTest.java @@ -6,8 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; -import jakarta.ws.rs.client.Entity; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -19,7 +18,7 @@ import org.testng.annotations.Parameters; -public class JansLinkConfigResourceTest extends ConfigServerBaseTest{ +public class JansLinkConfigResourceTest extends BaseTest { @Parameters({"issuer", "linkConfigUrl"}) @Test diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java index 42b888fd526..94eaa5a40e8 100644 --- a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java +++ b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java @@ -6,8 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; -import jakarta.ws.rs.client.Entity; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -19,7 +18,7 @@ import org.testng.annotations.Parameters; -public class JansKcLinkConfigResourceTest extends ConfigServerBaseTest{ +public class JansKcLinkConfigResourceTest extends BaseTest { @Parameters({"issuer", "kcLinkConfigUrl"}) @Test diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java index 7675faae318..02e5828c159 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java @@ -6,7 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; @@ -19,7 +19,7 @@ import org.testng.annotations.Parameters; -public class JansIdpResourceTest extends ConfigServerBaseTest{ +public class JansIdpResourceTest extends BaseTest { @Parameters({"issuer", "samlIdpUrl"}) @Test diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java index ec472fe2829..361209738a8 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java @@ -6,7 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; @@ -19,7 +19,7 @@ import org.testng.annotations.Parameters; -public class JansKcSAMLConfigResourceTest extends ConfigServerBaseTest{ +public class JansKcSAMLConfigResourceTest extends BaseTest { @Parameters({"issuer", "samlConfigUrl"}) @Test diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java index bb790a89623..f9e829a2a6f 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java @@ -6,8 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; -import jakarta.ws.rs.client.Entity; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -19,7 +18,7 @@ import org.testng.annotations.Parameters; -public class JansKcSAMLTrustRelationshipTest extends ConfigServerBaseTest{ +public class JansKcSAMLTrustRelationshipTest extends BaseTest { @Parameters({"issuer", "samlTrustRelationshipUrl"}) @Test diff --git a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java b/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java index 1b23c5ae35a..10d35f4a601 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java +++ b/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java @@ -6,8 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; -import jakarta.ws.rs.client.Entity; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -19,7 +18,7 @@ import org.testng.annotations.Parameters; -public class ScimConfigResourceTest extends ConfigServerBaseTest{ +public class ScimConfigResourceTest extends BaseTest { @Parameters({"issuer", "scimConfigUrl"}) @Test diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java index 1066e21aad9..f6c1e6eee4b 100644 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java @@ -6,8 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; -import jakarta.ws.rs.client.Entity; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -19,19 +18,19 @@ import org.testng.annotations.Parameters; -public class UserResourceTest extends ConfigServerBaseTest{ +public class UserResourceTest extends BaseTest { @Parameters({"issuer", "userUrl"}) - @Test + //@Test public void getUserResourceData(final String issuer, final String userUrl) { - log.error("getUserResourceData() - accessToken:{}, issuer:{}, userUrl:{}", accessToken, issuer, userUrl); + log.error("\n\n getUserResourceData() - accessToken:{}, issuer:{}, userUrl:{}", accessToken, issuer, userUrl); Builder request = getResteasyService().getClientBuilder(issuer + userUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getUserResourceData() - response:{}", response); + log.error("\n\n Response for getUserResourceData() - response:{}", response); } diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java index a43a3043853..9a1b56dc360 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java @@ -53,7 +53,7 @@ import org.apache.logging.log4j.Logger; import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java index 348ad66ff5f..8980a02aaff 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java @@ -56,7 +56,7 @@ import jakarta.annotation.PostConstruct; import jakarta.inject.Inject; import jakarta.servlet.http.HttpServletRequest; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.json.JSONObject; public class HttpService implements Serializable { diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/TokenService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/TokenService.java index 5a243cadc42..6a6d2251080 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/TokenService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/TokenService.java @@ -53,7 +53,7 @@ import org.apache.logging.log4j.Logger; import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; From dc1c0998221c16451a80333b74a0603bd30b00e0 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 10 Dec 2024 12:48:24 +0530 Subject: [PATCH 32/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../src/test/java/io/jans/configapi/test/UserResourceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java index f6c1e6eee4b..cd958dc631e 100644 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java @@ -30,7 +30,7 @@ public void getUserResourceData(final String issuer, final String userUrl) { Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("\n\n Response for getUserResourceData() - response:{}", response); + log.error("\n\cn Response for getUserResourceData() - response:{}", response); } From 7ba112478292dc3285dfef1c6de83bc38cfa7fb6 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 10 Dec 2024 14:19:19 +0530 Subject: [PATCH 33/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 88a09fa1aef..bbc9281a6da 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -4616,6 +4616,7 @@ paths: - uma_rpt_claims - uma_claims_gathering - access_evaluation + - access_evaluation_discovery - consent_gathering - dynamic_scope - spontaneous_scope @@ -9269,21 +9270,21 @@ components: $ref: '#/components/schemas/AttributeValidation' tooltip: type: string + selected: + type: boolean whitePagesCanView: type: boolean - adminCanEdit: + userCanEdit: type: boolean adminCanView: type: boolean - userCanView: - type: boolean - userCanEdit: + adminCanEdit: type: boolean - userCanAccess: + userCanView: type: boolean adminCanAccess: type: boolean - selected: + userCanAccess: type: boolean baseDn: type: string @@ -9371,6 +9372,9 @@ components: type: boolean accessEvaluationScriptName: type: string + accessEvaluationDiscoveryCacheLifetimeInMinutes: + type: integer + format: int32 requireRequestObjectEncryption: type: boolean requirePkce: @@ -11210,6 +11214,7 @@ components: - uma_rpt_claims - uma_claims_gathering - access_evaluation + - access_evaluation_discovery - consent_gathering - dynamic_scope - spontaneous_scope From 8449ff1224cc0d0de430578c5e278efe360e613c Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 10 Dec 2024 18:03:27 +0530 Subject: [PATCH 34/44] feat(config-api): testng framework wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 10 ++++----- .../ca/plugin/adminui/AdminUIBaseTest.java | 3 +++ .../test/JansKcLinkConfigResourceTest.java | 16 ++++++++++++++ .../src/test/resources/test.properties | 2 +- .../configapi/test/JansIdpResourceTest.java | 21 +++++++++++++++++-- .../test/JansKcSAMLConfigResourceTest.java | 14 +++++++++++-- .../test/JansKcSAMLTrustRelationshipTest.java | 14 ++++++++++++- .../src/test/resources/test.properties | 6 +++--- .../src/test/resources/testng.xml | 2 +- .../configapi/test/LockAuditResourceTest.java | 17 +++++++++++++++ .../test/LockConfigResourceTest.java | 16 ++++++++++++++ .../jans/configapi/test/UserResourceTest.java | 2 +- .../io/jans/configapi/core/test/BaseTest.java | 15 ++++++++++++- 13 files changed, 121 insertions(+), 17 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index c143c6532b2..394b7129364 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9305,16 +9305,16 @@ components: type: boolean adminCanEdit: type: boolean - userCanView: - type: boolean adminCanView: type: boolean userCanEdit: type: boolean - userCanAccess: + userCanView: type: boolean adminCanAccess: type: boolean + userCanAccess: + type: boolean whitePagesCanView: type: boolean baseDn: @@ -11730,10 +11730,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java index 81b2b3d4ba8..22b1c494fe9 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -118,6 +118,9 @@ public void getAccessToken() throws Exception { this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); log.error("\n\n\n\n AdminUI- accessToken:{}", accessToken); } + + + } diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java index 94eaa5a40e8..d4f1928135d 100644 --- a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java +++ b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java @@ -16,10 +16,26 @@ import static org.testng.Assert.assertEquals; +import java.lang.reflect.Method; + +import org.testng.SkipException; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; public class JansKcLinkConfigResourceTest extends BaseTest { + // Execute before each test is run + @BeforeMethod + public void before(Method methodName){ + boolean isServiceDeployed = isServiceDeployed("io.jans.configapi.plugin.kc.link.rest.ApiApplication"); + log.error("\n\n\n *** JansKcLinkConfigResourceTest - isServiceDeployed:{}",isServiceDeployed); + // check condition, note once you condition is met the rest of the tests will be skipped as well + if(!isServiceDeployed) { + throw new SkipException("KC-LINK Plugin not deployed"); + } + + } + @Parameters({"issuer", "kcLinkConfigUrl"}) @Test public void getKcLinkConfiguration(final String issuer, final String kcLinkConfigUrl) { diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties b/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties index e2d5977cfa7..44addec54e1 100644 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties @@ -8,4 +8,4 @@ clientSecret=k7gDCUKv1IMo issuer=https://pujavs-amazed-rat.gluu.info -kcLinkConfigUrl=/jans-config-api/kc-link/kc-link-config \ No newline at end of file +kcLinkConfigUrl=/jans-config-api/kc-link/kcLinkConfig \ No newline at end of file diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java index 02e5828c159..ed1154f8f2c 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java @@ -17,10 +17,27 @@ import static org.testng.Assert.assertEquals; +import java.lang.reflect.Method; + +import org.testng.SkipException; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; public class JansIdpResourceTest extends BaseTest { + + // Execute before each test is run + @BeforeMethod + public void before(Method methodName){ + boolean isServiceDeployed = isServiceDeployed("io.jans.configapi.plugin.saml.rest.ApiApplication"); + log.error("\n\n\n *** JansIdpResourceTest - isServiceDeployed:{}",isServiceDeployed); + // check condition, note once you condition is met the rest of the tests will be skipped as well + if(!isServiceDeployed) { + throw new SkipException("KC-SAML Plugin not deployed"); + } + + } + @Parameters({"issuer", "samlIdpUrl"}) @Test public void getKcSAMLIdp(final String issuer, final String samlIdpUrl) { @@ -28,9 +45,9 @@ public void getKcSAMLIdp(final String issuer, final String samlIdpUrl) { Builder request = getResteasyService().getClientBuilder(issuer + samlIdpUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - Response response = request.get(); - assertEquals(response.getStatus(), Status.OK.getStatusCode()); + + //assertEquals(response.getStatus(), Status.OK.getStatusCode()); log.error("Response for getKcSAMLIdp - response:{}", response); } diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java index 361209738a8..9bec6ae628c 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java @@ -6,6 +6,7 @@ package io.jans.configapi.test; +import java.lang.reflect.Method; import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; @@ -13,14 +14,23 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; - import static org.testng.Assert.assertEquals; +import org.testng.SkipException; import org.testng.annotations.Parameters; public class JansKcSAMLConfigResourceTest extends BaseTest { + // Execute before each test is run + @BeforeMethod + public void before(Method methodName){ + // check condition, note once you condition is met the rest of the tests will be skipped as well + if(!isServiceDeployed("io.jans.configapi.plugin.saml.rest.ApiApplication")) + throw new SkipException("KC-SAML Plugin not deployed"); + } + @Parameters({"issuer", "samlConfigUrl"}) @Test public void getKcSAMLConfiguration(final String issuer, final String samlConfigUrl) { @@ -30,7 +40,7 @@ public void getKcSAMLConfiguration(final String issuer, final String samlConfigU request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); - assertEquals(response.getStatus(), Status.OK.getStatusCode()); + //assertEquals(response.getStatus(), Status.OK.getStatusCode()); log.error("Response for getKcSAMLConfiguration - response:{}", response); } diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java index f9e829a2a6f..65a706706da 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java @@ -16,10 +16,22 @@ import static org.testng.Assert.assertEquals; +import java.lang.reflect.Method; + +import org.testng.SkipException; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; public class JansKcSAMLTrustRelationshipTest extends BaseTest { + // Execute before each test is run + @BeforeMethod + public void before(Method methodName){ + // check condition, note once you condition is met the rest of the tests will be skipped as well + if(!isServiceDeployed("io.jans.configapi.plugin.saml.rest.ApiApplication")) + throw new SkipException("KC-SAML Plugin not deployed"); + } + @Parameters({"issuer", "samlTrustRelationshipUrl"}) @Test public void getKcSAMLTrustRelationship(final String issuer, final String samlTrustRelationshipUrl) { @@ -29,7 +41,7 @@ public void getKcSAMLTrustRelationship(final String issuer, final String samlTru request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); - assertEquals(response.getStatus(), Status.OK.getStatusCode()); + // assertEquals(response.getStatus(), Status.OK.getStatusCode()); log.error("Response for getKcSAMLTrustRelationship - response:{}", response); } diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties index aea02eb5735..87adf7b6023 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties @@ -8,6 +8,6 @@ clientSecret=k7gDCUKv1IMo issuer=https://pujavs-amazed-rat.gluu.info -samlConfigUrl=/jans-config-api/saml/samlConfig -samlTrustRelationshipUrl=/jans-config-api/saml/trust-relationship -samlIdpUrl=/jans-config-api/saml/idp \ No newline at end of file +samlConfigUrl=/jans-config-api/kc/samlConfig +samlTrustRelationshipUrl=/jans-config-api/kc/saml/trust-relationship +samlIdpUrl=/jans-config-api/kc/saml/idp \ No newline at end of file diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testng.xml b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testng.xml index 5ecb09ce227..3027ee6fd06 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testng.xml +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testng.xml @@ -11,7 +11,7 @@ - + diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java index fc09ebae30c..028891c1285 100644 --- a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java +++ b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java @@ -17,9 +17,26 @@ import static org.testng.Assert.assertEquals; +import java.lang.reflect.Method; + +import org.testng.SkipException; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; public class LockAuditResourceTest extends ConfigServerBaseTest{ + + // Execute before each test is run + @BeforeMethod + public void before(Method methodName){ + boolean isServiceDeployed = isServiceDeployed("io.jans.configapi.plugin.lock.rest.ApiApplication"); + log.error("\n\n\n *** LockAuditResourceTest - isServiceDeployed:{}",isServiceDeployed); + // check condition, note once you condition is met the rest of the tests will be skipped as well + if(!isServiceDeployed) { + throw new SkipException("Lock Plugin not deployed"); + } + + } + @Parameters({"issuer", "lockAuditUrl"}) @Test diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java index 934e0695539..106b0335091 100644 --- a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java +++ b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java @@ -17,10 +17,26 @@ import static org.testng.Assert.assertEquals; +import java.lang.reflect.Method; + +import org.testng.SkipException; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; public class LockConfigResourceTest extends ConfigServerBaseTest{ + // Execute before each test is run + @BeforeMethod + public void before(Method methodName){ + boolean isServiceDeployed = isServiceDeployed("io.jans.configapi.plugin.lock.rest.ApiApplication"); + log.error("\n\n\n *** LockConfigResourceTest - isServiceDeployed:{}",isServiceDeployed); + // check condition, note once you condition is met the rest of the tests will be skipped as well + if(!isServiceDeployed) { + throw new SkipException("Lock Plugin not deployed"); + } + + } + @Parameters({"issuer", "lockConfigUrl"}) @Test public void getLockConfigUrlData(final String issuer, final String lockConfigUrl) { diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java index cd958dc631e..f6c1e6eee4b 100644 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java @@ -30,7 +30,7 @@ public void getUserResourceData(final String issuer, final String userUrl) { Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("\n\cn Response for getUserResourceData() - response:{}", response); + log.error("\n\n Response for getUserResourceData() - response:{}", response); } diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java index 9a1b56dc360..c23b7808e8e 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java @@ -217,6 +217,19 @@ protected String decodeFileValue(String value) { log.error("\n\n decodeFileValue - decoded:{}", decoded); return decoded; - } + + protected boolean isServiceDeployed(String serviceName) { + log.error("\n\n\n *** Check if service is deployed - serviceName:{}", serviceName+" *** \n\n\n"); + boolean isDeployed = false; + try { + Class.forName(serviceName); + isDeployed = true; + } catch (ClassNotFoundException ex) { + log.error("*** \n\n\n'{}' service is NOT deployed ***\n\n", serviceName); + return isDeployed; + } + return isDeployed; + } + } From 7cb59c5ea92e21f0504fcdfbee9d19de14a98e70 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 12 Dec 2024 21:29:51 +0530 Subject: [PATCH 35/44] feat(config-api): testng framework Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 17 +++--- .../src/test/resources/test.properties | 17 +++--- .../src/test/resources/test.properties | 8 +-- .../src/test/resources/test.properties | 8 +-- .../src/test/resources/test.properties | 8 +-- .../src/test/resources/test.properties | 9 ++- .../configapi/test/LockAuditResourceTest.java | 29 +++++++--- .../test/LockConfigResourceTest.java | 5 +- .../json/lock/lock-audit-health-post.json | 6 ++ .../json/lock/lock-audit-log-post.json | 9 +++ .../json/lock/lock-audit-telemetry-post.json | 9 +++ .../lock/lock-config.feature | 0 .../test/resources/json/lock/lock-config.json | 56 +++++++++++++++++++ .../src/test/resources/test.properties | 22 ++++++-- .../src/test/resources/test.properties | 8 +-- .../src/test/resources/test.properties | 8 +-- .../server/src/test/resources/test.properties | 8 +-- .../server/src/test/resources/testng.xml | 4 +- 18 files changed, 169 insertions(+), 62 deletions(-) create mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-health-post.json create mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-log-post.json create mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-telemetry-post.json rename jans-config-api/plugins/lock-plugin/src/test/resources/{feature => json}/lock/lock-config.feature (100%) create mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-config.json diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index e20a8f666fb..c26829c6f38 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9305,18 +9305,18 @@ components: type: boolean whitePagesCanView: type: boolean - adminCanEdit: + adminCanView: type: boolean - userCanView: + adminCanEdit: type: boolean userCanEdit: type: boolean - adminCanView: - type: boolean - userCanAccess: + userCanView: type: boolean adminCanAccess: type: boolean + userCanAccess: + type: boolean baseDn: type: string PatchRequest: @@ -9692,6 +9692,9 @@ components: accessTokenLifetime: type: integer format: int32 + userInfoLifetime: + type: integer + format: int32 cleanServiceInterval: type: integer format: int32 @@ -11730,10 +11733,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties index 667f61ea2ca..da3b670db39 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/resources/test.properties @@ -1,19 +1,20 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info + test.scopes=openid profile email user_name test.grant.type=authorization_code -test.client.id=2073c8e7-1060-4c09-b0f6-7d46fb6ff8f5 -test.client.secret=92bc4d8e-2f4c-4a4d-80ae-1e4eb1f5f463 -test.issuer=https://admin-ui-test.gluu.org -test.authzurl=https://admin-ui-test.gluu.org/jans-auth/authorize.htm +test.client.id=2001.3f672ceb-ff41-4cc6-8b68-57182314a2fd +test.client.secret=SK31nbIxwSAl +test.issuer=https://pujavs-witty-weasel.gluu.info +test.authzurl=https://pujavs-witty-weasel.gluu.info/jans-auth/authorize.htm ujwt=eyJraWQiOiI2NmQ1ODk4Ny03NjQ0LTRkYjEtOWU2YS04ZmFiNWFjYWVhNjVfc2lnX3JzMjU2IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJndFZ2cDJCMGlwdFN5bXFSTEpzc2ZZOWZNbjliWVZRNF8xVTBHSFlFWFRJIiwiYXVkIjoiMjA3M2M4ZTctMTA2MC00YzA5LWIwZjYtN2Q0NmZiNmZmOGY1IiwibmFtZSI6IkRlZmF1bHQgQWRtaW4gVXNlciIsIm5pY2tuYW1lIjoiQWRtaW4iLCJpc3MiOiJodHRwczovL2FkbWluLXVpLXRlc3QuZ2x1dS5vcmciLCJnaXZlbl9uYW1lIjoiQWRtaW4iLCJtaWRkbGVfbmFtZSI6IkFkbWluIiwiZmFtaWx5X25hbWUiOiJVc2VyIiwiamFuc0FkbWluVUlSb2xlIjpbImFwaS1hZG1pbiJdfQ.losuUsBib2YvB2t995iT0HJvE-q7uZT8zHrTJsWN8_rxB_-kawFNI6weWiH4hpAaIAIaw6Bnq5AczSW3OS6sn5fZDrBxuftrurCa7PK7uAeYim8Zozg0NHNQQ9FDe6MYg8FLtKI3eiusvgC3P4CClIFf1AMGVxREyBra87r_J8j2IyV86Ktjv_rVZLNm2mChOrbM5sIjaski4saKtZTMiVZoK7WMC4FJmS8ttysfG2w7-t8MoI9kiM890RhxSoUba9nQIVxKmpdJOzam8_FqNfQmC9fzI2XKjgRu16SoAoJxCNeTy8HHBCN4H_BwxgU2seSbDTMgU11GiApd4D2xaw authzurl=/jans-auth/authorize.htm diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/test.properties b/jans-config-api/plugins/fido2-plugin/src/test/resources/test.properties index a552226de85..31d2620b4b6 100644 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/fido2-plugin/src/test/resources/test.properties @@ -1,11 +1,11 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info fido2Url=/jans-config-api/fido2/fido2-config \ No newline at end of file diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties b/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties index cec57a86794..f018a240e3e 100644 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/jans-link-plugin/src/test/resources/test.properties @@ -1,11 +1,11 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info linkConfigUrl=/jans-config-api/jans-link/link-config \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties b/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties index 44addec54e1..30ac6460f26 100644 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties @@ -1,11 +1,11 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info kcLinkConfigUrl=/jans-config-api/kc-link/kcLinkConfig \ No newline at end of file diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties index 87adf7b6023..95a3cdef1a3 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/test.properties @@ -1,12 +1,11 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info - +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info samlConfigUrl=/jans-config-api/kc/samlConfig samlTrustRelationshipUrl=/jans-config-api/kc/saml/trust-relationship diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java index 028891c1285..3982dc2a64f 100644 --- a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java +++ b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java @@ -6,7 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; @@ -23,7 +23,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; -public class LockAuditResourceTest extends ConfigServerBaseTest{ +public class LockAuditResourceTest extends BaseTest{ // Execute before each test is run @BeforeMethod @@ -37,12 +37,27 @@ public void before(Method methodName){ } - - @Parameters({"issuer", "lockAuditUrl"}) + @Parameters({"issuer", "lockAuditHealthPostUrl", "audit_health_post_1"}) @Test - public void getLockAuditData(final String issuer, final String lockAuditUrl) { - log.error("getLockAuditData() - accessToken:{}, issuer:{}, lockAuditUrl:{}", accessToken, issuer, lockAuditUrl); - Builder request = getResteasyService().getClientBuilder(issuer + lockAuditUrl); + public void getLockAuditData(final String issuer, final String lockAuditHealthPostUrl, final String json) { + log.error("getLockAuditData() - accessToken:{}, issuer:{}, lockAuditHealthPostUrl:{}, json:{}", accessToken, issuer, lockAuditHealthPostUrl, json); + Builder request = getResteasyService().getClientBuilder(issuer + lockAuditHealthPostUrl); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); + log.error("post lock audit - response:{}", response); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.error("Response for getLockAuditData - response:{}", response); + } + + + + @Parameters({"issuer", "lockAuditHealthSearchUrl"}) + //@Test + public void getLockAuditData(final String issuer, final String lockAuditHealthSearchUrl) { + log.error("getLockAuditData() - accessToken:{}, issuer:{}, lockAuditHealthSearchUrl:{}", accessToken, issuer, lockAuditHealthSearchUrl); + Builder request = getResteasyService().getClientBuilder(issuer + lockAuditHealthSearchUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java index 106b0335091..ef91c2f304f 100644 --- a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java +++ b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java @@ -6,8 +6,7 @@ package io.jans.configapi.test; -import io.jans.configapi.ConfigServerBaseTest; -import jakarta.ws.rs.client.Entity; +import io.jans.configapi.core.test.BaseTest; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -23,7 +22,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; -public class LockConfigResourceTest extends ConfigServerBaseTest{ +public class LockConfigResourceTest extends BaseTest{ // Execute before each test is run @BeforeMethod diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-health-post.json b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-health-post.json new file mode 100644 index 00000000000..763018756bf --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-health-post.json @@ -0,0 +1,6 @@ +{ + "jansStatus": "Success", + "cedarEngineStatus": "fail", + "cedarPolicyStatus": "pass", + "tokenDataStatus": "error" +} \ No newline at end of file diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-log-post.json b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-log-post.json new file mode 100644 index 00000000000..65c11f6e7c7 --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-log-post.json @@ -0,0 +1,9 @@ +{ + "eventTime": "2012-04-21T18:25:43-05:00", + "eventType": "registration", + "severetyLevel": "warning", + "policyId": "PID001", + "policyResult": "deny", + "userAccountId": "ACC0001", + "clientId": "CLI001" +} \ No newline at end of file diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-telemetry-post.json b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-telemetry-post.json new file mode 100644 index 00000000000..65c11f6e7c7 --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-audit-telemetry-post.json @@ -0,0 +1,9 @@ +{ + "eventTime": "2012-04-21T18:25:43-05:00", + "eventType": "registration", + "severetyLevel": "warning", + "policyId": "PID001", + "policyResult": "deny", + "userAccountId": "ACC0001", + "clientId": "CLI001" +} \ No newline at end of file diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/feature/lock/lock-config.feature b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-config.feature similarity index 100% rename from jans-config-api/plugins/lock-plugin/src/test/resources/feature/lock/lock-config.feature rename to jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-config.feature diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-config.json b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-config.json new file mode 100644 index 00000000000..8a39e6b159a --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/test/resources/json/lock/lock-config.json @@ -0,0 +1,56 @@ +{ + "baseEndpoint": "https://pujavs-witty-weasel.gluu.info/jans-auth/v1", + "openIdIssuer": "https://pujavs-witty-weasel.gluu.info", + "tokenChannels": [ + "jans_token" + ], + "clientId": "2200.ea10b5a0-a6b7-45fd-ad0b-5e34f7f75fab", + "clientPassword": "zZn4wZAA+TU1OJ8s7z/l8g==", + "tokenUrl": "https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token", + "groupScopeEnabled": true, + "endpointGroups": { + "audit": [ + "telemetry", + "telemetry/bulk", + "health", + "health/bulk", + "log", + "log/bulk" + ] + }, + "endpointDetails": { + "jans-config-api/lock/audit/telemetry": [ + "https://jans.io/oauth/lock/telemetry.readonly", + "https://jans.io/oauth/lock/telemetry.write" + ], + "jans-config-api/lock/audit/telemetry/bulk": [ + "https://jans.io/oauth/lock/telemetry.readonly", + "https://jans.io/oauth/lock/telemetry.write" + ], + "jans-config-api/lock/audit/log": [ + "https://jans.io/oauth/lock/log.write" + ], + "jans-config-api/lock/audit/log/bulk": [ + "https://jans.io/oauth/lock/log.write" + ], + "jans-config-api/lock/audit/health": [ + "https://jans.io/oauth/lock/health.readonly", + "https://jans.io/oauth/lock/health.write" + ], + "jans-config-api/lock/audit/health/bulk": [ + "https://jans.io/oauth/lock/health.readonly", + "https://jans.io/oauth/lock/health.write" + ] + }, + "disableJdkLogger": true, + "loggingLevel": "INFO", + "loggingLayout": "text", + "metricReporterInterval": 300, + "metricReporterKeepDataDays": 15, + "metricReporterEnabled": true, + "cleanServiceInterval": 60, + "opaConfiguration": { + "baseUrl": "http://localhost:8181/v1/" + }, + "pdpType": "OPA" +} \ No newline at end of file diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/test.properties b/jans-config-api/plugins/lock-plugin/src/test/resources/test.properties index a0ddd308549..f191ad9ed07 100644 --- a/jans-config-api/plugins/lock-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/lock-plugin/src/test/resources/test.properties @@ -1,12 +1,22 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info -lockAuditUrl=/jans-config-api/lock/audit -lockConfigUrl=/jans-config-api/lock/lockConfig \ No newline at end of file +lockAuditHealthPostUrl=/jans-config-api/lock/audit/health +lockAuditHealthSearchUrl=/jans-config-api/lock/audit/health/search +lockAuditLogPostUrl=/jans-config-api/lock/audit/log +lockAuditLogSearchUrl=/jans-config-api/lock/audit/log/search +lockAuditTelemetryPostUrl=/jans-config-api/lock/audit/telemetry +lockAuditTelemetrySearchUrl=/jans-config-api/lock/audit/telemetry/search +lockConfigUrl=/jans-config-api/lock/lockConfig + + +audit_health_post_1=file:target/test-classes/json/lock/lock-audit-health-post.json +audit_log_post_1=file:target/test-classes/json/lock/lock-audit-log-post.json +audit_telemetry_post_1=file:target/test-classes/json/lock/lock-audit-telemetry-post.json diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/test.properties b/jans-config-api/plugins/scim-plugin/src/test/resources/test.properties index ad5e990ed00..fcb60d1ba19 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/test.properties @@ -1,11 +1,11 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info scimConfigUrl=/jans-config-api/scim/scim-config \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties index 77953be1675..05a8ea9fd8a 100644 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties @@ -1,11 +1,11 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info userUrl=/jans-config-api/mgt/configuser \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/test.properties b/jans-config-api/server/src/test/resources/test.properties index 460a2e643f9..beceb80ab7d 100644 --- a/jans-config-api/server/src/test/resources/test.properties +++ b/jans-config-api/server/src/test/resources/test.properties @@ -1,11 +1,11 @@ scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write https://jans.io/oauth/config/token.readonly https://jans.io/oauth/config/token.write https://jans.io/oauth/config/token.delete # Test env Setting -tokenEndpoint=https://pujavs-amazed-rat.gluu.info/jans-auth/restv1/token +tokenEndpoint=https://pujavs-witty-weasel.gluu.info/jans-auth/restv1/token tokenGrantType=client_credentials -clientId=1800.ca97c476-43bf-4d76-9f3b-6376b1a9122d -clientSecret=k7gDCUKv1IMo -issuer=https://pujavs-amazed-rat.gluu.info +clientId=1800.2602d79c-2c24-42ec-b229-1f951ea7c6f2 +clientSecret=eoT3tAwFVps0 +issuer=https://pujavs-witty-weasel.gluu.info statUrl=/jans-config-api/api/v1/stat diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index 77c72d62114..ff0a012a9bb 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -15,7 +15,7 @@ - + From ec4e5900dd6f574cda80d6e113a581174ded9fe9 Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 13 Dec 2024 12:01:22 +0530 Subject: [PATCH 36/44] feat(config-api): testng framework Signed-off-by: pujavs --- jans-config-api/docs/jans-config-api-swagger.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index c26829c6f38..435f6feffca 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9303,20 +9303,20 @@ components: type: string selected: type: boolean - whitePagesCanView: - type: boolean adminCanView: type: boolean - adminCanEdit: - type: boolean userCanEdit: type: boolean + adminCanEdit: + type: boolean userCanView: type: boolean adminCanAccess: type: boolean userCanAccess: type: boolean + whitePagesCanView: + type: boolean baseDn: type: string PatchRequest: @@ -11297,14 +11297,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: From 8b0e947093f06a83a574c7d98bcc8f63aa9a0ded Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 13 Dec 2024 17:42:20 +0530 Subject: [PATCH 37/44] feat(config-api): testNG framework changes Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 20 +- .../plugins/docs/fido2-plugin-swagger.yaml | 38 +- .../{feature => json}/fido2/dynamiconf.json | 0 .../{feature => json}/fido2/fido2.feature | 0 .../{feature => json}/fido2/fido2.json | 0 .../fido2/ref_dynami_conf.json | 0 .../src/test/resources/karate-config.js | 57 - .../{feature => json}/link/dynamiconf.json | 0 .../link/link-config.feature | 0 .../src/test/resources/karate-config.js | 57 - .../kc-link/kc-link-config.feature | 0 .../test/resources/karate-config-jenkins.js | 58 - .../src/test/resources/karate-config.js | 57 - .../src/test/resources/karate.properties | 5 - .../test/resources/karate_jenkins.properties | 2 - .../src/test/resources/testClient.feature | 13 - .../src/test/resources/token.feature | 45 - .../saml/config/saml.feature | 0 .../saml-trust-relationship.feature | 0 .../test/resources/karate-config-jenkins.js | 59 - .../src/test/resources/karate-config.js | 58 - .../src/test/resources/karate.properties | 5 - .../test/resources/karate_jenkins.properties | 2 - .../src/test/resources/testClient.feature | 13 - .../src/test/resources/token.feature | 45 - .../test/resources/karate-config-jenkins.js | 58 - .../src/test/resources/karate-config.js | 57 - .../src/test/resources/karate.properties | 5 - .../test/resources/karate_jenkins.properties | 2 - .../src/test/resources/testClient.feature | 13 - .../src/test/resources/token.feature | 45 - .../scim/config/scim-config.feature | 0 .../test/resources/karate-config-jenkins.js | 58 - .../src/test/resources/karate-config.js | 59 - .../src/test/resources/karate.properties | 5 - .../test/resources/karate_jenkins.properties | 2 - .../src/test/resources/testClient.feature | 13 - .../src/test/resources/token.feature | 45 - .../mgt/user/user-patch.json | 0 .../{feature => json}/mgt/user/user-ref.json | 0 .../{feature => json}/mgt/user/user.feature | 0 .../{feature => json}/mgt/user/user.json | 0 .../test/resources/karate-config-jenkins.js | 58 - .../src/test/resources/karate-config.js | 59 - .../src/test/resources/karate.properties | 5 - .../test/resources/karate_jenkins.properties | 2 - .../src/test/resources/testClient.feature | 13 - .../src/test/resources/token.feature | 45 - jans-config-api/pom.xml | 39 +- .../feature/agama/agama-deployment.feature | 47 - .../resources/feature/agama/agama-source.txt | 10 - .../resources/feature/agama/agama.feature | 309 ---- .../test/resources/feature/agama/agama.json | 5 - .../test/resources/feature/agama/agama1.json | 12 - .../attribute/attribute-for-patch.json | 27 - .../feature/attribute/attribute.json | 26 - .../feature/attribute/attributes.feature | 198 --- .../feature/client-auth/client-auth.feature | 24 - .../feature/config/api/properties.feature | 44 - .../feature/config/cache/cache.feature | 310 ---- .../database/ldap/get-ldap-config.feature | 15 - .../feature/config/database/ldap/ldap.feature | 161 --- .../feature/config/database/ldap/ldap.json | 19 - .../config/database/ldap/ldap_list.json | 21 - .../feature/config/jwks/jwk_key.json | 13 - .../feature/config/jwks/jwks-all.json | 191 --- .../feature/config/jwks/jwks.feature | 85 -- .../resources/feature/config/jwks/jwks.json | 113 -- .../feature/config/jwks/jwks_patch.json | 20 - .../feature/config/message/message.feature | 176 --- .../feature/config/org/org-config.feature | 45 - .../properties/authenticationFilters.json | 23 - .../backchannel/backchannel.feature | 49 - .../config/properties/ciba/ciba.feature | 221 --- .../feature/config/properties/ciba/ciba.json | 14 - .../clientAuthenticationFilters.json | 14 - .../config/properties/cors/cors.feature | 34 - .../feature/config/properties/cors/cors.json | 26 - .../feature/config/properties/custom.json | 14 - .../dynamic/registration/registration.feature | 129 -- .../dynamic/registration/registration.json | 21 - .../properties/endpoints/endpoints.feature | 274 ---- .../properties/endpoints/endpoints.json | 18 - .../properties/expiration/expiration.feature | 61 - .../properties/expiration/expiration.json | 5 - .../config/properties/grant/grant.feature | 44 - .../config/properties/grant/grant.json | 10 - .../config/properties/idToken/idToken.feature | 93 -- .../config/properties/idToken/idToken.json | 26 - .../janssenpkcs/janssenpkcs.feature | 33 - .../properties/keys/regen/regen.feature | 38 - .../config/properties/keys/regen/regen.json | 5 - .../config/properties/metrics/metrics.feature | 66 - .../properties/openid/config/config.feature | 287 ---- .../properties/openid/config/config.json | 79 -- .../properties/pairwise/pairwise.feature | 103 -- .../config/properties/properties.feature | 344 ----- .../config/properties/request/object.feature | 33 - .../properties/response/modes/modes.feature | 33 - .../properties/response/types/type.feature | 33 - .../config/properties/server/cleanup.feature | 50 - .../config/properties/server/cleanup.json | 6 - .../config/properties/server/config.feature | 63 - .../config/properties/server/config.json | 26 - .../server/session/sessionId.feature | 99 -- .../config/properties/subject/subject.feature | 38 - .../config/properties/subject/subject.json | 7 - .../config/properties/token/token.feature | 61 - .../config/properties/token/token.json | 6 - .../uma/configuration/configuration.feature | 118 -- .../properties/user/info/userInfo.feature | 84 -- .../scripts/custom/generic/all-script.json | 1249 ----------------- .../scripts/custom/generic/custom.feature | 103 -- .../scripts/custom/generic/post-script.json | 17 - .../scripts/custom/persons/person-script.json | 26 - .../custom/persons/person-scripts.feature | 122 -- .../feature/defaultAcr/defaultAcr.feature | 59 - .../feature/defaultAcr/defaultAcr.json | 3 - .../feature/health/auth-server-health.feature | 13 - .../feature/health/config-api-health.feature | 32 - .../feature/health/server-health.feature | 14 - .../resources/feature/logging/logging.feature | 37 - .../openid/clients/admin-ui-client.json | 1 - .../feature/openid/clients/client.json | 55 - .../client_custom_attribute_patch.json | 13 - .../feature/openid/clients/clients.feature | 141 -- .../openid/clients/custom-attribute.feature | 43 - .../feature/openid/clients/openid-client.json | 60 - .../openid/clients/openid_clients_create.json | 154 -- .../openid/scopes/generic_scopes.feature | 87 -- .../feature/openid/scopes/scope.json | 14 - .../feature/openid/scopes/scopes-all.json | 809 ----------- .../feature/openid/scopes/scopes.feature | 132 -- .../resources/feature/plugins/plugin-all.json | 14 - .../resources/feature/plugins/plugin.feature | 30 - .../resources/feature/session/session.feature | 52 - .../test/resources/feature/smtp/smtp.feature | 54 - .../src/test/resources/feature/smtp/smtp.json | 12 - .../test/resources/feature/stat/stat.feature | 24 - .../feature/token/client-token.feature | 27 - .../feature/uma/resource/resources.feature | 107 -- .../feature/uma/resource/uma-resource.json | 16 - .../feature/uma/scopes/uma-scope.json | 10 - .../feature/uma/scopes/umascopes.feature | 118 -- .../src/test/resources/karate-config.js | 82 -- 145 files changed, 42 insertions(+), 9364 deletions(-) rename jans-config-api/plugins/fido2-plugin/src/test/resources/{feature => json}/fido2/dynamiconf.json (100%) rename jans-config-api/plugins/fido2-plugin/src/test/resources/{feature => json}/fido2/fido2.feature (100%) rename jans-config-api/plugins/fido2-plugin/src/test/resources/{feature => json}/fido2/fido2.json (100%) rename jans-config-api/plugins/fido2-plugin/src/test/resources/{feature => json}/fido2/ref_dynami_conf.json (100%) delete mode 100644 jans-config-api/plugins/fido2-plugin/src/test/resources/karate-config.js rename jans-config-api/plugins/jans-link-plugin/src/test/resources/{feature => json}/link/dynamiconf.json (100%) rename jans-config-api/plugins/jans-link-plugin/src/test/resources/{feature => json}/link/link-config.feature (100%) delete mode 100644 jans-config-api/plugins/jans-link-plugin/src/test/resources/karate-config.js rename jans-config-api/plugins/kc-link-plugin/src/test/resources/{feature => json}/kc-link/kc-link-config.feature (100%) delete mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config-jenkins.js delete mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config.js delete mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/resources/karate.properties delete mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/resources/karate_jenkins.properties delete mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/resources/testClient.feature delete mode 100644 jans-config-api/plugins/kc-link-plugin/src/test/resources/token.feature rename jans-config-api/plugins/kc-saml-plugin/src/test/resources/{feature => json}/saml/config/saml.feature (100%) rename jans-config-api/plugins/kc-saml-plugin/src/test/resources/{feature => json}/saml/trust-relationship/saml-trust-relationship.feature (100%) delete mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate-config-jenkins.js delete mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate-config.js delete mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate.properties delete mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate_jenkins.properties delete mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/resources/testClient.feature delete mode 100644 jans-config-api/plugins/kc-saml-plugin/src/test/resources/token.feature delete mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/karate-config-jenkins.js delete mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/karate-config.js delete mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/karate.properties delete mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/karate_jenkins.properties delete mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/testClient.feature delete mode 100644 jans-config-api/plugins/lock-plugin/src/test/resources/token.feature rename jans-config-api/plugins/scim-plugin/src/test/resources/{feature => json}/scim/config/scim-config.feature (100%) delete mode 100644 jans-config-api/plugins/scim-plugin/src/test/resources/karate-config-jenkins.js delete mode 100644 jans-config-api/plugins/scim-plugin/src/test/resources/karate-config.js delete mode 100644 jans-config-api/plugins/scim-plugin/src/test/resources/karate.properties delete mode 100644 jans-config-api/plugins/scim-plugin/src/test/resources/karate_jenkins.properties delete mode 100644 jans-config-api/plugins/scim-plugin/src/test/resources/testClient.feature delete mode 100644 jans-config-api/plugins/scim-plugin/src/test/resources/token.feature rename jans-config-api/plugins/user-mgt-plugin/src/test/resources/{feature => json}/mgt/user/user-patch.json (100%) rename jans-config-api/plugins/user-mgt-plugin/src/test/resources/{feature => json}/mgt/user/user-ref.json (100%) rename jans-config-api/plugins/user-mgt-plugin/src/test/resources/{feature => json}/mgt/user/user.feature (100%) rename jans-config-api/plugins/user-mgt-plugin/src/test/resources/{feature => json}/mgt/user/user.json (100%) delete mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config-jenkins.js delete mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config.js delete mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate.properties delete mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate_jenkins.properties delete mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/resources/testClient.feature delete mode 100644 jans-config-api/plugins/user-mgt-plugin/src/test/resources/token.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/agama/agama-deployment.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/agama/agama-source.txt delete mode 100644 jans-config-api/server/src/test/resources/feature/agama/agama.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/agama/agama.json delete mode 100644 jans-config-api/server/src/test/resources/feature/agama/agama1.json delete mode 100644 jans-config-api/server/src/test/resources/feature/attribute/attribute-for-patch.json delete mode 100644 jans-config-api/server/src/test/resources/feature/attribute/attribute.json delete mode 100644 jans-config-api/server/src/test/resources/feature/attribute/attributes.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/client-auth/client-auth.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/api/properties.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/cache/cache.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/database/ldap/get-ldap-config.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap_list.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/jwks/jwk_key.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/jwks/jwks-all.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/jwks/jwks.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/jwks/jwks.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/jwks/jwks_patch.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/message/message.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/org/org-config.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/authenticationFilters.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/backchannel/backchannel.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/ciba/ciba.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/ciba/ciba.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/clientAuthenticationFilters.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/cors/cors.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/cors/cors.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/custom.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/dynamic/registration/registration.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/dynamic/registration/registration.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/endpoints/endpoints.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/endpoints/endpoints.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/expiration/expiration.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/expiration/expiration.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/grant/grant.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/grant/grant.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/idToken/idToken.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/idToken/idToken.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/janssenpkcs/janssenpkcs.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/keys/regen/regen.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/keys/regen/regen.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/metrics/metrics.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/openid/config/config.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/openid/config/config.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/pairwise/pairwise.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/properties.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/request/object.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/response/modes/modes.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/response/types/type.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/server/cleanup.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/server/cleanup.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/server/config.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/server/config.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/server/session/sessionId.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/subject/subject.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/subject/subject.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/token/token.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/token/token.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/uma/configuration/configuration.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/properties/user/info/userInfo.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/all-script.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/custom.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/post-script.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/scripts/custom/persons/person-script.json delete mode 100644 jans-config-api/server/src/test/resources/feature/config/scripts/custom/persons/person-scripts.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/defaultAcr/defaultAcr.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/defaultAcr/defaultAcr.json delete mode 100644 jans-config-api/server/src/test/resources/feature/health/auth-server-health.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/health/config-api-health.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/health/server-health.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/logging/logging.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/clients/admin-ui-client.json delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/clients/client.json delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/clients/client_custom_attribute_patch.json delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/clients/clients.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/clients/custom-attribute.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/clients/openid-client.json delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/clients/openid_clients_create.json delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/scopes/generic_scopes.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/scopes/scope.json delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/scopes/scopes-all.json delete mode 100644 jans-config-api/server/src/test/resources/feature/openid/scopes/scopes.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/plugins/plugin-all.json delete mode 100644 jans-config-api/server/src/test/resources/feature/plugins/plugin.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/session/session.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/smtp/smtp.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/smtp/smtp.json delete mode 100644 jans-config-api/server/src/test/resources/feature/stat/stat.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/token/client-token.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/uma/resource/resources.feature delete mode 100644 jans-config-api/server/src/test/resources/feature/uma/resource/uma-resource.json delete mode 100644 jans-config-api/server/src/test/resources/feature/uma/scopes/uma-scope.json delete mode 100644 jans-config-api/server/src/test/resources/feature/uma/scopes/umascopes.feature delete mode 100644 jans-config-api/server/src/test/resources/karate-config.js diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 435f6feffca..1333a299fde 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9303,14 +9303,14 @@ components: type: string selected: type: boolean - adminCanView: - type: boolean userCanEdit: type: boolean - adminCanEdit: - type: boolean userCanView: type: boolean + adminCanView: + type: boolean + adminCanEdit: + type: boolean adminCanAccess: type: boolean userCanAccess: @@ -10177,8 +10177,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10188,6 +10186,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -11297,14 +11297,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: @@ -11733,10 +11733,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml b/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml index d5b5360939b..0859f6b93a1 100644 --- a/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml @@ -564,6 +564,8 @@ components: type: boolean sessionIdPersistInCache: type: boolean + oldU2fMigrationEnabled: + type: boolean errorReasonEnabled: type: boolean fido2Configuration: @@ -581,7 +583,7 @@ components: type: string checkU2fAttestations: type: boolean - debugUserAutoEnrollment: + userAutoEnrollment: type: boolean unfinishedRequestExpiration: type: integer @@ -591,17 +593,17 @@ components: format: int32 serverMetadataFolder: type: string - enabledFidoAlgorithms: + requestedCredentialTypes: type: array items: type: string - rp: + requestedParties: type: array items: $ref: '#/components/schemas/RequestedParty' metadataUrlsProvider: type: string - disableMetadataService: + skipDownloadMdsEnabled: type: boolean skipValidateMdsInAttestationEnabled: type: boolean @@ -675,15 +677,15 @@ components: type: string username: type: string - domain: + origin: type: string userId: type: string challenge: type: string - attenstationRequest: + attestationRequest: type: string - attenstationResponse: + attestationResponse: type: string uncompressedECPoint: type: string @@ -706,8 +708,28 @@ components: signatureAlgorithm: type: integer format: int32 - applicationId: + rpId: type: string + backupStateFlag: + type: boolean + backupEligibilityFlag: + type: boolean + attestedCredentialDataFlag: + type: boolean + extensionDataFlag: + type: boolean + userVerifiedFlag: + type: boolean + userPresentFlag: + type: boolean + authentictatorAttachment: + type: string + credId: + type: string + transports: + type: array + items: + type: string Fido2RegistrationEntry: type: object properties: diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/feature/fido2/dynamiconf.json b/jans-config-api/plugins/fido2-plugin/src/test/resources/json/fido2/dynamiconf.json similarity index 100% rename from jans-config-api/plugins/fido2-plugin/src/test/resources/feature/fido2/dynamiconf.json rename to jans-config-api/plugins/fido2-plugin/src/test/resources/json/fido2/dynamiconf.json diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/feature/fido2/fido2.feature b/jans-config-api/plugins/fido2-plugin/src/test/resources/json/fido2/fido2.feature similarity index 100% rename from jans-config-api/plugins/fido2-plugin/src/test/resources/feature/fido2/fido2.feature rename to jans-config-api/plugins/fido2-plugin/src/test/resources/json/fido2/fido2.feature diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/feature/fido2/fido2.json b/jans-config-api/plugins/fido2-plugin/src/test/resources/json/fido2/fido2.json similarity index 100% rename from jans-config-api/plugins/fido2-plugin/src/test/resources/feature/fido2/fido2.json rename to jans-config-api/plugins/fido2-plugin/src/test/resources/json/fido2/fido2.json diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/feature/fido2/ref_dynami_conf.json b/jans-config-api/plugins/fido2-plugin/src/test/resources/json/fido2/ref_dynami_conf.json similarity index 100% rename from jans-config-api/plugins/fido2-plugin/src/test/resources/feature/fido2/ref_dynami_conf.json rename to jans-config-api/plugins/fido2-plugin/src/test/resources/json/fido2/ref_dynami_conf.json diff --git a/jans-config-api/plugins/fido2-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/fido2-plugin/src/test/resources/karate-config.js deleted file mode 100644 index 0a39c646bec..00000000000 --- a/jans-config-api/plugins/fido2-plugin/src/test/resources/karate-config.js +++ /dev/null @@ -1,57 +0,0 @@ -function() { - - var stream = read('classpath:karate.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate env :', env); - karate.log('karate url :', url); - karate.log('karate port :', port); - karate.log('karate baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - fido2Url: baseUrl + '/jans-config-api/fido2/fido2-config', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/feature/link/dynamiconf.json b/jans-config-api/plugins/jans-link-plugin/src/test/resources/json/link/dynamiconf.json similarity index 100% rename from jans-config-api/plugins/jans-link-plugin/src/test/resources/feature/link/dynamiconf.json rename to jans-config-api/plugins/jans-link-plugin/src/test/resources/json/link/dynamiconf.json diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/feature/link/link-config.feature b/jans-config-api/plugins/jans-link-plugin/src/test/resources/json/link/link-config.feature similarity index 100% rename from jans-config-api/plugins/jans-link-plugin/src/test/resources/feature/link/link-config.feature rename to jans-config-api/plugins/jans-link-plugin/src/test/resources/json/link/link-config.feature diff --git a/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate-config.js deleted file mode 100644 index 079922e6552..00000000000 --- a/jans-config-api/plugins/jans-link-plugin/src/test/resources/karate-config.js +++ /dev/null @@ -1,57 +0,0 @@ -function() { - - var stream = read('classpath:karate.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate env :', env); - karate.log('karate url :', url); - karate.log('karate port :', port); - karate.log('karate baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - jansLinkUrl: baseUrl + '/jans-config-api/jans-link/link-config', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/feature/kc-link/kc-link-config.feature b/jans-config-api/plugins/kc-link-plugin/src/test/resources/json/kc-link/kc-link-config.feature similarity index 100% rename from jans-config-api/plugins/kc-link-plugin/src/test/resources/feature/kc-link/kc-link-config.feature rename to jans-config-api/plugins/kc-link-plugin/src/test/resources/json/kc-link/kc-link-config.feature diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config-jenkins.js deleted file mode 100644 index f17ade676db..00000000000 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config-jenkins.js +++ /dev/null @@ -1,58 +0,0 @@ -function() { - - var stream = read('classpath:karate_jenkins.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate_jenkins env :', env); - karate.log('karate_jenkins url :', url); - karate.log('karate_jenkins port :', port); - karate.log('karate_jenkins baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - kcLinkUrl: baseUrl + '/jans-config-api/kc-link/kc-link-config', - - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config.js deleted file mode 100644 index 41958588071..00000000000 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config.js +++ /dev/null @@ -1,57 +0,0 @@ -function() { - - var stream = read('classpath:karate.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate env :', env); - karate.log('karate url :', url); - karate.log('karate port :', port); - karate.log('karate baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - kcLinkUrl: baseUrl + '/jans-config-api/kc-link/kc-link-config', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate.properties deleted file mode 100644 index 41c0d369aff..00000000000 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate.properties +++ /dev/null @@ -1,5 +0,0 @@ -#karate.test.url=http://localhost -#karate.test.port=8080 -#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api -#karate.test.port=443 -karate.test.url=${test.server} diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate_jenkins.properties deleted file mode 100644 index 0b44a8d7b13..00000000000 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate_jenkins.properties +++ /dev/null @@ -1,2 +0,0 @@ -karate.test.url=${test.server} -#karate.test.port=443 diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/kc-link-plugin/src/test/resources/testClient.feature deleted file mode 100644 index 34cfdffc438..00000000000 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/testClient.feature +++ /dev/null @@ -1,13 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - -Background: -* def mainUrl = test_url - -Scenario: Get Token -Given url mainUrl -And print url -And request '' -When method POST -Then status 204 -And print response diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/token.feature b/jans-config-api/plugins/kc-link-plugin/src/test/resources/token.feature deleted file mode 100644 index ef0ad0d262d..00000000000 --- a/jans-config-api/plugins/kc-link-plugin/src/test/resources/token.feature +++ /dev/null @@ -1,45 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - Do not remove ignore tag - -Background: -* def mainUrl = testProps.get('token.endpoint'); -* def grantType = testProps.get('token.grant.type'); -* def clientId = testProps.get('test.client.id'); -* def clientSecret = testProps.get('test.client.secret'); -* def scopes = testProps.get('test.scopes'); -* def authStr = clientId+':'+clientSecret -* def Base64 = Java.type('java.util.Base64') -* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) -* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') - - -Scenario: Get Token -Given url mainUrl -And print 'mainUrl = '+mainUrl -And print 'grantType = '+grantType -And print 'clientId = '+clientId -And print 'clientSecret = '+clientSecret -And print 'scopes = '+scopes -And print 'authStr = '+authStr -And print 'encodedAuth = '+encodedAuth -And print 'encodedScopes = '+encodedScopes -And header Accept = 'application/json' -And header Authorization = 'Basic '+encodedAuth -And form field grant_type = grantType -And form field scope = scopes -When method POST -Then status 200 -And print 'token response = '+response - - - - -#Scenario: Get Token -#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' -#And header Accept = 'application/json' -#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' -#And form field grant_type = 'client_credentials' -#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' -#When method POST -#Then status 200 -#And print 'token response = '+response diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/feature/saml/config/saml.feature b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/json/saml/config/saml.feature similarity index 100% rename from jans-config-api/plugins/kc-saml-plugin/src/test/resources/feature/saml/config/saml.feature rename to jans-config-api/plugins/kc-saml-plugin/src/test/resources/json/saml/config/saml.feature diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/feature/saml/trust-relationship/saml-trust-relationship.feature b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/json/saml/trust-relationship/saml-trust-relationship.feature similarity index 100% rename from jans-config-api/plugins/kc-saml-plugin/src/test/resources/feature/saml/trust-relationship/saml-trust-relationship.feature rename to jans-config-api/plugins/kc-saml-plugin/src/test/resources/json/saml/trust-relationship/saml-trust-relationship.feature diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate-config-jenkins.js deleted file mode 100644 index d32b307b93f..00000000000 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate-config-jenkins.js +++ /dev/null @@ -1,59 +0,0 @@ -function() { - - var stream = read('classpath:karate_jenkins.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate_jenkins env :', env); - karate.log('karate_jenkins url :', url); - karate.log('karate_jenkins port :', port); - karate.log('karate_jenkins baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - samlTrustRelationshipUrl: baseUrl + '/jans-config-api/saml/trust-relationship', - samlConfigUrl: baseUrl + '/jans-config-api/saml/samlConfig', - - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate-config.js deleted file mode 100644 index a8086c01326..00000000000 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate-config.js +++ /dev/null @@ -1,58 +0,0 @@ -function() { - - var stream = read('classpath:karate.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate env :', env); - karate.log('karate url :', url); - karate.log('karate port :', port); - karate.log('karate baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - samlTrustRelationshipUrl: baseUrl + '/jans-config-api/saml/trust-relationship', - samlConfigUrl: baseUrl + '/jans-config-api/saml/samlConfig', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate.properties deleted file mode 100644 index 41c0d369aff..00000000000 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate.properties +++ /dev/null @@ -1,5 +0,0 @@ -#karate.test.url=http://localhost -#karate.test.port=8080 -#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api -#karate.test.port=443 -karate.test.url=${test.server} diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate_jenkins.properties deleted file mode 100644 index 0b44a8d7b13..00000000000 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/karate_jenkins.properties +++ /dev/null @@ -1,2 +0,0 @@ -karate.test.url=${test.server} -#karate.test.port=443 diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testClient.feature deleted file mode 100644 index 34cfdffc438..00000000000 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/testClient.feature +++ /dev/null @@ -1,13 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - -Background: -* def mainUrl = test_url - -Scenario: Get Token -Given url mainUrl -And print url -And request '' -When method POST -Then status 204 -And print response diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/token.feature b/jans-config-api/plugins/kc-saml-plugin/src/test/resources/token.feature deleted file mode 100644 index ef0ad0d262d..00000000000 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/resources/token.feature +++ /dev/null @@ -1,45 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - Do not remove ignore tag - -Background: -* def mainUrl = testProps.get('token.endpoint'); -* def grantType = testProps.get('token.grant.type'); -* def clientId = testProps.get('test.client.id'); -* def clientSecret = testProps.get('test.client.secret'); -* def scopes = testProps.get('test.scopes'); -* def authStr = clientId+':'+clientSecret -* def Base64 = Java.type('java.util.Base64') -* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) -* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') - - -Scenario: Get Token -Given url mainUrl -And print 'mainUrl = '+mainUrl -And print 'grantType = '+grantType -And print 'clientId = '+clientId -And print 'clientSecret = '+clientSecret -And print 'scopes = '+scopes -And print 'authStr = '+authStr -And print 'encodedAuth = '+encodedAuth -And print 'encodedScopes = '+encodedScopes -And header Accept = 'application/json' -And header Authorization = 'Basic '+encodedAuth -And form field grant_type = grantType -And form field scope = scopes -When method POST -Then status 200 -And print 'token response = '+response - - - - -#Scenario: Get Token -#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' -#And header Accept = 'application/json' -#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' -#And form field grant_type = 'client_credentials' -#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' -#When method POST -#Then status 200 -#And print 'token response = '+response diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/lock-plugin/src/test/resources/karate-config-jenkins.js deleted file mode 100644 index 6689c423102..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/test/resources/karate-config-jenkins.js +++ /dev/null @@ -1,58 +0,0 @@ -function() { - - var stream = read('classpath:karate_jenkins.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate_jenkins env :', env); - karate.log('karate_jenkins url :', url); - karate.log('karate_jenkins port :', port); - karate.log('karate_jenkins baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - lockUrl: baseUrl + '/jans-config-api/lock/lock-config', - - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/lock-plugin/src/test/resources/karate-config.js deleted file mode 100644 index eed01e27f05..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/test/resources/karate-config.js +++ /dev/null @@ -1,57 +0,0 @@ -function() { - - var stream = read('classpath:karate.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate env :', env); - karate.log('karate url :', url); - karate.log('karate port :', port); - karate.log('karate baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - LockUrl: baseUrl + '/jans-config-api/lock/lock-config', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/lock-plugin/src/test/resources/karate.properties deleted file mode 100644 index 41c0d369aff..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/test/resources/karate.properties +++ /dev/null @@ -1,5 +0,0 @@ -#karate.test.url=http://localhost -#karate.test.port=8080 -#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api -#karate.test.port=443 -karate.test.url=${test.server} diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/lock-plugin/src/test/resources/karate_jenkins.properties deleted file mode 100644 index 0b44a8d7b13..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/test/resources/karate_jenkins.properties +++ /dev/null @@ -1,2 +0,0 @@ -karate.test.url=${test.server} -#karate.test.port=443 diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/lock-plugin/src/test/resources/testClient.feature deleted file mode 100644 index 34cfdffc438..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/test/resources/testClient.feature +++ /dev/null @@ -1,13 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - -Background: -* def mainUrl = test_url - -Scenario: Get Token -Given url mainUrl -And print url -And request '' -When method POST -Then status 204 -And print response diff --git a/jans-config-api/plugins/lock-plugin/src/test/resources/token.feature b/jans-config-api/plugins/lock-plugin/src/test/resources/token.feature deleted file mode 100644 index ef0ad0d262d..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/test/resources/token.feature +++ /dev/null @@ -1,45 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - Do not remove ignore tag - -Background: -* def mainUrl = testProps.get('token.endpoint'); -* def grantType = testProps.get('token.grant.type'); -* def clientId = testProps.get('test.client.id'); -* def clientSecret = testProps.get('test.client.secret'); -* def scopes = testProps.get('test.scopes'); -* def authStr = clientId+':'+clientSecret -* def Base64 = Java.type('java.util.Base64') -* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) -* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') - - -Scenario: Get Token -Given url mainUrl -And print 'mainUrl = '+mainUrl -And print 'grantType = '+grantType -And print 'clientId = '+clientId -And print 'clientSecret = '+clientSecret -And print 'scopes = '+scopes -And print 'authStr = '+authStr -And print 'encodedAuth = '+encodedAuth -And print 'encodedScopes = '+encodedScopes -And header Accept = 'application/json' -And header Authorization = 'Basic '+encodedAuth -And form field grant_type = grantType -And form field scope = scopes -When method POST -Then status 200 -And print 'token response = '+response - - - - -#Scenario: Get Token -#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' -#And header Accept = 'application/json' -#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' -#And form field grant_type = 'client_credentials' -#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' -#When method POST -#Then status 200 -#And print 'token response = '+response diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/config/scim-config.feature b/jans-config-api/plugins/scim-plugin/src/test/resources/json/scim/config/scim-config.feature similarity index 100% rename from jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/config/scim-config.feature rename to jans-config-api/plugins/scim-plugin/src/test/resources/json/scim/config/scim-config.feature diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config-jenkins.js deleted file mode 100644 index fd5214c5cfe..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config-jenkins.js +++ /dev/null @@ -1,58 +0,0 @@ -function() { - - var stream = read('classpath:karate_jenkins.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate_jenkins env :', env); - karate.log('karate_jenkins url :', url); - karate.log('karate_jenkins port :', port); - karate.log('karate_jenkins baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - //scim - scim_config_url: baseUrl + '/jans-config-api/scim/scim-config', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config.js deleted file mode 100644 index 0c8ff9e7111..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config.js +++ /dev/null @@ -1,59 +0,0 @@ -function() { - - var stream = read('classpath:karate.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate env :', env); - karate.log('karate url :', url); - karate.log('karate port :', port); - karate.log('karate baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - - //scim - scim_config_url: baseUrl + '/jans-config-api/scim/scim-config', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/scim-plugin/src/test/resources/karate.properties deleted file mode 100644 index 41c0d369aff..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/karate.properties +++ /dev/null @@ -1,5 +0,0 @@ -#karate.test.url=http://localhost -#karate.test.port=8080 -#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api -#karate.test.port=443 -karate.test.url=${test.server} diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/scim-plugin/src/test/resources/karate_jenkins.properties deleted file mode 100644 index 0b44a8d7b13..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/karate_jenkins.properties +++ /dev/null @@ -1,2 +0,0 @@ -karate.test.url=${test.server} -#karate.test.port=443 diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/scim-plugin/src/test/resources/testClient.feature deleted file mode 100644 index 34cfdffc438..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/testClient.feature +++ /dev/null @@ -1,13 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - -Background: -* def mainUrl = test_url - -Scenario: Get Token -Given url mainUrl -And print url -And request '' -When method POST -Then status 204 -And print response diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/token.feature b/jans-config-api/plugins/scim-plugin/src/test/resources/token.feature deleted file mode 100644 index ef0ad0d262d..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/token.feature +++ /dev/null @@ -1,45 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - Do not remove ignore tag - -Background: -* def mainUrl = testProps.get('token.endpoint'); -* def grantType = testProps.get('token.grant.type'); -* def clientId = testProps.get('test.client.id'); -* def clientSecret = testProps.get('test.client.secret'); -* def scopes = testProps.get('test.scopes'); -* def authStr = clientId+':'+clientSecret -* def Base64 = Java.type('java.util.Base64') -* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) -* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') - - -Scenario: Get Token -Given url mainUrl -And print 'mainUrl = '+mainUrl -And print 'grantType = '+grantType -And print 'clientId = '+clientId -And print 'clientSecret = '+clientSecret -And print 'scopes = '+scopes -And print 'authStr = '+authStr -And print 'encodedAuth = '+encodedAuth -And print 'encodedScopes = '+encodedScopes -And header Accept = 'application/json' -And header Authorization = 'Basic '+encodedAuth -And form field grant_type = grantType -And form field scope = scopes -When method POST -Then status 200 -And print 'token response = '+response - - - - -#Scenario: Get Token -#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' -#And header Accept = 'application/json' -#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' -#And form field grant_type = 'client_credentials' -#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' -#When method POST -#Then status 200 -#And print 'token response = '+response diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-patch.json b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/json/mgt/user/user-patch.json similarity index 100% rename from jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-patch.json rename to jans-config-api/plugins/user-mgt-plugin/src/test/resources/json/mgt/user/user-patch.json diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-ref.json b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/json/mgt/user/user-ref.json similarity index 100% rename from jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-ref.json rename to jans-config-api/plugins/user-mgt-plugin/src/test/resources/json/mgt/user/user-ref.json diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.feature b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/json/mgt/user/user.feature similarity index 100% rename from jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.feature rename to jans-config-api/plugins/user-mgt-plugin/src/test/resources/json/mgt/user/user.feature diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.json b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/json/mgt/user/user.json similarity index 100% rename from jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.json rename to jans-config-api/plugins/user-mgt-plugin/src/test/resources/json/mgt/user/user.json diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config-jenkins.js deleted file mode 100644 index bffd51af405..00000000000 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config-jenkins.js +++ /dev/null @@ -1,58 +0,0 @@ -function() { - - var stream = read('classpath:karate_jenkins.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate_jenkins env :', env); - karate.log('karate_jenkins url :', url); - karate.log('karate_jenkins port :', port); - karate.log('karate_jenkins baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - //mgt - user_url: baseUrl + '/jans-config-api/mgt/configuser', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config.js deleted file mode 100644 index ac0472c4dd1..00000000000 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config.js +++ /dev/null @@ -1,59 +0,0 @@ -function() { - - var stream = read('classpath:karate.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate env :', env); - karate.log('karate url :', url); - karate.log('karate port :', port); - karate.log('karate baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - - //mgt - user_url: baseUrl + '/jans-config-api/mgt/configuser', - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate.properties deleted file mode 100644 index 41c0d369aff..00000000000 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate.properties +++ /dev/null @@ -1,5 +0,0 @@ -#karate.test.url=http://localhost -#karate.test.port=8080 -#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api -#karate.test.port=443 -karate.test.url=${test.server} diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate_jenkins.properties deleted file mode 100644 index 0b44a8d7b13..00000000000 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate_jenkins.properties +++ /dev/null @@ -1,2 +0,0 @@ -karate.test.url=${test.server} -#karate.test.port=443 diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testClient.feature deleted file mode 100644 index 34cfdffc438..00000000000 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testClient.feature +++ /dev/null @@ -1,13 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - -Background: -* def mainUrl = test_url - -Scenario: Get Token -Given url mainUrl -And print url -And request '' -When method POST -Then status 204 -And print response diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/token.feature b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/token.feature deleted file mode 100644 index ef0ad0d262d..00000000000 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/token.feature +++ /dev/null @@ -1,45 +0,0 @@ -@ignore -Feature: This Feature is to get token to test the test cases - Do not remove ignore tag - -Background: -* def mainUrl = testProps.get('token.endpoint'); -* def grantType = testProps.get('token.grant.type'); -* def clientId = testProps.get('test.client.id'); -* def clientSecret = testProps.get('test.client.secret'); -* def scopes = testProps.get('test.scopes'); -* def authStr = clientId+':'+clientSecret -* def Base64 = Java.type('java.util.Base64') -* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) -* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') - - -Scenario: Get Token -Given url mainUrl -And print 'mainUrl = '+mainUrl -And print 'grantType = '+grantType -And print 'clientId = '+clientId -And print 'clientSecret = '+clientSecret -And print 'scopes = '+scopes -And print 'authStr = '+authStr -And print 'encodedAuth = '+encodedAuth -And print 'encodedScopes = '+encodedScopes -And header Accept = 'application/json' -And header Authorization = 'Basic '+encodedAuth -And form field grant_type = grantType -And form field scope = scopes -When method POST -Then status 200 -And print 'token response = '+response - - - - -#Scenario: Get Token -#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' -#And header Accept = 'application/json' -#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' -#And form field grant_type = 'client_credentials' -#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' -#When method POST -#Then status 200 -#And print 'token response = '+response diff --git a/jans-config-api/pom.xml b/jans-config-api/pom.xml index eacd0e0c372..b3023ecd0d5 100644 --- a/jans-config-api/pom.xml +++ b/jans-config-api/pom.xml @@ -1,4 +1,4 @@ - + 4.0.0 @@ -41,7 +41,6 @@ 4.7.5.Final 5.0.1 - 0.9.5 7.8.0 2.0 5.7.0 @@ -335,41 +334,7 @@ ${testng.version} - - com.intuit.karate - karate-junit5 - ${karate.version} - test - - - snakeyaml - * - - - - - com.intuit.karate - karate-apache - ${karate.version} - test - - - org.yaml - snakeyaml - ${snake.version} - - + net.masterthought cucumber-reporting diff --git a/jans-config-api/server/src/test/resources/feature/agama/agama-deployment.feature b/jans-config-api/server/src/test/resources/feature/agama/agama-deployment.feature deleted file mode 100644 index b5f7fcb1746..00000000000 --- a/jans-config-api/server/src/test/resources/feature/agama/agama-deployment.feature +++ /dev/null @@ -1,47 +0,0 @@ - -Feature: Agama Deployment - -Background: -* def mainUrl = agama_deployment_url -* def funGetEncodedValue = -""" -function(strValue) { -print(' strValue = '+strValue); -if(strValue == null || strValue.length==0){ -return strValue; -} -var URLEncoder = Java.type('java.net.URLEncoder'); -var encodedStrValue = URLEncoder.encode(strValue, "UTF-8"); -print(' encodedStrValue = '+encodedStrValue); -return encodedStrValue; -} -""" - -Scenario: Fetch all Agama deployment without bearer token - Given url mainUrl + '/list' - When method GET - Then status 401 - And print response - -@ignore -Scenario: Fetch all Agama deployment - Given url mainUrl + '/list' - And print 'accessToken = '+accessToken - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - -@ignore -Scenario: Fetch all Agama deployment - Given url mainUrl + '/list' - And print 'accessToken = '+accessToken - And header Authorization = 'Bearer ' + accessToken - And param start = 0 - And param count = 3 - When method GET - Then status 200 - And print response - - - diff --git a/jans-config-api/server/src/test/resources/feature/agama/agama-source.txt b/jans-config-api/server/src/test/resources/feature/agama/agama-source.txt deleted file mode 100644 index 98a793ed038..00000000000 --- a/jans-config-api/server/src/test/resources/feature/agama/agama-source.txt +++ /dev/null @@ -1,10 +0,0 @@ -//This is a comment -//Another comment -Flow test - Basepath "hello" - -in = { name: "John" } -RRF "index.ftlh" in - -Log "Done!" -Finish "john_doe" diff --git a/jans-config-api/server/src/test/resources/feature/agama/agama.feature b/jans-config-api/server/src/test/resources/feature/agama/agama.feature deleted file mode 100644 index f663df12815..00000000000 --- a/jans-config-api/server/src/test/resources/feature/agama/agama.feature +++ /dev/null @@ -1,309 +0,0 @@ - -Feature: Agama flow - -Background: -* def mainUrl = agama_url -* def funGetEncodedValue = -""" -function(strValue) { -print(' strValue = '+strValue); -if(strValue == null || strValue.length==0){ -return strValue; -} -var URLEncoder = Java.type('java.net.URLEncoder'); -var encodedStrValue = URLEncoder.encode(strValue, "UTF-8"); -print(' encodedStrValue = '+encodedStrValue); -return encodedStrValue; -} -""" - -@ignore -Scenario: Fetch all agama without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - -@ignore -Scenario: Fetch all agama flows - Given url mainUrl - And print 'accessToken = '+accessToken - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - -@ignore -Scenario: Fetch agama flow by name - Given url mainUrl - And print 'accessToken = '+accessToken - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response[0].qname - Then def flowName = response[0].qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - -@ignore -@CreateUpdateDelete -Scenario: Create, update and delete agama flow - #Create agama flow - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('agama.json') - When method POST - Then status 201 - And print response - And print response.qname - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Fetch agama flow by name and with source - Given url mainUrl + '/' +encodedFlowName+ '?includeSource=true' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - Then def result = response - And print result - And print 'Old revision ='+response.revision - Then set result.revision = response.revision+1 - And print result - And print response.qname - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Update agama flow - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - And print response.qname - And print response.revision - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Fetch agama flow by name - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And print response.qname - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Fetch agama flow by name and with source - Given url mainUrl + '/' +encodedFlowName + '?includeSource=true' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Delete agama flow by name - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - And print response - -@ignore -@CreateFlowWithDataInRequestBodyUpdateDelete -Scenario: Create agama flow with source data in request body - #Create agama flow - Then def flowName = 'test' - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'text/plain' - And header Accept = 'application/json' - And request read('agama-source.txt') - When method POST - Then status 201 - And print response - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Fetch agama flow by name and with source - Given url mainUrl + '/' +encodedFlowName+ '?includeSource=true' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And print response.qname - Then def flowName = response.qname - And print flowName - Then def result = response - And print 'Old revision ='+response.revision - Then set result.revision = response.revision+1 - And print encodedFlowName - #Update agama flow - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - And print response.qname - And print response.revision - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Fetch agama flow by name - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And print response.qname - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Delete agama flow by name - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - And print response - -@ignore -@CreateAndUpdateFlowWithDataInRequestBodyUpdateDelete -Scenario: Create agama flow with source data in request body - #Create agama flow - Then def flowName = 'test' - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'text/plain' - And header Accept = 'application/json' - And request read('agama-source.txt') - When method POST - Then status 201 - And print response - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Fetch agama flow by name and with source - Given url mainUrl + '/' +encodedFlowName+ '?includeSource=true' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And print response.qname - Then def flowName = response.qname - And print flowName - Then def result = response - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Update agama flow - Given url mainUrl + '/source/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'text/plain' - And header Accept = 'application/json' - And request read('agama-source.txt') - When method PUT - Then status 200 - And print response - And print response.qname - And print response.revision - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Fetch agama flow by name - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And print response.qname - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Delete agama flow by name - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - And print response - -@ignore -@CreateAndPatchFlowAndDelete -Scenario: Create and Patch agama flow - #Create agama flow - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('agama.json') - When method POST - Then status 201 - And print response - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Fetch agama flow by name and with source - Given url mainUrl + '/' +encodedFlowName+ '?includeSource=true' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - Then def result = response - And print response.qname - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Patch agama flow - Then def revision_before = response.revision - And print 'revision = '+revision_before - Then def revision_updated = revision_before+1 - And print 'revision_updated = '+revision_updated - And print result.jansHideOnDiscovery - And def request_body = (result.revision == null ? "[ {\"op\":\"add\", \"path\": \"/revision\", \"value\":"+revision_updated+" } ]" : "[ {\"op\":\"replace\", \"path\": \"/revision\", \"value\":"+revision_updated+" } ]") - And print 'request_body ='+request_body - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - Then def flowName = response.qname - And print flowName - Then def encodedFlowName = funGetEncodedValue(flowName) - And print encodedFlowName - #Delete agama flow by name - Given url mainUrl + '/' +encodedFlowName - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - And print response diff --git a/jans-config-api/server/src/test/resources/feature/agama/agama.json b/jans-config-api/server/src/test/resources/feature/agama/agama.json deleted file mode 100644 index 436410d5844..00000000000 --- a/jans-config-api/server/src/test/resources/feature/agama/agama.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "enabled": false, - "source":"Flow test\n\tBasepath \"hello\"\n\nin = { name: \"John\" }\nRRF \"index.ftlh\" in\n\nLog \"Done!\"\nFinish \"john_doe\"", - "qname": "test" -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/agama/agama1.json b/jans-config-api/server/src/test/resources/feature/agama/agama1.json deleted file mode 100644 index c83d18a15b1..00000000000 --- a/jans-config-api/server/src/test/resources/feature/agama/agama1.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "enabled": false, - "revision": 1, - "transHash": "4", - "source":"Flow test\n\tBasepath \"hello\"\n\nin = { name: \"John\" }\nRRF \"index.ftlh\" in\n\nLog \"Done!\"\nFinish \"john_doe\"", - "qname": "test", - "metadata":{ - "funcName": "Test_fun_4", - "inputs":["1","abc","exyz"], - "timeout": 9600 - } -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/attribute/attribute-for-patch.json b/jans-config-api/server/src/test/resources/feature/attribute/attribute-for-patch.json deleted file mode 100644 index 702ced2c3cf..00000000000 --- a/jans-config-api/server/src/test/resources/feature/attribute/attribute-for-patch.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "adminCanAccess": true, - "adminCanEdit": true, - "adminCanView": true, - "custom": false, - "dataType": "string", - "description": "Test Attribute", - "displayName": "Test Attribute", - "editType": [ - "admin", - "user" - ], - "name": "testAttribute", - "origin": "jansPerson", - "jansMultivaluedAttr": false, - "status": "active", - "urn": "urn:mace:dir:attribute-def:testAttribute", - "userCanAccess": true, - "userCanEdit": true, - "userCanView": true, - "viewType": [ - "admin", - "user" - ], - "whitePagesCanView": false, - "jansHideOnDiscovery": true -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/attribute/attribute.json b/jans-config-api/server/src/test/resources/feature/attribute/attribute.json deleted file mode 100644 index 524420a6895..00000000000 --- a/jans-config-api/server/src/test/resources/feature/attribute/attribute.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "adminCanAccess": true, - "adminCanEdit": true, - "adminCanView": true, - "custom": false, - "dataType": "string", - "description": "QAAdded Attribute", - "displayName": "QAAdded Attribute", - "editType": [ - "admin", - "user" - ], - "name": "qaattribute", - "origin": "jansPerson", - "jansMultivaluedAttr": false, - "status": "active", - "urn": "urn:mace:dir:attribute-def:qaattribute", - "userCanAccess": true, - "userCanEdit": true, - "userCanView": true, - "viewType": [ - "admin", - "user" - ], - "whitePagesCanView": false -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/attribute/attributes.feature b/jans-config-api/server/src/test/resources/feature/attribute/attributes.feature deleted file mode 100644 index 649ea1c74a0..00000000000 --- a/jans-config-api/server/src/test/resources/feature/attribute/attributes.feature +++ /dev/null @@ -1,198 +0,0 @@ - -Feature: Attributes - -Background: -* def mainUrl = attributes_url - -Scenario: Fetch all attributes without bearer token - Given url mainUrl - When method GET - Then status 401 - - -Scenario: Fetch all attributes - Given url mainUrl - And print 'accessToken = '+accessToken - And print 'issuer = '+issuer - And header Authorization = 'Bearer ' + accessToken - #And header issuer = issuer - When method GET - Then status 200 - And print response - #And assert response.length != null - #And assert response.length >= 10 - -@ignore -Scenario: Fetch based on filter - Given url mainUrl - And print 'accessToken = '+accessToken - And print 'issuer = '+issuer - And header Authorization = 'Bearer ' + accessToken - #And header issuer = issuer - And param limit = 3 - And param pattern = 'edu' - And param startIndex = 1 - When method GET - Then status 200 - And print response - #And assert response.length != null - #And assert response.length >= 10 - -Scenario: Fetch the first three attributes - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And param limit = 3 - When method GET - Then status 200 - And print response - #And assert response.length == 3 - - -Scenario: Search attributes given a search pattern - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And param pattern = 'city' - When method GET - Then status 200 - And print response - #And assert response.length != 0 - -Scenario: Fetch all active attributes - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And param status = 'active' - When method GET - Then status 200 - And print response - -Scenario: Fetch the first three active attributes - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And param limit = 3 - And param status = 'active' - When method GET - Then status 200 - And print response - #And assert response.length == 3 - #And assert response[0].status == 'ACTIVE' - #And assert response[1].status == 'ACTIVE' - #And assert response[2].status == 'ACTIVE' - - -Scenario: Fetch the first three inactive attributes - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And param limit = 3 - And param status = 'inactive' - When method GET - Then status 200 - And print response - #And assert response.length == 3 - #And assert response[0].status == 'INACTIVE' - #And assert response[1].status == 'INACTIVE' - #And assert response[2].status == 'INACTIVE' - - -@ignore -@CreateUpdateDelete -Scenario: Create new attribute - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('attribute.json') - When method POST - Then status 201 - Then def result = response - Then set result.displayName = 'UpdatedQAAddedAttribute' - Then def inum_before = result.inum - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And assert response.displayName == 'UpdatedQAAddedAttribute' - And assert response.inum == inum_before - Given url mainUrl + '/' +response.inum - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - - -Scenario: Delete a non-existion attribute by inum - Given url mainUrl + '/1402.66633-8675-473e-a749' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 404 - - -Scenario: Get an attribute by inum(unexisting attribute) - Given url mainUrl + '/53553532727272772' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 404 - -@ignore -Scenario: Get an attribute by inum - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Given url mainUrl + '/' +response[0].inum - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - - -@ignore -@CreateUpdate -Scenario: Create new attribute - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('attribute-for-patch.json') - When method POST - Then status 201 - Then def result = response - Then set result.jansHideOnDiscovery = 'true' - Then def inum_before = result.inum - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - And print response.inum - Given url mainUrl + '/' +response.inum - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - -@ignore -Scenario: Patch jansHideOnDiscovery configuration for Country attribute - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And param pattern = 'street' - And param limit = 1 - When method GET - Then status 200 - And print response - And assert response.length == 1 - Then def result = response[0] - And def inum_before = result.inum - And print 'inum = '+inum_before - And print result.jansHideOnDiscovery - And def orig_jansHideOnDiscovery = (result.jansHideOnDiscovery == null ? false : result.jansHideOnDiscovery) - And print 'orig_jansHideOnDiscovery = '+orig_jansHideOnDiscovery - #And def new_jansHideOnDiscovery = (orig_jansHideOnDiscovery == null || orig_jansHideOnDiscovery == false ? true : false) - And def request_body = (result.jansHideOnDiscovery == null ? "[ {\"op\":\"add\", \"path\": \"/jansHideOnDiscovery\", \"value\":"+orig_jansHideOnDiscovery+" } ]" : "[ {\"op\":\"replace\", \"path\": \"/jansHideOnDiscovery\", \"value\":"+orig_jansHideOnDiscovery+" } ]") - And print 'request_body ='+request_body - Given url mainUrl + '/' +inum_before - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/client-auth/client-auth.feature b/jans-config-api/server/src/test/resources/feature/client-auth/client-auth.feature deleted file mode 100644 index aea934d4f5a..00000000000 --- a/jans-config-api/server/src/test/resources/feature/client-auth/client-auth.feature +++ /dev/null @@ -1,24 +0,0 @@ - -Feature: Client Authorizations - -Background: -* def mainUrl = clients_authorizations_url - -Scenario: Fetch all clients authorizations without bearer token - Given url mainUrl + '/123' - When method GET - Then status 401 - - -Scenario: Fetch all clients authorizations - Given url mainUrl + '/123' - And print 'accessToken = '+accessToken - And print 'issuer = '+issuer - And header Authorization = 'Bearer ' + accessToken - #And header issuer = issuer - When method GET - Then status 200 - And print response - #And assert response.length != null - #And assert response.length >= 10 - diff --git a/jans-config-api/server/src/test/resources/feature/config/api/properties.feature b/jans-config-api/server/src/test/resources/feature/config/api/properties.feature deleted file mode 100644 index e6fa17bc6e6..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/api/properties.feature +++ /dev/null @@ -1,44 +0,0 @@ - -Feature: Verify Auth configuration endpoint - - Background: - * def mainUrl = api_config_url - - @config-get-error - Scenario: Retrieve configuration without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - @config-get - Scenario: Retrieve configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @config-patch - Scenario: Patch configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And print 'response.loggingLevel = '+response.loggingLevel - And def request_body = (response.loggingLevel == null ? "[ {\"op\":\"add\", \"path\": \"/loggingLevel\", \"value\":\"DEBUG\" } ]" : "[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\":\"DEBUG\" } ]") - And print 'request_body ='+request_body - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/cache/cache.feature b/jans-config-api/server/src/test/resources/feature/config/cache/cache.feature deleted file mode 100644 index 0737beca882..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/cache/cache.feature +++ /dev/null @@ -1,310 +0,0 @@ - -Feature: Verify Cache configuration endpoint - - Background: - * def mainUrl = cacheUrl - - @cache-get-error - Scenario: Retrieve Cache configuration without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - @cache-get - Scenario: Retrieve Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @cache-patch - Scenario: Patch cacheProviderType configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.cacheProviderType - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/cacheProviderType\", \"value\":\""+response.cacheProviderType+"\" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @cache-patch - Scenario: Patch nativePersistenceConfiguration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.nativePersistenceConfiguration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/nativePersistenceConfiguration\", \"value\":"+response.nativePersistenceConfiguration+" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @cache-patch - Scenario: Patch inMemoryConfiguration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.inMemoryConfiguration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/inMemoryConfiguration\", \"value\":"+response.inMemoryConfiguration+" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @cache-patch - Scenario: Patch redisConfiguration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.redisConfiguration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/redisConfiguration\", \"value\":"+response.redisConfiguration+" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @cache-patch - Scenario: Patch memcachedConfiguration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.memcachedConfiguration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/memcachedConfiguration\", \"value\":"+response.memcachedConfiguration+" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @cache-get-redis - Scenario: Retrieve Redis Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'redis' - When method GET - Then status 200 - And print response - And assert response.length != null - - @cache-put-redis - Scenario: Update Redis Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'redis' - When method GET - Then status 200 - Then print response - Then def first_response = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'redis' - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - @cache-patch-redis - Scenario: Patch redis configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'redis' - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/defaultPutExpiration\", \"value\":"+response.defaultPutExpiration+"} ]" - And path 'redis' - Then print request - When method PATCH - Then status 200 - And print response - - @cache-get-in-memory - Scenario: Retrieve in-memory Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'in-memory' - When method GET - Then status 200 - And print response - And assert response.length != null - - @cache-put-in-memory - Scenario: Update in-memory Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'in-memory' - When method GET - Then status 200 - Then print response - Then def first_response = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'in-memory' - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - @cache-patch-in-memory - Scenario: Patch in-memory configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'in-memory' - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/defaultPutExpiration\", \"value\":"+response.defaultPutExpiration+" } ]" - And path 'in-memory' - Then print request - When method PATCH - Then status 200 - And print response - - @cache-get-native-persistence - Scenario: Retrieve native-persistence Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'native-persistence' - When method GET - Then status 200 - And print response - And assert response.length != null - - @cache-put-native-persistence - Scenario: Update native-persistence Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'native-persistence' - When method GET - Then status 200 - Then print response - Then def first_response = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'native-persistence' - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - @cache-patch-native-persistence - Scenario: Patch native-persistence configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'native-persistence' - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/defaultPutExpiration\", \"value\":"+response.defaultPutExpiration+"} ]" - And path 'native-persistence' - Then print request - When method PATCH - Then status 200 - And print response - - @cache-get-memcached - Scenario: Retrieve memcached Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'memcached' - When method GET - Then status 200 - And print response - And assert response.length != null - - @cache-put-memcached - Scenario: Update memcached Cache configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'memcached' - When method GET - Then status 200 - Then print response - Then def first_response = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'memcached' - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - - @cache-patch-memcached - Scenario: Patch memcached configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'memcached' - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/defaultPutExpiration\", \"value\":"+response.defaultPutExpiration+"} ]" - And path 'memcached' - Then print request - When method PATCH - Then status 200 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/database/ldap/get-ldap-config.feature b/jans-config-api/server/src/test/resources/feature/config/database/ldap/get-ldap-config.feature deleted file mode 100644 index be874dad253..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/database/ldap/get-ldap-config.feature +++ /dev/null @@ -1,15 +0,0 @@ - -Feature: Verify LDAP configuration GET endpoint - - Background: - * def mainUrl = ldapUrl - - @ldap-config-get - Scenario: Retrieve LDAP configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap.feature b/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap.feature deleted file mode 100644 index ef50b1773bd..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap.feature +++ /dev/null @@ -1,161 +0,0 @@ - -@parallel=false -Feature: Verify LDAP configuration endpoint - - Background: - * def mainUrl = ldapUrl - * def result = call read('get-ldap-config.feature'); - * def funGetLdapConfig = -""" -function(ldap_array,ldap_id) { -print(' ldap_array = '+ldap_array); -print(' ldap_id = '+ldap_id); -var temp; -for (var i = 0; i < ldap_array.length; i++) { -print(' ldap_array[i] = '+ldap_array[i]); -if ( ldap_array[i].configId == ldap_id ){ - temp = ldap_array[i]; - print(' temp= '+temp); -} -} -return temp; -} -""" - - @ldap-config-get-without-bearer-token - Scenario: Get LDAP configuration By Name without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - @ignore - @ldap-config-get-by-name - Scenario: Get LDAP configuration By Name - And print result - And def first_response = result.response - And print first_response - Given url mainUrl + '/' +first_response[0].configId - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @ldap-config-get-by-name-invalid - Scenario: Get Non-existing LDAP configuration By Name - Given url mainUrl + '/' +'Non-existing-ldap' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 404 - And print response - And assert response.length != null - - @ldap-config-delete-by-name-invalid - Scenario: Delete Non-existing LDAP configuration By Name - Given url mainUrl + '/' +'Non-existing-ldap-XYZ' - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 404 - And print response - And assert response.length != null - - @ignore - @ldap-config-put - Scenario: Update LDAP configuration - And print result - And def first_response = result.response - And print first_response - And assert first_response.length != null - Then def result = first_response[0] - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - And print response.configId - And print response.version - - - @ignore - @ldap-config-delete-by-name-valid - Scenario: Delete LDAP configuration - And print result - And def first_response = result.response - And print first_response - And assert first_response.length != null - Then def data = funGetLdapConfig(first_response,'new_auth_ldap_server') - And print data - And match data != null - And print data.configId - Given url mainUrl + '/' +data.configId - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - And print response - And assert response.length != null - - @ignore - @ldap-config-patch - Scenario: Patch LDAP configuration - And print result - And def first_response = result.response - And print first_response - And assert first_response.length != null - And print 'Patch - ' + first_response[0].configId - Given url mainUrl + '/' +first_response[0].configId - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/maxConnections\", \"value\": "+first_response[0].maxConnections+"} ]" - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @ldap-config-post - Scenario: Add LDAP configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('ldap.json') - When method POST - Then status 201 - And print response - And assert response.length != null - And print response.configId - And print response.version - - @ignore - @ldap-config-post-same-name-ldap-error - Scenario: Add LDAP configuration with same name as existing - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('ldap.json') - When method POST - Then status 406 - And print response - - @ignore - @ldap-config-test - Scenario: Test LDAP configuration - #Given url mainUrl - Given url mainUrl + '/' +'auth_ldap_server' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And def result = response - And print result - Given url mainUrl + '/test/' - And header Authorization = 'Bearer ' + accessToken - And request result - When method POST - Then status 200 - And print response - - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap.json b/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap.json deleted file mode 100644 index 7ca3b04ba4c..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "bindPassword": "8OId4NKmlxY0eRdig9c1Dw==", - "level": 0, - "localPrimaryKey": "uid", - "version": 0, - "enabled": false, - "useSSL": true, - "bindDN": "cn=directory manager", - "servers": [ - "localhost:1636" - ], - "baseDNs": [ - "ou=people,o=gluu" - ], - "configId": "new_auth_ldap_server", - "useAnonymousBind": false, - "maxConnections": 1000, - "primaryKey": "uid" -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap_list.json b/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap_list.json deleted file mode 100644 index 2c940d9b4ee..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/database/ldap/ldap_list.json +++ /dev/null @@ -1,21 +0,0 @@ -[ - { - "bindPassword": "8OId4NKmlxY0eRdig9c1Dw==", - "level": 0, - "localPrimaryKey": "uid", - "version": 0, - "enabled": false, - "useSSL": true, - "bindDN": "cn=directory manager", - "servers": [ - "localhost:1636" - ], - "baseDNs": [ - "ou=people,o=gluu" - ], - "configId": "auth_ldap_server", - "useAnonymousBind": false, - "maxConnections": 1000, - "primaryKey": "uid" - } -] \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/jwks/jwk_key.json b/jans-config-api/server/src/test/resources/feature/config/jwks/jwk_key.json deleted file mode 100644 index c92b4a92a5d..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/jwks/jwk_key.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "kty": "RSA", - "e": "AQAB", - "use": "sig", - "crv": "", - "kid": "test12345-66f1-4b4a-92ec-d969522f4cbc_sig_rs256", - "x5c": [ - "MIIDCTCCAfGgAwIBAgIgTN/ufyTSP6YI3xSN3Gv/z0eh6D+NiVjAgoHilvQmJzQwDQYJKoZIhvcNAQELBQAwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMTAyMjQxMzEwMjlaFw0yMTAyMjYxMzEwMzhaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyowxR94xQfv9qlTjtMutSLY3wKWIorgnzKZzAyEscNxqke6YwE+DsZ9OM5Zo3nk5LZpyJzJKk0jgL3ZR616j5j5d6tCmKt2DCQjnkeJjSRZz9A0XAE2RLW1taX37zKhtTNE9LJ4Wr/P3EioiW7Ax0w6QpBxbGFNmJ+HhzQrR8sXv8TtB47e1a/Zx/4lSx96VaVxaN8JQNGOlE5xcxUyzLZ64gdOEq8Igvt8R520jxMnguS5cNWR9ooZdyz13ujc+YYw2axFfTL96FDOUK5syXT52mF0XLcwPX2YTcKkTrIESiPNiSODqQMIxjs9MvJBEcJn8elBjrbltyb0yjBpV/AgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAEBQVhijiNBC90nU0WNVsWeuoady7/XgQ0an0CKrmvrRTw+nVRWa8UxS5LJu6I+/GIsHs5P8NBN9/slUZJQ2+tAai2ZNyxm+c63Y3KY5Tth9bxVugJzFKNpbFh7zqQ9mlTkYierrhyzwk5iXRmtkDoRANwCcs0yvPN3aC0ZF+ESpUk+FlHKOzb0hpip7NumHPAHbLXpdk1SNLvr4kdYQ9ZQSuIZETBwr2bbQF8KxMEqQMY1nJuJvPLdkFS7Eg+LkfJbpKMXUwUOdOtU/HoO1njwPWhVN4xOoXalpQmTowu0yc7H2vtZPEIyKJcURgYekZGKiBWin9Z7gD6C14JB4kKg==" - ], - "exp": 1614345038838, - "alg": "RS256", - "n": "sqMMUfeMUH7_apU47TLrUi2N8CliKK4J8ymcwMhLHDcapHumMBPg7GfTjOWaN55OS2acicySpNI4C92Ueteo-Y-XerQpirdgwkI55HiY0kWc_QNFwBNkS1tbWl9-8yobUzRPSyeFq_z9xIqIluwMdMOkKQcWxhTZifh4c0K0fLF7_E7QeO3tWv2cf-JUsfelWlcWjfCUDRjpROcXMVMsy2euIHThKvCIL7fEedtI8TJ4LkuXDVkfaKGXcs9d7o3PmGMNmsRX0y_ehQzlCubMl0-dphdFy3MD19mE3CpE6yBEojzYkjg6kDCMY7PTLyQRHCZ_HpQY625bcm9MowaVfw" - } \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/jwks/jwks-all.json b/jans-config-api/server/src/test/resources/feature/config/jwks/jwks-all.json deleted file mode 100644 index f97e8bc10fe..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/jwks/jwks-all.json +++ /dev/null @@ -1,191 +0,0 @@ -{ - "keys": [ - { - "descr": "Signature Key: RSA RSASSA-PKCS1-v1_5 using SHA-256", - "kty": "RSA", - "e": "AQAB", - "use": "sig", - "kid": "dca3a91b-dd1b-47b0-b7e7-aaf2ec3b9d5e_sig_rs256", - "x5c": [ - "MIIDCTCCAfGgAwIBAgIgf95rqCSrHjanJBBTIvH3DztRlQWwj8ALPz0TBLda6KAwDQYJKoZIhvcNAQELBQAwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMjEwMjQwOTE0MTdaFw0yMjEwMjYwOTE0MjZaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRdu67/p8Gaab5p5tSDbELvb0nTVm5LmmqPjnddxPpVmYnb0Xf26D8hSCasaE1cKvzv6if4eu/e+fxTmki8qJxsiEqJCjoOG0VysjTL2FGeywaohJ6zdZxyWh3QQ0+oOAQqqIBZ3FBvfRzkCXOvIrmGZaBJHLsABBhbcjncmViFFWkq7iSiB6kmYvD1YQp1iOZoKA2ICmxoeDBrtm/AGihlVa9hGl9m3kX+h0JnlKu6jwYteZGIhjMavqeWq821BM80Td7tt563P7D+Io2mmrO7aNGXpShOedQlLrODuCFq+6mJRDdTHh8AfofsMJcX5y46B6UGNSP8Ys+rPkV44KdAgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAkVKraMEmpqsAddmnq6ow0BvpSxFMtXSXJzJlhrrai7UeidyIMD6t9VEDDwj4N5TbvXPz9YjtVC5I7/yprcoqcb63m6TM7WvkB3blVG5JCP7RvI+t2/4q+0tMf4xSmJ7/lAREpCNhFr7FV+q74R6KaLvFsVRnQyGJKpjuFWV3itskexsjWhgvagt3iScWsoquGkzg1pqyn+z3P4FxEWA55Bl3wP4g+Ys79OzrBA9d/sz81xQGFRmIB7TyDz12OyCcdWQOMVxRrgKbz3FxsscE3+Z7Ie9FVpDIqeBo/xI8/q7CCDxCHTtiTQjGS5j/XV4VcPt7i9mrQsajbndCAmynVw==" - ], - "name": "id_token RS256 Sign Key", - "exp": 1666775666429, - "alg": "RS256", - "n": "0Xbuu_6fBmmm-aebUg2xC729J01ZuS5pqj453XcT6VZmJ29F39ug_IUgmrGhNXCr87-on-Hrv3vn8U5pIvKicbIhKiQo6DhtFcrI0y9hRnssGqISes3Wcclod0ENPqDgEKqiAWdxQb30c5AlzryK5hmWgSRy7AAQYW3I53JlYhRVpKu4kogepJmLw9WEKdYjmaCgNiApsaHgwa7ZvwBooZVWvYRpfZt5F_odCZ5Sruo8GLXmRiIYzGr6nlqvNtQTPNE3e7beetz-w_iKNppqzu2jRl6UoTnnUJS6zg7ghavupiUQ3Ux4fAH6H7DCXF-cuOgelBjUj_GLPqz5FeOCnQ" - }, - { - "descr": "Signature Key: RSA RSASSA-PKCS1-v1_5 using SHA-384", - "kty": "RSA", - "e": "AQAB", - "use": "sig", - "kid": "80772339-b845-46c9-b185-e792596d3f60_sig_rs384", - "x5c": [ - "MIIDCjCCAfKgAwIBAgIhANBQZi8WsEmLvgk+JG8y1FQGR0G61l3eGKFuVtYV6tciMA0GCSqGSIb3DQEBDAUAMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE3WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm4T1IBZXVtek7bLlVmU4yy8qjI/1dipnS4TfB0C8gIN2Q2dB0aw4ee6DqrWfw+HblhJDamBdtm28k8LVDkbOC2E3dLhfiOXKtiIynvFO9kD3kPKrHwJ7OpsLow7CJoAG7usd5iPREeno/MyfchQBMT7FbtIwJ5tkU/kaHVPcaGL1yXcYwW7Pd+MmMhJn10jMgjsp1Ox2fRGPL8UBj98ppoOJV+cX0+X3R/YkDSSdEhrb27/strpxrJG3Xy5uh4O055+hlUn0aaIV1Nr1P6+62g1e3s8EyK7fZnM6kbxQkhN/VdNpl0CqSSqN0H/aQsoPTM+57h1kFEPWdHbQPAoaBwIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQEMBQADggEBAJIgf1diGfhmTmxzlKt0jHv0ATCzeIBCLBQrUF56KyOzsObouQxL3RGfak7EJLxWhC9eND9DyWpk3sQiypm4LHDrFDNcZcQ1ZCiFcd6/LGoTsNgT3cAaQdflBNTrkuhQPPHW6W4ZxoW75krliZAsp9QvWbu8BJB98kF4EfkfexwJ22hvoe/Eu9uO2/QE0mnw03U+WpVOilGNpsAoqbRZ1AFNNRaIeH/1aaT/ChxcLyvLaas/Q02D/p6jviWkgRYM2mIBSvgleHKQO5wzCVsopbYpkFogYpTNf6q6CMXncvmOBB+g+IXT8gKC2Mc00FWUuDIFUgJCRX7QpoFFXwql5/I=" - ], - "name": "id_token RS384 Sign Key", - "exp": 1666775666429, - "alg": "RS384", - "n": "m4T1IBZXVtek7bLlVmU4yy8qjI_1dipnS4TfB0C8gIN2Q2dB0aw4ee6DqrWfw-HblhJDamBdtm28k8LVDkbOC2E3dLhfiOXKtiIynvFO9kD3kPKrHwJ7OpsLow7CJoAG7usd5iPREeno_MyfchQBMT7FbtIwJ5tkU_kaHVPcaGL1yXcYwW7Pd-MmMhJn10jMgjsp1Ox2fRGPL8UBj98ppoOJV-cX0-X3R_YkDSSdEhrb27_strpxrJG3Xy5uh4O055-hlUn0aaIV1Nr1P6-62g1e3s8EyK7fZnM6kbxQkhN_VdNpl0CqSSqN0H_aQsoPTM-57h1kFEPWdHbQPAoaBw" - }, - { - "descr": "Signature Key: RSA RSASSA-PKCS1-v1_5 using SHA-512", - "kty": "RSA", - "e": "AQAB", - "use": "sig", - "kid": "fd9389bb-1207-4c7c-88bd-9e3ab0f3f0ac_sig_rs512", - "x5c": [ - "MIIDCjCCAfKgAwIBAgIhAJDr8HefaC+vEAvJ0rfP3hOrdGwyjxYwSotcB491FLJLMA0GCSqGSIb3DQEBDQUAMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE4WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArxc+2RuMFXLcL/PTj4VybbnSET25kPb/F5NrW1/zjAuA/njkGyoKDCxN1jUcQ0PSFRWGcIPnF7eP8iU6Jf7NornY3OT318hHm6L9t6M0Hx6K+APBgAf6pNrQ7Y6EEnHMwQWPhS8tVNh/G7ckVOFtTKI0v3bvNwp2LADEsPgFoOFGo6V/YydjZrbCrFa1caTsX9WGCEPa6qZYTZSbCWCLR/1NwJ2EuFyTNs2UetLa7kCTv4NfCwjaXCwvH5EVbpUr/PY8CvfuacFSFdvkx0TKlwIcRvOxSL3XfE7dDVZ6DoaMax/sVdJ08U87F2KhhROPf+wrMN1vkVUE6VEkMY+0JwIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQENBQADggEBAEzw9RrC+kQ4Fyi9edL5b4f0YiQqCXPQeGXeiRAs+aFvZVvXwx2Idt4Ah5HBs7oGey1Yaoj/GNLxBe5iMd1sGk+QR7q6wtxAIr1r0ARAdVxlM8wEOtYAgIZqbRkv73gMyt5nDLPKhQMhDwRPpBT3iKhnGF95B2Q0FbkqJCLXY4KMfVn1ANNao3jUFeT7kbZF3nTH80y2iuyP2v8w6RjY8ko378D/Knp1TINX96oYbm3GCptO2DU7mykHB96hOh/KY3DivWxznaIKoKaU0FJYIAP83yITnJ8qkjeXOipTb3fvMYRg/ki1kBiiD8V+GI0p1MjRtdAtp6kmWmQLZg+yHRg=" - ], - "name": "id_token RS512 Sign Key", - "exp": 1666775666429, - "alg": "RS512", - "n": "rxc-2RuMFXLcL_PTj4VybbnSET25kPb_F5NrW1_zjAuA_njkGyoKDCxN1jUcQ0PSFRWGcIPnF7eP8iU6Jf7NornY3OT318hHm6L9t6M0Hx6K-APBgAf6pNrQ7Y6EEnHMwQWPhS8tVNh_G7ckVOFtTKI0v3bvNwp2LADEsPgFoOFGo6V_YydjZrbCrFa1caTsX9WGCEPa6qZYTZSbCWCLR_1NwJ2EuFyTNs2UetLa7kCTv4NfCwjaXCwvH5EVbpUr_PY8CvfuacFSFdvkx0TKlwIcRvOxSL3XfE7dDVZ6DoaMax_sVdJ08U87F2KhhROPf-wrMN1vkVUE6VEkMY-0Jw" - }, - { - "descr": "Signature Key: ECDSA using P-256 (secp256r1) and SHA-256", - "kty": "EC", - "use": "sig", - "crv": "P-256", - "kid": "1b4a4c44-4663-40f7-9e49-4cf1ccd91568_sig_es256", - "x5c": [ - "MIIBfTCCASSgAwIBAgIhAOxqrUaVo0XVfNvwDGt3NJE3YogX4hEHdqIGj3YRMP2+MAoGCCqGSM49BAMCMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE4WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfoM8AxICX7x9LBqZEVi7ggEu4nLiZdwojMKyiNE6dNFUALefe9ejqYGqxg2ISXjcfZKSsH/0h4woqt8MxSdTk6MnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMCA0cAMEQCIFvH+2Ix3jeHqw0hcm83nnIDuXE2Fk9mSlQDUGEOCUfRAiAGIEcVUqvPBiexpPJB+Tyl+6JeIwOI5DnsIRIdZtMM6Q==" - ], - "name": "id_token ES256 Sign Key", - "x": "foM8AxICX7x9LBqZEVi7ggEu4nLiZdwojMKyiNE6dNE", - "y": "VAC3n3vXo6mBqsYNiEl43H2SkrB_9IeMKKrfDMUnU5M", - "exp": 1666775666429, - "alg": "ES256" - }, - { - "descr": "Signature Key: ECDSA using secp256k1 and SHA-256", - "kty": "EC", - "use": "sig", - "crv": "P-256K", - "kid": "a2dbca16-4a7b-458a-8324-f866553c6135_sig_es256k", - "x5c": [ - "MIIBejCCASCgAwIBAgIgHPM2yIWT0/QoSffQsYMN9sCda5tmotFqdmob2inDou4wCgYIKoZIzj0EAwIwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMjEwMjQwOTE0MThaFw0yMjEwMjYwOTE0MjZaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwVjAQBgcqhkjOPQIBBgUrgQQACgNCAAQ/9BpgfKOdeRi3L3n+Mmat4KiGIJunGWnkQg6Wa6qPFtI+qlef2USK4lwRrSf+TxvR9HsaCqq4DkgfKXTzbxl7oycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwCgYIKoZIzj0EAwIDSAAwRQIhALew2FxbJ+7Khafw6pQg8IqKGp5/vUDRErpr9f155noBAiAcWi3sczGMC1Y/kwZDcjRVcCwNS1uOzSzGkX3xQPUS4g==" - ], - "name": "id_token ES256K Sign Key", - "x": "P_QaYHyjnXkYty95_jJmreCohiCbpxlp5EIOlmuqjxY", - "y": "0j6qV5_ZRIriXBGtJ_5PG9H0exoKqrgOSB8pdPNvGXs", - "exp": 1666775666429, - "alg": "ES256K" - }, - { - "descr": "Signature Key: ECDSA using P-384 (secp384r1) and SHA-384", - "kty": "EC", - "use": "sig", - "crv": "P-384", - "kid": "4b8c4a4d-ed06-41d5-a395-c9fe310aa1b2_sig_es384", - "x5c": [ - "MIIBuzCCAUGgAwIBAgIhAPkMA75M75uGAw4sOLj1qJZRGN3+Drjtf/+7D6A/mNGvMAoGCCqGSM49BAMDMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE4WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEmOyHruRxia8lKckotlkp8GA038ouYZTQslucQCZRbC6zZGEZturw1D7Sd7z5waIa4mKFTX+E1j8OEKbdPbGBE6/MaiQXHUTnWhsyAhofPHyLye76zrRgNjLmnfFYon6HoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwCgYIKoZIzj0EAwMDaAAwZQIwOkXPAea4Q/XeUFn5pEndSiO2oIPIL+vGdWZ98eqE72wMp1t0B9iVfICLvgHmKgkjAjEAlqWlICL1/45Pn5hFOs3z6UB0isZy9JA8dd1uEljfcmZv9PjBAa2Of7VkRYxFA7YP" - ], - "name": "id_token ES384 Sign Key", - "x": "mOyHruRxia8lKckotlkp8GA038ouYZTQslucQCZRbC6zZGEZturw1D7Sd7z5waIa", - "y": "4mKFTX-E1j8OEKbdPbGBE6_MaiQXHUTnWhsyAhofPHyLye76zrRgNjLmnfFYon6H", - "exp": 1666775666429, - "alg": "ES384" - }, - { - "descr": "Signature Key: ECDSA using P-521 (secp521r1) and SHA-512", - "kty": "EC", - "use": "sig", - "crv": "P-521", - "kid": "a9a729fe-3dfa-473d-b6ec-f9e3907d3b9b_sig_es512", - "x5c": [ - "MIICBTCCAWagAwIBAgIgSBMzUCcQQTNTP1stoDO8OnNQg3V6pJ0l/UOxCzmoboIwCgYIKoZIzj0EAwQwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMjEwMjQwOTE0MThaFw0yMjEwMjYwOTE0MjZaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAEegoUizxm3wdtpHpyP1WTjW7Y5VgI2eKVOKl4FiJCY3fxehtXVeqArFiYCo+RljGBAq2f/dttNcOO351Fi0Nc95wB7JCoJeq/a84fbTrc8W5XZ1+HnU06Y0FGITZbpghowox1pzSmOrMI+vyjVtgHTB+uDd8+yucUrKbr7N5LTBq1wyKMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMEA4GMADCBiAJCAJgO51ZIw9yv0jEkxj9pESaEJAiAeIkRXr6YojILE4P4hSJtbcRV3sZ7zFhOIc50OEmqBOZYlOTpH2Z4wkXfkQ7KAkIAq3Wfr1uRUKF63RGp9R5RDhRsX8RgKe3ze1O5E86uRe8Y/fRd4eFs1i0oaIUwJ2WOxkY4VTty6Cu7B6pGHrB+vqQ=" - ], - "name": "id_token ES512 Sign Key", - "x": "AR6ChSLPGbfB22kenI_VZONbtjlWAjZ4pU4qXgWIkJjd_F6G1dV6oCsWJgKj5GWMYECrZ_92201w47fnUWLQ1z3n", - "y": "eyQqCXqv2vOH2063PFuV2dfh51NOmNBRiE2W6YIaMKMdac0pjqzCPr8o1bYB0wfrg3fPsrnFKym6-zeS0watcMg", - "exp": 1666775666429, - "alg": "ES512" - }, - { - "descr": "Signature Key: RSASSA-PSS using SHA-256 and MGF1 with SHA-256", - "kty": "RSA", - "e": "AQAB", - "use": "sig", - "kid": "75b6b370-d447-4c8e-8912-51d8bc95d6c6_sig_ps256", - "x5c": [ - "MIIDcTCCAiWgAwIBAgIgEKm7QdjAhBGEbX3TB3f6EsOCZgFNbEukvE8Cz/Kl/JswQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDE5WhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1FF6FSbVQKH7crwTPprDQlmo7wQ+47HaVLv+4gR3izZFgrLdezpexWvafKzghHhZO0YFge9hY+jx0lVy0fltFVULRucexhHIANAIvvL9aDorRPnbMV2EG4Yv0Xsy4ZC3fjNi5SidYydlYL8XL4jpdS1L58hWQzAL5uagojvwIlJ1H8m+aUTR8LyOecNjSar/jB/h6E8h/e1MCtqX56KD6F4euGAqDbt3GJsoUP+qch3RoPZdNxlY2wYLrprz7GukUvrZWgpX5dVVtrJkgYIVuNT3EtHvseL4SYkY7DGdR51ov2pu8dvAQ8x6Jyc/XXtNVzUF/rYPQfJkdYWlrMATmQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgA4IBAQAile70cfWTK+dTQOi6LWdN6ldAyieXOK9SsVN0EgQMhmLlXQlCGjRzypCrG0m778T/fqhT6ENlJ5jvIXfaCiq3bjrf6350fV9/70QBIvSGBa/SVwll1Y9464sB1BwCNd9DAvV0wPmEw7fwyW+Uh6PceNP4zOVfBReoP8kWFMhzpkbm0KwlAnJoRWniUt10RJqOWOUgvYpu4vWhy9EatSZMYxswRxuzW2JAFa7otOXbK7mCElboNIua9v4751N5HqZLmmOOpvKFTlbqzM5WHkWTfROfrm9cqpQWShg5uiuzjBBQiPiskrEjYRw+fQs3zDSbvIEdrx2FeAjuXCMoqyWQ" - ], - "name": "id_token PS256 Sign Key", - "exp": 1666775666429, - "alg": "PS256", - "n": "1FF6FSbVQKH7crwTPprDQlmo7wQ-47HaVLv-4gR3izZFgrLdezpexWvafKzghHhZO0YFge9hY-jx0lVy0fltFVULRucexhHIANAIvvL9aDorRPnbMV2EG4Yv0Xsy4ZC3fjNi5SidYydlYL8XL4jpdS1L58hWQzAL5uagojvwIlJ1H8m-aUTR8LyOecNjSar_jB_h6E8h_e1MCtqX56KD6F4euGAqDbt3GJsoUP-qch3RoPZdNxlY2wYLrprz7GukUvrZWgpX5dVVtrJkgYIVuNT3EtHvseL4SYkY7DGdR51ov2pu8dvAQ8x6Jyc_XXtNVzUF_rYPQfJkdYWlrMATmQ" - }, - { - "descr": "Signature Key: RSASSA-PSS using SHA-384 and MGF1 with SHA-384", - "kty": "RSA", - "e": "AQAB", - "use": "sig", - "kid": "5006e6f7-bd41-4228-b413-236a6cd06e8f_sig_ps384", - "x5c": [ - "MIIDcjCCAiagAwIBAgIhAKe3eCpsdD8vEST+NTE0TjTApnfWOb3YiL7ihGnGHSpxMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMDAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMB4XDTIyMTAyNDA5MTQxOVoXDTIyMTAyNjA5MTQyNlowJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANHPn1MC1924tZBa4bf11TGqN7nrx/DWruol56RP7tts1kku5jbGVNVsUSseaAY7n5vAxxuxM8EEBnKkIIj/Z76s0RvG0N4RReua3qclpN0QUqxXtm0uugDs4P11nZwX7yZ89DHCWEr4lqG0Bp5sMR4fNWpx2ULpJOGNZKmcIYMmsYueJv8w5Ndg4Z5NDY1R6OGr642/bhowvQy2SX3cDQFV2sOM41DOxDQYwoAWZ/BJoroV9dKgNwKV8Wi/LTCBqLcH1uh3ffWLCoQqHWFZ5HGn+sN5xUiOeKHpIiQBAfX6rgbDrdBFeYWptrSSIPMVMIW5MrJpeTvdwxER/LeuqHkCAwEAAaMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMAOCAQEAQGXNsTojD8CGZ5rtETY7IQc3VskiPGzoHRTmgUqWP1sB6RwZKPrLdqP/CUvcKjwrxfALjhiB689l0Ec8qw9YzBzXB+qHc9JS1QnmRjmPAggShRajTxbyMIdHrQayGjZ+D4gvR8lPGGlbWM/KuNGBEouq5EH4lfIvPQdcgxutwqAtMxpSwIS5nlREsSAPoyO01aywcaQgeHFNhZX5xH/U1Rdt5czF00S/AgC5PYxVzlRDpnThMTjOu/zuOTBdGbjtnC4qP1YITn6EdCtp2pGQ068pArnjGIgSSxmDWISJBTBE6QwUgNX9J7V3B6Hxg6YU12WMvbXFTEikJRVtULbnuw==" - ], - "name": "id_token PS384 Sign Key", - "exp": 1666775666429, - "alg": "PS384", - "n": "0c-fUwLX3bi1kFrht_XVMao3uevH8Nau6iXnpE_u22zWSS7mNsZU1WxRKx5oBjufm8DHG7EzwQQGcqQgiP9nvqzRG8bQ3hFF65repyWk3RBSrFe2bS66AOzg_XWdnBfvJnz0McJYSviWobQGnmwxHh81anHZQukk4Y1kqZwhgyaxi54m_zDk12Dhnk0NjVHo4avrjb9uGjC9DLZJfdwNAVXaw4zjUM7ENBjCgBZn8EmiuhX10qA3ApXxaL8tMIGotwfW6Hd99YsKhCodYVnkcaf6w3nFSI54oekiJAEB9fquBsOt0EV5ham2tJIg8xUwhbkysml5O93DERH8t66oeQ" - }, - { - "descr": "Signature Key: RSASSA-PSS using SHA-512 and MGF1 with SHA-512", - "kty": "RSA", - "e": "AQAB", - "use": "sig", - "kid": "bdc7de11-eeac-4814-a0f7-f02e5fe32005_sig_ps512", - "x5c": [ - "MIIDcTCCAiWgAwIBAgIgXxNyneXLuExN4eVmjyegbb5qwCC4KUomlf8LULpGwGQwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDIwWhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA93X7DgguE/GPsC5vpQa4yOnfyxNQAEzW9iaTjPAkcazuajvbPwXtk7l/BxBEWBtyFoIkMytWh3vyFQpSSYwEIOak5XSwSGBqynDOx78Xcqy6LhYv101YRItNhNL+0fGkLVqAJLYBQM3x4/e9wooilFTOtq9CbqYBV4wUZC3BwmMUGBr34xYWAyCdJfzgzDtm5vAxg33AaGbUQbh2yM3j97Eca3G6JxhNkAYriJfaycGr4vpmU5WHGcceccYSdiPBxxKblS14yB9WZsuBEciw2BVVhS+7oYYbPfimpUw9uNi4uQZkjoFk3ECd468IAKxEtYXBAMZok39irvaPnK6RGQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAA4IBAQCpr43l5d0qA/rljv3kOBz46o0nRMHw3UHqze/AaVeaOhAEMCmncgOrfjKNJmdcE1fW3kL6WEJ6PTF77/v26xb3xWX5nrbbpnftJ2iEXZk1lqhRCiccQv8EFIaLt1xuTw9nmMeUIRIsTE5rEbFJfzI5hEfQ9Kmeo4ZbW3qUuuaWiNsSR6HihuxekG8K4Y2ap6JwvLWaTSk7t2U96gjvUmkEWEaBjqexBhxNE5vPH3oCJj4132EWm364OCZbe0mT7e0eId++6G9EoO9hS7eu+NaRG2K8HvSgMC6C67VNHVoDy8m5niax8XBcqTM8mj8fkJ8C1y1TU0awlrNTTk4q5Rgz" - ], - "name": "id_token PS512 Sign Key", - "exp": 1666775666429, - "alg": "PS512", - "n": "93X7DgguE_GPsC5vpQa4yOnfyxNQAEzW9iaTjPAkcazuajvbPwXtk7l_BxBEWBtyFoIkMytWh3vyFQpSSYwEIOak5XSwSGBqynDOx78Xcqy6LhYv101YRItNhNL-0fGkLVqAJLYBQM3x4_e9wooilFTOtq9CbqYBV4wUZC3BwmMUGBr34xYWAyCdJfzgzDtm5vAxg33AaGbUQbh2yM3j97Eca3G6JxhNkAYriJfaycGr4vpmU5WHGcceccYSdiPBxxKblS14yB9WZsuBEciw2BVVhS-7oYYbPfimpUw9uNi4uQZkjoFk3ECd468IAKxEtYXBAMZok39irvaPnK6RGQ" - }, - { - "descr": "Encryption Key: RSAES-PKCS1-v1_5", - "kty": "RSA", - "e": "AQAB", - "use": "enc", - "kid": "49a80d60-c3da-4930-baae-75c1a93db1bf_enc_rsa1_5", - "x5c": [ - "MIIDCTCCAfGgAwIBAgIgf8De7cNPhPeX2SjsAhznXmKdMsyf5ErgdO0Q7NhZW/YwDQYJKoZIhvcNAQELBQAwJDEiMCAGA1UEAwwZSmFucyBBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMjEwMjQwOTE0MjBaFw0yMjEwMjYwOTE0MjZaMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfGSbYMhG6yMgyH+aFZko259ax4BX8rTKWCz4jhkZNtHNroEs7WNJoYbbyF0AFhL91oY1YM4EkqG9e+FB7/r9v2H38yu+9rkuXeYZcEqPKCd0EJcgGYFjGga4wj7sqygcZprl9bho3OnHEaHGonMNxcEzac32B1Pg0O6SLCKzUpB+JBeL21Xu4grAuc2DFNq7TkOYd341KTUZO6rDKIBszKJCfTd8Su7HvkaCsSDSP0o9uCGeCHDWIVReU840uOLGcv2ldwOOKwbt97ZyT7/01xQjS8A8XeMH+b+aKTEk5bR08o6CST26Q/ddjVnieCXc4ztAYYuLYzNc0j2MPwAy/AgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAVYCgI+jzc4MpfQa5mmiURvAt8yIPQQUKxEFeZAVleKrxKn0pPe2gJKOjFj8LqL4Jjz6Pzys3ERiQJu7fSfQHGqN7VL1x3K5wUZDWUTq25Ci0YL9gH5ByAUun+MN5uSKTNHHEUafgq5fhN4n4WRq4SPZPkieKvPPEv1PjT9cVmt8+kFLR2xiaJhLYz3z5qQzrj4BhbIwbqby7R329l8EBUrA0xLs8G65sHtCGTU33OdBmP38PvIPdVHjAed08LG+QfjLO98qE7fvGhx1HmnH1BifAOpLZsYu4zkTUF3ufcBYvdDpgwBOgjN67esi5qMMP/6OBXi0K2tsBz3mwpdGPUQ==" - ], - "name": "id_token RSA1_5 Encryption Key", - "exp": 1666775666429, - "alg": "RSA1_5", - "n": "nxkm2DIRusjIMh_mhWZKNufWseAV_K0ylgs-I4ZGTbRza6BLO1jSaGG28hdABYS_daGNWDOBJKhvXvhQe_6_b9h9_Mrvva5Ll3mGXBKjygndBCXIBmBYxoGuMI-7KsoHGaa5fW4aNzpxxGhxqJzDcXBM2nN9gdT4NDukiwis1KQfiQXi9tV7uIKwLnNgxTau05DmHd-NSk1GTuqwyiAbMyiQn03fErux75GgrEg0j9KPbghnghw1iFUXlPONLjixnL9pXcDjisG7fe2ck-_9NcUI0vAPF3jB_m_mikxJOW0dPKOgkk9ukP3XY1Z4ngl3OM7QGGLi2MzXNI9jD8AMvw" - }, - { - "descr": "Encryption Key: RSAES OAEP using default parameters", - "kty": "RSA", - "e": "AQAB", - "use": "enc", - "kid": "55aed597-4fc4-4dc7-babd-e1acf672c3c8_enc_rsa-oaep", - "x5c": [ - "MIIDCjCCAfKgAwIBAgIhAJESxnSQz5Ejg+hW70GYN7yOFQdtTxwpmRNGnq5ff/H2MA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDIxWhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1VVP4NEBRujsnuKZg4jqJBE51GVfgScBT9NLgkF3IErXZ7RL0XrOCD4wqhMQw7DREw9cQpumJ9Qi0quuAPWIjhfoslvTVLa8TlzpHky0xv10FFtB28Tf6n0BK7nYe/UJaQlbQYCO05VPlD8lBU8vNkNVA8ZS7KqWdoQQfZY02Y9CEsyLu8t/PRsP/6UrOhl1G6aGupvKVUeD9NFLubmP31MycJIG6EhdjUc1VLfjEcNHeQ7Py1w/BjWT2JX3aBBeQIICCrlG2gUGad4/01kk24nHY69wdshQ4LnjIRwoaALC4SI33ndsUEzHvWHTD4Wild+JJ+xp0efydRrSoKd89wIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBAMuwBGIPL1epfF5GnIU3XlKs91c9AbnsSxpW/zv3un+ptaYF5qCv9LlMaGx3r9d6oOj6wmf5A1sFEUuE0U+TMwoR7KS+flOrEfaCMi0qUbg245Lc+2tsnVVV133qXnsvRYig325WFC469ECjumeDjd0HKZIcs7qLQN//J3+uA0d/mKgW+fqkGO50qGGd6n8Emw4Gas3SUxqal5Yh1nnIPaVy7holjAO8Jsgjunf1s05EXWzL8BQm+qYiiuYPQM+Zm0I69fmo7GB55i9h8ejf3tQ6iAY7gfRX1c1zCpR7CvwE4iqujOvc61y8aFfTdC1rg+/YHsZnTrxaToSJKBo98uA=" - ], - "name": "id_token RSA-OAEP Encryption Key", - "exp": 1666775666429, - "alg": "RSA-OAEP", - "n": "1VVP4NEBRujsnuKZg4jqJBE51GVfgScBT9NLgkF3IErXZ7RL0XrOCD4wqhMQw7DREw9cQpumJ9Qi0quuAPWIjhfoslvTVLa8TlzpHky0xv10FFtB28Tf6n0BK7nYe_UJaQlbQYCO05VPlD8lBU8vNkNVA8ZS7KqWdoQQfZY02Y9CEsyLu8t_PRsP_6UrOhl1G6aGupvKVUeD9NFLubmP31MycJIG6EhdjUc1VLfjEcNHeQ7Py1w_BjWT2JX3aBBeQIICCrlG2gUGad4_01kk24nHY69wdshQ4LnjIRwoaALC4SI33ndsUEzHvWHTD4Wild-JJ-xp0efydRrSoKd89w" - }, - { - "descr": "Encryption Key: Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF", - "kty": "EC", - "use": "enc", - "crv": "P-256", - "kid": "0270a2b9-1200-42a2-9b12-e2fa89ce3bd0_enc_ecdh-es", - "x5c": [ - "MIIBfzCCASSgAwIBAgIhAIa6KUAXzFx537jBtB37JqtIquhWWkoqWtMzoDCj24LxMAoGCCqGSM49BAMCMCQxIjAgBgNVBAMMGUphbnMgQXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjIxMDI0MDkxNDIxWhcNMjIxMDI2MDkxNDI2WjAkMSIwIAYDVQQDDBlKYW5zIEF1dGggQ0EgQ2VydGlmaWNhdGVzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZx77ZxYm0XJKNpgxChTlK+NBJAtpZ+jWGjaXDFYgt3+x1IAktFvlkQraoWlJuQx+LfufqhL3Lm83ZetMowqKWqMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMCA0kAMEYCIQCT6uXIMyOg34+khFbRbrUxE/ozSVu3tE24Ofz3eFhtBAIhAINgdWN86TOOEAUXUr2ijmaAPBgn7mGoeg4c7FfyZTxn" - ], - "name": "id_token ECDH-ES Encryption Key", - "x": "Zx77ZxYm0XJKNpgxChTlK-NBJAtpZ-jWGjaXDFYgt38", - "y": "sdSAJLRb5ZEK2qFpSbkMfi37n6oS9y5vN2XrTKMKilo", - "exp": 1666775666429, - "alg": "ECDH-ES" - } - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/jwks/jwks.feature b/jans-config-api/server/src/test/resources/feature/config/jwks/jwks.feature deleted file mode 100644 index 89d7fe0bdfb..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/jwks/jwks.feature +++ /dev/null @@ -1,85 +0,0 @@ - -Feature: JWKS endpoint - - Background: - * def mainUrl = jwksUrl - - Scenario: Retrieve JWKS without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - - Scenario: Retrieve JWKS - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - Scenario: Patch JWKS with new key - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And print response.keys[0].exp - And request "[ {\"op\":\"replace\", \"path\": \"/keys/0/exp\", \"value\":\""+response.keys[0].exp+"\" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - Scenario: Put JWKS - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then print response - Then def first_response = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - Scenario: POST, GET, PATCH and selete a Key - #Given url mainUrl + '/test12345-66f1-4b4a-92ec-d969522f4cbc_sig_rs256' - #And header Authorization = 'Bearer ' + accessToken - #When method DELETE - #Then status 204 - Given url mainUrl + '/key' - And header Authorization = 'Bearer ' + accessToken - And request read('jwk_key.json') - When method POST - Then status 201 - And print response - Given url mainUrl + '/' +response.kid - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - Given url mainUrl + '/' +response.kid - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And print response.exp - And request "[ {\"op\":\"replace\", \"path\": \"/exp\", \"value\":\""+response.exp+"\" } ]" - Then print request - When method PATCH - Then status 200 - And print response - Given url mainUrl + '/test12345-66f1-4b4a-92ec-d969522f4cbc_sig_rs256' - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 diff --git a/jans-config-api/server/src/test/resources/feature/config/jwks/jwks.json b/jans-config-api/server/src/test/resources/feature/config/jwks/jwks.json deleted file mode 100644 index aaa2ac85f6d..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/jwks/jwks.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "keys" : [ { - "kty" : "RSA", - "e" : "AQAB", - "use" : "sig", - "crv" : "", - "kid" : "b9570bfb-276a-44aa-a97d-667b57587108_sig_rs256", - "x5c" : [ "MIIDBDCCAeygAwIBAgIhAOviRkmppgF16wC7nMg17Jt4P7lNoLglfLDxLAPYn4J0MA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjE3WhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzj1NEHyGk/ywG25py2s/zVVrRggzRO0jE6VOUvqUzsEJwt1aszQ4onFu6vgtjNwq2ZmEFZbw1Jw7dlz4Xrdj12pQlLVuEhyVaTziQp3LvspqxyACHQb8XSKFdKZaa1eBF8PGN5zDN/d+tIrAZYnQS2gH8BoPIuB3Z9AoCLTzifnPvmOwW/e+/Wags/ApZiEfF2Po0InV5NeJAyoIpaGhlwjqqOWXm/GpCASAk9ZD8Ebnmy9RM71zDCgmvq/hPueKnbNTZdQ3TQdzEuSwxbWEHu16v5MbF7QtNzvFSFlllhgwqI2ccEljDbs18j3DUS2B1VTTAr/DLR3SVyCYbKBbRQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBADaqrfVH1FX0FLp99TG9fHOiOMD12vsIPANb9QbIADineFrSvUI3zIX56PpvMT+EApaLPcIYSwG1YziWT1oGDGkfyinofSRGl4JcC63slChUBfjlBZlXTIlc7CJA7CfzO6BW3SvO0GPF0NStCUD9Ou4oOVaIc3XrPzhIAp71cF9iLFnQUK1hiD9NhQUm5v2Nq+sQdjAxSlqigXnc+rB9+V8snCkr9x9q1cysq1ZyCRT55psa53Irqtc50T2PHA6kyzEVW51+yFaZa8z+WMoofr6ndx2DFI7n5+8jFGs9WoP+/zV8E/XK61iy+EdXVjXQYVcArjEzeIahn8QOd/hUcfo=" ], - "exp" : 1599751946863, - "alg" : "RS256", - "n" : "zj1NEHyGk_ywG25py2s_zVVrRggzRO0jE6VOUvqUzsEJwt1aszQ4onFu6vgtjNwq2ZmEFZbw1Jw7dlz4Xrdj12pQlLVuEhyVaTziQp3LvspqxyACHQb8XSKFdKZaa1eBF8PGN5zDN_d-tIrAZYnQS2gH8BoPIuB3Z9AoCLTzifnPvmOwW_e-_Wags_ApZiEfF2Po0InV5NeJAyoIpaGhlwjqqOWXm_GpCASAk9ZD8Ebnmy9RM71zDCgmvq_hPueKnbNTZdQ3TQdzEuSwxbWEHu16v5MbF7QtNzvFSFlllhgwqI2ccEljDbs18j3DUS2B1VTTAr_DLR3SVyCYbKBbRQ" - }, { - "kty" : "RSA", - "e" : "AQAB", - "use" : "sig", - "crv" : "", - "kid" : "73d7df05-4f74-4b97-b1ad-409ac8366f6c_sig_rs384", - "x5c" : [ "MIIDAzCCAeugAwIBAgIgd+52BoAVgGuQ2FNHdDS396toOB4IR75RHW674ADcDh0wDQYJKoZIhvcNAQEMBQAwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA5MDgxNTMyMThaFw0yMDA5MTAxNTMyMjZaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPKfukpHh5egfqpIkNNmr/5XWjIcP6TkdlWARBcJfeCXDCUMBhh1SWXJgy8edPvbrMUxuQX/CorEM5LtoUgi4tHK2DRHa9IeZ8w/PYmLQipqcv7vsFbABiGvpQxYx88VDKTeH0RVzzKl+pqvqphSqj04rV6dGpNWJo7RMK3Cc6RkTtPR66neVeRi33ZJB0EyZ1TtZy8Qs5u66UaH+FkVjvWGFvXmSVc5cL3xCi9SmFwkmZPYR8B0zaUZNURDKlPEdxk8NWTdK2AsnRxGw/mS+VJjPLGinC9kGaEdzIKwCSrBwGmhlnnEKG/t3DAg2X95f+iztXrvBJDvolz9LLz16tAgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQwFAAOCAQEAy5IIlC1GFeGM2s8twBCZ04WmusrOlgyNDBCaji5LonAQWJobIVRr4bztjHJvPGa/bm5v1rVWf0Pafs9A2m81EnGl49UtrvGnOv/wvuHHoU+gbZJBLU2odTRegwlk1pnLDngd5SAPEM8+KhwtSKWYBZMlN2rZfbQ0MMW98DvNqsKUJzzQa46+NUhDalEphWxRdBRoN2NuZE35tSkiLk2sSGcHtrOV42lMa3nhEUFcfe+BsIflK5KxaWP5VNaCkabPUlBpcvxrQDWXDEmhVIADi4MzeiNO4BESw3u3L5zO19GozDi45UOqTQzhSEi+SZphi8Ylhet0Ol/9+jr/4OIHrQ==" ], - "exp" : 1599751946863, - "alg" : "RS384", - "n" : "zyn7pKR4eXoH6qSJDTZq_-V1oyHD-k5HZVgEQXCX3glwwlDAYYdUllyYMvHnT726zFMbkF_wqKxDOS7aFIIuLRytg0R2vSHmfMPz2Ji0IqanL-77BWwAYhr6UMWMfPFQyk3h9EVc8ypfqar6qYUqo9OK1enRqTViaO0TCtwnOkZE7T0eup3lXkYt92SQdBMmdU7WcvELObuulGh_hZFY71hhb15klXOXC98QovUphcJJmT2EfAdM2lGTVEQypTxHcZPDVk3StgLJ0cRsP5kvlSYzyxopwvZBmhHcyCsAkqwcBpoZZ5xChv7dwwINl_eX_os7V67wSQ76Jc_Sy89erQ" - }, { - "kty" : "RSA", - "e" : "AQAB", - "use" : "sig", - "crv" : "", - "kid" : "496d7428-e7ca-4478-bfc9-11f5e03df0c3_sig_rs512", - "x5c" : [ "MIIDBDCCAeygAwIBAgIhALcfg1yR7RpfrkQxqiLTGl1bVNQ/NxR9eknVcNDVgiLXMA0GCSqGSIb3DQEBDQUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjE5WhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAumiN4IX4kRc55haCN9/gCUy4gGknS8LwGUkd53ukePnVz1qJgWGaHfkmztiepmvLmiE5f4/0eUTr5gxnFTErQtI8mL+DAIo1yrw+/9TI6+cf+JOhgPfl7P475Za8SiRg295CUCQXCInMCBh7HV0Bm5QsHzMDYdDQuGMAlEfdVB2cpKwXZ+j9Nlbx/UWeHCHuaKyyHMtGDYd1jp/bce4ix5DdlndH6OuMGQ59DwyXPMWLMgaQ+EkcX7th5TfYTEa0ZiPTEmU3nEvAm04vu2MkolPEvviKmLu1QeYsQhgMMzi17+/8ZZlp3qJWjonoeWNtG4UIqvc3Mt3Lo7p/WKz18wIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQENBQADggEBALSFKriw7UgxRztq65MaxeiqmFDla81ylVcq+NL07NMispkmhDT00F+yuSi+YyBCIh1FExBnZj6+cFGAb0mwbCOEIgpiVluy9wHzcfg5aeoZr2ZWFmJjHVzq/1b/9+X8SP5cwwFEzkYEVwOu3bMmLE1QyHZwjNKoC2d30jSV5YTZEEmIWbjb6tT+l36W72Ei4Sy0AhHYpCMEvV0AoonRN4kfgtbTv94jKbDBURI/cBeffAzgGVdh/+NVi4qzZ2t27pLwtr3R7Gqn3xpdOnB98vNch/FPVg5i2BaSm5s6+fybIBlkMqBAf58YYVeQbCIqC9Z8ATl6vTKkXYsKZTtivDw=" ], - "exp" : 1599751946863, - "alg" : "RS512", - "n" : "umiN4IX4kRc55haCN9_gCUy4gGknS8LwGUkd53ukePnVz1qJgWGaHfkmztiepmvLmiE5f4_0eUTr5gxnFTErQtI8mL-DAIo1yrw-_9TI6-cf-JOhgPfl7P475Za8SiRg295CUCQXCInMCBh7HV0Bm5QsHzMDYdDQuGMAlEfdVB2cpKwXZ-j9Nlbx_UWeHCHuaKyyHMtGDYd1jp_bce4ix5DdlndH6OuMGQ59DwyXPMWLMgaQ-EkcX7th5TfYTEa0ZiPTEmU3nEvAm04vu2MkolPEvviKmLu1QeYsQhgMMzi17-_8ZZlp3qJWjonoeWNtG4UIqvc3Mt3Lo7p_WKz18w" - }, { - "kty" : "EC", - "use" : "sig", - "crv" : "P-256", - "kid" : "d367d67d-b37f-4b08-81fa-84b4c987afc3_sig_es256", - "x5c" : [ "MIIBdzCCAR6gAwIBAgIhAK2emGoVz5nJlXKsXFMxmTMBD9GmfcrPg3FRxKozPyg3MAoGCCqGSM49BAMCMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjE5WhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE18KafCZYAgursgoHnU1ut2UUV6SKr/kQ44WLt0IzJFXoyz8GtsXvqjzV9rkcHUEkV6AyhyL9Z7sVgn9253jQhaMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMCA0cAMEQCIFURCwsdDwk+OmV2ut1h50EwqZsbjLJ8JOy0GzcbXX/tAiAK6/vJ35TNS7xpO+fGb9ICjn1KzCeGFWMrIsC6eZWzug==" ], - "x" : "18KafCZYAgursgoHnU1ut2UUV6SKr_kQ44WLt0IzJFU", - "y" : "6Ms_BrbF76o81fa5HB1BJFegMoci_We7FYJ_dud40IU", - "exp" : 1599751946863, - "alg" : "ES256" - }, { - "kty" : "EC", - "use" : "sig", - "crv" : "P-384", - "kid" : "6e8830e0-7a8a-4679-8256-663b6890374c_sig_es384", - "x5c" : [ "MIIBtTCCATqgAwIBAgIgERC4xtLgpnMCjW2lXkb1YumMfwcUzpya5JDczd8Cp00wCgYIKoZIzj0EAwMwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA5MDgxNTMyMTlaFw0yMDA5MTAxNTMyMjZaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7K1xIcfy6p3Nv5W4vCIChYsAkLWl4q06TwYWGXlK9NFnNAd/z6QHLf1KKeLCAk6IOT1xhSEJmtLr+dX89JxyJV8pEGPJgb3jAq/kUjAiV53XZgKPKl490K9h/gEYo6qOjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADAKBggqhkjOPQQDAwNpADBmAjEAnYoxgRlKV6wCfkLZfRbtMXaMTk7Cb3IEyVd2/hzOoYRku7f3GWOmYnWHX7QiLzBQAjEAtPC4FqrmU4OSE/htC3d+grKop/cx9fc68Re+lJx8mvV5qbbJ4jsMJRkDvWdtpxxF" ], - "x" : "-ytcSHH8uqdzb-VuLwiAoWLAJC1peKtOk8GFhl5SvTRZzQHf8-kBy39SiniwgJOi", - "y" : "Dk9cYUhCZrS6_nV_PScciVfKRBjyYG94wKv5FIwIled12YCjypePdCvYf4BGKOqj", - "exp" : 1599751946863, - "alg" : "ES384" - }, { - "kty" : "EC", - "use" : "sig", - "crv" : "P-521", - "kid" : "fc52f71c-5677-4621-9b86-5d4264d4cb89_sig_es512", - "x5c" : [ "MIIB/zCCAWCgAwIBAgIgRs3ZEs9bIWkIGKve8Y0hwYKUnjdF5gaNbPKiBUlkiDUwCgYIKoZIzj0EAwQwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA5MDgxNTMyMjBaFw0yMDA5MTAxNTMyMjZaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACetWweGJigofZcb4UBiLdbL7TuFhEfJUXKIQZDau5Gm+2vpxXvwn/++xwB4XbWwRifBzfE04HQk260jc2hovD14wFKMV1KG3S/gRy0uJs4zcC03ZJNvDYseEwU4+wcLf1jipD5tlwLNUXwlK2cQpo8USu+nvkA8dko6Qa6kxd26SfMB6MnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMAoGCCqGSM49BAMEA4GMADCBiAJCAOc7jyzI5I6LoOeSxPqGBOsw1LXEQ9Y5JYy3vQbZnCTMkBp3YNl0kqC5YGeqphfK+kolAHlzXmBEwWJssosXHVpSAkIAg6vBNorRjZxZ9n8j1WJuNQJpw8mcUKi3S9HPtxjaix8WD3PAI9Ale4++2qqcL8IN7+X6cGV555SIrU4t2RKT5/c=" ], - "x" : "nrVsHhiYoKH2XG-FAYi3Wy-07hYRHyVFyiEGQ2ruRpvtr6cV78J__vscAeF21sEYnwc3xNOB0JNutI3NoaLw9eM", - "y" : "AUoxXUobdL-BHLS4mzjNwLTdkk28Nix4TBTj7Bwt_WOKkPm2XAs1RfCUrZxCmjxRK76e-QDx2SjpBrqTF3bpJ8wH", - "exp" : 1599751946863, - "alg" : "ES512" - }, { - "kty" : "RSA", - "e" : "AQAB", - "use" : "sig", - "crv" : "", - "kid" : "d521319b-072f-4ee9-8424-03c36ebf2d73_sig_ps256", - "x5c" : [ "MIIDbDCCAiCgAwIBAgIhAK7FPZIFwZHkUMt7d+iD4lekMBx2XRby5RlTb39cTJppMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIBIDAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMB4XDTIwMDkwODE1MzIyMVoXDTIwMDkxMDE1MzIyNlowITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANND+hdT97J+sPjpLSOggo5x14LmIZVd6To+0sTSrgiJrkBboninj+ks/BJgVbCw0XF/tgHbTq3ieMAFTc9XjXjoL6NxskBfM3Mu6r/4OcTUzWrnm3sQ4IEKx3uYiKI3rxSlLsBmCrfn9GZRuH3dFWdW5i0d63pfeM0OOi7xLhNdbVxRxTsg3n8BzqQXsxTNrYTuOKPnwzrw0M19IQcvRHwY+EbU9z+Yk/14eUhsyshT+IjHQvzKAyHBV/dKLIl2JVjiHt7nxinMasfEaUuxdsXsf2PvWqZbuVtIN2qqO6kPbJdnAqIuL6OyeTTzuwtSi3mxBALVX+Ui1yG/quStSjkCAwEAAaMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiAwIBIAOCAQEAqLCfnuergo+JWjrXWJ4VPWCubuItdtroKY6In8s4nuTAYLctwOAlOn5l95oqetejacIxQkA4AB6pg1hKRKxWWaZiMpYM+PYlwU9lN0IfbPvr9CgYhioRXyPztjXOmt7P1OQpBGFHX2O65CgFz/c/PaA+2MhPtb6nfU4LxPTk7iOJkzJLzeuEPycdIaBO3tCA3hN4o+v2bsEkqQ9tMuxNWMi8raMdFed0oYrOyDgurvIgQDxW50GxJMhERkKT9LRMVZNsUqwr0St5fwJL+9Y1SszZVOLm5fXyiJ/QavOaTlOoZIbSRpqmf3kNAljrNTPkgvLH/T/ebcmLh814dM0tYw==" ], - "exp" : 1599751946863, - "alg" : "PS256", - "n" : "00P6F1P3sn6w-OktI6CCjnHXguYhlV3pOj7SxNKuCImuQFuieKeP6Sz8EmBVsLDRcX-2AdtOreJ4wAVNz1eNeOgvo3GyQF8zcy7qv_g5xNTNauebexDggQrHe5iIojevFKUuwGYKt-f0ZlG4fd0VZ1bmLR3rel94zQ46LvEuE11tXFHFOyDefwHOpBezFM2thO44o-fDOvDQzX0hBy9EfBj4RtT3P5iT_Xh5SGzKyFP4iMdC_MoDIcFX90osiXYlWOIe3ufGKcxqx8RpS7F2xex_Y-9aplu5W0g3aqo7qQ9sl2cCoi4vo7J5NPO7C1KLebEEAtVf5SLXIb-q5K1KOQ" - }, { - "kty" : "RSA", - "e" : "AQAB", - "use" : "sig", - "crv" : "", - "kid" : "ce9ea6f7-6522-4d2f-8ad9-9ce99eb7009e_sig_ps384", - "x5c" : [ "MIIDbDCCAiCgAwIBAgIhAMWm7mGmlN8U/ZBjvkFGZMA5wwOvvasjNBL613iQKTwEMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMDAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMB4XDTIwMDkwODE1MzIyMVoXDTIwMDkxMDE1MzIyNlowITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO1HF1uu5TxhdiMuAiVfyap8t/wZaHKnWWpIO13n8hsg+atAcRLQWGZCtzbZ3N4r2M2clKrICyxvy4eVK5mWYsWsaiMH5XpHmuu6QBLKur7KNIQww13r5236KsTf2Tb7l+4wBQtmo2MN81tT4VWg+gVz7zfvKnqLUHvFhexHOoNvkBAUeq0qxO+FwT9s1sCdKnmeioQBuCxdbFisKTWiulBBtNu6B0EL6BBynnhAQ/3VQhuEe0UFf1tgd8Gzi8HumP/YvYYCwRi15HCmQ1MwJtPRhAn8xgfdCo86yP5Iw5vX3d5AvxwUmf+tumPdPmWiSqsC2z3VTxnOvFvdRjrywa0CAwEAAaMnMCUwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMEEGCSqGSIb3DQEBCjA0oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMAOCAQEAZPXVLMaR97iemBwAS4yUQkHYrtBtfJTIK6qd8H+ZewRjLpek+GHiAyo4gH90xoQICmQoLiOwi8McOG7JFd1Eymg8sV+qNKi4c8Cna/HdOp6ExTGvqYWkz9tGik9OVhIvggWmA0B8H+lXudzqkD+7AZkK/eVbHhMflFEhsCtsTnJ8zGpVmscX7eg97KzEGCAHaNKh/J0N0OVW875p7rIixuOxynPH+3lfBviMVmmIIOqZvd8pO6BIyWxTAS3d7nKsF9QI86HRr/bynUl1qyn9B3BCJT0RCd9byPW5a78xWZk03GA8UJWhV2g2Qt6ZO1A0e68SrHx2uHYIR6aXEU0TrQ==" ], - "exp" : 1599751946863, - "alg" : "PS384", - "n" : "7UcXW67lPGF2Iy4CJV_Jqny3_BlocqdZakg7XefyGyD5q0BxEtBYZkK3Ntnc3ivYzZyUqsgLLG_Lh5UrmZZixaxqIwflekea67pAEsq6vso0hDDDXevnbfoqxN_ZNvuX7jAFC2ajYw3zW1PhVaD6BXPvN-8qeotQe8WF7Ec6g2-QEBR6rSrE74XBP2zWwJ0qeZ6KhAG4LF1sWKwpNaK6UEG027oHQQvoEHKeeEBD_dVCG4R7RQV_W2B3wbOLwe6Y_9i9hgLBGLXkcKZDUzAm09GECfzGB90KjzrI_kjDm9fd3kC_HBSZ_626Y90-ZaJKqwLbPdVPGc68W91GOvLBrQ" - }, { - "kty" : "RSA", - "e" : "AQAB", - "use" : "sig", - "crv" : "", - "kid" : "79871adb-0b4d-4f85-995c-a34b6d1df522_sig_ps512", - "x5c" : [ "MIIDazCCAh+gAwIBAgIgfOQFwOuh1OnHzMeOOcD0m7muXOMvFpAf8pl7GEyJejUwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjIxWhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjsaqXikeYT3wxhGnGcOLsF/i+++Rv3ywZH8TAK4DCdZW0Vuq97YACZq6AF7TWlSrx4ujHkW4jcksqdrFVJCJ3ECS8HT3YutPJgi6s9mJo46dWBD5yZGr6DzdtRGCKeTLl4NOyl7JmYhj0qpHJhujp4R8Ns4znFPaG6QZprj1G7DcKMsJ/vEbRmVJVWoMqOlhpWQNods51b+7WnkKObEpk9m4wl9R4FA98Xsc46IXS8+dwvA9kJVfyVkRSgCjaHA69877+H4EjsCNN1DUS0MrLwliyvu4brLdbROirrjrQ+RIkJQqS/Q573qZW8R53xM8c+IbN0fa4hU2RCirKzC8GQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAA4IBAQAIDS3xGrrY4RboyoSuad/yXOlxelvMZFbHBoYszJcPZX4LvUR0GEJTF+MXFCYjhQmFrd9db2SIpcX2705clK1bq7MIaR7fPYAFeC7Or/8rzsdyCxDdfwM0cOIwZY06Pcmv2zuSFeVXweVU7GOw8GN0lMlkbWPR5DPjWSiLrBrWpNMF0DmoMZ63DzQVF7N/2LEjTA+5Z12PxLijVpPDY1UajB7MJVG78Ls4nnWgiDPdYyInFworv+A5aCqVYgXQ+QFEgSIfJZfr9VeVrJKCjferfnkMNDH3vlWSgEOp1YkQ2OU3hc3Kb1+mI4xiRYAy4ukLhs7KN6AZwYE+cA9URfyl" ], - "exp" : 1599751946863, - "alg" : "PS512", - "n" : "jsaqXikeYT3wxhGnGcOLsF_i---Rv3ywZH8TAK4DCdZW0Vuq97YACZq6AF7TWlSrx4ujHkW4jcksqdrFVJCJ3ECS8HT3YutPJgi6s9mJo46dWBD5yZGr6DzdtRGCKeTLl4NOyl7JmYhj0qpHJhujp4R8Ns4znFPaG6QZprj1G7DcKMsJ_vEbRmVJVWoMqOlhpWQNods51b-7WnkKObEpk9m4wl9R4FA98Xsc46IXS8-dwvA9kJVfyVkRSgCjaHA69877-H4EjsCNN1DUS0MrLwliyvu4brLdbROirrjrQ-RIkJQqS_Q573qZW8R53xM8c-IbN0fa4hU2RCirKzC8GQ" - }, { - "kty" : "RSA", - "e" : "AQAB", - "use" : "enc", - "crv" : "", - "kid" : "b9fbfa5b-e720-4602-88cc-fa25ca49b2f7_enc_rsa1_5", - "x5c" : [ "MIIDBDCCAeygAwIBAgIhANjrub7uPwzxastlEA+yUDinE2aijdIoK4TtWS3zjiYBMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjIyWhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxGv/3QD894qstz20lNiK1btBNz5i6WYxcGiX6oBKP3lU4t2LA3hPf9Kevxbgkcj/2SWdrNA2g0lSWIglb621qfMnz/2C42Bu1bOGEwR2T9HdC/dTN1nmmSEymej5tA5zs3qcxsrRjKBFRcKaktO5WUmoKDZNw+pVKWOr1DY+oQ4enuP/xdZ7JJsccR6487smDmwjNw3DymL388G8cCNri9rF/j4pRX+vJd9VSM8qZDKYk3s4qKkZ8PtJx+tITYPp7Yijw1u1zdEnEcLgZ5gmpCejhjWZAbxyhGahdL78Y7dR/KeL0Ukeo11hUER62KWVH7lSh/Ix2GaAYnqTbxBFHQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBAIiTUPWXODrcpRpvU1xW4NA2upMs5yKsrtPJmIOB07lxqEhX7rm/JXaDmy9sBCWDO4G56WnynXFjKON39w52PKtPBvtVqLVTpaVu5rTGva3Q/IFcRGMMTPr0HTMnuLUOy7tcyqOvcdAZnI/vLH+/ovxMBVC8q0jOms9XSvNMSUwisX/PckWMaCOb1f7Hmu3gLws45f9Tz/AKgnb4MQQ0kH1cQ1KmDpaQmK3OhelHHZ2JjtBJbL5Ig1sEffpySln8ZK07F3CSeeJAOhTr8bz8HyQ7rgTxFrs7oJs9rWbIiVqR138kEWKe8B6JTRujVGwb8zLuff490Jeix64U3mqQebM=" ], - "exp" : 1599751946863, - "alg" : "RSA1_5", - "n" : "xGv_3QD894qstz20lNiK1btBNz5i6WYxcGiX6oBKP3lU4t2LA3hPf9Kevxbgkcj_2SWdrNA2g0lSWIglb621qfMnz_2C42Bu1bOGEwR2T9HdC_dTN1nmmSEymej5tA5zs3qcxsrRjKBFRcKaktO5WUmoKDZNw-pVKWOr1DY-oQ4enuP_xdZ7JJsccR6487smDmwjNw3DymL388G8cCNri9rF_j4pRX-vJd9VSM8qZDKYk3s4qKkZ8PtJx-tITYPp7Yijw1u1zdEnEcLgZ5gmpCejhjWZAbxyhGahdL78Y7dR_KeL0Ukeo11hUER62KWVH7lSh_Ix2GaAYnqTbxBFHQ" - }, { - "kty" : "RSA", - "e" : "AQAB", - "use" : "enc", - "crv" : "", - "kid" : "d86d28c3-ccd5-4d38-8985-f6d6cfbf5688_enc_rsa-oaep", - "x5c" : [ "MIIDAzCCAeugAwIBAgIgGdQU0RWuwHvXO/24IJJNbVPOVcqSja8SfIzdYGtcG10wDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWb3hBdXRoIENBIENlcnRpZmljYXRlczAeFw0yMDA5MDgxNTMyMjNaFw0yMDA5MTAxNTMyMjZaMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKDOUm+qP2hSEiN3jZWa8Nvpm1kzAFGTtcyz6Bhdy4bI2NnKJEc+kQuPNB/+7ovX8jxfFwE/AWfh89QEXJizd4UJ3qfjKTYjmns60b2k8o1iGjkdWaNFzbVWfKgjhkfiobhZL5vZ3c4vYut4M++q7sTWM5cEyBfZlExD0NfS5F7omclnmMs/zb3QzCUrXbikS1qu5+LwIdslx3VrewmuYjlWOGgqK6jIMxJoOvt2OEvHqg4HyC0GMo3X8JUATwidEk9gMn2jJxj27P4P1Ac6TBIVZI/PAAv1fmam/LfMWPIBPRp84ekasCHWTKEThmuWfm3RAipVKyEn/dKqdwa2rDAgMBAAGjJzAlMCMGA1UdJQQcMBoGCCsGAQUFBwMBBggrBgEFBQcDAgYEVR0lADANBgkqhkiG9w0BAQsFAAOCAQEAm8snq5tIpwFRKi9Q1llRkYSWTsa4ToskQjWD9hfo5EJesGBZmsGIRWpWKvT6z5vn06mU966lc3KVT59LPP7dEevl+VRrhN3imjC/QgURg2cn0xZEXB8UbMrfTXdGDlvHyLwkF06wPv7K4lg2bDm8teyrTnVkoMLoWzcIj5LXNREq2Mh2mSM2yCZ9haHBYj42vXhaQXUXe50ChtJP4o+auZA+XGM+veRm6fm4/zKccYsT4W3RjrBtK3pkcjcfzYsSATNwndkRxtKWFWPo6KRf6NGl8C20tq3qFQx3eRzw6QNJmQpjdhTuX03DZkCGfgRUq7WQCF/nvbTdTa22I8TWDg==" ], - "exp" : 1599751946863, - "alg" : "RSA-OAEP", - "n" : "ygzlJvqj9oUhIjd42VmvDb6ZtZMwBRk7XMs-gYXcuGyNjZyiRHPpELjzQf_u6L1_I8XxcBPwFn4fPUBFyYs3eFCd6n4yk2I5p7OtG9pPKNYho5HVmjRc21VnyoI4ZH4qG4WS-b2d3OL2LreDPvqu7E1jOXBMgX2ZRMQ9DX0uRe6JnJZ5jLP8290MwlK124pEtarufi8CHbJcd1a3sJrmI5VjhoKiuoyDMSaDr7djhLx6oOB8gtBjKN1_CVAE8InRJPYDJ9oycY9uz-D9QHOkwSFWSPzwAL9X5mpvy3zFjyAT0afOHpGrAh1kyhE4Zrln5t0QIqVSshJ_3SqncGtqww" - } ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/jwks/jwks_patch.json b/jans-config-api/server/src/test/resources/feature/config/jwks/jwks_patch.json deleted file mode 100644 index af946915832..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/jwks/jwks_patch.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "op": "add", - "path": "/keys/1", - "value": { - "kty": "RSA", - "e": "AQAB", - "use": "sig", - "crv": "", - "kid": "dd570bfb-276a-44aa-a97d-667b57587108_sig_rs256", - "x5c": [ - "MIIDBDCCAeygAwIBAgIhAOviRkmppgF16wC7nMg17Jt4P7lNoLglfLDxLAPYn4J0MA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMMFm94QXV0aCBDQSBDZXJ0aWZpY2F0ZXMwHhcNMjAwOTA4MTUzMjE3WhcNMjAwOTEwMTUzMjI2WjAhMR8wHQYDVQQDDBZveEF1dGggQ0EgQ2VydGlmaWNhdGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzj1NEHyGk/ywG25py2s/zVVrRggzRO0jE6VOUvqUzsEJwt1aszQ4onFu6vgtjNwq2ZmEFZbw1Jw7dlz4Xrdj12pQlLVuEhyVaTziQp3LvspqxyACHQb8XSKFdKZaa1eBF8PGN5zDN/d+tIrAZYnQS2gH8BoPIuB3Z9AoCLTzifnPvmOwW/e+/Wags/ApZiEfF2Po0InV5NeJAyoIpaGhlwjqqOWXm/GpCASAk9ZD8Ebnmy9RM71zDCgmvq/hPueKnbNTZdQ3TQdzEuSwxbWEHu16v5MbF7QtNzvFSFlllhgwqI2ccEljDbs18j3DUS2B1VTTAr/DLR3SVyCYbKBbRQIDAQABoycwJTAjBgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQELBQADggEBADaqrfVH1FX0FLp99TG9fHOiOMD12vsIPANb9QbIADineFrSvUI3zIX56PpvMT+EApaLPcIYSwG1YziWT1oGDGkfyinofSRGl4JcC63slChUBfjlBZlXTIlc7CJA7CfzO6BW3SvO0GPF0NStCUD9Ou4oOVaIc3XrPzhIAp71cF9iLFnQUK1hiD9NhQUm5v2Nq+sQdjAxSlqigXnc+rB9+V8snCkr9x9q1cysq1ZyCRT55psa53Irqtc50T2PHA6kyzEVW51+yFaZa8z+WMoofr6ndx2DFI7n5+8jFGs9WoP+/zV8E/XK61iy+EdXVjXQYVcArjEzeIahn8QOd/hUcfo=" - ], - "exp": 1599751946863, - "alg": "RS256", - "n": "zj1NEHyGk_ywG25py2s_zVVrRggzRO0jE6VOUvqUzsEJwt1aszQ4onFu6vgtjNwq2ZmEFZbw1Jw7dlz4Xrdj12pQlLVuEhyVaTziQp3LvspqxyACHQb8XSKFdKZaa1eBF8PGN5zDN_d-tIrAZYnQS2gH8BoPIuB3Z9AoCLTzifnPvmOwW_e-_Wags_ApZiEfF2Po0InV5NeJAyoIpaGhlwjqqOWXm_GpCASAk9ZD8Ebnmy9RM71zDCgmvq_hPueKnbNTZdQ3TQdzEuSwxbWEHu16v5MbF7QtNzvFSFlllhgwqI2ccEljDbs18j3DUS2B1VTTAr_DLR3SVyCYbKBbRQ" - } - } -] - diff --git a/jans-config-api/server/src/test/resources/feature/config/message/message.feature b/jans-config-api/server/src/test/resources/feature/config/message/message.feature deleted file mode 100644 index f3fac9eef5e..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/message/message.feature +++ /dev/null @@ -1,176 +0,0 @@ - -Feature: Verify Message configuration endpoint - - Background: - * def mainUrl = messageUrl - - @message-get-error - Scenario: Retrieve Message configuration without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - @message-get - Scenario: Retrieve Message configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @message-patch - Scenario: Patch messageProviderType configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.messageProviderType - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/messageProviderType\", \"value\":\""+response.messageProviderType+"\" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @message-patch - Scenario: Patch redisConfiguration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.redisConfiguration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/redisConfiguration\", \"value\":"+response.redisConfiguration+" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @message-patch - Scenario: Patch postgresConfiguration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.postgresConfiguration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/postgresConfiguration\", \"value\":"+response.postgresConfiguration+" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @message-get-redis - Scenario: Retrieve Redis message configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'redis' - When method GET - Then status 200 - And print response - And assert response.length != null - - @message-put-redis - Scenario: Update Redis message configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'redis' - When method GET - Then status 200 - Then print response - Then def first_response = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'redis' - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - @message-patch-redis - Scenario: Patch Redis message configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'redis' - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/servers\", \"value\":\""+response.servers+"\"} ]" - And path 'redis' - Then print request - When method PATCH - Then status 200 - And print response - - @message-get-postgres - Scenario: Retrieve Postgres message configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'postgres' - When method GET - Then status 200 - And print response - And assert response.length != null - - @message-put-postgres - Scenario: Update Postgres message configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'postgres' - When method GET - Then status 200 - Then print response - Then def first_response = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'postgres' - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - @message-patch-postgres - Scenario: Patch Postgres message configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'postgres' - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/dbSchemaName\", \"value\":\""+response.dbSchemaName+"\"} ]" - And path 'postgres' - Then print request - When method PATCH - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/org/org-config.feature b/jans-config-api/server/src/test/resources/feature/config/org/org-config.feature deleted file mode 100644 index 756025630fe..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/org/org-config.feature +++ /dev/null @@ -1,45 +0,0 @@ - -Feature: Verify Organization configuration endpoint - - Background: - * def mainUrl = org_configuration_url - - @auth-config-get-error - Scenario: Retrieve Organization configuration without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - @auth-config-get - Scenario: Retrieve Organization configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @auth-config-patch - Scenario: Patch Organization configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And print response.description - #And def request_body = (response.description == null ? "[ {\"op\":\"add\", \"path\": \"/description\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/description\", \"value\":"+response.description+" } ]") - And def request_body = (response.description == null ? "[ {\"op\":\"add\", \"path\": \"/description\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/description\", \"value\":\""+response.description+"\" } ]") - And print request_body - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/authenticationFilters.json b/jans-config-api/server/src/test/resources/feature/config/properties/authenticationFilters.json deleted file mode 100644 index edb80f4ccf5..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/authenticationFilters.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "authenticationFilters": [ - { - "filter": "(&(mail=*{0}*)(inum={1}))", - "bind": false, - "bindPasswordAttribute": "", - "baseDn": "ou=people,o=gluu" - }, - { - "filter": "uid={0}", - "bind": true, - "bindPasswordAttribute": "pwd", - "baseDn": "ou=people,o=gluu" - } - , - { - "filter": "uid={0}", - "bind": false, - "bindPasswordAttribute": "pwd", - "baseDn": "ou=people,o=gluu,uid=pujavs" - } - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/backchannel/backchannel.feature b/jans-config-api/server/src/test/resources/feature/config/properties/backchannel/backchannel.feature deleted file mode 100644 index 8365e9d3a0f..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/backchannel/backchannel.feature +++ /dev/null @@ -1,49 +0,0 @@ -@ignore -Feature: Verify backchannel configuration endpoint - -Background: - * def mainUrl = backchannelUrl - - @backchannel-get - Scenario: Retrieve backchannel configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @backchannel-put - Scenario: Update backchannel configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - #And print response - Then def first_response = response - #And print first_response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 200 - And print response - - - @error - Scenario: Error case while updating backchannel configuration min validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.backchannelAuthenticationResponseExpiresIn = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/ciba/ciba.feature b/jans-config-api/server/src/test/resources/feature/config/properties/ciba/ciba.feature deleted file mode 100644 index d4d0a004b1d..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/ciba/ciba.feature +++ /dev/null @@ -1,221 +0,0 @@ -@ignore -Feature: Verify CIBA configuration endpoint - - Background: - * def mainUrl = cibaUrl - - @ignore - @ciba-put-json - Scenario: Update CIBA configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('ciba.json') - When method PUT - Then status 200 - And print response - And assert response.length != null - - @ciba-get - Scenario: Retrieve CIBA configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @ciba-put - Scenario: Update CIBA configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - #Then set result.cibaMaxExpirationTimeAllowedSec = 1000 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - - @ciba-error - Scenario: apiKey configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.apiKey = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @ciba-error - Scenario: authDomain configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.authDomain = '' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @ciba-error - Scenario: databaseURL configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.databaseURL = '' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @ciba-error - Scenario: projectId configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.projectId = '' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @ciba-error - Scenario: storageBucket configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.storageBucket = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @ciba-error - Scenario: messagingSenderId configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.messagingSenderId = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @ciba-error - Scenario: appId configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.appId = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @ciba-error - Scenario: notificationUrl configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.notificationUrl = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @ciba-error - Scenario: notificationKey configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.notificationKey = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @ciba-error - Scenario: publicVapidKey configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.publicVapidKey = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/ciba/ciba.json b/jans-config-api/server/src/test/resources/feature/config/properties/ciba/ciba.json deleted file mode 100644 index a2cb6db256c..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/ciba/ciba.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "apiKey": "AIzaSyDwJtxZV-ApPlApt7HdXkleEZhseURgzHI", - "authDomain": "api-project-561176510817.firebaseapp.com", - "databaseURL": "https://api-project-561176510817.firebaseio.com", - "projectId": "api-project-561176510817", - "storageBucket": "api-project-561176510817.appspot.com", - "messagingSenderId": "561176510817", - "appId": "1:561176510817:web:8e327e72cd49e8d5", - "notificationUrl": "https://fcm.googleapis.com/fcm/send", - "notificationKey": "csyBj39m4uPHbs2oHeTw40KfgCiUbgxBKPPz6ZXgkpF4EMQvMOAHAoM7up1UlfHk9GD5QnqdMktzjpmEuKd5xlD2kRDhwMIJ8JYbTA5+Cv39CxuWOiFuuMPJZqg+VqT4X7Ne9sXvm3UtMe8PxmRAoXlSZ1kElT/AuQvC2+YyiqlmLpXoCU01waEtIajltap5TrFuXvAvkmYJjvCkFIdWsg==", - "publicVapidKey": "BOH-FKi3U-7cr5Wv3WeS8RJXXaGpf1R7tlgKSOvYCbFrJRaJER4kI_0xCN", - "cibaMaxExpirationTimeAllowedSec": 1800, - "cibaGrantLifeExtraTimeSec": 180, -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/clientAuthenticationFilters.json b/jans-config-api/server/src/test/resources/feature/config/properties/clientAuthenticationFilters.json deleted file mode 100644 index 6aff8183e13..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/clientAuthenticationFilters.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "clientAuthenticationFilters": [ - { - "filter": "myCustomAttr1={0}", - "bindPasswordAttribute": "", - "baseDn": "ou=clients,o=gluu" - }, - { - "filter": "myCustomAttr2={0}", - "bindNameAttribute": "", - "baseDn": "ou=clients,o=gluu,uid=pujavs" - } - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/cors/cors.feature b/jans-config-api/server/src/test/resources/feature/config/properties/cors/cors.feature deleted file mode 100644 index 54a0f75f17c..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/cors/cors.feature +++ /dev/null @@ -1,34 +0,0 @@ -@ignore -Feature: Verify Cors configuration filter endpoint - - Background: - * def mainUrl = corsUrl - - @cors-get - Scenario: Retrieve Cors configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @cors-put - Scenario: Update Cors configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - #And print response - Then def first_response = response - #And print first_response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/cors/cors.json b/jans-config-api/server/src/test/resources/feature/config/properties/cors/cors.json deleted file mode 100644 index 9b6d288da54..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/cors/cors.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "corsSupportCredentials": true, - "corsPreflightMaxAge": 1800, - "corsEnabled": true, - "corsAllowedMethods": "GET,POST,HEAD,OPTIONS", - "filterName": "CorsFilter", - "corsAllowedHeaders": "Origin,Authorization,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers", - "corsLoggingEnabled": false, - "corsAllowedOrigins": "*", - "corsExposedHeaders": "", - "corsRequestDecorate": true - }, - { - "corsSupportCredentials": false, - "corsPreflightMaxAge": -1, - "corsEnabled": true, - "corsAllowedMethods": "PUT", - "filterName": "CorsFilter_2", - "corsAllowedHeaders": "Access-Control-Request-Headers", - "corsLoggingEnabled": false, - "corsAllowedOrigins": "*", - "corsExposedHeaders": "", - "corsRequestDecorate": true - } -] \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/custom.json b/jans-config-api/server/src/test/resources/feature/config/properties/custom.json deleted file mode 100644 index a2cb6db256c..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/custom.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "apiKey": "AIzaSyDwJtxZV-ApPlApt7HdXkleEZhseURgzHI", - "authDomain": "api-project-561176510817.firebaseapp.com", - "databaseURL": "https://api-project-561176510817.firebaseio.com", - "projectId": "api-project-561176510817", - "storageBucket": "api-project-561176510817.appspot.com", - "messagingSenderId": "561176510817", - "appId": "1:561176510817:web:8e327e72cd49e8d5", - "notificationUrl": "https://fcm.googleapis.com/fcm/send", - "notificationKey": "csyBj39m4uPHbs2oHeTw40KfgCiUbgxBKPPz6ZXgkpF4EMQvMOAHAoM7up1UlfHk9GD5QnqdMktzjpmEuKd5xlD2kRDhwMIJ8JYbTA5+Cv39CxuWOiFuuMPJZqg+VqT4X7Ne9sXvm3UtMe8PxmRAoXlSZ1kElT/AuQvC2+YyiqlmLpXoCU01waEtIajltap5TrFuXvAvkmYJjvCkFIdWsg==", - "publicVapidKey": "BOH-FKi3U-7cr5Wv3WeS8RJXXaGpf1R7tlgKSOvYCbFrJRaJER4kI_0xCN", - "cibaMaxExpirationTimeAllowedSec": 1800, - "cibaGrantLifeExtraTimeSec": 180, -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/dynamic/registration/registration.feature b/jans-config-api/server/src/test/resources/feature/config/properties/dynamic/registration/registration.feature deleted file mode 100644 index 8dbf5f898ae..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/dynamic/registration/registration.feature +++ /dev/null @@ -1,129 +0,0 @@ -@ignore -Feature: Verify DynamicRegistration configuration endpoint - - Background: - * def mainUrl = dynamicRegistrationUrl - - @ignore - @dynamicRegistration-put-json - Scenario: Update Dynamic Registration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('registration.json') - When method PUT - Then status 200 - And print response - And assert response.length != null - - @dynamicRegistration-get - Scenario: Retrieve Dynamic Registration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @dynamicRegistration-put - Scenario: Update Dynamic Registration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - @error - Scenario: dynamicRegistrationCustomObjectClass configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.dynamicRegistrationCustomObjectClass = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @error - Scenario: defaultSubjectType configuration cannot be other than public or pairwise - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.defaultSubjectType = 'abc' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @error - Scenario: dynamicRegistrationExpirationTime configuration should be int and not decimal - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.dynamicRegistrationExpirationTime = 20.5 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @error - Scenario: grantTypesSupportedByDynamicRegistration configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.grantTypesSupportedByDynamicRegistration = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @error - Scenario: dynamicRegistrationCustomAttributes configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.dynamicRegistrationCustomAttributes = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/dynamic/registration/registration.json b/jans-config-api/server/src/test/resources/feature/config/properties/dynamic/registration/registration.json deleted file mode 100644 index 2054ae09418..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/dynamic/registration/registration.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "dynamicRegistrationExpirationTime": 10, - "dynamicRegistrationScopesParamEnabled": true, - "dynamicRegistrationPersistClientAuthorizations": true, - "returnClientSecretOnRead": false, - "dynamicRegistrationPasswordGrantTypeEnabled": false, - "trustedClientEnabled": true, - "dynamicRegistrationCustomObjectClass": "MyDynamicRegistrationCustomObject", - "grantTypesSupportedByDynamicRegistration": [ - "REFRESH_TOKEN", - "OXAUTH_UMA_TICKET", - "IMPLICIT", - "CLIENT_CREDENTIALS", - "AUTHORIZATION_CODE" - ], - "dynamicRegistrationCustomAttributes": [ - "jansTrustedClnt" - ], - "defaultSubjectType": "pairwise", - "legacyDynamicRegistrationScopeParam": false -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/endpoints/endpoints.feature b/jans-config-api/server/src/test/resources/feature/config/properties/endpoints/endpoints.feature deleted file mode 100644 index 8af79c179f4..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/endpoints/endpoints.feature +++ /dev/null @@ -1,274 +0,0 @@ -@ignore -Feature: Verify jans-auth available endpoints. - - Background: - * def mainUrl = endpointsUrl - - @ignore - @endpoints-put-json - Scenario: Update available endpoints. - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('endpoints.json') - When method PUT - Then status 200 - And print response - And assert response.length != null - - @endpoints-get - Scenario: Retrieve available endpoints. - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @endpoints-put - Scenario: Update available endpoints. - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - @endpoints-error - Scenario: baseEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.baseEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: authorizationEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.authorizationEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: tokenEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.tokenEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: tokenRevocationEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.tokenRevocationEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: userInfoEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.userInfoEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: clientInfoEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.clientInfoEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: endSessionEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.endSessionEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: registrationEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.registrationEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: openIdDiscoveryEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.openIdDiscoveryEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: openIdConfigurationEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.openIdConfigurationEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: idGenerationEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.idGenerationEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @endpoints-error - Scenario: introspectionEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.introspectionEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @endpoints-error - Scenario: umaConfigurationEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.umaConfigurationEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/endpoints/endpoints.json b/jans-config-api/server/src/test/resources/feature/config/properties/endpoints/endpoints.json deleted file mode 100644 index f8a728bea00..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/endpoints/endpoints.json +++ /dev/null @@ -1,18 +0,0 @@ - { - "tokenRevocationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/revoke", - "introspectionEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/introspection", - "umaConfigurationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/uma2-configuration", - "clientInfoEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/clientinfo", - "authorizationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/authorize", - "authorizationChallengeEndpoint":"https://pujavs3.infinity.com/jans-auth/restv1/authorize-challenge", - "backchannelAuthenticationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/bc-authorize", - "baseEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1", - "tokenEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/token", - "endSessionEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/end_session", - "idGenerationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/id", - "backchannelDeviceRegistrationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/bc-deviceRegistration", - "openIdDiscoveryEndpoint": "https://pujavs3.infinity.com/.well-known/webfinger", - "openIdConfigurationEndpoint": "https://pujavs3.infinity.com/.well-known/openid-configuration", - "userInfoEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/userinfo", - "registrationEndpoint": "https://pujavs3.infinity.com/jans-auth/restv1/register" -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/expiration/expiration.feature b/jans-config-api/server/src/test/resources/feature/config/properties/expiration/expiration.feature deleted file mode 100644 index d1fd52a9230..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/expiration/expiration.feature +++ /dev/null @@ -1,61 +0,0 @@ -@ignore -Feature: Verify Expiration Notificator configuration endpoint - - Background: - * def mainUrl = expirationUrl - - @expiration-get - Scenario: Retrieve Expiration Notificator configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @expiration-put - Scenario: Update Expiration Notificator configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - #And print response - Then def first_response = response - #And print first_response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 200 - And print response - - @error - Scenario: Error case for expirationNotificatorMapSizeLimit configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.expirationNotificatorMapSizeLimit = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - @error - Scenario: Error case for expirationNotificatorIntervalInSeconds configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.expirationNotificatorIntervalInSeconds = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/expiration/expiration.json b/jans-config-api/server/src/test/resources/feature/config/properties/expiration/expiration.json deleted file mode 100644 index 872403ffbd6..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/expiration/expiration.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "expirationNotificatorIntervalInSeconds": 600, - "expirationNotificatorEnabled": false, - "expirationNotificatorMapSizeLimit": 100000 -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/grant/grant.feature b/jans-config-api/server/src/test/resources/feature/config/properties/grant/grant.feature deleted file mode 100644 index 479b1e16864..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/grant/grant.feature +++ /dev/null @@ -1,44 +0,0 @@ -@ignore -Feature: Verify supported Grant Type configuration endpoint - - Background: - * def mainUrl = grantUrl - - @grant-get - Scenario: Retrieve Grant Type configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @grant-put - Scenario: Update Grant Type configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('grant.json') - When method PUT - Then status 200 - And print response - And assert response.length != null - - - @error - Scenario: Error case while updating grantTypesSupported configuration min validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.grantTypesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/grant/grant.json b/jans-config-api/server/src/test/resources/feature/config/properties/grant/grant.json deleted file mode 100644 index 20e6e15282b..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/grant/grant.json +++ /dev/null @@ -1,10 +0,0 @@ - { - "grantTypesSupported": [ - "IMPLICIT", - "AUTHORIZATION_CODE", - "REFRESH_TOKEN", - "RESOURCE_OWNER_PASSWORD_CREDENTIALS", - "OXAUTH_UMA_TICKET", - "CLIENT_CREDENTIALS" - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/idToken/idToken.feature b/jans-config-api/server/src/test/resources/feature/config/properties/idToken/idToken.feature deleted file mode 100644 index 480110f3dd9..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/idToken/idToken.feature +++ /dev/null @@ -1,93 +0,0 @@ -@ignore -Feature: Verify idToken configuration endpoint - - Background: - * def mainUrl = idTokenUrl - - @idtoken-put-json - Scenario: Update idToken configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('idToken.json') - When method PUT - Then status 200 - And print response - - @idtoken-get - Scenario: Retrieve idToken configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @idtoken-put - Scenario: Update idToken configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - @error - Scenario: idTokenSigningAlgValuesSupported configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.idTokenSigningAlgValuesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @error - Scenario: idTokenEncryptionAlgValuesSupported configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.idTokenEncryptionAlgValuesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @error - Scenario: idTokenEncryptionEncValuesSupported configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.idTokenEncryptionEncValuesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/idToken/idToken.json b/jans-config-api/server/src/test/resources/feature/config/properties/idToken/idToken.json deleted file mode 100644 index 02d916a30be..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/idToken/idToken.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "idTokenSigningAlgValuesSupported": [ - "none", - "HS256", - "HS384", - "HS512", - "RS256", - "RS384", - "RS512", - "ES256", - "ES384", - "ES512" - ], - "idTokenEncryptionAlgValuesSupported": [ - "RSA1_5", - "RSA-OAEP", - "A128KW", - "A256KW" - ], - "idTokenEncryptionEncValuesSupported": [ - "A128CBC+HS256", - "A256CBC+HS512", - "A128GCM", - "A256GCM" - ] -} diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/janssenpkcs/janssenpkcs.feature b/jans-config-api/server/src/test/resources/feature/config/properties/janssenpkcs/janssenpkcs.feature deleted file mode 100644 index a558ca8cbd6..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/janssenpkcs/janssenpkcs.feature +++ /dev/null @@ -1,33 +0,0 @@ -@ignore -Feature: Verify JanssenPKCS configuration endpoint - - Background: - * def mainUrl = janssenPKCSUrl - - @janssenPKCS-get - Scenario: Retrieve JanssenPKCS configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @janssenPKCS-put - Scenario: Update JanssenPKCS configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/keys/regen/regen.feature b/jans-config-api/server/src/test/resources/feature/config/properties/keys/regen/regen.feature deleted file mode 100644 index e4edba692d2..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/keys/regen/regen.feature +++ /dev/null @@ -1,38 +0,0 @@ -@ignore -Feature: Verify Key Regeneration Resource endpoint - - Background: - * def mainUrl = keyRegenUrl - - @key-regen-get - Scenario: Retrieve Key Regeneration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @key-regen-put - Scenario: Update Key Regeneration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('regen.json') - When method PUT - Then status 200 - And print response - And assert response.length != null - - @error - Scenario: Error case for keyRegenerationInterval configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - Then def request_json = read('regen.json') - Then set request_json.keyRegenerationInterval = 0 - #And print request_json - And request request_json - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/keys/regen/regen.json b/jans-config-api/server/src/test/resources/feature/config/properties/keys/regen/regen.json deleted file mode 100644 index 9a655784798..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/keys/regen/regen.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "defaultSignatureAlgorithm": "RS256", - "keyRegenerationInterval": 48, - "keyRegenerationEnabled": true -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/metrics/metrics.feature b/jans-config-api/server/src/test/resources/feature/config/properties/metrics/metrics.feature deleted file mode 100644 index 5c686775283..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/metrics/metrics.feature +++ /dev/null @@ -1,66 +0,0 @@ -@ignore -Feature: Verify Metrics configuration endpoint - - Background: - * def mainUrl = metricsUrl - - @metrics-get - Scenario: Retrieve metrics configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @metrics-put - Scenario: Update metrics configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - @error - Scenario: metricReporterKeepDataDays cannot be less than 1 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.metricReporterKeepDataDays = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - @error - Scenario: metricReporterInterval cannot be less than 1 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.metricReporterInterval = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/openid/config/config.feature b/jans-config-api/server/src/test/resources/feature/config/properties/openid/config/config.feature deleted file mode 100644 index 3ee257285ad..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/openid/config/config.feature +++ /dev/null @@ -1,287 +0,0 @@ -@ignore -Feature: Verify OpenId configuration endpoint - - Background: - * def mainUrl = openidUrl - - @openid-get - Scenario: Retrieve OpenId configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @openid-put - Scenario: Update OpenId configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - #And print response - Then def first_response = response - #And print first_response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 200 - And print response - - - @error - Scenario: Error case for oxOpenIdConnectVersion configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.oxOpenIdConnectVersion = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - @error - Scenario: Error case for issuer configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.issuer = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - @error - Scenario: Error case for jwksUri configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.jwksUri = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for tokenEndpointAuthMethodsSupported configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.tokenEndpointAuthMethodsSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for tokenEndpointAuthSigningAlgValuesSupported configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.tokenEndpointAuthSigningAlgValuesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for serviceDocumentation configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.serviceDocumentation = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for uiLocalesSupported configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.uiLocalesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for opPolicyUri configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.opPolicyUri = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for opTosUri configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.opTosUri = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for checkSessionIFrame configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.checkSessionIFrame = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for displayValuesSupported configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.displayValuesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for claimTypesSupported configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.claimTypesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for claimsLocalesSupported configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.claimsLocalesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for idTokenTokenBindingCnfValuesSupported configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.idTokenTokenBindingCnfValuesSupported = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for spontaneousScopeLifetime configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.spontaneousScopeLifetime = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for openidSubAttribute configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.openidSubAttribute = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/openid/config/config.json b/jans-config-api/server/src/test/resources/feature/config/properties/openid/config/config.json deleted file mode 100644 index 98804774ef5..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/openid/config/config.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "openidSubAttribute": "inum", - "tokenEndpointAuthSigningAlgValuesSupported": [ - "HS256", - "HS384", - "HS512", - "RS256", - "RS384", - "RS512", - "ES256", - "ES384", - "ES512" - ], - "claimsLocalesSupported": [ - "en" - ], - "keepAuthenticatorAttributesOnAcrChange": false, - "checkSessionIFrame": "https://pujavs3.infinity.com/jans-auth/opiframe.htm", - "clientWhiteList": [ - "*" - ], - "removeRefreshTokensForClientOnLogout": true, - "jwksUri": "https://pujavs3.infinity.com/jans-auth/restv1/jwks", - "customHeadersWithAuthorizationResponse": true, - "displayValuesSupported": [ - "page", - "popup" - ], - "issuer": "https://pujavs3.infinity.com", - "clientBlackList": [ - "*.attacker.com/*" - ], - "forceOfflineAccessScopeToEnableRefreshToken": true, - "deviceAuthzTokenPollInterval": 0, - "invalidateSessionCookiesAfterAuthorizationFlow": false, - "oxOpenIdConnectVersion": "openidconnect-1.0", - "openidScopeBackwardCompatibility": true, - "legacyIdTokenClaims": true, - "endSessionWithAccessToken": false, - "idTokenTokenBindingCnfValuesSupported": [ - "tbh" - ], - "serviceDocumentation": "http://gluu.org/docs", - "frontChannelLogoutSessionSupported": true, - "spontaneousScopeLifetime": 86400, - "forceIdTokenHintPrecense": false, - "rejectEndSessionIfIdTokenExpired": false, - "allowEndSessionWithUnmatchedSid": false, - "claimsParameterSupported": false, - "claimTypesSupported": [ - "normal" - ], - "deviceAuthzRequestExpiresIn": 0, - "requestUriParameterSupported": true, - "uiLocalesSupported": [ - "en", - "bg", - "de", - "es", - "fr", - "it", - "ru", - "tr" - ], - "useCacheForAllImplicitFlowObjects": false, - "requireRequestUriRegistration": false, - "skipAuthorizationForOpenIdScopeAndPairwiseId": false, - "opPolicyUri": "http://ox.gluu.org/doku.php?id=jans-auth:policy", - "opTosUri": "http://ox.gluu.org/doku.php?id=jans-auth:tos", - "introspectionAccessTokenMustHaveUmaProtectionScope": false, - "requestParameterSupported": true, - "tokenEndpointAuthMethodsSupported": [ - "client_secret_basic", - "client_secret_post", - "client_secret_jwt", - "private_key_jwt" - ], - "allowPostLogoutRedirectWithoutValidation": false -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/pairwise/pairwise.feature b/jans-config-api/server/src/test/resources/feature/config/properties/pairwise/pairwise.feature deleted file mode 100644 index 33441fb2136..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/pairwise/pairwise.feature +++ /dev/null @@ -1,103 +0,0 @@ -@ignore -Feature: Verify Pairwise configuration endpoint - - Background: - * def mainUrl = pairwiseUrl - - @pairwise-get - Scenario: Retrieve pairwise configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @pairwise-put - Scenario: Update pairwise configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - #Then set result.pairwiseIdType = 'algorithmic' - #Then set result.pairwiseCalculationKey = 'YQmxW1ciznJW0SojsddI5ksk' - #Then set result.pairwiseCalculationSalt = 'xewqsr9U3bO7HRAJYmu25' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - @error - Scenario: pairwiseIdType configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.pairwiseIdType = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @error - Scenario: pairwiseIdType configuration cannot be other than persistent or algorithmic - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.pairwiseIdType = 'xyz' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @error - Scenario: pairwiseCalculationKey configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.pairwiseCalculationKey = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @error - Scenario: pairwiseCalculationSalt configuration cannot be null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.pairwiseCalculationSalt = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/properties.feature b/jans-config-api/server/src/test/resources/feature/config/properties/properties.feature deleted file mode 100644 index db9c9c33a54..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/properties.feature +++ /dev/null @@ -1,344 +0,0 @@ - -Feature: Verify Auth configuration endpoint - - Background: - * def mainUrl = authConfigurationUrl - - @auth-config-get-error - Scenario: Retrieve Auth configuration without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - @auth-config-get - Scenario: Retrieve Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @ignore - @auth-config-get-persistence-details - Scenario: Get Persistence details - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And path 'persistence' - Then print url - When method GET - Then status 200 - And print response - - @auth-config-dcr-patch - Scenario: Patch dcrSignatureValidationEnabled configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - #And request "[ {\"op\":\"replace\", \"path\": \"/dcrSignatureValidationEnabled\", \"value\": "+(response.dcrSignatureValidationEnabled == null ? false : response.dcrSignatureValidationEnabled)+" } ,{\"op\":\"replace\", \"path\": \"/dcrSignatureValidationSoftwareStatementJwksURIClaim\", \"value\": "+(response.dcrSignatureValidationSoftwareStatementJwksURIClaim == null ? null : response.dcrSignatureValidationSoftwareStatementJwksURIClaim)+" } ,{\"op\":\"replace\", \"path\": \"/dcrSignatureValidationSoftwareStatementJwksClaim\", \"value\": \+(response.dcrSignatureValidationSoftwareStatementJwksClaim == null ? null : response.dcrSignatureValidationSoftwareStatementJwksClaim)+} ,{\"op\":\"replace\", \"path\": \"/dcrSignatureValidationJwksUri\", \"value\": +(response.dcrSignatureValidationJwksUri == null ? null : response.dcrSignatureValidationJwksUri)+},{\"op\":\"replace\", \"path\": \"/dcrSignatureValidationJwks\", \"value\": +(response.dcrSignatureValidationJwks == null ? null : response.dcrSignatureValidationJwks)+} }, {\"op\":\"replace\", \"path\": \"/dcrAuthorizationWithClientCredentials\", \"value\": +(response.dcrAuthorizationWithClientCredentials == null ? false : response.dcrAuthorizationWithClientCredentials)+" }]" - And def request_body = (response.dcrSignatureValidationEnabled == null ? "[ {\"op\":\"add\", \"path\": \"/dcrSignatureValidationEnabled\", \"value\":false } ]" : "[ {\"op\":\"replace\", \"path\": \"/dcrSignatureValidationEnabled\", \"value\":"+response.dcrSignatureValidationEnabled+" } ]") - And print 'request_body ='+request_body - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - Scenario: Patch dcrSignatureValidationSoftwareStatementJwksURIClaim configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And def request_body = (response.dcrSignatureValidationSoftwareStatementJwksURIClaim == null ? "[ {\"op\":\"add\", \"path\": \"/dcrSignatureValidationSoftwareStatementJwksURIClaim\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/dcrSignatureValidationSoftwareStatementJwksURIClaim\", \"value\":\""+response.dcrSignatureValidationSoftwareStatementJwksURIClaim+"\" } ]") - And print 'request_body ='+request_body - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-softwareStatementValidationType-patch - Scenario: Patch softwareStatementValidationType Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - #And request "[ {\"op\":\"replace\", \"path\": \"/softwareStatementValidationType\", \"value\": +(response.softwareStatementValidationType == null ? null : response.softwareStatementValidationType)+ } ,{\"op\":\"replace\", \"path\": \"/softwareStatementValidationClaimName\", \"value\": +(response.softwareStatementValidationClaimName == null ? null : response.softwareStatementValidationClaimName)+ } ]" - And def request_body = (response.softwareStatementValidationType == null ? "[ {\"op\":\"add\", \"path\": \"/softwareStatementValidationType\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/softwareStatementValidationType\", \"value\":\""+response.softwareStatementValidationType+"\" } ]") - And print 'request_body ='+request_body - And request request_body - Then print request - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-cleanServiceBaseDns-patch - Scenario: Patch cleanServiceBaseDns Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And def request_body = (response.cleanServiceBaseDns == null ? "[ {\"op\":\"add\", \"path\": \"/cleanServiceBaseDns\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/cleanServiceBaseDns\", \"value\":"+response.cleanServiceBaseDns+" } ]") - And print 'request_body ='+request_body - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-statistical-patch - Scenario: Patch statistical Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/statTimerIntervalInSeconds\", \"value\": "+response.statTimerIntervalInSeconds+" },{\"op\":\"replace\", \"path\": \"/statWebServiceIntervalLimitInSeconds\", \"value\": "+response.statWebServiceIntervalLimitInSeconds+" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch - Scenario: Patch loggingLevel Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And request "[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]" - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch - Scenario: Patch clientBlackList Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - #And request "[ {\"op\":\"replace\", \"path\": \"/clientBlackList\", \"value\": ['/*.attacker.com/*','/*.hackers.com/*']\" } ]" - And def request_body = (response.clientBlackList == null ? "[ {\"op\":\"add\", \"path\": \"/clientBlackList\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/clientBlackList\", \"value\":"+response.clientBlackList+" } ]") - And print 'request_body ='+request_body - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch - Scenario: Patch clientAuthenticationFilters Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - #And request "[ {\"op\":\"replace\", \"path\": \"/clientAuthenticationFilters\", \"value\": read('clientAuthenticationFilters.json')\" } ]" - And def request_body = (response.clientAuthenticationFilters == null ? "[ {\"op\":\"add\", \"path\": \"/clientAuthenticationFilters\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/clientAuthenticationFilters\", \"value\":"+response.clientAuthenticationFilters+" } ]") - And print 'request_body ='+request_body - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch - Scenario: Patch authenticationFilters Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And def request_body = (response.authenticationFilters == null ? "[ {\"op\":\"add\", \"path\": \"/authenticationFilters\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/authenticationFilters\", \"value\":"+response.authenticationFilters+"} ]") - And print 'request_body ='+request_body - And request request_body - Then print request - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch - Scenario: Patch keyAlgsAllowedForGeneration Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - #And def request_body = (response.keyAlgsAllowedForGeneration == null ? "[ {\"op\":\"add\", \"path\": \"/keyAlgsAllowedForGeneration\", \"value\":[\"RS256\"\,\"PS256\"] } ]" : "[ {\"op\":\"replace\", \"path\": \"/keyAlgsAllowedForGeneration\", \"value\":"+response.keyAlgsAllowedForGeneration+"} ]") - And def request_body = (response.keyAlgsAllowedForGeneration == null ? "[ {\"op\":\"add\", \"path\": \"/keyAlgsAllowedForGeneration\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/keyAlgsAllowedForGeneration\", \"value\":"+response.keyAlgsAllowedForGeneration+"} ]") - And print 'request_body ='+request_body - And request request_body - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch-discoveryAllowedKeys - Scenario: Patch discoveryAllowedKeys Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And def request_body = (response.discoveryAllowedKeys == null ? "[ {\"op\":\"add\", \"path\": \"/discoveryAllowedKeys\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/discoveryAllowedKeys\", \"value\":"+response.discoveryAllowedKeys+"} ]") - #And def request_body = (response.discoveryAllowedKeys == null ? "[ {\"op\":\"add\", \"path\": \"/discoveryAllowedKeys\", \"value\":[\"authorization_endpoint\",\"claims_parameter_supported\"] } ]" : "[ {\"op\":\"replace\", \"path\": \"/discoveryAllowedKeys\", \"value\":"+response.discoveryAllowedKeys+"} ]") - And print 'request_body ='+request_body - And request request_body - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch-dcrSignatureValidationSharedSecret -field - Scenario: Patch dcrSignatureValidationSharedSecret Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And def request_body = (response.dcrSignatureValidationSharedSecret == null ? "[ {\"op\":\"add\", \"path\": \"/dcrSignatureValidationSharedSecret\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/dcrSignatureValidationSharedSecret\", \"value\":\""+response.dcrSignatureValidationSharedSecret+"\" } ]") - And print 'request_body ='+request_body - And request request_body - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch-allowIdTokenWithoutImplicitGrantType - Scenario: Patch allowIdTokenWithoutImplicitGrantType Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And def request_body = (response.allowIdTokenWithoutImplicitGrantType == null ? "[ {\"op\":\"add\", \"path\": \"/allowIdTokenWithoutImplicitGrantType\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/allowIdTokenWithoutImplicitGrantType\", \"value\":"+response.allowIdTokenWithoutImplicitGrantType+"} ]") - And print 'request_body ='+request_body - And request request_body - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch-keySignWithSameKeyButDiffAlg - Scenario: Patch keySignWithSameKeyButDiffAlg Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And def request_body = (response.keySignWithSameKeyButDiffAlg == null ? "[ {\"op\":\"add\", \"path\": \"/keySignWithSameKeyButDiffAlg\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/keySignWithSameKeyButDiffAlg\", \"value\":"+response.keySignWithSameKeyButDiffAlg+"} ]") - And print 'request_body ='+request_body - And request request_body - When method PATCH - Then status 200 - And print response - - @ignore - @auth-config-patch-staticKid - Scenario: Patch staticKid Auth configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And header Accept = 'application/json' - And def request_body = (response.staticKid == null ? "[ {\"op\":\"add\", \"path\": \"/staticKid\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/staticKid\", \"value\":\""+response.staticKid+"\"} ]") - And print 'request_body ='+request_body - And request request_body - When method PATCH - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/request/object.feature b/jans-config-api/server/src/test/resources/feature/config/properties/request/object.feature deleted file mode 100644 index b829bb7f44a..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/request/object.feature +++ /dev/null @@ -1,33 +0,0 @@ -@ignore -Feature: Verify RequestObject configuration endpoint - - Background: - * def mainUrl = requestObjectUrl - - @request_object-get - Scenario: Retrieve RequestObject configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @request_object-put - Scenario: Update RequestObject configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/response/modes/modes.feature b/jans-config-api/server/src/test/resources/feature/config/properties/response/modes/modes.feature deleted file mode 100644 index 0839593a138..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/response/modes/modes.feature +++ /dev/null @@ -1,33 +0,0 @@ -@ignore -Feature: Verify ResponseMode configuration endpoint - - Background: - * def mainUrl = responseModeUrl - - @responses_modes-get - Scenario: Retrieve ResponseMode configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @responses_modes-put - Scenario: Update ResponseMode configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/response/types/type.feature b/jans-config-api/server/src/test/resources/feature/config/properties/response/types/type.feature deleted file mode 100644 index 309b8efead6..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/response/types/type.feature +++ /dev/null @@ -1,33 +0,0 @@ -@ignore -Feature: Verify ResponseTypes configuration endpoint - - Background: - * def mainUrl = responsesTypesUrl - - @responses_types-get - Scenario: Retrieve ResponseType configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @responses_types-put - Scenario: Update ResponseType configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/server/cleanup.feature b/jans-config-api/server/src/test/resources/feature/config/properties/server/cleanup.feature deleted file mode 100644 index f9c3f2da493..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/server/cleanup.feature +++ /dev/null @@ -1,50 +0,0 @@ -@ignore -Feature: Verify Server cleanup configuration endpoint - - Background: - * def mainUrl = serverCleanupUrl - - @server-get - Scenario: Retrieve Server cleanup configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @server-put - Scenario: Update Server cleanup configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('cleanup.json') - When method PUT - Then status 200 - And print response - And assert response.length != null - - @error - Scenario: Error case for cleanServiceInterval configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - Then def request_json = read('cleanup.json') - Then set request_json.cleanServiceInterval = 0 - #And print request_json - And request request_json - When method PUT - Then status 400 - And print response - - @error - Scenario: Error case for cleanServiceBatchChunkSize configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - Then def request_json = read('cleanup.json') - Then set request_json.cleanServiceBatchChunkSize = 0 - #And print request_json - And request request_json - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/server/cleanup.json b/jans-config-api/server/src/test/resources/feature/config/properties/server/cleanup.json deleted file mode 100644 index 704c9b7f820..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/server/cleanup.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "cleanServiceBatchChunkSize": 10000, - "cleanServiceInterval": 60, - "cleanServiceBaseDns": [ - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/server/config.feature b/jans-config-api/server/src/test/resources/feature/config/properties/server/config.feature deleted file mode 100644 index 87cf1dc78b0..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/server/config.feature +++ /dev/null @@ -1,63 +0,0 @@ -@ignore -Feature: Verify Server config configuration endpoint - - Background: - * def mainUrl = serverConfigUrl - - @server-get - Scenario: Retrieve Server config configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @server-put - Scenario: Update Server config configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - #And print response - Then def first_response = response - #And print first_response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 200 - And print response - - @error - Scenario: Error case for oxId configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.oxId = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - - @error - Scenario: Error case for configurationUpdateInterval configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - Then def first_response = response - Then set first_response.configurationUpdateInterval = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/server/config.json b/jans-config-api/server/src/test/resources/feature/config/properties/server/config.json deleted file mode 100644 index 9248a4bb6a8..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/server/config.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "useLocalCache": true, - "logClientNameOnClientAuthentication": false, - "fapiCompatibility": false, - "logClientIdOnClientAuthentication": true, - "errorReasonEnabled": false, - "cssLocation": "", - "jsLocation": "", - "clientRegDefaultToCodeFlowWithRefresh": true, - "introspectionScriptBackwardCompatibility": false, - "oxId": "https://pujavs3.infinity.com/oxid/service/gluu/inum", - "configurationUpdateInterval": 3600, - "authorizationRequestCustomAllowedParameters": [ - "customParam2", - "customParam3", - "customParam1" - ], - "disableU2fEndpoint": false, - "errorHandlingMethod": "INTERNAL", - "imgLocation": "", - "consentGatheringScriptBackwardCompatibility": false, - "personCustomObjectClassList": [ - "jansCustomPerson", - "jansPerson" - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/server/session/sessionId.feature b/jans-config-api/server/src/test/resources/feature/config/properties/server/session/sessionId.feature deleted file mode 100644 index 249e224a544..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/server/session/sessionId.feature +++ /dev/null @@ -1,99 +0,0 @@ -@ignore -Feature: Verify SessionId configuration endpoint - - Background: - * def mainUrl = sessionIdUrl - - @sessionid-get - Scenario: Retrieve SessionId configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @sessionid-put - Scenario: Update SessionId configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - @sessionid-error - Scenario: sessionIdUnusedLifetime configuration cannot be less than 1 (one) - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.sessionIdUnusedLifetime = -8 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @sessionid-error - Scenario: sessionIdUnusedLifetime configuration cannot be less than 1 (one) - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.sessionIdUnauthenticatedUnusedLifetime = -2 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @sessionid-error - Scenario: sessionIdLifetime configuration cannot be less than -1 (minus one) - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.sessionIdUnauthenticatedUnusedLifetime = -3 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @sessionid-error - Scenario: sessionIdCookieLifetime configuration cannot be less than -1 (minus one) - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.sessionIdCookieLifetime = -5 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/subject/subject.feature b/jans-config-api/server/src/test/resources/feature/config/properties/subject/subject.feature deleted file mode 100644 index 58a53ef79de..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/subject/subject.feature +++ /dev/null @@ -1,38 +0,0 @@ -@ignore -Feature: Verify Subject configuration endpoint - - Background: - * def mainUrl = subjectUrl - - @subject-get - Scenario: Retrieve Subject configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @subject-put - Scenario: Update Subject configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('subject.json') - When method PUT - Then status 200 - And print response - And assert response.length != null - - @error - Scenario: Error case for subjectTypesSupported configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - Then def request_json = read('subject.json') - Then set request_json.subjectTypesSupported = null - And print request_json - And request request_json - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/subject/subject.json b/jans-config-api/server/src/test/resources/feature/config/properties/subject/subject.json deleted file mode 100644 index dfa9a632981..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/subject/subject.json +++ /dev/null @@ -1,7 +0,0 @@ - { - "subjectTypesSupported": [ - "public", - "pairwise" - ], - "shareSubjectIdBetweenClientsWithSameSectorId": true -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/token/token.feature b/jans-config-api/server/src/test/resources/feature/config/properties/token/token.feature deleted file mode 100644 index f32a2ba31f2..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/token/token.feature +++ /dev/null @@ -1,61 +0,0 @@ -@ignore -Feature: Verify Token configuration endpoint - - Background: - * def mainUrl = tokenUrl - - @token-get - Scenario: Retrieve Token configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @token-put - Scenario: Update Token configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('token.json') - When method PUT - Then status 200 - And print response - And assert response.length != null - - @error - Scenario: Error case for authorizationCodeLifetime configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - Then def request_json = read('token.json') - Then set request_json.authorizationCodeLifetime = 0 - And print request_json - And request request_json - When method PUT - Then status 400 - And print response - - @error - Scenario: Error case for refreshTokenLifetime configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - Then def request_json = read('token.json') - Then set request_json.refreshTokenLifetime = 0 - And print request_json - And request request_json - When method PUT - Then status 400 - And print response - - @error - Scenario: Error case for accessTokenLifetime configuration validation - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - Then def request_json = read('token.json') - Then set request_json.accessTokenLifetime = 0 - And print request_json - And request request_json - When method PUT - Then status 400 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/token/token.json b/jans-config-api/server/src/test/resources/feature/config/properties/token/token.json deleted file mode 100644 index c571aadcb21..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/token/token.json +++ /dev/null @@ -1,6 +0,0 @@ - { - "persistRefreshToken": true, - "authorizationCodeLifetime": 60, - "refreshTokenLifetime": 14400, - "accessTokenLifetime": 300 -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/uma/configuration/configuration.feature b/jans-config-api/server/src/test/resources/feature/config/properties/uma/configuration/configuration.feature deleted file mode 100644 index 61d15304c64..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/uma/configuration/configuration.feature +++ /dev/null @@ -1,118 +0,0 @@ -@ignore -Feature: Verify UmaConfiguration endpoint - - Background: - * def mainUrl = umaConfigurationUrl - - @uma-get - Scenario: Retrieve UmaConfiguration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @uma-put - Scenario: Update UmaConfiguration configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - @uma-error - Scenario: umaConfigurationEndpoint configuration cannot be null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.umaConfigurationEndpoint = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @uma-error - Scenario: umaRptLifetime configuration cannot be less than 1 (one) - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.umaRptLifetime = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @uma-error - Scenario: umaTicketLifetime configuration cannot be less than 1 (one) - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.umaTicketLifetime = -100 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @uma-error - Scenario: umaPctLifetime configuration cannot be less than 1 (one) - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.umaPctLifetime = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @uma-error - Scenario: umaResourceLifetime configuration cannot be less than 1 (one) - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.umaResourceLifetime = 0 - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/properties/user/info/userInfo.feature b/jans-config-api/server/src/test/resources/feature/config/properties/user/info/userInfo.feature deleted file mode 100644 index 251652abb0f..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/properties/user/info/userInfo.feature +++ /dev/null @@ -1,84 +0,0 @@ -@ignore -Feature: Verify UserInfo configuration endpoint - - Background: - * def mainUrl = userInfoUrl - - @userInfo-get - Scenario: Retrieve UserInfo configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @userInfo-put - Scenario: Update UserInfo configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - - @userInfo-error - Scenario: userInfoSigningAlgValuesSupported configuration is null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.userInfoSigningAlgValuesSupported = '' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @userInfo-error - Scenario: userInfoEncryptionAlgValuesSupported configuration is null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.userInfoEncryptionAlgValuesSupported = '' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - @userInfo-error - Scenario: userInfoEncryptionEncValuesSupported configuration is null or empty - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.userInfoEncryptionEncValuesSupported = '' - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/all-script.json b/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/all-script.json deleted file mode 100644 index c3cf5e2763c..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/all-script.json +++ /dev/null @@ -1,1249 +0,0 @@ - [ - { - "internal": false, - "level": 1, - "programmingLanguage": "PYTHON", - "description": "Introspection Custom Parameters Sample Script", - "locationType": "LDAP", - "dn": "inum=2DAF-BA90,ou=scripts,o=gluu", - "inum": "2DAF-BA90", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2019, Gluu\n#\n# Author: Yuriy Mochan\n#\n#\n\nfrom org.gluu.model.custom.script.type.introspection import IntrospectionType\nfrom org.gluu.oxauth.model.common import AuthorizationGrantList\nfrom org.gluu.oxauth.service import SessionIdService\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom java.lang import String\n\nclass Introspection(IntrospectionType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Introspection script. Initializing ...\"\n print \"Introspection script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Introspection script. Destroying ...\"\n print \"Introspection script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns boolean, true - apply introspection method, false - ignore it.\n # This method is called after introspection response is ready. This method can modify introspection response.\n # Note :\n # responseAsJsonObject - is org.codehaus.jettison.json.JSONObject, you can use any method to manipulate json\n # context is reference of org.gluu.oxauth.service.external.context.ExternalIntrospectionContext (in https://github.com/GluuFederation/oxauth project, )\n def modifyResponse(self, responseAsJsonObject, context):\n token = context.getHttpRequest().getParameter(\"token\")\n if token is None:\n print \"Introspection. There is no token in request\"\n return False\n\n authorizationGrantList = CdiUtil.bean(AuthorizationGrantList)\n authorizationGrant = authorizationGrantList.getAuthorizationGrantByAccessToken(token);\n if authorizationGrant is None:\n print \"Introspection. Failed to load authorization grant by token\"\n return False\n\n # Put user_id into response\n responseAsJsonObject.accumulate(\"user_id\", authorizationGrant.getUser().getUserId())\n\n # Put custom parameters into response\n sessionDn = authorizationGrant.getSessionDn();\n if sessionDn is None:\n # There is no session\n return True\n\n sessionIdService = CdiUtil.bean(SessionIdService)\n session = sessionIdService.getSessionById(sessionDn)\n if sessionDn is None:\n print \"Introspection. Failed to load session '%s'\" % sessionDn\n return False\n\n # Return session_id\n responseAsJsonObject.accumulate(\"session_id\", sessionDn)\n \n sessionAttributes = session.getSessionAttributes()\n if sessionAttributes is None:\n # There is no session attributes\n return True\n\n # Append custom claims\n if sessionAttributes.containsKey(\"custom1\"):\n responseAsJsonObject.accumulate(\"custom1\", sessionAttributes.get(\"custom1\"))\n if sessionAttributes.containsKey(\"custom2\"):\n responseAsJsonObject.accumulate(\"custom2\", sessionAttributes.get(\"custom2\"))\n\n return True\n\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "INTROSPECTION", - "name": "introspection_custom_params", - "modified": false, - "baseDn": "inum=2DAF-BA90,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 1, - "programmingLanguage": "PYTHON", - "description": "Resource Owner Password Credentials Example", - "locationType": "LDAP", - "dn": "inum=2DAF-AA91,ou=scripts,o=gluu", - "inum": "2DAF-AA91", - "script": "from org.gluu.model.custom.script.type.owner import ResourceOwnerPasswordCredentialsType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom java.lang import String\n\nclass ResourceOwnerPasswordCredentials(ResourceOwnerPasswordCredentialsType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"ROPC script. Initializing ...\"\n\n self.usernameParamName = \"username\"\n self.passwordParamName = \"password\"\n\n print \"ROPC script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"ROPC script. Destroying ...\"\n print \"ROPC script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns True and set user into context when user authenticated succesfully\n # Returns False when user not authenticated or it's needed to cancel notmal flow\n # Note :\n # context is reference of org.gluu.oxauth.service.external.context.ExternalResourceOwnerPasswordCredentialsContext#ExternalResourceOwnerPasswordCredentialsContext (in https://github.com/GluuFederation/oxauth project, )\n def authenticate(self, context):\n print \"ROPC script. Authenticate\"\n deviceIdParam = context.getHttpRequest().getParameterValues(\"device_id\")\n if deviceIdParam != None and (deviceIdParam.lenght > 0 ):\n result = deviceIdParam[0] == \"device_id_1\"\n if not result:\n return False\n\n # Set auntenticated user in context\n # context.setUser(user)\n return True\n\n # Do generic authentication in other cases\n authService = CdiUtil.bean(AuthenticationService)\n\n username = context.getHttpRequest().getParameter(self.usernameParamName)\n password = context.getHttpRequest().getParameter(self.passwordParamName)\n result = authService.authenticate(username, password)\n if not result:\n print \"ROPC script. Authenticate. Could not authenticate user '%s' \" % username\n return False\n\n context.setUser(authService.getAuthenticatedUser())\n\n return True\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "RESOURCE_OWNER_PASSWORD_CREDENTIALS", - "name": "resource_owner_password_credentials_example", - "modified": false, - "baseDn": "inum=2DAF-AA91,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 1, - "programmingLanguage": "PYTHON", - "description": "Frontchannel logout Sample", - "locationType": "LDAP", - "dn": "inum=2DAF-CA90,ou=scripts,o=gluu", - "inum": "2DAF-CA90", - "script": "# Copyright (c) 2020, Gluu\n#\n# Author: Yuriy Zabrovarnyy\n#\n\nfrom org.gluu.model.custom.script.type.logout import EndSessionType\nfrom java.lang import String\n\nclass EndSession(EndSessionType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"EndSession script. Initializing ...\"\n print \"EndSession script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"EndSession script. Destroying ...\"\n print \"EndSession script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns string, it must be valid HTML (with iframes according to spec http://openid.net/specs/openid-connect-frontchannel-1_0.html)\n # This method is called on `/end_session` after actual session is killed and oxauth construct HTML to return to RP.\n # Note :\n # context is reference of org.gluu.oxauth.service.external.context.EndSessionContext (in https://github.com/GluuFederation/oxauth project, )\n def getFrontchannelHtml(self, context):\n return \"\"", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "END_SESSION", - "name": "frontchannel_logout_sample", - "modified": false, - "baseDn": "inum=2DAF-CA90,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 1, - "programmingLanguage": "PYTHON", - "description": "Sample UMA Claims Gathering", - "locationType": "LDAP", - "dn": "inum=2DAF-F996,ou=scripts,o=gluu", - "inum": "2DAF-F996", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2017, Gluu\r\n#\r\n# Author: Yuriy Zabrovarnyy\r\n#\r\n\r\nfrom org.gluu.model.custom.script.type.uma import UmaClaimsGatheringType\r\n\r\nclass UmaClaimsGathering(UmaClaimsGatheringType):\r\n\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Claims-Gathering. Initializing ...\"\r\n print \"Claims-Gathering. Initialized successfully\"\r\n\r\n return True\r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Claims-Gathering. Destroying ...\"\r\n print \"Claims-Gathering. Destroyed successfully\"\r\n return True\r\n\r\n def getApiVersion(self):\r\n return 11\r\n\r\n\r\n # Main gather method. Must return True (if gathering performed successfully) or False (if fail).\r\n # Method must set claim into context (via context.putClaim('name', value)) in order to persist it (otherwise it will be lost).\r\n # All user entered values can be access via Map context.getPageClaims()\r\n def gather(self, step, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaGatherContext\r\n print \"Claims-Gathering. Gathering ...\"\r\n\r\n if step == 1:\r\n if (context.getPageClaims().containsKey(\"country\")):\r\n country = context.getPageClaims().get(\"country\")\r\n print \"Country: \" + country\r\n\r\n context.putClaim(\"country\", country)\r\n return True\r\n\r\n print \"Claims-Gathering. 'country' is not provided on step 1.\"\r\n return False\r\n\r\n elif step == 2:\r\n if (context.getPageClaims().containsKey(\"city\")):\r\n city = context.getPageClaims().get(\"city\")\r\n print \"City: \" + city\r\n\r\n context.putClaim(\"city\", city)\r\n print \"Claims-Gathering. 'city' is not provided on step 2.\"\r\n return True\r\n\r\n return False\r\n\r\n def getNextStep(self, step, context):\r\n return -1\r\n\r\n def prepareForStep(self, step, context):\r\n if step == 10 and not context.isAuthenticated():\r\n # user is not authenticated, so we are redirecting user to authorization endpoint\r\n # client_id is specified via configuration attribute.\r\n # Make sure that given client has redirect_uri to Claims-Gathering Endpoint with parameter authentication=true\r\n # Sample https://sample.com/restv1/uma/gather_claims?authentication=true\r\n # If redirect to external url is performated, make sure that viewAction has onPostback=\"true\" (otherwise redirect will not work)\r\n # After user is authenticated then within the script it's possible to get user attributes as\r\n # context.getUser(\"uid\", \"sn\")\r\n # If user is authenticated to current AS (to the same server, not external one) then it's possible to\r\n # access Connect session attributes directly (no need to obtain id_token after redirect with 'code').\r\n # To fetch attributes please use getConnectSessionAttributes() method.\r\n\r\n print \"User is not authenticated. Redirect for authentication ...\"\r\n clientId = context.getConfigurationAttributes().get(\"client_id\").getValue2()\r\n redirectUri = context.getClaimsGatheringEndpoint() + \"?authentication=true\" # without authentication=true parameter it will not work\r\n authorizationUrl = context.getAuthorizationEndpoint() + \"?client_id=\" + clientId + \"&redirect_uri=\" + redirectUri + \"&scope=openid&response_type=code\"\r\n context.redirectToExternalUrl(authorizationUrl) # redirect to external url\r\n return False\r\n if step == 10 and context.isAuthenticated(): # example how to get session attribute if user is authenticated to same AS\r\n arc = context.getConnectSessionAttributes().get(\"acr\")\r\n\r\n return True\r\n\r\n def getStepsCount(self, context):\r\n return 2\r\n\r\n def getPageForStep(self, step, context):\r\n if step == 1:\r\n return \"/uma2/sample/country.xhtml\"\r\n elif step == 2:\r\n return \"/uma2/sample/city.xhtml\"\r\n return \"\"", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "UMA_CLAIMS_GATHERING", - "name": "sampleClaimsGathering", - "modified": false, - "baseDn": "inum=2DAF-F996,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 1, - "programmingLanguage": "PYTHON", - "description": "Super Gluu RO Password Credentials Script", - "locationType": "LDAP", - "dn": "inum=B8FD-4C11,ou=scripts,o=gluu", - "inum": "B8FD-4C11", - "script": "# Super Gluu Radius Resource Owner Password Credentials Script\n# Copyright (c) 2019 Gluu Inc.\n\nfrom java.util import Date , HashMap\nfrom org.gluu.oxnotify.client import NotifyClientFactory\n\nfrom org.gluu.model.custom.script.type.owner import ResourceOwnerPasswordCredentialsType\nfrom org.gluu.oxauth.model.common import SessionIdState\nfrom org.gluu.oxauth.model.config import ConfigurationFactory , Constants\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.common import EncryptionService, UserService\nfrom org.gluu.oxauth.service.push.sns import PushPlatform, PushSnsService\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\nfrom gluu_common import PushNotificationManager, NetworkApi, GeolocationData, SuperGluuRequestBuilder\n\nimport java\nimport json\nimport sys\n\n\nclass ResourceOwnerPasswordCredentials(ResourceOwnerPasswordCredentialsType):\n def __init__(self,currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n self.initiateAuthStepName = \"initiate_auth\"\n self.verifyAuthStepName = \"verify_auth\"\n self.resendNotificationStepName = \"resend_notification\"\n self.stepParamName = \"__step\"\n self.acrvaluesParamName = \"__acr_values\"\n self.usernameParamName = \"username\"\n self.passwordParamName = \"__password\"\n self.idtokenParamName = \"__id_token\"\n self.sessionIdParamName = \"__session_id\"\n self.remoteIpParamName = \"__remote_ip\"\n self.sessionIdClaimName = \"__session_id\"\n self.clientIdSessionParamName = \"__client_id\"\n self.authSchemeParamName = \"__auth_scheme\"\n self.oneStepAuthScheme = \"onestep\"\n self.twoStepAuthScheme = \"twostep\"\n \n def init(self, customScript, configurationAttributes):\n\n print \"Super-Gluu-RO Init\"\n if not configurationAttributes.containsKey(\"application_id\"):\n print \"Super-Gluu-Radius RO PW Init Failed. application_id property is required\"\n return False\n \n if not configurationAttributes.containsKey(\"credentials_file\"):\n print \"Super-Gluu-RO Init Failed. credentials_file is required\"\n return False\n \n notificationServiceMode = None\n if configurationAttributes.containsKey(\"notification_service_mode\"):\n notificationServiceMode = configurationAttributes.get(\"notification_service_mode\").getValue2()\n \n \n self.applicationId = \"*\" # wildcard. Selects all devices irrespective of the application \n if configurationAttributes.containsKey(\"application_id\"):\n self.applicationId = configurationAttributes.get(\"application_id\").getValue2()\n \n credentialsFile = configurationAttributes.get(\"credentials_file\").getValue2()\n\n if configurationAttributes.containsKey(\"push_notification_title\"):\n self.pushNotificationManager.titleTemplate = configurationAttributes.get(\"push_notification_title\").getValue2()\n \n if configurationAttributes.containsKey(\"push_notification_message\"):\n self.pushNotificationManager.messageTemplate = configurationAttributes.get(\"push_notification_message\").getValue2()\n \n self.authWithoutPassword = False\n if configurationAttributes.containsKey(\"auth_without_password\"):\n auth_without_password = configurationAttributes.get(\"auth_without_password\").getValue2()\n if StringHelper.equalsIgnoreCase(auth_without_password,\"yes\"):\n self.authWithoutPassword = True\n \n self.issuerId = CdiUtil.bean(ConfigurationFactory).getAppConfiguration().getIssuer()\n if configurationAttributes.containsKey(\"issuer_id\"):\n self.issuerId = configurationAttributes.get(\"issuer_id\").getValue2()\n \n self.pushNotificationManager = PushNotificationManager(notificationServiceMode,credentialsFile)\n self.networkApi = NetworkApi()\n\n return True\n \n def destroy(self, configurationAttributes):\n\n print \"Super-Gluu-RO. Destroy\"\n self.pushNotificationManager = None\n print \"Super-Gluu-RO. Destroyed Successfully\"\n\n return True\n \n def getApiVersion(self):\n return 11\n \n def authenticate(self, context): \n if self.perform_preliminary_user_authentication(context) == False:\n print \"Super-Gluu-RO. User authentication state not validated\"\n return False\n \n step = context.getHttpRequest().getParameter(self.stepParamName)\n if StringHelper.equalsIgnoreCase(step,self.initiateAuthStepName):\n return self.initiate_authentication(context)\n elif StringHelper.equalsIgnoreCase(step,self.resendNotificationStepName):\n return self.resend_push_notification(context)\n elif StringHelper.equalsIgnoreCase(step,self.verifyAuthStepName):\n return self.verify_authentication(context)\n else:\n context.setUser(None)\n print \"Super-Gluu-RO. Unknown authentication step '%s'\" % step\n return False\n \n def initiate_authentication(self, context):\n print \"Super-Gluu-RO initiatate_authentication\"\n\n authscheme = context.getHttpRequest().getParameter(self.authSchemeParamName)\n if authscheme == None:\n authscheme = self.twoStepAuthScheme\n \n if StringHelper.equalsIgnoreCase(authscheme,self.oneStepAuthScheme):\n print \"Super-Gluu-RO using one-step authentication\"\n print \"User '%s' authenticated using one-step\" % context.getUser().getUserId()\n return True\n elif StringHelper.equalsIgnoreCase(authscheme,self.twoStepAuthScheme):\n print \"Super-Gluu-RO using two-step authentication\"\n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n sessionId = self.new_unauthenticated_session(context.getUser(),client)\n # set session id in identity object \n # this will be used by our dynamic scope script \n identity = CdiUtil.bean(Identity)\n identity.setSessionId(sessionId)\n if not self.send_push_notification_to_user(sessionId,context):\n print \"Send push notification to user '%s' failed\" % context.getUser().getUserId()\n context.setUser(None)\n return False\n print \"Super-Gluu-RO initiate_authentication complete\"\n return True\n else:\n print \"Super-Gluu-RO. Unknown authentication scheme specified '%s'\" % authscheme\n context.setUser(None)\n return False\n \n \n print \"Super-Gluu-RO using two-step authentication\"\n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n sessionId = self.new_unauthenticated_session(context.getUser(),client)\n # set session id in identity object\n # this will be used by our dynamic scope script\n identity = CdiUtil.bean(Identity)\n identity.setSessionId(sessionId)\n if not self.send_push_notification_to_user(sessionId,context):\n print \"Send push notification to user '%s' failed \" % context.getUser().getUserId()\n context.setUser(None)\n return False\n print \"Super-Gluu-RO initiate_authentication complete\"\n return True\n \n def resend_push_notification(self,context):\n print \"Super-Gluu-RO resend_push_notification\"\n\n sessionIdService = CdiUtil.bean(SessionIdService)\n session_id = context.getHttpRequest().getParameter(self.sessionIdParamName)\n if session_id == None:\n print \"Super-Gluu-RO. No session_id was specified for resend_push_notification\"\n context.setUser(None)\n return False\n \n sessionId = sessionIdService.getSessionId(session_id)\n if sessionId == None:\n print \"Super-Gluu-RO. Session '%s' does not exist or has expired\" % session_id\n context.setUser(None)\n return False\n \n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n if not self.verify_session_ownership(sessionId,context.getUser(),client):\n print \"Super-Gluu-RO. resend_push_notification_failed due to invalid session ownership\"\n context.setUser(None)\n return False\n \n self.send_push_notification_to_user(sessionId,context)\n print \"Super-Gluu-RO resend_push_notification complete\"\n return True\n \n def verify_authentication(self, context):\n print \"Super-Gluu-RO verify_authentication\"\n session_id = context.getHttpRequest().getParameter(self.sessionIdParamName)\n sessionId = CdiUtil.bean(SessionIdService).getSessionId(session_id)\n if sessionId == None:\n print \"Super-Gluu-RO.verify_authentication failed. Session {%s} does not exist or has expired\" % session_id\n context.setUser(None)\n return False\n \n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n if not self.verify_session_ownership(sessionId,context.getUser(),client):\n print \"Super-Gluu-RO. verify_authentication failed due to invalid session ownership\"\n context.setUser(None)\n return False\n \n if not self.is_session_authenticated(sessionId):\n print \"Super-Gluu-Ro. verify_authentication failed. Session is not authenticated\"\n context.setUser(None)\n return False\n \n print \"Super-Gluu-RO verify_authentication complete\"\n return True\n \n def perform_preliminary_user_authentication(self, context):\n username = context.getHttpRequest().getParameter(self.usernameParamName)\n if self.authWithoutPassword:\n userService = CdiUtil.bean(UserService)\n user = userService.getUser(username,\"uid\")\n if user == None:\n print \"Super-Gluu-RO. User '%s' not found\" % username\n return False\n context.setUser(user)\n print \"Super-Gluu-RO. User '%s' authenticated without password\" % username\n return True\n \n password = context.getHttpRequest().getParameter(self.passwordParamName)\n authService = CdiUtil.bean(AuthenticationService)\n if authService.authenticate(username, password) == False:\n print \"Super-Gluu-RO. Could not authenticate user '%s' \" % username\n return False\n\n context.setUser(authService.getAuthenticatedUser())\n return True\n \n def new_unauthenticated_session(self,user,client):\n sessionIdService = CdiUtil.bean(SessionIdService)\n authDate = Date()\n sid_attrs = HashMap()\n sid_attrs.put(Constants.AUTHENTICATED_USER,user.getUserId())\n sid_attrs.put(self.clientIdSessionParamName,client.getClientId())\n sessionId = sessionIdService.generateUnauthenticatedSessionId(user.getDn(),authDate,SessionIdState.UNAUTHENTICATED,sid_attrs,True)\n print \"Super-Gluu-RO. Generated session id. DN: '%s'\" % sessionId.getDn()\n return sessionId\n \n def send_push_notification_to_user(self, sessionId,context):\n remote_ip = context.getHttpRequest().getParameter(self.remoteIpParamName)\n if remote_ip == None or (remote_ip != None and StringHelper.isEmpty(remote_ip)):\n remote_ip = self.networkApi.get_remote_ip_from_request(context.getHttpRequest())\n \n user = context.getUser()\n srbuilder = SuperGluuRequestBuilder()\n srbuilder.username = user.getUserId()\n srbuilder.app = self.applicationId\n srbuilder.issuer = self.issuerId\n srbuilder.state = sessionId.getId()\n srbuilder.requestLocation(self.networkApi.get_geolocation_data(remote_ip))\n srbuilder.req_ip = remote_ip \n device_count = self.pushNotificationManager.sendPushNotification(user,self.applicationId,srbuilder.build())\n \n if device_count == 0:\n print \"User %s has no device enrolled for Super-Gluu authentication\" % user.getUserId()\n return False\n return True\n\n \n\n def is_session_authenticated(self, sessionId):\n if sessionId == None:\n return False\n \n state = sessionId.getState()\n custom_state = sessionId.getSessionAttributes().get(SessionIdService.SESSION_CUSTOM_STATE)\n if state == None:\n print \"Super-Gluu-RO. Session {%s} has no state variable set\" % sessionId.getId()\n return False\n \n state_unauthenticated = SessionIdState.UNAUTHENTICATED == state\n state_authenticated = SessionIdState.AUTHENTICATED == state\n custom_state_declined = StringHelper.equalsIgnoreCase(\"declined\",custom_state) \n custom_state_expired = StringHelper.equalsIgnoreCase(\"expired\",custom_state)\n custom_stated_approved = StringHelper.equalsIgnoreCase(\"approved\",custom_state)\n\n if state_unauthenticated and (custom_state_declined or custom_state_expired):\n print \"Super-Gluu-RO. Session {%s} isn't authenticated\" % sessionId.getId()\n return False\n \n if state_authenticated or (state_unauthenticated and custom_stated_approved):\n print \"Super-Gluu-RO. Session {%s} is authenticated\" % sessionId.getId()\n return True\n\n return False\n \n # this function verifies if the session was created when invoked with the \n # current client's credentials and with the current user's credentials\n\n def verify_session_ownership(self, sessionId, user, client):\n session_attributes = sessionId.getSessionAttributes()\n client_id = session_attributes.get(self.clientIdSessionParamName)\n if not StringHelper.equalsIgnoreCase(client.getClientId(),client_id):\n print \"Super-Gluu-RO. Session {%s} client_id mismatch\" % sessionId.getId()\n return False\n \n user_id = session_attributes.get(Constants.AUTHENTICATED_USER)\n if not StringHelper.equalsIgnoreCase(user_id,user.getUserId()):\n print \"Super-Gluu-RO. Session {%s} user_id mismatch\" % sessionId.getId() \n return False\n \n return True\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "RESOURCE_OWNER_PASSWORD_CREDENTIALS", - "name": "super_gluu_ro", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "/etc/certs/super_gluu_creds.json", - "value1": "credentials_file" - }, - { - "hide": false, - "value2": "gluu", - "value1": "notification_service_mode" - }, - { - "hide": false, - "value2": "https://pujavs4.2.gluu.server/identity/authcode.htm", - "value1": "application_id" - } - ], - "baseDn": "inum=B8FD-4C11,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 1, - "programmingLanguage": "PYTHON", - "description": "Introspection Sample Script", - "locationType": "LDAP", - "dn": "inum=2DAF-AA90,ou=scripts,o=gluu", - "inum": "2DAF-AA90", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2018, Gluu\n#\n# Author: Yuriy Zabrovarnyy\n#\n#\n\nfrom org.gluu.model.custom.script.type.introspection import IntrospectionType\nfrom java.lang import String\n\nclass Introspection(IntrospectionType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Introspection script. Initializing ...\"\n print \"Introspection script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Introspection script. Destroying ...\"\n print \"Introspection script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns boolean, true - apply introspection method, false - ignore it.\n # This method is called after introspection response is ready. This method can modify introspection response.\n # Note :\n # responseAsJsonObject - is org.codehaus.jettison.json.JSONObject, you can use any method to manipulate json\n # context is reference of org.gluu.oxauth.service.external.context.ExternalIntrospectionContext (in https://github.com/GluuFederation/oxauth project, )\n def modifyResponse(self, responseAsJsonObject, context):\n responseAsJsonObject.accumulate(\"key_from_script\", \"value_from_script\")\n return True\n\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "INTROSPECTION", - "name": "introspection_sample", - "modified": false, - "baseDn": "inum=2DAF-AA90,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 1, - "programmingLanguage": "PYTHON", - "description": "Resource Owner Password Credentials Custom Parameters Example", - "locationType": "LDAP", - "dn": "inum=2DAF-BA91,ou=scripts,o=gluu", - "inum": "2DAF-BA91", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2019, Gluu\n#\n# Author: Yuriy Mochan\n#\n#\n\nfrom org.gluu.model.custom.script.type.owner import ResourceOwnerPasswordCredentialsType\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.model.common import SessionIdState\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.model.authorize import AuthorizeRequestParam\nfrom org.gluu.oxauth.model.config import Constants\nfrom org.gluu.util import StringHelper\nfrom java.lang import String\nfrom java.util import Date, HashMap\n\nclass ResourceOwnerPasswordCredentials(ResourceOwnerPasswordCredentialsType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"ROPC script. Initializing ...\"\n print \"ROPC script. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"ROPC script. Destroying ...\"\n print \"ROPC script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Returns True and set user into context when user authenticated succesfully\n # Returns False when user not authenticated or it's needed to cancel notmal flow\n # Note :\n # context is reference of org.gluu.oxauth.service.external.context.ExternalResourceOwnerPasswordCredentialsContext#ExternalResourceOwnerPasswordCredentialsContext (in https://github.com/GluuFederation/oxauth project, )\n def authenticate(self, context):\n print \"ROPC script. Authenticate\"\n\n # Do generic authentication\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n username = context.getHttpRequest().getParameter(\"username\")\n password = context.getHttpRequest().getParameter(\"password\")\n result = authenticationService.authenticate(username, password)\n if not result:\n print \"ROPC script. Authenticate. Could not authenticate user '%s' \" % username\n return False\n\n context.setUser(authenticationService.getAuthenticatedUser())\n print \"ROPC script. Authenticate. User '%s' authenticated successfully\" % username\n \n\n # Get cusom parameters from request\n customParam1Value = context.getHttpRequest().getParameter(\"custom1\")\n customParam2Value = context.getHttpRequest().getParameter(\"custom2\")\n\n customParameters = {}\n customParameters[\"custom1\"] = customParam1Value\n customParameters[\"custom2\"] = customParam2Value\n print \"ROPC script. Authenticate. User '%s'. Creating authenticated session with custom attributes: '%s'\" % (username, customParameters)\n\n session = self.createNewAuthenticatedSession(context, customParameters)\n \n # This is needed to allow store in token entry sessionId\n authenticationService.configureEventUser(session)\n\n print \"ROPC script. Authenticate. User '%s'. Created authenticated session: '%s'\" % (username, customParameters)\n\n return True\n\n def createNewAuthenticatedSession(self, context, customParameters={}):\n sessionIdService = CdiUtil.bean(SessionIdService)\n\n user = context.getUser()\n client = CdiUtil.bean(Identity).getSessionClient().getClient()\n\n # Add mandatory session parameters\n sessionAttributes = HashMap()\n sessionAttributes.put(Constants.AUTHENTICATED_USER, user.getUserId())\n sessionAttributes.put(AuthorizeRequestParam.CLIENT_ID, client.getClientId())\n sessionAttributes.put(AuthorizeRequestParam.PROMPT, \"\")\n\n # Add custom session parameters\n for key, value in customParameters.iteritems():\n if StringHelper.isNotEmpty(value):\n sessionAttributes.put(key, value)\n\n # Generate authenticated session\n sessionId = sessionIdService.generateAuthenticatedSessionId(context.getHttpRequest(), user.getDn(), sessionAttributes)\n\n print \"ROPC script. Generated session id. DN: '%s'\" % sessionId.getDn()\n\n return sessionId\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "RESOURCE_OWNER_PASSWORD_CREDENTIALS", - "name": "resource_owner_password_credentials_custom_params_example", - "modified": false, - "baseDn": "inum=2DAF-BA91,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 10, - "programmingLanguage": "PYTHON", - "description": "Firebase notification sender", - "locationType": "LDAP", - "dn": "inum=C1BA-C1BA,ou=scripts,o=gluu", - "inum": "C1BA-C1BA", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2018, Gluu\n#\n# Author: Milton BO\n#\n#\n\nfrom org.gluu.oxauth.client.fcm import FirebaseCloudMessagingResponse\nfrom org.gluu.oxauth.client.fcm import FirebaseCloudMessagingClient\nfrom org.gluu.oxauth.client.fcm import FirebaseCloudMessagingRequest\nfrom org.gluu.oxauth.util import RedirectUri\nfrom org.gluu.model.custom.script.type.ciba import EndUserNotificationType\nfrom java.lang import String\nfrom java.util import UUID\n\nclass EndUserNotification(EndUserNotificationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, configurationAttributes):\n print \"Firebase EndUserNotification script. Initializing ...\"\n print \"Firebase EndUserNotification script. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Firebase EndUserNotification script. Destroying ...\"\n print \"Firebase EndUserNotification script. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 1\n\n # Returns boolean true or false depending on the process, if the notification\n # is sent successfully or not.\n def notifyEndUser(self, context):\n print 'Sending push notification using Firebase Cloud Messaging'\n appConfiguration = context.getAppConfiguration()\n encryptionService = context.getEncryptionService()\n clientId = appConfiguration.getBackchannelClientId()\n redirectUri = appConfiguration.getBackchannelRedirectUri()\n url = appConfiguration.getCibaEndUserNotificationConfig().getNotificationUrl()\n key = encryptionService.decrypt(appConfiguration.getCibaEndUserNotificationConfig().getNotificationKey(), True)\n to = context.getDeviceRegistrationToken()\n title = \"oxAuth Authentication Request\"\n body = \"Client Initiated Backchannel Authentication (CIBA)\"\n\n authorizationRequestUri = RedirectUri(appConfiguration.getAuthorizationEndpoint())\n authorizationRequestUri.addResponseParameter(\"client_id\", clientId)\n authorizationRequestUri.addResponseParameter(\"response_type\", \"id_token\")\n authorizationRequestUri.addResponseParameter(\"scope\", context.getScope())\n authorizationRequestUri.addResponseParameter(\"acr_values\", context.getAcrValues())\n authorizationRequestUri.addResponseParameter(\"redirect_uri\", redirectUri)\n authorizationRequestUri.addResponseParameter(\"state\", UUID.randomUUID().toString())\n authorizationRequestUri.addResponseParameter(\"nonce\", UUID.randomUUID().toString())\n authorizationRequestUri.addResponseParameter(\"prompt\", \"consent\")\n authorizationRequestUri.addResponseParameter(\"auth_req_id\", context.getAuthReqId())\n\n clickAction = authorizationRequestUri.toString()\n\n firebaseCloudMessagingRequest = FirebaseCloudMessagingRequest(key, to, title, body, clickAction)\n firebaseCloudMessagingClient = FirebaseCloudMessagingClient(url)\n firebaseCloudMessagingClient.setRequest(firebaseCloudMessagingRequest)\n firebaseCloudMessagingResponse = firebaseCloudMessagingClient.exec()\n\n responseStatus = firebaseCloudMessagingResponse.getStatus()\n print \"CIBA: firebase cloud messaging result status \" + str(responseStatus)\n return (responseStatus >= 200 and responseStatus < 300 )\n\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "CIBA_END_USER_NOTIFICATION", - "name": "firebase_ciba_end_user_notification", - "modified": false, - "baseDn": "inum=C1BA-C1BA,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 10, - "programmingLanguage": "PYTHON", - "description": "Sample authentication module", - "locationType": "LDAP", - "dn": "inum=A51E-76DA,ou=scripts,o=gluu", - "inum": "A51E-76DA", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.util import StringHelper\n\nimport java\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Basic. Initialization\"\n print \"Basic. Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"Basic. Destroy\"\n print \"Basic. Destroyed successfully\"\n return True\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def getApiVersion(self):\n return 11\n\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n if (step == 1):\n print \"Basic. Authenticate for step 1\"\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if (not logged_in):\n return False\n\n return True\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n if (step == 1):\n print \"Basic. Prepare for Step 1\"\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 1\n\n def getPageForStep(self, configurationAttributes, step):\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "basic", - "modified": false, - "baseDn": "inum=A51E-76DA,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 10, - "programmingLanguage": "PYTHON", - "description": "Consent Gathering script", - "locationType": "LDAP", - "dn": "inum=DAA9-BA60,ou=scripts,o=gluu", - "inum": "DAA9-BA60", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2017, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.authz import ConsentGatheringType\nfrom org.gluu.util import StringHelper\n\nimport java\nimport random\n\nclass ConsentGathering(ConsentGatheringType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Consent-Gathering. Initializing ...\"\n print \"Consent-Gathering. Initialized successfully\"\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Consent-Gathering. Destroying ...\"\n print \"Consent-Gathering. Destroyed successfully\"\n\n return True\n\n def getApiVersion(self):\n return 1\n\n # Main consent-gather method. Must return True (if gathering performed successfully) or False (if fail).\n # All user entered values can be access via Map context.getPageAttributes()\n def authorize(self, step, context): # context is reference of org.gluu.oxauth.service.external.context.ConsentGatheringContext\n print \"Consent-Gathering. Authorizing...\"\n\n if step == 1:\n allowButton = context.getRequestParameters().get(\"authorizeForm:allowButton\")\n if (allowButton != None) and (len(allowButton) > 0):\n print \"Consent-Gathering. Authorization success for step 1\"\n return True\n\n print \"Consent-Gathering. Authorization declined for step 1\"\n elif step == 2:\n allowButton = context.getRequestParameters().get(\"authorizeForm:allowButton\")\n if (allowButton != None) and (len(allowButton) > 0):\n print \"Consent-Gathering. Authorization success for step 2\"\n return True\n\n print \"Consent-Gathering. Authorization declined for step 2\"\n\n return False\n\n def getNextStep(self, step, context):\n return -1\n\n def prepareForStep(self, step, context):\n if not context.isAuthenticated():\n print \"User is not authenticated. Aborting authorization flow ...\"\n return False\n\n if step == 2:\n pageAttributes = context.getPageAttributes()\n \n # Generate random consent gathering request\n consentRequest = \"Requested transaction #%s approval for the amount of sum $ %s.00\" % ( random.randint(100000, 1000000), random.randint(1, 100) )\n pageAttributes.put(\"consent_request\", consentRequest)\n return True\n\n return True\n\n def getStepsCount(self, context):\n return 11\n\n def getPageForStep(self, step, context):\n if step == 1:\n return \"/authz/authorize.xhtml\"\n elif step == 2:\n return \"/authz/transaction.xhtml\"\n\n return \"\"\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "CONSENT_GATHERING", - "name": "consent_gathering", - "modified": false, - "baseDn": "inum=DAA9-BA60,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 20, - "programmingLanguage": "PYTHON", - "description": "Basic (with user locking) authentication module", - "locationType": "LDAP", - "dn": "inum=4BBE-C6A8,ou=scripts,o=gluu", - "inum": "4BBE-C6A8", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n# Author: Gasmyr Mougang\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.service import CacheService\nfrom org.gluu.util import StringHelper\nfrom org.gluu.persist.exception import AuthenticationException\nfrom javax.faces.application import FacesMessage\nfrom org.gluu.jsf2.message import FacesMessages\nfrom java.time import LocalDateTime, Duration\nfrom java.time.format import DateTimeFormatter\n\nimport java\nimport datetime\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Basic (lock account). Initialization\"\n\n self.invalidLoginCountAttribute = \"oxCountInvalidLogin\"\n if configurationAttributes.containsKey(\"invalid_login_count_attribute\"):\n self.invalidLoginCountAttribute = configurationAttributes.get(\"invalid_login_count_attribute\").getValue2()\n else:\n print \"Basic (lock account). Initialization. Using default attribute\"\n\n self.maximumInvalidLoginAttemps = 3\n if configurationAttributes.containsKey(\"maximum_invalid_login_attemps\"):\n self.maximumInvalidLoginAttemps = StringHelper.toInteger(configurationAttributes.get(\"maximum_invalid_login_attemps\").getValue2())\n else:\n print \"Basic (lock account). Initialization. Using default number attempts\"\n\n self.lockExpirationTime = 180\n if configurationAttributes.containsKey(\"lock_expiration_time\"):\n self.lockExpirationTime = StringHelper.toInteger(configurationAttributes.get(\"lock_expiration_time\").getValue2())\n else:\n print \"Basic (lock account). Initialization. Using default lock expiration time\"\n\n\n print \"Basic (lock account). Initialized successfully. invalid_login_count_attribute: '%s', maximum_invalid_login_attemps: '%s', lock_expiration_time: '%s'\" % (self.invalidLoginCountAttribute, self.maximumInvalidLoginAttemps, self.lockExpirationTime)\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Basic (lock account). Destroy\"\n print \"Basic (lock account). Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n if step == 1:\n print \"Basic (lock account). Authenticate for step 1\"\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n cacheService = CdiUtil.bean(CacheService)\n userService = CdiUtil.bean(UserService)\n\n\n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n try:\n logged_in = authenticationService.authenticate(user_name, user_password)\n except AuthenticationException:\n print \"Basic (lock account). Authenticate. Failed to authenticate user '%s'\" % user_name\n\n if logged_in:\n self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(0))\n else:\n countInvalidLoginArributeValue = self.getUserAttributeValue(user_name, self.invalidLoginCountAttribute)\n userSatus = self.getUserAttributeValue(user_name, \"gluuStatus\")\n print \"Current user '%s' status is '%s'\" % ( user_name, userSatus )\n\n countInvalidLogin = StringHelper.toInteger(countInvalidLoginArributeValue, 0)\n\n if countInvalidLogin < self.maximumInvalidLoginAttemps:\n countInvalidLogin = countInvalidLogin + 1\n remainingAttempts = self.maximumInvalidLoginAttemps - countInvalidLogin\n\n print \"Remaining login count attempts '%s' for user '%s'\" % ( remainingAttempts, user_name )\n\n self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(countInvalidLogin))\n if remainingAttempts > 0 and userSatus == \"active\":\n facesMessages.add(FacesMessage.SEVERITY_INFO, StringHelper.toString(remainingAttempts)+\" more attempt(s) before account is LOCKED!\")\n\n if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and ((userSatus == None) or (userSatus == \"active\")):\n print \"Basic (lock account). Locking '%s' for '%s' seconds\" % ( user_name, self.lockExpirationTime)\n self.lockUser(user_name)\n return False\n\n if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and userSatus == \"inactive\":\n print \"Basic (lock account). User '%s' is locked. Checking if we can unlock him\" % user_name\n \n unlock_and_authenticate = False\n\n object_from_store = cacheService.get(None, \"lock_user_\" + user_name)\n if object_from_store == None:\n # Object in cache was expired. We need to unlock user\n print \"Basic (lock account). User locking details for user '%s' not exists\" % user_name\n unlock_and_authenticate = True\n else:\n # Analyze object from cache\n user_lock_details = json.loads(object_from_store)\n\n user_lock_details_locked = user_lock_details['locked']\n user_lock_details_created = user_lock_details['created']\n user_lock_details_created_date = LocalDateTime.parse(user_lock_details_created, DateTimeFormatter.ISO_LOCAL_DATE_TIME)\n user_lock_details_created_diff = Duration.between(user_lock_details_created_date, LocalDateTime.now()).getSeconds()\n print \"Basic (lock account). Get user '%s' locking details. locked: '%s', Created: '%s', Difference in seconds: '%s'\" % ( user_name, user_lock_details_locked, user_lock_details_created, user_lock_details_created_diff )\n\n if user_lock_details_locked and user_lock_details_created_diff >= self.lockExpirationTime:\n print \"Basic (lock account). Unlocking user '%s' after lock expiration\" % user_name\n unlock_and_authenticate = True\n\n if unlock_and_authenticate:\n self.unLockUser(user_name)\n self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(0))\n logged_in = authenticationService.authenticate(user_name, user_password)\n if not logged_in:\n # Update number of attempts \n self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(1))\n if self.maximumInvalidLoginAttemps == 1:\n # Lock user if maximum count login attempts is 1 \n self.lockUser(user_name)\n return False\n\n\n return logged_in\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n if step == 1:\n print \"Basic (lock account). Prepare for Step 1\"\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 1\n\n def getPageForStep(self, configurationAttributes, step):\n return \"\"\n \n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def getUserAttributeValue(self, user_name, attribute_name):\n if StringHelper.isEmpty(user_name):\n return None\n\n userService = CdiUtil.bean(UserService)\n\n find_user_by_uid = userService.getUser(user_name, attribute_name)\n if find_user_by_uid == None:\n return None\n\n custom_attribute_value = userService.getCustomAttribute(find_user_by_uid, attribute_name)\n if custom_attribute_value == None:\n return None\n \n attribute_value = custom_attribute_value.getValue()\n\n print \"Basic (lock account). Get user attribute. User's '%s' attribute '%s' value is '%s'\" % (user_name, attribute_name, attribute_value)\n\n return attribute_value\n\n def setUserAttributeValue(self, user_name, attribute_name, attribute_value):\n if StringHelper.isEmpty(user_name):\n return None\n\n userService = CdiUtil.bean(UserService)\n\n find_user_by_uid = userService.getUser(user_name)\n if find_user_by_uid == None:\n return None\n \n userService.setCustomAttribute(find_user_by_uid, attribute_name, attribute_value)\n updated_user = userService.updateUser(find_user_by_uid)\n\n print \"Basic (lock account). Set user attribute. User's '%s' attribute '%s' value is '%s'\" % (user_name, attribute_name, attribute_value)\n\n return updated_user\n\n def lockUser(self, user_name):\n if StringHelper.isEmpty(user_name):\n return None\n\n userService = CdiUtil.bean(UserService)\n cacheService= CdiUtil.bean(CacheService)\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n\n find_user_by_uid = userService.getUser(user_name)\n if (find_user_by_uid == None):\n return None\n\n status_attribute_value = userService.getCustomAttribute(find_user_by_uid, \"gluuStatus\")\n if status_attribute_value != None:\n user_status = status_attribute_value.getValue()\n if StringHelper.equals(user_status, \"inactive\"):\n print \"Basic (lock account). Lock user. User '%s' locked already\" % user_name\n return\n \n userService.setCustomAttribute(find_user_by_uid, \"gluuStatus\", \"inactive\")\n updated_user = userService.updateUser(find_user_by_uid)\n\n object_to_store = json.dumps({'locked': True, 'created': LocalDateTime.now().toString()}, separators=(',',':'))\n\n cacheService.put(StringHelper.toString(self.lockExpirationTime), \"lock_user_\"+user_name, object_to_store);\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Your account is locked. Please try again after \" + StringHelper.toString(self.lockExpirationTime) + \" secs\")\n\n print \"Basic (lock account). Lock user. User '%s' locked\" % user_name\n\n def unLockUser(self, user_name):\n if StringHelper.isEmpty(user_name):\n return None\n\n userService = CdiUtil.bean(UserService)\n cacheService= CdiUtil.bean(CacheService)\n\n find_user_by_uid = userService.getUser(user_name)\n if (find_user_by_uid == None):\n return None\n\n object_to_store = json.dumps({'locked': False, 'created': LocalDateTime.now().toString()}, separators=(',',':'))\n cacheService.put(StringHelper.toString(self.lockExpirationTime), \"lock_user_\"+user_name, object_to_store);\n\n userService.setCustomAttribute(find_user_by_uid, \"gluuStatus\", \"active\")\n userService.setCustomAttribute(find_user_by_uid, self.invalidLoginCountAttribute, None)\n updated_user = userService.updateUser(find_user_by_uid)\n\n\n print \"Basic (lock account). Lock user. User '%s' unlocked\" % user_name\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - }, - { - "value2": "interactive", - "value1": "usage_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "basic_lock", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "oxCountInvalidLogin", - "value1": "invalid_login_count_attribute" - }, - { - "hide": false, - "value2": "3", - "value1": "maximum_invalid_login_attemps" - }, - { - "hide": false, - "value2": "120", - "value1": "lock_expiration_time" - } - ], - "baseDn": "inum=4BBE-C6A8,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 30, - "programmingLanguage": "PYTHON", - "description": "Cert authentication module", - "locationType": "LDAP", - "dn": "inum=2124-0CF1,ou=scripts,o=gluu", - "inum": "2124-0CF1", - "script": "#\n# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom javax.faces.context import FacesContext\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.util import StringHelper\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.oxauth.service.common import EncryptionService\nfrom java.util import Arrays\nfrom org.gluu.oxauth.cert.fingerprint import FingerprintHelper\nfrom org.gluu.oxauth.cert.validation import GenericCertificateVerifier, PathCertificateVerifier, OCSPCertificateVerifier, CRLCertificateVerifier\nfrom org.gluu.oxauth.cert.validation.model import ValidationStatus\nfrom org.gluu.oxauth.util import CertUtil\nfrom org.gluu.oxauth.model.util import CertUtils\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.apache.http.params import CoreConnectionPNames\n\nimport sys\nimport base64\nimport urllib\n\nimport java\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Cert. Initialization\"\n\n if not (configurationAttributes.containsKey(\"chain_cert_file_path\")):\n print \"Cert. Initialization. Property chain_cert_file_path is mandatory\"\n return False\n\n if not (configurationAttributes.containsKey(\"map_user_cert\")):\n print \"Cert. Initialization. Property map_user_cert is mandatory\"\n return False\n\n chain_cert_file_path = configurationAttributes.get(\"chain_cert_file_path\").getValue2()\n\n self.chain_certs = CertUtil.loadX509CertificateFromFile(chain_cert_file_path)\n if self.chain_certs == None:\n print \"Cert. Initialization. Failed to load chain certificates from '%s'\" % chain_cert_file_path\n return False\n\n print \"Cert. Initialization. Loaded '%d' chain certificates\" % self.chain_certs.size()\n \n crl_max_response_size = 5 * 1024 * 1024 # 10Mb\n if configurationAttributes.containsKey(\"crl_max_response_size\"):\n crl_max_response_size = StringHelper.toInteger(configurationAttributes.get(\"crl_max_response_size\").getValue2(), crl_max_response_size)\n print \"Cert. Initialization. CRL max response size is '%d'\" % crl_max_response_size\n\n # Define array to order methods correctly\n self.validator_types = [ 'generic', 'path', 'ocsp', 'crl']\n self.validators = { 'generic' : [GenericCertificateVerifier(), False],\n 'path' : [PathCertificateVerifier(False), False],\n 'ocsp' : [OCSPCertificateVerifier(), False],\n 'crl' : [CRLCertificateVerifier(crl_max_response_size), False] }\n\n for type in self.validator_types:\n validator_param_name = \"use_%s_validator\" % type\n if configurationAttributes.containsKey(validator_param_name):\n validator_status = StringHelper.toBoolean(configurationAttributes.get(validator_param_name).getValue2(), False)\n self.validators[type][1] = validator_status\n\n print \"Cert. Initialization. Validation method '%s' status: '%s'\" % (type, self.validators[type][1])\n\n self.map_user_cert = StringHelper.toBoolean(configurationAttributes.get(\"map_user_cert\").getValue2(), False)\n print \"Cert. Initialization. map_user_cert: '%s'\" % self.map_user_cert\n\n self.enabled_recaptcha = self.initRecaptcha(configurationAttributes)\n print \"Cert. Initialization. enabled_recaptcha: '%s'\" % self.enabled_recaptcha\n\n print \"Cert. Initialized successfully\"\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Cert. Destroy\"\n\n for type in self.validator_types:\n self.validators[type][0].destroy()\n\n print \"Cert. Destroyed successfully\"\n\n return True\n\n def getApiVersion(self):\n return 11\n\n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n user_name = credentials.getUsername()\n\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n if step == 1:\n print \"Cert. Authenticate for step 1\"\n login_button = ServerUtil.getFirstValue(requestParameters, \"loginForm:loginButton\")\n if StringHelper.isEmpty(login_button):\n print \"Cert. Authenticate for step 1. Form were submitted incorrectly\"\n return False\n if self.enabled_recaptcha:\n print \"Cert. Authenticate for step 1. Validating recaptcha response\"\n recaptcha_response = ServerUtil.getFirstValue(requestParameters, \"g-recaptcha-response\")\n\n recaptcha_result = self.validateRecaptcha(recaptcha_response)\n print \"Cert. Authenticate for step 1. recaptcha_result: '%s'\" % recaptcha_result\n \n return recaptcha_result\n\n return True\n elif step == 2:\n print \"Cert. Authenticate for step 2\"\n\n # Validate if user selected certificate\n cert_x509 = self.getSessionAttribute(\"cert_x509\")\n if cert_x509 == None:\n print \"Cert. Authenticate for step 2. User not selected any certs\"\n identity.setWorkingParameter(\"cert_selected\", False)\n \n # Return True to inform user how to reset workflow\n return True\n else:\n identity.setWorkingParameter(\"cert_selected\", True)\n x509Certificate = self.certFromString(cert_x509)\n\n subjectX500Principal = x509Certificate.getSubjectX500Principal()\n print \"Cert. Authenticate for step 2. User selected certificate with DN '%s'\" % subjectX500Principal\n \n # Validate certificates which user selected\n valid = self.validateCertificate(x509Certificate)\n if not valid:\n print \"Cert. Authenticate for step 2. Certificate DN '%s' is not valid\" % subjectX500Principal\n identity.setWorkingParameter(\"cert_valid\", False)\n \n # Return True to inform user how to reset workflow\n return True\n\n identity.setWorkingParameter(\"cert_valid\", True)\n \n # Calculate certificate fingerprint\n x509CertificateFingerprint = self.calculateCertificateFingerprint(x509Certificate)\n identity.setWorkingParameter(\"cert_x509_fingerprint\", x509CertificateFingerprint)\n print \"Cert. Authenticate for step 2. Fingerprint is '%s' of certificate with DN '%s'\" % (x509CertificateFingerprint, subjectX500Principal)\n \n # Attempt to find user by certificate fingerprint\n cert_user_external_uid = \"cert:%s\" % x509CertificateFingerprint\n print \"Cert. Authenticate for step 2. Attempting to find user by oxExternalUid attribute value %s\" % cert_user_external_uid\n\n find_user_by_external_uid = userService.getUserByAttribute(\"oxExternalUid\", cert_user_external_uid)\n if find_user_by_external_uid == None:\n print \"Cert. Authenticate for step 2. Failed to find user\"\n \n if self.map_user_cert:\n print \"Cert. Authenticate for step 2. Storing cert_user_external_uid for step 3\"\n identity.setWorkingParameter(\"cert_user_external_uid\", cert_user_external_uid)\n return True\n else:\n print \"Cert. Authenticate for step 2. Mapping cert to user account is not allowed\"\n identity.setWorkingParameter(\"cert_count_login_steps\", 2)\n return False\n\n foundUserName = find_user_by_external_uid.getUserId()\n print \"Cert. Authenticate for step 2. foundUserName: \" + foundUserName\n\n logged_in = False\n userService = CdiUtil.bean(UserService)\n logged_in = authenticationService.authenticate(foundUserName)\n \n print \"Cert. Authenticate for step 2. Setting count steps to 2\"\n identity.setWorkingParameter(\"cert_count_login_steps\", 2)\n\n return logged_in\n elif step == 3:\n print \"Cert. Authenticate for step 3\"\n\n cert_user_external_uid = self.getSessionAttribute(\"cert_user_external_uid\")\n if cert_user_external_uid == None:\n print \"Cert. Authenticate for step 3. cert_user_external_uid is empty\"\n return False\n\n user_password = credentials.getPassword()\n\n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if (not logged_in):\n return False\n\n # Double check just to make sure. We did checking in previous step\n # Check if there is user which has cert_user_external_uid\n # Avoid mapping user cert to more than one IDP account\n find_user_by_external_uid = userService.getUserByAttribute(\"oxExternalUid\", cert_user_external_uid)\n if find_user_by_external_uid == None:\n # Add cert_user_external_uid to user's external GUID list\n find_user_by_external_uid = userService.addUserAttribute(user_name, \"oxExternalUid\", cert_user_external_uid)\n if find_user_by_external_uid == None:\n print \"Cert. Authenticate for step 3. Failed to update current user\"\n return False\n\n return True\n \n return True\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n print \"Cert. Prepare for step %d\" % step\n identity = CdiUtil.bean(Identity)\n \n if step == 1:\n if self.enabled_recaptcha:\n identity.setWorkingParameter(\"recaptcha_site_key\", self.recaptcha_creds['site_key'])\n elif step == 2:\n # Store certificate in session\n facesContext = CdiUtil.bean(FacesContext)\n externalContext = facesContext.getExternalContext()\n request = externalContext.getRequest()\n\n # Try to get certificate from header X-ClientCert\n clientCertificate = externalContext.getRequestHeaderMap().get(\"X-ClientCert\")\n if clientCertificate != None:\n x509Certificate = self.certFromPemString(clientCertificate)\n identity.setWorkingParameter(\"cert_x509\", self.certToString(x509Certificate))\n print \"Cert. Prepare for step 2. Storing user certificate obtained from 'X-ClientCert' header\"\n return True\n\n # Try to get certificate from attribute javax.servlet.request.X509Certificate\n x509Certificates = request.getAttribute('javax.servlet.request.X509Certificate')\n if (x509Certificates != None) and (len(x509Certificates) > 0):\n identity.setWorkingParameter(\"cert_x509\", self.certToString(x509Certificates[0]))\n print \"Cert. Prepare for step 2. Storing user certificate obtained from 'javax.servlet.request.X509Certificate' attribute\"\n return True\n\n if step < 4:\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return Arrays.asList(\"cert_selected\", \"cert_valid\", \"cert_x509\", \"cert_x509_fingerprint\", \"cert_count_login_steps\", \"cert_user_external_uid\")\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n cert_count_login_steps = self.getSessionAttribute(\"cert_count_login_steps\")\n if cert_count_login_steps != None:\n return cert_count_login_steps\n else:\n return 3\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 1:\n return \"/auth/cert/login.xhtml\"\n if step == 2:\n return \"/auth/cert/cert-login.xhtml\"\n elif step == 3:\n cert_selected = self.getSessionAttribute(\"cert_selected\")\n if True != cert_selected:\n return \"/auth/cert/cert-not-selected.xhtml\"\n\n cert_valid = self.getSessionAttribute(\"cert_valid\")\n if True != cert_valid:\n return \"/auth/cert/cert-invalid.xhtml\"\n \n return \"/login.xhtml\"\n\n return \"\"\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def processBasicAuthentication(self, credentials):\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if (not logged_in):\n return None\n\n find_user_by_uid = authenticationService.getAuthenticatedUser()\n if (find_user_by_uid == None):\n print \"Cert. Process basic authentication. Failed to find user '%s'\" % user_name\n return None\n \n return find_user_by_uid\n\n def getSessionAttribute(self, attribute_name):\n identity = CdiUtil.bean(Identity)\n\n # Try to get attribute value from Seam event context\n if identity.isSetWorkingParameter(attribute_name):\n return identity.getWorkingParameter(attribute_name)\n \n # Try to get attribute from persistent session\n session_id = identity.getSessionId()\n if session_id == None:\n return None\n\n session_attributes = session_id.getSessionAttributes()\n if session_attributes == None:\n return None\n\n if session_attributes.containsKey(attribute_name):\n return session_attributes.get(attribute_name)\n\n return None\n\n def calculateCertificateFingerprint(self, x509Certificate):\n print \"Cert. Calculate fingerprint for certificate DN '%s'\" % x509Certificate.getSubjectX500Principal()\n \n publicKey = x509Certificate.getPublicKey()\n \n # Use oxAuth implementation\n fingerprint = FingerprintHelper.getPublicKeySshFingerprint(publicKey)\n \n return fingerprint \n\n def validateCertificate(self, x509Certificate):\n subjectX500Principal = x509Certificate.getSubjectX500Principal()\n\n print \"Cert. Validating certificate with DN '%s'\" % subjectX500Principal\n \n validation_date = java.util.Date()\n\n for type in self.validator_types:\n if self.validators[type][1]:\n result = self.validators[type][0].validate(x509Certificate, self.chain_certs, validation_date)\n print \"Cert. Validate certificate: '%s'. Validation method '%s' result: '%s'\" % (subjectX500Principal, type, result)\n \n if (result.getValidity() != ValidationStatus.CertificateValidity.VALID):\n print \"Cert. Certificate: '%s' is invalid\" % subjectX500Principal\n return False\n \n return True\n\n def certToString(self, x509Certificate):\n if x509Certificate == None:\n return None\n return base64.b64encode(x509Certificate.getEncoded())\n\n def certFromString(self, x509CertificateEncoded):\n x509CertificateDecoded = base64.b64decode(x509CertificateEncoded)\n return CertUtils.x509CertificateFromBytes(x509CertificateDecoded)\n\n def certFromPemString(self, pemCertificate):\n x509CertificateEncoded = pemCertificate.replace(\"-----BEGIN CERTIFICATE-----\", \"\").replace(\"-----END CERTIFICATE-----\", \"\").strip()\n return self.certFromString(x509CertificateEncoded)\n\n def initRecaptcha(self, configurationAttributes):\n print \"Cert. Initialize recaptcha\"\n if not configurationAttributes.containsKey(\"credentials_file\"):\n return False\n\n cert_creds_file = configurationAttributes.get(\"credentials_file\").getValue2()\n\n # Load credentials from file\n f = open(cert_creds_file, 'r')\n try:\n creds = json.loads(f.read())\n except:\n print \"Cert. Initialize recaptcha. Failed to load credentials from file: %s\" % cert_creds_file\n return False\n finally:\n f.close()\n \n try:\n recaptcha_creds = creds[\"recaptcha\"]\n except:\n print \"Cert. Initialize recaptcha. Invalid credentials file '%s' format:\" % cert_creds_file\n return False\n \n self.recaptcha_creds = None\n if recaptcha_creds[\"enabled\"]:\n print \"Cert. Initialize recaptcha. Recaptcha is enabled\"\n\n encryptionService = CdiUtil.bean(EncryptionService)\n\n site_key = recaptcha_creds[\"site_key\"]\n secret_key = recaptcha_creds[\"secret_key\"]\n\n try:\n site_key = encryptionService.decrypt(site_key)\n except:\n # Ignore exception. Value is not encrypted\n print \"Cert. Initialize recaptcha. Assuming that 'site_key' in not encrypted\"\n\n try:\n secret_key = encryptionService.decrypt(secret_key)\n except:\n # Ignore exception. Value is not encrypted\n print \"Cert. Initialize recaptcha. Assuming that 'secret_key' in not encrypted\"\n\n \n self.recaptcha_creds = { 'site_key' : site_key, \"secret_key\" : secret_key }\n print \"Cert. Initialize recaptcha. Recaptcha is configured correctly\"\n\n return True\n else:\n print \"Cert. Initialize recaptcha. Recaptcha is disabled\"\n\n return False\n\n def validateRecaptcha(self, recaptcha_response):\n print \"Cert. Validate recaptcha response\"\n\n facesContext = CdiUtil.bean(FacesContext)\n request = facesContext.getExternalContext().getRequest()\n\n remoteip = ServerUtil.getIpAddress(request)\n print \"Cert. Validate recaptcha response. remoteip: '%s'\" % remoteip\n\n httpService = CdiUtil.bean(HttpService)\n\n http_client = httpService.getHttpsClient()\n http_client_params = http_client.getParams()\n http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000)\n \n recaptcha_validation_url = \"https://www.google.com/recaptcha/api/siteverify\"\n recaptcha_validation_request = urllib.urlencode({ \"secret\" : self.recaptcha_creds['secret_key'], \"response\" : recaptcha_response, \"remoteip\" : remoteip })\n recaptcha_validation_headers = { \"Content-type\" : \"application/x-www-form-urlencoded\", \"Accept\" : \"application/json\" }\n\n try:\n http_service_response = httpService.executePost(http_client, recaptcha_validation_url, None, recaptcha_validation_headers, recaptcha_validation_request)\n http_response = http_service_response.getHttpResponse()\n except:\n print \"Cert. Validate recaptcha response. Exception: \", sys.exc_info()[1]\n return False\n\n try:\n if not httpService.isResponseStastusCodeOk(http_response):\n print \"Cert. Validate recaptcha response. Get invalid response from validation server: \", str(http_response.getStatusLine().getStatusCode())\n httpService.consume(http_response)\n return False\n \n response_bytes = httpService.getResponseContent(http_response)\n response_string = httpService.convertEntityToString(response_bytes)\n httpService.consume(http_response)\n finally:\n http_service_response.closeConnection()\n\n if response_string == None:\n print \"Cert. Validate recaptcha response. Get empty response from validation server\"\n return False\n \n response = json.loads(response_string)\n \n return response[\"success\"]\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - }, - { - "value2": "interactive", - "value1": "usage_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "cert", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "/etc/certs/chain_cert.pem", - "value1": "chain_cert_file_path" - }, - { - "hide": false, - "value2": "/etc/certs/cert_creds.json", - "value1": "credentials_file" - }, - { - "hide": false, - "value2": "true", - "value1": "map_user_cert" - }, - { - "hide": false, - "value2": "true", - "value1": "use_generic_validator" - }, - { - "hide": false, - "value2": "true", - "value1": "use_path_validator" - }, - { - "hide": false, - "value2": "false", - "value1": "use_ocsp_validator" - }, - { - "hide": false, - "value2": "false", - "value1": "use_crl_validator" - }, - { - "hide": false, - "value2": "10485760", - "value1": "crl_max_response_size" - } - ], - "baseDn": "inum=2124-0CF1,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 40, - "programmingLanguage": "PYTHON", - "description": "OTP Validation of passwords using Yubicloud authentication module", - "locationType": "LDAP", - "dn": "inum=24FD-B96E,ou=scripts,o=gluu", - "inum": "24FD-B96E", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan, Arunmozhi\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import UserService\nfrom org.gluu.util import StringHelper\n\nimport java\n\nimport urllib2\nimport urllib\nimport uuid\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Yubicloud. Initialization\"\n\n self.api_server = configurationAttributes.get(\"yubicloud_uri\").getValue2()\n self.api_key = configurationAttributes.get(\"yubicloud_api_key\").getValue2()\n self.client_id = configurationAttributes.get(\"yubicloud_id\").getValue2()\n\n return True\n\n def destroy(self, configurationAttributes):\n print \"Yubicloud. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n if (step == 1):\n print \"Yubicloud. Authenticate for step 1\"\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n username = credentials.getUsername()\n otp = credentials.getPassword()\n\n # Validate otp length\n if len(otp) < 32 or len(otp) > 48:\n print \"Yubicloud. Invalid OTP length\"\n return False\n\n user_service = CdiUtil.bean(UserService)\n user = user_service.getUser(username)\n\n public_key = user.getAttribute('yubikeyId')\n\n # Match the user with the yubikey\n if public_key not in otp:\n print \"Yubicloud. Public Key not matching OTP\"\n return False\n\n data = \"\"\n try:\n nonce = str(uuid.uuid4()).replace(\"-\", \"\")\n params = urllib.urlencode({\"id\": self.client_id, \"otp\": otp, \"nonce\": nonce})\n url = \"https://\" + self.api_server + \"/wsapi/2.0/verify/?\" + params\n f = urllib2.urlopen(url)\n data = f.read()\n except Exception as e:\n print \"Yubicloud. Exception \", e\n\n if 'status=OK' in data:\n user_service.authenticate(username)\n print \"Yubicloud. Authentication Successful\"\n return True\n\n print \"Yubicloud. End of Step 1. Returning False.\"\n return False\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n if (step == 1):\n print \"Yubicloud. Prepare for Step 1\"\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 1\n\n def getPageForStep(self, configurationAttributes, step):\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "yubicloud", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "api.yubico.com", - "value1": "yubicloud_uri" - }, - { - "hide": false, - "value1": "yubicloud_api_key" - }, - { - "hide": false, - "value1": "yubicloud_id" - } - ], - "baseDn": "inum=24FD-B96E,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 40, - "programmingLanguage": "PYTHON", - "description": "HOTP/TOPT authentication module", - "locationType": "LDAP", - "dn": "inum=5018-D4BF,ou=scripts,o=gluu", - "inum": "5018-D4BF", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\n# Requires the following custom properties and values:\n# otp_type: totp/hotp\n# issuer: Gluu Inc\n# otp_conf_file: /etc/certs/otp_configuration.json\n#\n# These are non mandatory custom properties and values:\n# label: Gluu OTP\n# qr_options: { width: 400, height: 400 }\n# registration_uri: https://ce-dev.gluu.org/identity/register\n\nimport jarray\nimport json\nimport sys\nfrom com.google.common.io import BaseEncoding\nfrom com.lochbridge.oath.otp import HOTP\nfrom com.lochbridge.oath.otp import HOTPValidator\nfrom com.lochbridge.oath.otp import HmacShaAlgorithm\nfrom com.lochbridge.oath.otp import TOTP\nfrom com.lochbridge.oath.otp.keyprovisioning import OTPAuthURIBuilder\nfrom com.lochbridge.oath.otp.keyprovisioning import OTPKey\nfrom com.lochbridge.oath.otp.keyprovisioning.OTPKey import OTPType\nfrom java.security import SecureRandom\nfrom java.util import Arrays\nfrom java.util.concurrent import TimeUnit\nfrom javax.faces.application import FacesMessage\nfrom org.gluu.jsf2.message import FacesMessages\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"OTP. Initialization\"\n\n if not configurationAttributes.containsKey(\"otp_type\"):\n print \"OTP. Initialization. Property otp_type is mandatory\"\n return False\n self.otpType = configurationAttributes.get(\"otp_type\").getValue2()\n\n if not self.otpType in [\"hotp\", \"totp\"]:\n print \"OTP. Initialization. Property value otp_type is invalid\"\n return False\n\n if not configurationAttributes.containsKey(\"issuer\"):\n print \"OTP. Initialization. Property issuer is mandatory\"\n return False\n self.otpIssuer = configurationAttributes.get(\"issuer\").getValue2()\n\n self.customLabel = None\n if configurationAttributes.containsKey(\"label\"):\n self.customLabel = configurationAttributes.get(\"label\").getValue2()\n\n self.customQrOptions = {}\n if configurationAttributes.containsKey(\"qr_options\"):\n self.customQrOptions = configurationAttributes.get(\"qr_options\").getValue2()\n\n self.registrationUri = None\n if configurationAttributes.containsKey(\"registration_uri\"):\n self.registrationUri = configurationAttributes.get(\"registration_uri\").getValue2()\n\n validOtpConfiguration = self.loadOtpConfiguration(configurationAttributes)\n if not validOtpConfiguration:\n return False\n\n print \"OTP. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"OTP. Destroy\"\n print \"OTP. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n print \"getNextStep Invoked\"\n # If user not pass current step change step to previous\n identity = CdiUtil.bean(Identity)\n retry_current_step = identity.getWorkingParameter(\"retry_current_step\")\n if retry_current_step:\n print \"OTP. Get next step. Retrying current step %s\" % step\n # Remove old QR code\n #identity.setWorkingParameter(\"super_gluu_request\", \"timeout\")\n resultStep = step\n return resultStep\n return -1\n\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n self.setRequestScopedParameters(identity)\n\n if step == 1:\n print \"OTP. Authenticate for step 1\"\n authenticated_user = self.processBasicAuthentication(credentials)\n if authenticated_user == None:\n return False\n\n otp_auth_method = \"authenticate\"\n # Uncomment this block if you need to allow user second OTP registration\n #enrollment_mode = ServerUtil.getFirstValue(requestParameters, \"loginForm:registerButton\")\n #if StringHelper.isNotEmpty(enrollment_mode):\n # otp_auth_method = \"enroll\"\n\n if otp_auth_method == \"authenticate\":\n user_enrollments = self.findEnrollments(authenticated_user.getUserId())\n if len(user_enrollments) == 0:\n otp_auth_method = \"enroll\"\n print \"OTP. Authenticate for step 1. There is no OTP enrollment for user '%s'. Changing otp_auth_method to '%s'\" % (authenticated_user.getUserId(), otp_auth_method)\n\n if otp_auth_method == \"enroll\":\n print \"OTP. Authenticate for step 1. Setting count steps: '%s'\" % 3\n identity.setWorkingParameter(\"otp_count_login_steps\", 3)\n\n print \"OTP. Authenticate for step 1. otp_auth_method: '%s'\" % otp_auth_method\n identity.setWorkingParameter(\"otp_auth_method\", otp_auth_method)\n\n return True\n elif step == 2:\n print \"OTP. Authenticate for step 2\"\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"OTP. Authenticate for step 2. Failed to determine user name\"\n return False\n\n session_id_validation = self.validateSessionId(identity)\n if not session_id_validation:\n return False\n\n # Restore state from session\n identity.setWorkingParameter(\"retry_current_step\", False)\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n if otp_auth_method == 'enroll':\n auth_result = ServerUtil.getFirstValue(requestParameters, \"auth_result\")\n if not StringHelper.isEmpty(auth_result):\n # defect fix #1225 - Retry the step, show QR code again\n if auth_result == 'timeout':\n\t\t\t\t\t\tprint \"OTP. QR-code timeout. Authenticate for step %s. Reinitializing current step\" % step\n\t\t\t\t\t\tidentity.setWorkingParameter(\"retry_current_step\", True)\n\t\t\t\t\t\treturn True\n\n print \"OTP. Authenticate for step 2. User not enrolled OTP\"\n return False\n\n print \"OTP. Authenticate for step 2. Skipping this step during enrollment\"\n return True\n\n otp_auth_result = self.processOtpAuthentication(requestParameters, user.getUserId(), identity, otp_auth_method)\n print \"OTP. Authenticate for step 2. OTP authentication result: '%s'\" % otp_auth_result\n\n return otp_auth_result\n elif step == 3:\n print \"OTP. Authenticate for step 3\"\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"OTP. Authenticate for step 2. Failed to determine user name\"\n return False\n\n session_id_validation = self.validateSessionId(identity)\n if not session_id_validation:\n return False\n\n # Restore state from session\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n if otp_auth_method != 'enroll':\n return False\n\n otp_auth_result = self.processOtpAuthentication(requestParameters, user.getUserId(), identity, otp_auth_method)\n print \"OTP. Authenticate for step 3. OTP authentication result: '%s'\" % otp_auth_result\n\n return otp_auth_result\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n self.setRequestScopedParameters(identity)\n\n if step == 1:\n print \"OTP. Prepare for step 1\"\n\n return True\n elif step == 2:\n print \"OTP. Prepare for step 2\"\n\n session_id_validation = self.validateSessionId(identity)\n if not session_id_validation:\n return False\n\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n print \"OTP. Prepare for step 2. otp_auth_method: '%s'\" % otp_auth_method\n\n if otp_auth_method == 'enroll':\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"OTP. Prepare for step 2. Failed to load user enty\"\n return False\n\n if self.otpType == \"hotp\":\n otp_secret_key = self.generateSecretHotpKey()\n otp_enrollment_request = self.generateHotpSecretKeyUri(otp_secret_key, self.otpIssuer, user.getAttribute(\"displayName\"))\n elif self.otpType == \"totp\":\n otp_secret_key = self.generateSecretTotpKey()\n otp_enrollment_request = self.generateTotpSecretKeyUri(otp_secret_key, self.otpIssuer, user.getAttribute(\"displayName\"))\n else:\n print \"OTP. Prepare for step 2. Unknown OTP type: '%s'\" % self.otpType\n return False\n\n print \"OTP. Prepare for step 2. Prepared enrollment request for user: '%s'\" % user.getUserId()\n identity.setWorkingParameter(\"otp_secret_key\", self.toBase64Url(otp_secret_key))\n identity.setWorkingParameter(\"otp_enrollment_request\", otp_enrollment_request)\n\n return True\n elif step == 3:\n print \"OTP. Prepare for step 3\"\n\n session_id_validation = self.validateSessionId(identity)\n if not session_id_validation:\n return False\n\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n print \"OTP. Prepare for step 3. otp_auth_method: '%s'\" % otp_auth_method\n\n if otp_auth_method == 'enroll':\n return True\n\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return Arrays.asList(\"otp_auth_method\", \"otp_count_login_steps\", \"otp_secret_key\", \"otp_enrollment_request\",\"retry_current_step\")\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n identity = CdiUtil.bean(Identity)\n\n if identity.isSetWorkingParameter(\"otp_count_login_steps\"):\n return StringHelper.toInteger(\"%s\" % identity.getWorkingParameter(\"otp_count_login_steps\"))\n else:\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 2:\n identity = CdiUtil.bean(Identity)\n\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n print \"OTP. Gep page for step 2. otp_auth_method: '%s'\" % otp_auth_method\n\n if otp_auth_method == 'enroll':\n return \"/auth/otp/enroll.xhtml\"\n else:\n return \"/auth/otp/otplogin.xhtml\"\n elif step == 3:\n return \"/auth/otp/otplogin.xhtml\"\n\n return \"\"\n\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def setRequestScopedParameters(self, identity):\n if self.registrationUri != None:\n identity.setWorkingParameter(\"external_registration_uri\", self.registrationUri)\n\n if self.customLabel != None:\n identity.setWorkingParameter(\"qr_label\", self.customLabel)\n\n identity.setWorkingParameter(\"qr_options\", self.customQrOptions)\n\n def loadOtpConfiguration(self, configurationAttributes):\n print \"OTP. Load OTP configuration\"\n if not configurationAttributes.containsKey(\"otp_conf_file\"):\n return False\n\n otp_conf_file = configurationAttributes.get(\"otp_conf_file\").getValue2()\n\n # Load configuration from file\n f = open(otp_conf_file, 'r')\n try:\n otpConfiguration = json.loads(f.read())\n except:\n print \"OTP. Load OTP configuration. Failed to load configuration from file:\", otp_conf_file\n return False\n finally:\n f.close()\n\n # Check configuration file settings\n try:\n self.hotpConfiguration = otpConfiguration[\"hotp\"]\n self.totpConfiguration = otpConfiguration[\"totp\"]\n \n hmacShaAlgorithm = self.totpConfiguration[\"hmacShaAlgorithm\"]\n hmacShaAlgorithmType = None\n\n if StringHelper.equalsIgnoreCase(hmacShaAlgorithm, \"sha1\"):\n hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_1\n elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, \"sha256\"):\n hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_256\n elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, \"sha512\"):\n hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_512\n else:\n print \"OTP. Load OTP configuration. Invalid TOTP HMAC SHA algorithm: '%s'\" % hmacShaAlgorithm\n \n self.totpConfiguration[\"hmacShaAlgorithmType\"] = hmacShaAlgorithmType\n except:\n print \"OTP. Load OTP configuration. Invalid configuration file '%s' format. Exception: '%s'\" % (otp_conf_file, sys.exc_info()[1])\n return False\n \n\n return True\n\n def processBasicAuthentication(self, credentials):\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return None\n\n find_user_by_uid = authenticationService.getAuthenticatedUser()\n if find_user_by_uid == None:\n print \"OTP. Process basic authentication. Failed to find user '%s'\" % user_name\n return None\n \n return find_user_by_uid\n\n def findEnrollments(self, user_name, skipPrefix = True):\n result = []\n\n userService = CdiUtil.bean(UserService)\n user = userService.getUser(user_name, \"oxExternalUid\")\n if user == None:\n print \"OTP. Find enrollments. Failed to find user\"\n return result\n \n user_custom_ext_attribute = userService.getCustomAttribute(user, \"oxExternalUid\")\n if user_custom_ext_attribute == None:\n return result\n\n otp_prefix = \"%s:\" % self.otpType\n \n otp_prefix_length = len(otp_prefix) \n for user_external_uid in user_custom_ext_attribute.getValues():\n index = user_external_uid.find(otp_prefix)\n if index != -1:\n if skipPrefix:\n enrollment_uid = user_external_uid[otp_prefix_length:]\n else:\n enrollment_uid = user_external_uid\n\n result.append(enrollment_uid)\n \n return result\n\n def validateSessionId(self, identity):\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"OTP. Validate session id. Failed to determine session_id\"\n return False\n\n otp_auth_method = identity.getWorkingParameter(\"otp_auth_method\")\n if not otp_auth_method in ['enroll', 'authenticate']:\n print \"OTP. Validate session id. Failed to authenticate user. otp_auth_method: '%s'\" % otp_auth_method\n return False\n\n return True\n\n def processOtpAuthentication(self, requestParameters, user_name, identity, otp_auth_method):\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n\n userService = CdiUtil.bean(UserService)\n\n otpCode = ServerUtil.getFirstValue(requestParameters, \"loginForm:otpCode\")\n if StringHelper.isEmpty(otpCode):\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to authenticate. OTP code is empty\")\n print \"OTP. Process OTP authentication. otpCode is empty\"\n\n return False\n \n if otp_auth_method == \"enroll\":\n # Get key from session\n otp_secret_key_encoded = identity.getWorkingParameter(\"otp_secret_key\")\n if otp_secret_key_encoded == None:\n print \"OTP. Process OTP authentication. OTP secret key is invalid\"\n return False\n \n otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)\n\n if self.otpType == \"hotp\":\n validation_result = self.validateHotpKey(otp_secret_key, 1, otpCode)\n \n if (validation_result != None) and validation_result[\"result\"]:\n print \"OTP. Process HOTP authentication during enrollment. otpCode is valid\"\n # Store HOTP Secret Key and moving factor in user entry\n otp_user_external_uid = \"hotp:%s;%s\" % ( otp_secret_key_encoded, validation_result[\"movingFactor\"] )\n\n # Add otp_user_external_uid to user's external GUID list\n find_user_by_external_uid = userService.addUserAttribute(user_name, \"oxExternalUid\", otp_user_external_uid)\n if find_user_by_external_uid != None:\n return True\n\n print \"OTP. Process HOTP authentication during enrollment. Failed to update user entry\"\n elif self.otpType == \"totp\":\n validation_result = self.validateTotpKey(otp_secret_key, otpCode,user_name)\n if (validation_result != None) and validation_result[\"result\"]:\n print \"OTP. Process TOTP authentication during enrollment. otpCode is valid\"\n # Store TOTP Secret Key and moving factor in user entry\n otp_user_external_uid = \"totp:%s\" % otp_secret_key_encoded\n\n # Add otp_user_external_uid to user's external GUID list\n find_user_by_external_uid = userService.addUserAttribute(user_name, \"oxExternalUid\", otp_user_external_uid)\n if find_user_by_external_uid != None:\n return True\n\n print \"OTP. Process TOTP authentication during enrollment. Failed to update user entry\"\n elif otp_auth_method == \"authenticate\":\n user_enrollments = self.findEnrollments(user_name)\n\n if len(user_enrollments) == 0:\n print \"OTP. Process OTP authentication. There is no OTP enrollment for user '%s'\" % user_name\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"There is no valid OTP user enrollments\")\n return False\n\n if self.otpType == \"hotp\":\n for user_enrollment in user_enrollments:\n user_enrollment_data = user_enrollment.split(\";\")\n otp_secret_key_encoded = user_enrollment_data[0]\n\n # Get current moving factor from user entry\n moving_factor = StringHelper.toInteger(user_enrollment_data[1])\n otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)\n\n # Validate TOTP\n validation_result = self.validateHotpKey(otp_secret_key, moving_factor, otpCode)\n if (validation_result != None) and validation_result[\"result\"]:\n print \"OTP. Process HOTP authentication during authentication. otpCode is valid\"\n otp_user_external_uid = \"hotp:%s;%s\" % ( otp_secret_key_encoded, moving_factor )\n new_otp_user_external_uid = \"hotp:%s;%s\" % ( otp_secret_key_encoded, validation_result[\"movingFactor\"] )\n \n # Update moving factor in user entry\n find_user_by_external_uid = userService.replaceUserAttribute(user_name, \"oxExternalUid\", otp_user_external_uid, new_otp_user_external_uid)\n if find_user_by_external_uid != None:\n return True\n \n print \"OTP. Process HOTP authentication during authentication. Failed to update user entry\"\n elif self.otpType == \"totp\":\n for user_enrollment in user_enrollments:\n otp_secret_key = self.fromBase64Url(user_enrollment)\n\n # Validate TOTP\n validation_result = self.validateTotpKey(otp_secret_key, otpCode, user_name)\n if (validation_result != None) and validation_result[\"result\"]:\n print \"OTP. Process TOTP authentication during authentication. otpCode is valid\"\n return True\n\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to authenticate. OTP code is invalid\")\n print \"OTP. Process OTP authentication. OTP code is invalid\"\n\n return False\n\n # Shared HOTP/TOTP methods\n def generateSecretKey(self, keyLength):\n bytes = jarray.zeros(keyLength, \"b\")\n secureRandom = SecureRandom()\n secureRandom.nextBytes(bytes)\n \n return bytes\n \n # HOTP methods\n def generateSecretHotpKey(self):\n keyLength = self.hotpConfiguration[\"keyLength\"]\n \n return self.generateSecretKey(keyLength)\n\n def generateHotpKey(self, secretKey, movingFactor):\n digits = self.hotpConfiguration[\"digits\"]\n\n hotp = HOTP.key(secretKey).digits(digits).movingFactor(movingFactor).build()\n \n return hotp.value()\n\n def validateHotpKey(self, secretKey, movingFactor, totpKey):\n lookAheadWindow = self.hotpConfiguration[\"lookAheadWindow\"]\n digits = self.hotpConfiguration[\"digits\"]\n\n htopValidationResult = HOTPValidator.lookAheadWindow(lookAheadWindow).validate(secretKey, movingFactor, digits, totpKey)\n if htopValidationResult.isValid():\n return { \"result\": True, \"movingFactor\": htopValidationResult.getNewMovingFactor() }\n\n return { \"result\": False, \"movingFactor\": None }\n\n def generateHotpSecretKeyUri(self, secretKey, issuer, userDisplayName):\n digits = self.hotpConfiguration[\"digits\"]\n\n secretKeyBase32 = self.toBase32(secretKey)\n otpKey = OTPKey(secretKeyBase32, OTPType.HOTP)\n label = issuer + \" %s\" % userDisplayName\n\n otpAuthURI = OTPAuthURIBuilder.fromKey(otpKey).label(label).issuer(issuer).digits(digits).build()\n\n return otpAuthURI.toUriString()\n\n # TOTP methods\n def generateSecretTotpKey(self):\n keyLength = self.totpConfiguration[\"keyLength\"]\n \n return self.generateSecretKey(keyLength)\n\n def generateTotpKey(self, secretKey):\n digits = self.totpConfiguration[\"digits\"]\n timeStep = self.totpConfiguration[\"timeStep\"]\n hmacShaAlgorithmType = self.totpConfiguration[\"hmacShaAlgorithmType\"]\n\n totp = TOTP.key(secretKey).digits(digits).timeStep(TimeUnit.SECONDS.toMillis(timeStep)).hmacSha(hmacShaAlgorithmType).build()\n \n return totp.value()\n\n def validateTotpKey(self, secretKey, totpKey, user_name):\n localTotpKey = self.generateTotpKey(secretKey)\n cachedOTP = self.getCachedOTP(user_name)\n\n if StringHelper.equals(localTotpKey, totpKey) and not StringHelper.equals(localTotpKey, cachedOTP):\n userService = CdiUtil.bean(UserService)\n if cachedOTP is None:\n userService.addUserAttribute(user_name, \"oxOTPCache\",localTotpKey)\n else :\n userService.replaceUserAttribute(user_name, \"oxOTPCache\", cachedOTP, localTotpKey)\n print \"OTP. Caching OTP: '%s'\" % localTotpKey\n return { \"result\": True }\n return { \"result\": False }\n\t\n def getCachedOTP(self, user_name):\n userService = CdiUtil.bean(UserService)\n user = userService.getUser(user_name, \"oxOTPCache\")\n if user is None:\n print \"OTP. Get Cached OTP. Failed to find OTP\"\n return None\n customAttribute = userService.getCustomAttribute(user, \"oxOTPCache\")\n \n if customAttribute is None:\n print \"OTP. Custom attribute is null\"\n return None\n user_cached_OTP = customAttribute.getValue()\n if user_cached_OTP is None:\n print \"OTP. no OTP is present in LDAP\"\n return None\n \n print \"OTP.Cached OTP: '%s'\" % user_cached_OTP\n return user_cached_OTP\n \n def generateTotpSecretKeyUri(self, secretKey, issuer, userDisplayName):\n digits = self.totpConfiguration[\"digits\"]\n timeStep = self.totpConfiguration[\"timeStep\"]\n\n secretKeyBase32 = self.toBase32(secretKey)\n otpKey = OTPKey(secretKeyBase32, OTPType.TOTP)\n label = issuer + \" %s\" % userDisplayName\n\n otpAuthURI = OTPAuthURIBuilder.fromKey(otpKey).label(label).issuer(issuer).digits(digits).timeStep(TimeUnit.SECONDS.toMillis(timeStep)).build()\n\n return otpAuthURI.toUriString()\n\n # Utility methods\n def toBase32(self, bytes):\n return BaseEncoding.base32().omitPadding().encode(bytes)\n\n def toBase64Url(self, bytes):\n return BaseEncoding.base64Url().encode(bytes)\n\n def fromBase64Url(self, chars):\n return BaseEncoding.base64Url().decode(chars)\n\n\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - }, - { - "value2": "interactive", - "value1": "usage_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "otp", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "totp", - "value1": "otp_type" - }, - { - "hide": false, - "value2": "/etc/certs/otp_configuration.json", - "value1": "otp_conf_file" - }, - { - "hide": false, - "value2": "Gluu Inc", - "value1": "issuer" - }, - { - "hide": false, - "value2": "Gluu OTP", - "value1": "label" - }, - { - "hide": false, - "value2": "{ size: 400, mSize: 0.05 }", - "value1": "qr_options" - }, - { - "hide": false, - "value2": "https://pujavs4.2.gluu.server/identity/register", - "value1": "registration_uri" - } - ], - "baseDn": "inum=5018-D4BF,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 40, - "programmingLanguage": "PYTHON", - "description": "Passport authentication module", - "locationType": "LDAP", - "dn": "inum=2FDB-CF02,ou=scripts,o=gluu", - "inum": "2FDB-CF02", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2019, Gluu\n#\n# Author: Jose Gonzalez\n# Author: Yuriy Movchan\n#\nfrom org.gluu.jsf2.service import FacesService\nfrom org.gluu.jsf2.message import FacesMessages\n\nfrom org.gluu.oxauth.model.common import User, WebKeyStorage\nfrom org.gluu.oxauth.model.configuration import AppConfiguration\nfrom org.gluu.oxauth.model.crypto import CryptoProviderFactory\nfrom org.gluu.oxauth.model.jwt import Jwt, JwtClaimName\nfrom org.gluu.oxauth.model.util import Base64Util\nfrom org.gluu.oxauth.service import AppInitializer, AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService, EncryptionService\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.config.oxtrust import LdapOxPassportConfiguration\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.persist import PersistenceEntryManager\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\nfrom java.util import ArrayList, Arrays, Collections\n\nfrom javax.faces.application import FacesMessage\nfrom javax.faces.context import FacesContext\n\nimport json\nimport sys\nimport datetime\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Passport. init called\"\n\n self.extensionModule = self.loadExternalModule(configurationAttributes.get(\"extension_module\"))\n extensionResult = self.extensionInit(configurationAttributes)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. init. Behaviour is social\"\n success = self.processKeyStoreProperties(configurationAttributes)\n\n if success:\n self.providerKey = \"provider\"\n self.customAuthzParameter = self.getCustomAuthzParameter(configurationAttributes.get(\"authz_req_param_provider\"))\n self.passportDN = self.getPassportConfigDN()\n print \"Passport. init. Initialization success\"\n else:\n print \"Passport. init. Initialization failed\"\n return success\n\n\n def destroy(self, configurationAttributes):\n print \"Passport. destroy called\"\n return True\n\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n\n extensionResult = self.extensionAuthenticate(configurationAttributes, requestParameters, step)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. authenticate for step %s called\" % str(step)\n identity = CdiUtil.bean(Identity)\n\n if step == 1:\n # Get JWT token\n jwt_param = ServerUtil.getFirstValue(requestParameters, \"user\")\n\n if jwt_param != None:\n print \"Passport. authenticate for step 1. JWT user profile token found\"\n\n # Parse JWT and validate\n jwt = Jwt.parse(jwt_param)\n if not self.validSignature(jwt):\n return False\n\n if self.jwtHasExpired(jwt):\n return False\n\n (user_profile, jsonp) = self.getUserProfile(jwt)\n if user_profile == None:\n return False\n\n return self.attemptAuthentication(identity, user_profile, jsonp)\n\n #See passportlogin.xhtml\n provider = ServerUtil.getFirstValue(requestParameters, \"loginForm:provider\")\n if StringHelper.isEmpty(provider):\n\n #it's username + passw auth\n print \"Passport. authenticate for step 1. Basic authentication detected\"\n logged_in = False\n\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n authenticationService = CdiUtil.bean(AuthenticationService)\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n print \"Passport. authenticate for step 1. Basic authentication returned: %s\" % logged_in\n return logged_in\n\n elif provider in self.registeredProviders:\n #it's a recognized external IDP\n identity.setWorkingParameter(\"selectedProvider\", provider)\n print \"Passport. authenticate for step 1. Retrying step 1\"\n #see prepareForStep (step = 1)\n return True\n\n if step == 2:\n mail = ServerUtil.getFirstValue(requestParameters, \"loginForm:email\")\n jsonp = identity.getWorkingParameter(\"passport_user_profile\")\n\n if mail == None:\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email was missing in user profile\")\n elif jsonp != None:\n # Completion of profile takes place\n user_profile = json.loads(jsonp)\n user_profile[\"mail\"] = [ mail ]\n\n return self.attemptAuthentication(identity, user_profile, jsonp)\n\n print \"Passport. authenticate for step 2. Failed: expected mail value in HTTP request and json profile in session\"\n return False\n\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n\n extensionResult = self.extensionPrepareForStep(configurationAttributes, requestParameters, step)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. prepareForStep called %s\" % str(step)\n identity = CdiUtil.bean(Identity)\n\n if step == 1:\n #re-read the strategies config (for instance to know which strategies have enabled the email account linking)\n self.parseProviderConfigs()\n identity.setWorkingParameter(\"externalProviders\", json.dumps(self.registeredProviders))\n\n providerParam = self.customAuthzParameter\n url = None\n\n sessionAttributes = identity.getSessionId().getSessionAttributes()\n self.skipProfileUpdate = StringHelper.equalsIgnoreCase(sessionAttributes.get(\"skipPassportProfileUpdate\"), \"true\")\n\n #this param could have been set previously in authenticate step if current step is being retried\n provider = identity.getWorkingParameter(\"selectedProvider\")\n if provider != None:\n url = self.getPassportRedirectUrl(provider)\n identity.setWorkingParameter(\"selectedProvider\", None)\n\n elif providerParam != None:\n paramValue = sessionAttributes.get(providerParam)\n\n if paramValue != None:\n print \"Passport. prepareForStep. Found value in custom param of authorization request: %s\" % paramValue\n provider = self.getProviderFromJson(paramValue)\n\n if provider == None:\n print \"Passport. prepareForStep. A provider value could not be extracted from custom authorization request parameter\"\n elif not provider in self.registeredProviders:\n print \"Passport. prepareForStep. Provider '%s' not part of known configured IDPs/OPs\" % provider\n else:\n url = self.getPassportRedirectUrl(provider)\n\n if url == None:\n print \"Passport. prepareForStep. A page to manually select an identity provider will be shown\"\n else:\n facesService = CdiUtil.bean(FacesService)\n facesService.redirectToExternalURL(url)\n\n return True\n\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n print \"Passport. getExtraParametersForStep called\"\n if step == 1:\n return Arrays.asList(\"selectedProvider\", \"externalProviders\")\n elif step == 2:\n return Arrays.asList(\"passport_user_profile\")\n return None\n\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n print \"Passport. getCountAuthenticationSteps called\"\n identity = CdiUtil.bean(Identity)\n if identity.getWorkingParameter(\"passport_user_profile\") != None:\n return 2\n return 1\n\n\n def getPageForStep(self, configurationAttributes, step):\n print \"Passport. getPageForStep called\"\n\n extensionResult = self.extensionGetPageForStep(configurationAttributes, step)\n if extensionResult != None:\n return extensionResult\n\n if step == 1:\n return \"/auth/passport/passportlogin.xhtml\"\n return \"/auth/passport/passportpostlogin.xhtml\"\n\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n\n if step == 1:\n identity = CdiUtil.bean(Identity)\n provider = identity.getWorkingParameter(\"selectedProvider\")\n if provider != None:\n return 1\n\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n# Extension module related functions\n\n def extensionInit(self, configurationAttributes):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.init(configurationAttributes)\n\n\n def extensionAuthenticate(self, configurationAttributes, requestParameters, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.authenticate(configurationAttributes, requestParameters, step)\n\n\n def extensionPrepareForStep(self, configurationAttributes, requestParameters, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.prepareForStep(configurationAttributes, requestParameters, step)\n\n\n def extensionGetPageForStep(self, configurationAttributes, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.getPageForStep(configurationAttributes, step)\n\n# Initalization routines\n\n def loadExternalModule(self, simpleCustProperty):\n\n if simpleCustProperty != None:\n print \"Passport. loadExternalModule. Loading passport extension module...\"\n moduleName = simpleCustProperty.getValue2()\n try:\n module = __import__(moduleName)\n return module\n except:\n print \"Passport. loadExternalModule. Failed to load module %s\" % moduleName\n print \"Exception: \", sys.exc_info()[1]\n print \"Passport. loadExternalModule. Flow will be driven entirely by routines of main passport script\"\n return None\n\n\n def processKeyStoreProperties(self, attrs):\n file = attrs.get(\"key_store_file\")\n password = attrs.get(\"key_store_password\")\n\n if file != None and password != None:\n file = file.getValue2()\n password = password.getValue2()\n\n if StringHelper.isNotEmpty(file) and StringHelper.isNotEmpty(password):\n self.keyStoreFile = file\n self.keyStorePassword = password\n return True\n\n print \"Passport. readKeyStoreProperties. Properties key_store_file or key_store_password not found or empty\"\n return False\n\n\n def getCustomAuthzParameter(self, simpleCustProperty):\n\n customAuthzParameter = None\n if simpleCustProperty != None:\n prop = simpleCustProperty.getValue2()\n if StringHelper.isNotEmpty(prop):\n customAuthzParameter = prop\n\n if customAuthzParameter == None:\n print \"Passport. getCustomAuthzParameter. No custom param for OIDC authz request in script properties\"\n print \"Passport. getCustomAuthzParameter. Passport flow cannot be initiated by doing an OpenID connect authorization request\"\n else:\n print \"Passport. getCustomAuthzParameter. Custom param for OIDC authz request in script properties: %s\" % customAuthzParameter\n\n return customAuthzParameter\n\n# Configuration parsing\n\n def getPassportConfigDN(self):\n\n f = open('/etc/gluu/conf/gluu.properties', 'r')\n for line in f:\n prop = line.split(\"=\")\n if prop[0] == \"oxpassport_ConfigurationEntryDN\":\n prop.pop(0)\n break\n\n f.close()\n return \"=\".join(prop).strip()\n\n\n def parseAllProviders(self):\n\n registeredProviders = {}\n print \"Passport. parseAllProviders. Adding providers\"\n entryManager = CdiUtil.bean(PersistenceEntryManager)\n\n config = LdapOxPassportConfiguration()\n config = entryManager.find(config.getClass(), self.passportDN).getPassportConfiguration()\n config = config.getProviders() if config != None else config\n\n if config != None and len(config) > 0:\n for prvdetails in config:\n if prvdetails.isEnabled():\n registeredProviders[prvdetails.getId()] = {\n \"emailLinkingSafe\": prvdetails.isEmailLinkingSafe(),\n \"requestForEmail\" : prvdetails.isRequestForEmail(),\n \"logo_img\": prvdetails.getLogoImg(),\n \"displayName\": prvdetails.getDisplayName(),\n \"type\": prvdetails.getType()\n }\n\n return registeredProviders\n\n\n def parseProviderConfigs(self):\n\n registeredProviders = {}\n try:\n registeredProviders = self.parseAllProviders()\n toRemove = []\n\n for provider in registeredProviders:\n if registeredProviders[provider][\"type\"] == \"saml\":\n toRemove.append(provider)\n else:\n registeredProviders[provider][\"saml\"] = False\n\n for provider in toRemove:\n registeredProviders.pop(provider)\n\n if len(registeredProviders.keys()) > 0:\n print \"Passport. parseProviderConfigs. Configured providers:\", registeredProviders\n else:\n print \"Passport. parseProviderConfigs. No providers registered yet\"\n except:\n print \"Passport. parseProviderConfigs. An error occurred while building the list of supported authentication providers\", sys.exc_info()[1]\n\n self.registeredProviders = registeredProviders\n\n# Auxiliary routines\n\n def getProviderFromJson(self, providerJson):\n\n provider = None\n try:\n obj = json.loads(Base64Util.base64urldecodeToString(providerJson))\n provider = obj[self.providerKey]\n except:\n print \"Passport. getProviderFromJson. Could not parse provided Json string. Returning None\"\n\n return provider\n\n\n def getPassportRedirectUrl(self, provider):\n\n # provider is assumed to exist in self.registeredProviders\n url = None\n try:\n facesContext = CdiUtil.bean(FacesContext)\n tokenEndpoint = \"https://%s/passport/token\" % facesContext.getExternalContext().getRequest().getServerName()\n\n httpService = CdiUtil.bean(HttpService)\n httpclient = httpService.getHttpsClient()\n\n print \"Passport. getPassportRedirectUrl. Obtaining token from passport at %s\" % tokenEndpoint\n resultResponse = httpService.executeGet(httpclient, tokenEndpoint, Collections.singletonMap(\"Accept\", \"text/json\"))\n httpResponse = resultResponse.getHttpResponse()\n bytes = httpService.getResponseContent(httpResponse)\n\n response = httpService.convertEntityToString(bytes)\n print \"Passport. getPassportRedirectUrl. Response was %s\" % httpResponse.getStatusLine().getStatusCode()\n\n tokenObj = json.loads(response)\n url = \"/passport/auth/%s/%s\" % (provider, tokenObj[\"token_\"])\n except:\n print \"Passport. getPassportRedirectUrl. Error building redirect URL: \", sys.exc_info()[1]\n\n return url\n\n\n def validSignature(self, jwt):\n\n print \"Passport. validSignature. Checking JWT token signature\"\n valid = False\n\n try:\n appConfiguration = AppConfiguration()\n appConfiguration.setWebKeysStorage(WebKeyStorage.KEYSTORE)\n appConfiguration.setKeyStoreFile(self.keyStoreFile)\n appConfiguration.setKeyStoreSecret(self.keyStorePassword)\n appConfiguration.setKeyRegenerationEnabled(False)\n\n cryptoProvider = CryptoProviderFactory.getCryptoProvider(appConfiguration)\n valid = cryptoProvider.verifySignature(jwt.getSigningInput(), jwt.getEncodedSignature(), jwt.getHeader().getKeyId(),\n None, None, jwt.getHeader().getSignatureAlgorithm())\n except:\n print \"Exception: \", sys.exc_info()[1]\n\n print \"Passport. validSignature. Validation result was %s\" % valid\n return valid\n\n\n def jwtHasExpired(self, jwt):\n # Check if jwt has expired\n jwt_claims = jwt.getClaims()\n try:\n exp_date = jwt_claims.getClaimAsDate(JwtClaimName.EXPIRATION_TIME)\n hasExpired = exp_date < datetime.datetime.now()\n except:\n print \"Exception: The JWT does not have '%s' attribute\" % JwtClaimName.EXPIRATION_TIME\n return False\n\n return hasExpired\n\n\n def getUserProfile(self, jwt):\n jwt_claims = jwt.getClaims()\n user_profile_json = None\n\n try:\n user_profile_json = CdiUtil.bean(EncryptionService).decrypt(jwt_claims.getClaimAsString(\"data\"))\n user_profile = json.loads(user_profile_json)\n except:\n print \"Passport. getUserProfile. Problem obtaining user profile json representation\"\n\n return (user_profile, user_profile_json)\n\n\n def attemptAuthentication(self, identity, user_profile, user_profile_json):\n\n uidKey = \"uid\"\n if not self.checkRequiredAttributes(user_profile, [uidKey, self.providerKey]):\n return False\n\n provider = user_profile[self.providerKey]\n if not provider in self.registeredProviders:\n print \"Passport. attemptAuthentication. Identity Provider %s not recognized\" % provider\n return False\n\n uid = user_profile[uidKey][0]\n externalUid = \"passport-%s:%s\" % (provider, uid)\n\n userService = CdiUtil.bean(UserService)\n userByUid = userService.getUserByAttribute(\"oxExternalUid\", externalUid)\n\n email = None\n if \"mail\" in user_profile:\n email = user_profile[\"mail\"]\n if len(email) == 0:\n email = None\n else:\n email = email[0]\n user_profile[\"mail\"] = [ email ]\n\n if email == None and self.registeredProviders[provider][\"requestForEmail\"]:\n print \"Passport. attemptAuthentication. Email was not received\"\n\n if userByUid != None:\n # This avoids asking for the email over every login attempt\n email = userByUid.getAttribute(\"mail\")\n if email != None:\n print \"Passport. attemptAuthentication. Filling missing email value with %s\" % email\n user_profile[\"mail\"] = [ email ]\n\n if email == None:\n # Store user profile in session and abort this routine\n identity.setWorkingParameter(\"passport_user_profile\", user_profile_json)\n return True\n\n userByMail = None if email == None else userService.getUserByAttribute(\"mail\", email)\n\n # Determine if we should add entry, update existing, or deny access\n doUpdate = False\n doAdd = False\n if userByUid != None:\n print \"User with externalUid '%s' already exists\" % externalUid\n if userByMail == None:\n doUpdate = True\n else:\n if userByMail.getUserId() == userByUid.getUserId():\n doUpdate = True\n else:\n print \"Users with externalUid '%s' and mail '%s' are different. Access will be denied. Impersonation attempt?\" % (externalUid, email)\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email value corresponds to an already existing provisioned account\")\n else:\n if userByMail == None:\n doAdd = True\n elif self.registeredProviders[provider][\"emailLinkingSafe\"]:\n\n tmpList = userByMail.getAttributeValues(\"oxExternalUid\")\n tmpList = ArrayList() if tmpList == None else ArrayList(tmpList)\n tmpList.add(externalUid)\n userByMail.setAttribute(\"oxExternalUid\", tmpList)\n\n userByUid = userByMail\n print \"External user supplying mail %s will be linked to existing account '%s'\" % (email, userByMail.getUserId())\n doUpdate = True\n else:\n print \"An attempt to supply an email of an existing user was made. Turn on 'emailLinkingSafe' if you want to enable linking\"\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email value corresponds to an already existing account. If you already have a username and password use those instead of an external authentication site to get access.\")\n\n username = None\n try:\n if doUpdate:\n username = userByUid.getUserId()\n print \"Passport. attemptAuthentication. Updating user %s\" % username\n self.updateUser(userByUid, user_profile, userService)\n elif doAdd:\n print \"Passport. attemptAuthentication. Creating user %s\" % externalUid\n newUser = self.addUser(externalUid, user_profile, userService)\n username = newUser.getUserId()\n except:\n print \"Exception: \", sys.exc_info()[1]\n print \"Passport. attemptAuthentication. Authentication failed\"\n return False\n\n if username == None:\n print \"Passport. attemptAuthentication. Authentication attempt was rejected\"\n return False\n else:\n logged_in = CdiUtil.bean(AuthenticationService).authenticate(username)\n print \"Passport. attemptAuthentication. Authentication for %s returned %s\" % (username, logged_in)\n return logged_in\n\n\n def setMessageError(self, severity, msg):\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n facesMessages.clear()\n facesMessages.add(severity, msg)\n\n\n def checkRequiredAttributes(self, profile, attrs):\n\n for attr in attrs:\n if (not attr in profile) or len(profile[attr]) == 0:\n print \"Passport. checkRequiredAttributes. Attribute '%s' is missing in profile\" % attr\n return False\n return True\n\n\n def addUser(self, externalUid, profile, userService):\n\n newUser = User()\n #Fill user attrs\n newUser.setAttribute(\"oxExternalUid\", externalUid)\n self.fillUser(newUser, profile)\n newUser = userService.addUser(newUser, True)\n return newUser\n\n\n def updateUser(self, foundUser, profile, userService):\n\n # when this is false, there might still some updates taking place (e.g. not related to profile attrs released by external provider)\n if (not self.skipProfileUpdate):\n self.fillUser(foundUser, profile)\n userService.updateUser(foundUser)\n\n\n def fillUser(self, foundUser, profile):\n\n for attr in profile:\n # \"provider\" is disregarded if part of mapping\n if attr != self.providerKey:\n values = profile[attr]\n print \"%s = %s\" % (attr, values)\n foundUser.setAttribute(attr, values)\n\n if attr == \"mail\":\n oxtrustMails = []\n for mail in values:\n oxtrustMails.append('{\"value\":\"%s\",\"primary\":false}' % mail)\n foundUser.setAttribute(\"oxTrustEmail\", oxtrustMails)\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "passport_social", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "/etc/certs/passport-rp.jks", - "value1": "key_store_file" - }, - { - "hide": false, - "value2": "secret", - "value1": "key_store_password" - } - ], - "baseDn": "inum=2FDB-CF02,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 45, - "programmingLanguage": "PYTHON", - "description": "SMPP SMS authentication module", - "locationType": "LDAP", - "dn": "inum=09A0-93D7,ou=scripts,o=gluu", - "inum": "09A0-93D7", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2018, Gluu\n# Copyright (c) 2019, Tele2\n\n# Author: Jose Gonzalez\n# Author: Gasmyr Mougang\n# Author: Stefan Andersson\n\nfrom java.util import Arrays, Date\nfrom java.io import IOException\nfrom java.lang import Enum\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom javax.faces.application import FacesMessage\nfrom org.gluu.jsf2.message import FacesMessages\n\nfrom org.jsmpp import InvalidResponseException, PDUException\nfrom org.jsmpp.bean import Alphabet, BindType, ESMClass, GeneralDataCoding, MessageClass, NumberingPlanIndicator, RegisteredDelivery, SMSCDeliveryReceipt, TypeOfNumber\nfrom org.jsmpp.extra import NegativeResponseException, ResponseTimeoutException\nfrom org.jsmpp.session import BindParameter, SMPPSession\nfrom org.jsmpp.util import AbsoluteTimeFormatter, TimeFormatter\nimport random\n\n\nclass SmppAttributeError(Exception):\n pass\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n self.identity = CdiUtil.bean(Identity)\n\n def get_and_parse_smpp_config(self, config, attribute, _type = None, convert = False, optional = False, default_desc = None):\n try:\n value = config.get(attribute).getValue2()\n except:\n if default_desc:\n default_desc = \" using default '{}'\".format(default_desc)\n else:\n default_desc = \"\"\n\n if optional:\n raise SmppAttributeError(\"SMPP missing optional configuration attribute '{}'{}\".format(attribute, default_desc))\n else:\n raise SmppAttributeError(\"SMPP missing required configuration attribute '{}'\".format(attribute))\n\n if _type and issubclass(_type, Enum):\n try:\n return getattr(_type, value)\n except AttributeError:\n raise SmppAttributeError(\"SMPP could not find attribute '{}' in {}\".format(attribute, _type))\n\n if convert:\n try:\n value = int(value)\n except AttributeError:\n try:\n value = int(value, 16)\n except AttributeError:\n raise SmppAttributeError(\"SMPP could not parse value '{}' of attribute '{}'\".format(value, attribute))\n\n return value\n\n def init(self, customScript, configurationAttributes):\n print(\"SMPP Initialization\")\n\n self.TIME_FORMATTER = AbsoluteTimeFormatter()\n\n self.SMPP_SERVER = None\n self.SMPP_PORT = None\n\n self.SYSTEM_ID = None\n self.PASSWORD = None\n\n # Setup some good defaults for TON, NPI and source (from) address\n # TON (Type of Number), NPI (Number Plan Indicator)\n self.SRC_ADDR_TON = TypeOfNumber.ALPHANUMERIC # Alphanumeric\n self.SRC_ADDR_NPI = NumberingPlanIndicator.ISDN # ISDN (E163/E164)\n self.SRC_ADDR = \"Gluu OTP\"\n\n # Don't touch these unless you know what your doing, we don't handle number reformatting for\n # any other type than international.\n self.DST_ADDR_TON = TypeOfNumber.INTERNATIONAL # International\n self.DST_ADDR_NPI = NumberingPlanIndicator.ISDN # ISDN (E163/E164)\n\n # Priority flag and data_coding bits\n self.PRIORITY_FLAG = 3 # Very Urgent (ANSI-136), Emergency (IS-95)\n self.DATA_CODING_ALPHABET = Alphabet.ALPHA_DEFAULT # SMS default alphabet\n self.DATA_CODING_MESSAGE_CLASS = MessageClass.CLASS1 # EM (Mobile Equipment (mobile memory), normal message\n\n # Required server settings\n try:\n self.SMPP_SERVER = self.get_and_parse_smpp_config(configurationAttributes, \"smpp_server\")\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.SMPP_PORT = self.get_and_parse_smpp_config(configurationAttributes, \"smpp_port\", convert = True)\n except SmppAttributeError as e:\n print(e)\n\n if None in (self.SMPP_SERVER, self.SMPP_PORT):\n print(\"SMPP smpp_server and smpp_port is empty, will not enable SMPP service\")\n return False\n\n # Optional system_id and password for bind auth\n try:\n self.SYSTEM_ID = self.get_and_parse_smpp_config(configurationAttributes, \"system_id\", optional = True)\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.PASSWORD = self.get_and_parse_smpp_config(configurationAttributes, \"password\", optional = True)\n except SmppAttributeError as e:\n print(e)\n\n if None in (self.SYSTEM_ID, self.PASSWORD):\n print(\"SMPP Authentication disabled\")\n\n # From number and to number settings\n try:\n self.SRC_ADDR_TON = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"source_addr_ton\",\n _type = TypeOfNumber,\n optional = True,\n default_desc = self.SRC_ADDR_TON\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.SRC_ADDR_NPI = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"source_addr_npi\",\n _type = NumberingPlanIndicator,\n optional = True,\n default_desc = self.SRC_ADDR_NPI\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.SRC_ADDR = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"source_addr\",\n optional = True,\n default_desc = self.SRC_ADDR\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.DST_ADDR_TON = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"dest_addr_ton\",\n _type = TypeOfNumber,\n optional = True,\n default_desc = self.DST_ADDR_TON\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.DST_ADDR_NPI = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"dest_addr_npi\",\n _type = NumberingPlanIndicator,\n optional = True,\n default_desc = self.DST_ADDR_NPI\n )\n except SmppAttributeError as e:\n print(e)\n\n # Priority flag and data coding, don't touch these unless you know what your doing...\n try:\n self.PRIORITY_FLAG = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"priority_flag\",\n convert = True,\n optional = True,\n default_desc = \"3 (Very Urgent, Emergency)\"\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.DATA_CODING_ALPHABET = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"data_coding_alphabet\",\n _type = Alphabet,\n optional = True,\n default_desc = self.DATA_CODING_ALPHABET\n )\n except SmppAttributeError as e:\n print(e)\n\n try:\n self.DATA_CODING_MESSAGE_CLASS = self.get_and_parse_smpp_config(\n configurationAttributes,\n \"data_coding_alphabet\",\n _type = MessageClass,\n optional = True,\n default_desc = self.DATA_CODING_MESSAGE_CLASS\n )\n except SmppAttributeError as e:\n print(e)\n\n print(\"SMPP Initialized successfully\")\n return True\n\n def destroy(self, configurationAttributes):\n print(\"SMPP Destroy\")\n print(\"SMPP Destroyed successfully\")\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n\n session_attributes = self.identity.getSessionId().getSessionAttributes()\n form_passcode = ServerUtil.getFirstValue(requestParameters, \"passcode\")\n\n print(\"SMPP form_response_passcode: {}\".format(str(form_passcode)))\n\n if step == 1:\n print(\"SMPP Step 1 Password Authentication\")\n credentials = self.identity.getCredentials()\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return False\n\n # Get the Person's number and generate a code\n foundUser = None\n try:\n foundUser = authenticationService.getAuthenticatedUser()\n except:\n print(\"SMPP Error retrieving user {} from LDAP\".format(user_name))\n return False\n\n mobile_number = None\n try:\n isVerified = foundUser.getAttribute(\"phoneNumberVerified\")\n if isVerified:\n mobile_number = foundUser.getAttribute(\"employeeNumber\")\n if not mobile_number:\n mobile_number = foundUser.getAttribute(\"mobile\")\n if not mobile_number:\n mobile_number = foundUser.getAttribute(\"telephoneNumber\")\n if not mobile_number:\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to determine mobile phone number\")\n print(\"SMPP Error finding mobile number for user '{}'\".format(user_name))\n return False\n except Exception as e:\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to determine mobile phone number\")\n print(\"SMPP Error finding mobile number for {}: {}\".format(user_name, e))\n return False\n\n # Generate Random six digit code\n code = random.randint(100000, 999999)\n\n # Get code and save it in LDAP temporarily with special session entry\n self.identity.setWorkingParameter(\"code\", code)\n\n self.identity.setWorkingParameter(\"mobile_number\", mobile_number)\n self.identity.getSessionId().getSessionAttributes().put(\"mobile_number\", mobile_number)\n if not self.sendMessage(mobile_number, str(code)):\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to send message to mobile phone\")\n return False\n\n return True\n elif step == 2:\n # Retrieve the session attribute\n print(\"SMPP Step 2 SMS/OTP Authentication\")\n code = session_attributes.get(\"code\")\n print(\"SMPP Code: {}\".format(str(code)))\n\n if code is None:\n print(\"SMPP Failed to find previously sent code\")\n return False\n\n if form_passcode is None:\n print(\"SMPP Passcode is empty\")\n return False\n\n if len(form_passcode) != 6:\n print(\"SMPP Passcode from response is not 6 digits: {}\".format(form_passcode))\n return False\n\n if form_passcode == code:\n print(\"SMPP SUCCESS! User entered the same code!\")\n return True\n\n print(\"SMPP failed, user entered the wrong code! {} != {}\".format(form_passcode, code))\n facesMessages.add(facesMessage.SEVERITY_ERROR, \"Incorrect SMS code, please try again.\")\n return False\n\n print(\"SMPP ERROR: step param not found or != (1|2)\")\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n if step == 1:\n print(\"SMPP Prepare for Step 1\")\n return True\n elif step == 2:\n print(\"SMPP Prepare for Step 2\")\n return True\n\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n if step == 2:\n return Arrays.asList(\"code\")\n\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 2:\n return \"/auth/otp_sms/otp_sms.xhtml\"\n\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def sendMessage(self, number, code):\n status = False\n session = SMPPSession()\n session.setTransactionTimer(10000)\n\n # We only handle international destination number reformatting.\n # All others may vary by configuration decisions taken on SMPP\n # server side which we have no clue about.\n if self.DST_ADDR_TON == TypeOfNumber.INTERNATIONAL and number.startswith(\"+\"):\n number = number[1:]\n\n try:\n print(\"SMPP Connecting\")\n reference_id = session.connectAndBind(\n self.SMPP_SERVER,\n self.SMPP_PORT,\n BindParameter(\n BindType.BIND_TX,\n self.SYSTEM_ID,\n self.PASSWORD,\n None,\n self.SRC_ADDR_TON,\n self.SRC_ADDR_NPI,\n None\n )\n )\n print(\"SMPP Connected to server with system id {}\".format(reference_id))\n\n try:\n message_id = session.submitShortMessage(\n \"CMT\",\n self.SRC_ADDR_TON,\n self.SRC_ADDR_NPI,\n self.SRC_ADDR,\n self.DST_ADDR_TON,\n self.DST_ADDR_NPI,\n number,\n ESMClass(),\n 0,\n self.PRIORITY_FLAG,\n self.TIME_FORMATTER.format(Date()),\n None,\n RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT),\n 0,\n GeneralDataCoding(\n self.DATA_CODING_ALPHABET,\n self.DATA_CODING_MESSAGE_CLASS,\n False\n ),\n 0,\n code\n )\n print(\"SMPP Message '{}' sent to #{} with message id {}\".format(code, number, message_id))\n status = True\n except PDUException as e:\n print(\"SMPP Invalid PDU parameter: {}\".format(e))\n except ResponseTimeoutException as e:\n print(\"SMPP Response timeout: {}\".format(e))\n except InvalidResponseException as e:\n print(\"SMPP Receive invalid response: {}\".format(e))\n except NegativeResponseException as e:\n print(\"SMPP Receive negative response: {}\".format(e))\n except IOException as e:\n print(\"SMPP IO error occured: {}\".format(e))\n finally:\n session.unbindAndClose()\n except IOException as e:\n print(\"SMPP Failed connect and bind to host: {}\".format(e))\n\n return status\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "smpp", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value1": "smpp_server", - "description": "IP or FQDN of SMPP server" - }, - { - "hide": false, - "value1": "smpp_port", - "description": "TCP port of the SMPP server" - }, - { - "hide": false, - "value1": "system_id", - "description": "Use if SMPP server requires authentication" - }, - { - "hide": false, - "value1": "password", - "description": "Use if SMPP server requires authentication" - }, - { - "hide": false, - "value1": "source_addr_ton", - "description": "Type of number, eg ALPHANUMERIC, INTERNATIONAL" - }, - { - "hide": false, - "value1": "source_addr", - "description": "From number/name" - } - ], - "baseDn": "inum=09A0-93D7,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 50, - "programmingLanguage": "PYTHON", - "description": "ThumbSignIn authentication module", - "locationType": "LDAP", - "dn": "inum=92F0-759E,ou=scripts,o=gluu", - "inum": "92F0-759E", - "script": "# Author: ThumbSignIn\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.util import StringHelper\nfrom org.gluu.oxauth.util import ServerUtil\nfrom com.pramati.ts.thumbsignin_java_sdk import ThumbsigninApiController\nfrom org.json import JSONObject\nfrom org.gluu.oxauth.model.util import Base64Util\nfrom java.lang import String\n\nimport java\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n\n def __init__(self, current_time_millis):\n self.currentTimeMillis = current_time_millis\n self.thumbsigninApiController = ThumbsigninApiController()\n\n def init(self, customScript, configuration_attributes):\n print \"ThumbSignIn. Initialization\"\n\n global ts_host\n ts_host = configuration_attributes.get(\"ts_host\").getValue2()\n print \"ThumbSignIn. Initialization. Value of ts_host is %s\" % ts_host\n\n global ts_api_key\n ts_api_key = configuration_attributes.get(\"ts_apiKey\").getValue2()\n print \"ThumbSignIn. Initialization. Value of ts_api_key is %s\" % ts_api_key\n\n global ts_api_secret\n ts_api_secret = configuration_attributes.get(\"ts_apiSecret\").getValue2()\n\n global ts_statusPath\n ts_statusPath = \"/ts/secure/txn-status/\"\n\n global AUTHENTICATE\n AUTHENTICATE = \"authenticate\"\n\n global REGISTER\n REGISTER = \"register\"\n\n global TRANSACTION_ID\n TRANSACTION_ID = \"transactionId\"\n\n global USER_ID\n USER_ID = \"userId\"\n\n global USER_LOGIN_FLOW\n USER_LOGIN_FLOW = \"userLoginFlow\"\n\n global THUMBSIGNIN_AUTHENTICATION\n THUMBSIGNIN_AUTHENTICATION = \"ThumbSignIn_Authentication\"\n\n global THUMBSIGNIN_REGISTRATION\n THUMBSIGNIN_REGISTRATION = \"ThumbSignIn_Registration\"\n\n global THUMBSIGNIN_LOGIN_POST_REGISTRATION\n THUMBSIGNIN_LOGIN_POST_REGISTRATION = \"ThumbSignIn_RegistrationSucess\"\n\n global RELYING_PARTY_ID\n RELYING_PARTY_ID = \"relyingPartyId\"\n\n global RELYING_PARTY_LOGIN_URL\n RELYING_PARTY_LOGIN_URL = \"relyingPartyLoginUrl\"\n\n global TSI_LOGIN_PAGE\n TSI_LOGIN_PAGE = \"/auth/thumbsignin/tsLogin.xhtml\"\n\n global TSI_REGISTER_PAGE\n TSI_REGISTER_PAGE = \"/auth/thumbsignin/tsRegister.xhtml\"\n\n global TSI_LOGIN_POST_REGISTRATION_PAGE\n TSI_LOGIN_POST_REGISTRATION_PAGE = \"/auth/thumbsignin/tsRegistrationSuccess.xhtml\"\n\n print \"ThumbSignIn. Initialized successfully\"\n return True\n\n @staticmethod\n def set_relying_party_login_url(identity):\n print \"ThumbSignIn. Inside set_relying_party_login_url...\"\n session_id = identity.getSessionId()\n session_attribute = session_id.getSessionAttributes()\n state_jwt_token = session_attribute.get(\"state\")\n print \"ThumbSignIn. Value of state_jwt_token is %s\" % state_jwt_token\n relying_party_login_url = \"\"\n if (state_jwt_token is None) or (\".\" not in state_jwt_token):\n print \"ThumbSignIn. Value of state parameter is not in the format of JWT Token\"\n identity.setWorkingParameter(RELYING_PARTY_LOGIN_URL, relying_party_login_url)\n return None\n\n state_jwt_token_array = String(state_jwt_token).split(\"\\\\.\")\n state_jwt_token_payload = state_jwt_token_array[1]\n state_payload_str = String(Base64Util.base64urldecode(state_jwt_token_payload), \"UTF-8\")\n state_payload_json = JSONObject(state_payload_str)\n print \"ThumbSignIn. Value of state JWT token Payload is %s\" % state_payload_json\n if state_payload_json.has(\"additional_claims\"):\n additional_claims = state_payload_json.get(\"additional_claims\")\n relying_party_id = additional_claims.get(RELYING_PARTY_ID)\n print \"ThumbSignIn. Value of relying_party_id is %s\" % relying_party_id\n identity.setWorkingParameter(RELYING_PARTY_ID, relying_party_id)\n\n if String(relying_party_id).startsWith(\"google.com\"):\n # google.com/a/unphishableenterprise.com\n relying_party_id_array = String(relying_party_id).split(\"/\")\n google_domain = relying_party_id_array[2]\n print \"ThumbSignIn. Value of google_domain is %s\" % google_domain\n relying_party_login_url = \"https://www.google.com/accounts/AccountChooser?hd=\"+ google_domain + \"%26continue=https://apps.google.com/user/hub\"\n # elif (String(relying_party_id).startsWith(\"xyz\")):\n # relying_party_login_url = \"xyz.com\"\n else:\n # If relying_party_login_url is empty, Gluu's default login URL will be used\n relying_party_login_url = \"\"\n\n print \"ThumbSignIn. Value of relying_party_login_url is %s\" % relying_party_login_url\n identity.setWorkingParameter(RELYING_PARTY_LOGIN_URL, relying_party_login_url)\n return None\n\n def initialize_thumbsignin(self, identity, request_path):\n # Invoking the authenticate/register ThumbSignIn API via the Java SDK\n thumbsignin_response = self.thumbsigninApiController.handleThumbSigninRequest(request_path, ts_api_key, ts_api_secret)\n print \"ThumbSignIn. Value of thumbsignin_response is %s\" % thumbsignin_response\n\n thumbsignin_response_json = JSONObject(thumbsignin_response)\n transaction_id = thumbsignin_response_json.get(TRANSACTION_ID)\n status_request_type = \"authStatus\" if request_path == AUTHENTICATE else \"regStatus\"\n status_request = status_request_type + \"/\" + transaction_id\n print \"ThumbSignIn. Value of status_request is %s\" % status_request\n\n authorization_header = self.thumbsigninApiController.getAuthorizationHeaderJsonStr(status_request, ts_api_key, ts_api_secret)\n print \"ThumbSignIn. Value of authorization_header is %s\" % authorization_header\n # {\"authHeader\":\"HmacSHA256 Credential=X,SignedHeaders=accept;content-type;x-ts-date,Signature=X\",\"XTsDate\":\"X\"}\n authorization_header_json = JSONObject(authorization_header)\n auth_header = authorization_header_json.get(\"authHeader\")\n x_ts_date = authorization_header_json.get(\"XTsDate\")\n\n tsi_response_key = \"authenticateResponseJsonStr\" if request_path == AUTHENTICATE else \"registerResponseJsonStr\"\n identity.setWorkingParameter(tsi_response_key, thumbsignin_response)\n identity.setWorkingParameter(\"authorizationHeader\", auth_header)\n identity.setWorkingParameter(\"xTsDate\", x_ts_date)\n return None\n\n def prepareForStep(self, configuration_attributes, request_parameters, step):\n print \"ThumbSignIn. Inside prepareForStep. Step %d\" % step\n identity = CdiUtil.bean(Identity)\n authentication_service = CdiUtil.bean(AuthenticationService)\n\n identity.setWorkingParameter(\"ts_host\", ts_host)\n identity.setWorkingParameter(\"ts_statusPath\", ts_statusPath)\n\n self.set_relying_party_login_url(identity)\n\n if step == 1 or step == 3:\n print \"ThumbSignIn. Prepare for step 1\"\n self.initialize_thumbsignin(identity, AUTHENTICATE)\n return True\n\n elif step == 2:\n print \"ThumbSignIn. Prepare for step 2\"\n if identity.isSetWorkingParameter(USER_LOGIN_FLOW):\n user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW)\n print \"ThumbSignIn. Value of user_login_flow is %s\" % user_login_flow\n user = authentication_service.getAuthenticatedUser()\n if user is None:\n print \"ThumbSignIn. Prepare for step 2. Failed to determine user name\"\n return False\n user_name = user.getUserId()\n print \"ThumbSignIn. Prepare for step 2. user_name: \" + user_name\n if user_name is None:\n return False\n identity.setWorkingParameter(USER_ID, user_name)\n self.initialize_thumbsignin(identity, REGISTER + \"/\" + user_name)\n return True\n else:\n return False\n\n def get_user_id_from_thumbsignin(self, request_parameters):\n transaction_id = ServerUtil.getFirstValue(request_parameters, TRANSACTION_ID)\n print \"ThumbSignIn. Value of transaction_id is %s\" % transaction_id\n get_user_request = \"getUser/\" + transaction_id\n print \"ThumbSignIn. Value of get_user_request is %s\" % get_user_request\n\n get_user_response = self.thumbsigninApiController.handleThumbSigninRequest(get_user_request, ts_api_key, ts_api_secret)\n print \"ThumbSignIn. Value of get_user_response is %s\" % get_user_response\n get_user_response_json = JSONObject(get_user_response)\n thumbsignin_user_id = get_user_response_json.get(USER_ID)\n print \"ThumbSignIn. Value of thumbsignin_user_id is %s\" % thumbsignin_user_id\n return thumbsignin_user_id\n\n def authenticate(self, configuration_attributes, request_parameters, step):\n print \"ThumbSignIn. Inside authenticate. Step %d\" % step\n authentication_service = CdiUtil.bean(AuthenticationService)\n identity = CdiUtil.bean(Identity)\n\n identity.setWorkingParameter(\"ts_host\", ts_host)\n identity.setWorkingParameter(\"ts_statusPath\", ts_statusPath)\n\n if step == 1 or step == 3:\n print \"ThumbSignIn. Authenticate for Step %d\" % step\n\n login_flow = ServerUtil.getFirstValue(request_parameters, \"login_flow\")\n print \"ThumbSignIn. Value of login_flow parameter is %s\" % login_flow\n\n # Logic for ThumbSignIn Authentication Flow (Either step 1 or step 3)\n if login_flow == THUMBSIGNIN_AUTHENTICATION or login_flow == THUMBSIGNIN_LOGIN_POST_REGISTRATION:\n identity.setWorkingParameter(USER_LOGIN_FLOW, login_flow)\n print \"ThumbSignIn. Value of userLoginFlow is %s\" % identity.getWorkingParameter(USER_LOGIN_FLOW)\n logged_in_status = authentication_service.authenticate(self.get_user_id_from_thumbsignin(request_parameters))\n print \"ThumbSignIn. logged_in status : %r\" % logged_in_status\n return logged_in_status\n\n # Logic for traditional login flow (step 1)\n print \"ThumbSignIn. User credentials login flow\"\n identity.setWorkingParameter(USER_LOGIN_FLOW, THUMBSIGNIN_REGISTRATION)\n print \"ThumbSignIn. Value of userLoginFlow is %s\" % identity.getWorkingParameter(USER_LOGIN_FLOW)\n logged_in = self.authenticate_user_credentials(identity, authentication_service)\n print \"ThumbSignIn. Status of User Credentials based Authentication : %r\" % logged_in\n\n # When the traditional login fails, reinitialize the ThumbSignIn data before sending error response to UI\n if not logged_in:\n self.initialize_thumbsignin(identity, AUTHENTICATE)\n return False\n\n print \"ThumbSignIn. Authenticate successful for step %d\" % step\n return True\n\n elif step == 2:\n print \"ThumbSignIn. Registration flow (step 2)\"\n self.verify_user_login_flow(identity)\n\n user = self.get_authenticated_user_from_gluu(authentication_service)\n if user is None:\n print \"ThumbSignIn. Registration flow (step 2). Failed to determine user name\"\n return False\n\n user_name = user.getUserId()\n print \"ThumbSignIn. Registration flow (step 2) successful. user_name: %s\" % user_name\n return True\n\n else:\n return False\n\n def authenticate_user_credentials(self, identity, authentication_service):\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n print \"ThumbSignIn. user_name: \" + user_name\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = self.authenticate_user_in_gluu_ldap(authentication_service, user_name, user_password)\n return logged_in\n\n @staticmethod\n def authenticate_user_in_gluu_ldap(authentication_service, user_name, user_password):\n return authentication_service.authenticate(user_name, user_password)\n\n @staticmethod\n def get_authenticated_user_from_gluu(authentication_service):\n return authentication_service.getAuthenticatedUser()\n\n @staticmethod\n def verify_user_login_flow(identity):\n if identity.isSetWorkingParameter(USER_LOGIN_FLOW):\n user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW)\n print \"ThumbSignIn. Value of user_login_flow is %s\" % user_login_flow\n else:\n identity.setWorkingParameter(USER_LOGIN_FLOW, THUMBSIGNIN_REGISTRATION)\n print \"ThumbSignIn. Setting the value of user_login_flow to %s\" % identity.getWorkingParameter(USER_LOGIN_FLOW)\n\n def getExtraParametersForStep(self, configuration_attributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configuration_attributes):\n print \"ThumbSignIn. Inside getCountAuthenticationSteps..\"\n identity = CdiUtil.bean(Identity)\n\n user_login_flow = identity.getWorkingParameter(USER_LOGIN_FLOW)\n print \"ThumbSignIn. Value of userLoginFlow is %s\" % user_login_flow\n if user_login_flow == THUMBSIGNIN_AUTHENTICATION:\n print \"ThumbSignIn. Total Authentication Steps is: 1\"\n return 1\n print \"ThumbSignIn. Total Authentication Steps is: 3\"\n return 3\n\n def getPageForStep(self, configuration_attributes, step):\n print \"ThumbSignIn. Inside getPageForStep. Step %d\" % step\n if step == 3:\n return TSI_LOGIN_POST_REGISTRATION_PAGE\n thumbsignin_page = TSI_REGISTER_PAGE if step == 2 else TSI_LOGIN_PAGE\n return thumbsignin_page\n\n def destroy(self, configurationAttributes):\n print \"ThumbSignIn. Destroy\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - }, - { - "value2": "interactive", - "value1": "usage_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "thumb_sign_in", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "https://ts.host.com", - "value1": "ts_host" - }, - { - "hide": false, - "value2": "ts_api_key", - "value1": "ts_apiKey" - }, - { - "hide": false, - "value2": "ts_api_secret", - "value1": "ts_apiSecret" - } - ], - "baseDn": "inum=92F0-759E,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 50, - "programmingLanguage": "PYTHON", - "description": "DUO authentication module", - "locationType": "LDAP", - "dn": "inum=5018-F9CF,ou=scripts,o=gluu", - "inum": "5018-F9CF", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.service import AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.service import MailService\nfrom org.gluu.util import ArrayHelper\nfrom org.gluu.util import StringHelper\nfrom java.util import Arrays\n\nimport duo_web\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Duo. Initialization\"\n\n duo_creds_file = configurationAttributes.get(\"duo_creds_file\").getValue2()\n # Load credentials from file\n f = open(duo_creds_file, 'r')\n try:\n creds = json.loads(f.read())\n except:\n print \"Duo. Initialization. Failed to load creds from file:\", duo_creds_file\n return False\n finally:\n f.close()\n\n self.ikey = str(creds[\"ikey\"])\n self.skey = str(creds[\"skey\"])\n self.akey = str(creds[\"akey\"])\n\n self.use_duo_group = False\n if (configurationAttributes.containsKey(\"duo_group\")):\n self.duo_group = configurationAttributes.get(\"duo_group\").getValue2()\n self.use_duo_group = True\n print \"Duo. Initialization. Using Duo only if user belong to group:\", self.duo_group\n\n self.use_audit_group = False\n if (configurationAttributes.containsKey(\"audit_group\")):\n self.audit_group = configurationAttributes.get(\"audit_group\").getValue2()\n\n if (not configurationAttributes.containsKey(\"audit_group_email\")):\n print \"Duo. Initialization. Property audit_group_email is not specified\"\n return False\n\n self.audit_email = configurationAttributes.get(\"audit_group_email\").getValue2()\n self.use_audit_group = True\n\n print \"Duo. Initialization. Using audito group:\", self.audit_group\n \n if (self.use_duo_group or self.use_audit_group):\n if (not configurationAttributes.containsKey(\"audit_attribute\")):\n print \"Duo. Initialization. Property audit_attribute is not specified\"\n return False\n else:\n self.audit_attribute = configurationAttributes.get(\"audit_attribute\").getValue2()\n\n print \"Duo. Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"Duo. Destroy\"\n print \"Duo. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n duo_host = configurationAttributes.get(\"duo_host\").getValue2()\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n\n if (step == 1):\n print \"Duo. Authenticate for step 1\"\n\n # Check if user authenticated already in another custom script\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n \n logged_in = False\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\n userService = CdiUtil.bean(UserService)\n logged_in = authenticationService.authenticate(user_name, user_password)\n \n if (not logged_in):\n return False\n \n user = authenticationService.getAuthenticatedUser()\n\n if (self.use_duo_group):\n print \"Duo. Authenticate for step 1. Checking if user belong to Duo group\"\n is_member_duo_group = self.isUserMemberOfGroup(user, self.audit_attribute, self.duo_group)\n if (is_member_duo_group):\n print \"Duo. Authenticate for step 1. User '\" + user.getUserId() + \"' member of Duo group\"\n duo_count_login_steps = 2\n else:\n self.processAuditGroup(user)\n duo_count_login_steps = 1\n\n identity.setWorkingParameter(\"duo_count_login_steps\", duo_count_login_steps)\n\n return True\n elif (step == 2):\n print \"Duo. Authenticate for step 2\"\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"Duo. Authenticate for step 2. Failed to determine user name\"\n return False\n\n user_name = user.getUserId()\n\n sig_response_array = requestParameters.get(\"sig_response\")\n if ArrayHelper.isEmpty(sig_response_array):\n print \"Duo. Authenticate for step 2. sig_response is empty\"\n return False\n\n duo_sig_response = sig_response_array[0]\n\n print \"Duo. Authenticate for step 2. duo_sig_response: \" + duo_sig_response\n\n authenticated_username = duo_web.verify_response(self.ikey, self.skey, self.akey, duo_sig_response)\n\n print \"Duo. Authenticate for step 2. authenticated_username: \" + authenticated_username + \", expected user_name: \" + user_name\n\n if (not StringHelper.equals(user_name, authenticated_username)):\n return False\n\n self.processAuditGroup(user)\n\n return True\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n duo_host = configurationAttributes.get(\"duo_host\").getValue2()\n\n if (step == 1):\n print \"Duo. Prepare for step 1\"\n\n return True\n elif (step == 2):\n print \"Duo. Prepare for step 2\"\n\n user = authenticationService.getAuthenticatedUser()\n if (user == None):\n print \"Duo. Prepare for step 2. Failed to determine user name\"\n return False\n user_name = user.getUserId()\n\n duo_sig_request = duo_web.sign_request(self.ikey, self.skey, self.akey, user_name)\n print \"Duo. Prepare for step 2. duo_sig_request: \" + duo_sig_request\n \n identity.setWorkingParameter(\"duo_host\", duo_host)\n identity.setWorkingParameter(\"duo_sig_request\", duo_sig_request)\n\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n if step == 2:\n return Arrays.asList(\"duo_count_login_steps\", \"cas2_user_uid\")\n\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n identity = CdiUtil.bean(Identity)\n if (identity.isSetWorkingParameter(\"duo_count_login_steps\")):\n return int(identity.getWorkingParameter(\"duo_count_login_steps\"))\n\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if (step == 2):\n return \"/auth/duo/duologin.xhtml\"\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def isUserMemberOfGroup(self, user, attribute, group):\n is_member = False\n member_of_list = user.getAttributeValues(attribute)\n if (member_of_list != None):\n for member_of in member_of_list:\n if StringHelper.equalsIgnoreCase(group, member_of) or member_of.endswith(group):\n is_member = True\n break\n\n return is_member\n\n def processAuditGroup(self, user):\n if (self.use_audit_group):\n is_member = self.isUserMemberOfGroup(user, self.audit_attribute, self.audit_group)\n if (is_member):\n print \"Duo. Authenticate for processAuditGroup. User '\" + user.getUserId() + \"' member of audit group\"\n print \"Duo. Authenticate for processAuditGroup. Sending e-mail about user '\" + user.getUserId() + \"' login to\", self.audit_email\n \n # Send e-mail to administrator\n user_id = user.getUserId()\n mailService = CdiUtil.bean(MailService)\n subject = \"User log in: \" + user_id\n body = \"User log in: \" + user_id\n mailService.sendMail(self.audit_email, subject, body)\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "duo", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "/etc/certs/duo_creds.json", - "value1": "duo_creds_file" - }, - { - "hide": false, - "value2": "api-random.duosecurity.com", - "value1": "duo_host" - } - ], - "baseDn": "inum=5018-F9CF,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 50, - "programmingLanguage": "PYTHON", - "description": "Twilio SMS authentication module", - "locationType": "LDAP", - "dn": "inum=09A0-93D6,ou=scripts,o=gluu", - "inum": "09A0-93D6", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2018, Gluu\r\n#\r\n# Author: Jose Gonzalez\r\n# Author: Gasmyr Mougang\r\n\r\nfrom org.gluu.service.cdi.util import CdiUtil\r\nfrom org.gluu.oxauth.security import Identity\r\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\r\nfrom org.gluu.oxauth.service import AuthenticationService\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.oxauth.util import ServerUtil\r\nfrom org.gluu.util import StringHelper, ArrayHelper\r\nfrom java.util import Arrays\r\nfrom javax.faces.application import FacesMessage\r\nfrom org.gluu.jsf2.message import FacesMessages\r\n\r\nimport com.twilio.Twilio as Twilio\r\nimport com.twilio.rest.api.v2010.account.Message as Message\r\nimport com.twilio.type.PhoneNumber as PhoneNumber\r\nimport org.codehaus.jettison.json.JSONArray as JSONArray\r\n\r\n\r\nimport java\r\nimport random\r\nimport jarray\r\n\r\nclass PersonAuthentication(PersonAuthenticationType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n self.mobile_number = None\r\n self.identity = CdiUtil.bean(Identity)\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Twilio SMS. Initialization\"\r\n self.ACCOUNT_SID = None\r\n self.AUTH_TOKEN = None\r\n self.FROM_NUMBER = None\r\n\r\n # Get Custom Properties\r\n try:\r\n self.ACCOUNT_SID = configurationAttributes.get(\"twilio_sid\").getValue2()\r\n except:\r\n print 'TwilioSMS, Missing required configuration attribute \"twilio_sid\"'\r\n\r\n try:\r\n self.AUTH_TOKEN = configurationAttributes.get(\"twilio_token\").getValue2()\r\n except:\r\n print'TwilioSMS, Missing required configuration attribute \"twilio_token\"'\r\n try:\r\n self.FROM_NUMBER = configurationAttributes.get(\"from_number\").getValue2()\r\n except:\r\n print'TwilioSMS, Missing required configuration attribute \"from_number\"'\r\n\r\n if None in (self.ACCOUNT_SID, self.AUTH_TOKEN, self.FROM_NUMBER):\r\n print \"twilio_sid, twilio_token, from_number is empty ... returning False\"\r\n return False\r\n\r\n print \"Twilio SMS. Initialized successfully\"\r\n\r\n return True\r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Twilio SMS. Destroy\"\r\n print \"Twilio SMS. Destroyed successfully\"\r\n return True\r\n\r\n def getApiVersion(self):\r\n return 11\r\n \r\n def getAuthenticationMethodClaims(self, requestParameters):\r\n return None\r\n \r\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\r\n return True\r\n\r\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\r\n return None\r\n\r\n def authenticate(self, configurationAttributes, requestParameters, step):\r\n userService = CdiUtil.bean(UserService)\r\n authenticationService = CdiUtil.bean(AuthenticationService)\r\n\r\n facesMessages = CdiUtil.bean(FacesMessages)\r\n facesMessages.setKeepMessages()\r\n\r\n session_attributes = self.identity.getSessionId().getSessionAttributes()\r\n form_passcode = ServerUtil.getFirstValue(requestParameters, \"passcode\")\r\n form_name = ServerUtil.getFirstValue(requestParameters, \"TwilioSmsloginForm\")\r\n\r\n print \"TwilioSMS. form_response_passcode: %s\" % str(form_passcode)\r\n\r\n if step == 1:\r\n print \"TwilioSMS. Step 1 Password Authentication\"\r\n credentials = self.identity.getCredentials()\r\n\r\n user_name = credentials.getUsername()\r\n user_password = credentials.getPassword()\r\n\r\n logged_in = False\r\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\r\n logged_in = authenticationService.authenticate(user_name, user_password)\r\n\r\n if not logged_in:\r\n return False\r\n\r\n # Get the Person's number and generate a code\r\n foundUser = None\r\n try:\r\n foundUser = authenticationService.getAuthenticatedUser()\r\n except:\r\n print 'TwilioSMS, Error retrieving user %s from LDAP' % (user_name)\r\n return False\r\n\r\n try:\r\n isVerified = foundUser.getAttribute(\"phoneNumberVerified\")\r\n if isVerified:\r\n self.mobile_number = foundUser.getAttribute(\"employeeNumber\")\r\n if self.mobile_number == None:\r\n self.mobile_number = foundUser.getAttribute(\"mobile\")\r\n if self.mobile_number == None:\r\n self.mobile_number = foundUser.getAttribute(\"telephoneNumber\")\r\n if self.mobile_number == None:\r\n print \"TwilioSMS, Error finding mobile number for user '%s'\" % user_name \r\n \r\n except:\r\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to determine mobile phone number\")\r\n print 'TwilioSMS, Error finding mobile number for \"%s\". Exception: %s` % (user_name, sys.exc_info()[1])`'\r\n return False\r\n\r\n # Generate Random six digit code and store it in array\r\n code = random.randint(100000, 999999)\r\n\r\n # Get code and save it in LDAP temporarily with special session entry\r\n self.identity.setWorkingParameter(\"code\", code)\r\n\r\n try:\r\n Twilio.init(self.ACCOUNT_SID, self.AUTH_TOKEN);\r\n message = Message.creator(PhoneNumber(self.mobile_number), PhoneNumber(self.FROM_NUMBER), str(code)).create();\r\n print \"++++++++++++++++++++++++++++++++++++++++++++++\"\r\n print 'TwilioSMs, Message Sid: %s' % (message.getSid())\r\n print 'TwilioSMs, User phone: %s' % (self.mobile_number)\r\n print \"++++++++++++++++++++++++++++++++++++++++++++++\"\r\n self.identity.setWorkingParameter(\"mobile_number\", self.mobile_number)\r\n self.identity.getSessionId().getSessionAttributes().put(\"mobile_number\",self.mobile_number)\r\n self.identity.setWorkingParameter(\"mobile\", self.mobile_number)\r\n self.identity.getSessionId().getSessionAttributes().put(\"mobile\",self.mobile_number)\r\n print \"++++++++++++++++++++++++++++++++++++++++++++++\"\r\n print \"Number: %s\" % (self.identity.getWorkingParameter(\"mobile_number\"))\r\n print \"Mobile: %s\" % (self.identity.getWorkingParameter(\"mobile\"))\r\n print \"++++++++++++++++++++++++++++++++++++++++++++++\"\r\n return True\r\n except Exception, ex:\r\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Failed to send message to mobile phone\")\r\n print \"TwilioSMS. Error sending message to Twilio\"\r\n print \"TwilioSMS. Unexpected error:\", ex\r\n\r\n return False\r\n elif step == 2:\r\n # Retrieve the session attribute\r\n print \"TwilioSMS. Step 2 SMS/OTP Authentication\"\r\n code = session_attributes.get(\"code\")\r\n print \"----------------------------------\"\r\n print \"TwilioSMS. Code: %s\" % str(code)\r\n print \"----------------------------------\"\r\n\r\n if code is None:\r\n print \"TwilioSMS. Failed to find previously sent code\"\r\n return False\r\n\r\n if form_passcode is None:\r\n print \"TwilioSMS. Passcode is empty\"\r\n return False\r\n\r\n if len(form_passcode) != 6:\r\n print \"TwilioSMS. Passcode from response is not 6 digits: %s\" % form_passcode\r\n return False\r\n\r\n if form_passcode == code:\r\n print \"TiwlioSMS, SUCCESS! User entered the same code!\"\r\n return True\r\n\r\n print \"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\" \r\n print \"TwilioSMS. FAIL! User entered the wrong code! %s != %s\" % (form_passcode, code)\r\n print \"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\" \r\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Incorrect Twilio code, please try again.\")\r\n\r\n return False\r\n\r\n print \"TwilioSMS. ERROR: step param not found or != (1|2)\"\r\n\r\n return False\r\n\r\n def prepareForStep(self, configurationAttributes, requestParameters, step):\r\n if step == 1:\r\n print \"TwilioSMS. Prepare for Step 1\"\r\n return True\r\n elif step == 2:\r\n print \"TwilioSMS. Prepare for Step 2\"\r\n return True\r\n return False\r\n\r\n def getExtraParametersForStep(self, configurationAttributes, step):\r\n if step == 2:\r\n return Arrays.asList(\"code\")\r\n\r\n return None\r\n\r\n def getCountAuthenticationSteps(self, configurationAttributes):\r\n return 2\r\n\r\n def getPageForStep(self, configurationAttributes, step):\r\n if step == 2:\r\n return \"/auth/otp_sms/otp_sms.xhtml\"\r\n\r\n return \"\"\r\n \r\n def getNextStep(self, configurationAttributes, requestParameters, step):\r\n return -1\r\n\r\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\r\n print \"Get external logout URL call\"\r\n return None\r\n \r\n def logout(self, configurationAttributes, requestParameters):\r\n return True\r\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "twilio_sms", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value1": "twilio_sid", - "description": "Twilio account SID" - }, - { - "hide": false, - "value1": "twilio_token", - "description": "Twilio API token" - }, - { - "hide": false, - "value1": "from_number", - "description": "Twilio phone number with SMS capabilities" - } - ], - "baseDn": "inum=09A0-93D6,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 50, - "programmingLanguage": "PYTHON", - "description": "Fido U2F authentication module", - "locationType": "LDAP", - "dn": "inum=8BAF-80D6,ou=scripts,o=gluu", - "inum": "8BAF-80D6", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2016, Gluu\r\n#\r\n# Author: Yuriy Movchan\r\n#\r\n\r\nimport java\r\nimport sys\r\nfrom javax.ws.rs.core import Response\r\nfrom org.jboss.resteasy.client import ClientResponseFailure\r\nfrom org.jboss.resteasy.client.exception import ResteasyClientException\r\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\r\nfrom org.gluu.oxauth.client.fido.u2f import FidoU2fClientFactory\r\nfrom org.gluu.oxauth.model.config import Constants\r\nfrom org.gluu.oxauth.security import Identity\r\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.oxauth.service.fido.u2f import DeviceRegistrationService\r\nfrom org.gluu.oxauth.util import ServerUtil\r\nfrom org.gluu.service.cdi.util import CdiUtil\r\nfrom org.gluu.util import StringHelper\r\n\r\n\r\nclass PersonAuthentication(PersonAuthenticationType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"U2F. Initialization\"\r\n\r\n print \"U2F. Initialization. Downloading U2F metadata\"\r\n u2f_server_uri = configurationAttributes.get(\"u2f_server_uri\").getValue2()\r\n u2f_server_metadata_uri = u2f_server_uri + \"/.well-known/fido-u2f-configuration\"\r\n\r\n metaDataConfigurationService = FidoU2fClientFactory.instance().createMetaDataConfigurationService(u2f_server_metadata_uri)\r\n\r\n max_attempts = 20\r\n for attempt in range(1, max_attempts + 1):\r\n try:\r\n self.metaDataConfiguration = metaDataConfigurationService.getMetadataConfiguration()\r\n break\r\n except ClientResponseFailure, ex:\r\n # Detect if last try or we still get Service Unavailable HTTP error\r\n if (attempt == max_attempts) or (ex.getResponse().getResponseStatus() != Response.Status.SERVICE_UNAVAILABLE):\r\n raise ex\r\n\r\n java.lang.Thread.sleep(3000)\r\n print \"Attempting to load metadata: %d\" % attempt\r\n except ResteasyClientException, ex:\r\n # Detect if last try or we still get Service Unavailable HTTP error\r\n if attempt == max_attempts:\r\n raise ex\r\n\r\n java.lang.Thread.sleep(3000)\r\n print \"Attempting to load metadata: %d\" % attempt\r\n \r\n print \"U2F. Initialized successfully\"\r\n return True \r\n\r\n def destroy(self, configurationAttributes):\r\n print \"U2F. Destroy\"\r\n print \"U2F. Destroyed successfully\"\r\n return True\r\n\r\n def getApiVersion(self):\r\n return 11\r\n \r\n def getAuthenticationMethodClaims(self, requestParameters):\r\n return None\r\n \r\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\r\n return True\r\n\r\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\r\n return None\r\n\r\n def authenticate(self, configurationAttributes, requestParameters, step):\r\n authenticationService = CdiUtil.bean(AuthenticationService)\r\n\r\n identity = CdiUtil.bean(Identity)\r\n credentials = identity.getCredentials()\r\n\r\n user_name = credentials.getUsername()\r\n\r\n if (step == 1):\r\n print \"U2F. Authenticate for step 1\"\r\n\r\n user_password = credentials.getPassword()\r\n logged_in = False\r\n if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):\r\n userService = CdiUtil.bean(UserService)\r\n logged_in = authenticationService.authenticate(user_name, user_password)\r\n\r\n if (not logged_in):\r\n return False\r\n\r\n return True\r\n elif (step == 2):\r\n print \"U2F. Authenticate for step 2\"\r\n\r\n token_response = ServerUtil.getFirstValue(requestParameters, \"tokenResponse\")\r\n if token_response == None:\r\n print \"U2F. Authenticate for step 2. tokenResponse is empty\"\r\n return False\r\n\r\n auth_method = ServerUtil.getFirstValue(requestParameters, \"authMethod\")\r\n if auth_method == None:\r\n print \"U2F. Authenticate for step 2. authMethod is empty\"\r\n return False\r\n\r\n authenticationService = CdiUtil.bean(AuthenticationService)\r\n user = authenticationService.getAuthenticatedUser()\r\n if (user == None):\r\n print \"U2F. Prepare for step 2. Failed to determine user name\"\r\n return False\r\n\r\n if (auth_method == 'authenticate'):\r\n print \"U2F. Prepare for step 2. Call FIDO U2F in order to finish authentication workflow\"\r\n authenticationRequestService = FidoU2fClientFactory.instance().createAuthenticationRequestService(self.metaDataConfiguration)\r\n authenticationStatus = authenticationRequestService.finishAuthentication(user.getUserId(), token_response)\r\n\r\n if (authenticationStatus.getStatus() != Constants.RESULT_SUCCESS):\r\n print \"U2F. Authenticate for step 2. Get invalid authentication status from FIDO U2F server\"\r\n return False\r\n\r\n return True\r\n elif (auth_method == 'enroll'):\r\n print \"U2F. Prepare for step 2. Call FIDO U2F in order to finish registration workflow\"\r\n registrationRequestService = FidoU2fClientFactory.instance().createRegistrationRequestService(self.metaDataConfiguration)\r\n registrationStatus = registrationRequestService.finishRegistration(user.getUserId(), token_response)\r\n\r\n if (registrationStatus.getStatus() != Constants.RESULT_SUCCESS):\r\n print \"U2F. Authenticate for step 2. Get invalid registration status from FIDO U2F server\"\r\n return False\r\n\r\n return True\r\n else:\r\n print \"U2F. Prepare for step 2. Authenticatiod method is invalid\"\r\n return False\r\n\r\n return False\r\n else:\r\n return False\r\n\r\n def prepareForStep(self, configurationAttributes, requestParameters, step):\r\n identity = CdiUtil.bean(Identity)\r\n\r\n if (step == 1):\r\n return True\r\n elif (step == 2):\r\n print \"U2F. Prepare for step 2\"\r\n\r\n session = CdiUtil.bean(SessionIdService).getSessionId()\r\n if session == None:\r\n print \"U2F. Prepare for step 2. Failed to determine session_id\"\r\n return False\r\n\r\n authenticationService = CdiUtil.bean(AuthenticationService)\r\n user = authenticationService.getAuthenticatedUser()\r\n if (user == None):\r\n print \"U2F. Prepare for step 2. Failed to determine user name\"\r\n return False\r\n\r\n u2f_application_id = configurationAttributes.get(\"u2f_application_id\").getValue2()\r\n\r\n # Check if user have registered devices\r\n deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)\r\n\r\n userInum = user.getAttribute(\"inum\")\r\n\r\n registrationRequest = None\r\n authenticationRequest = None\r\n\r\n deviceRegistrations = deviceRegistrationService.findUserDeviceRegistrations(userInum, u2f_application_id)\r\n if (deviceRegistrations.size() > 0):\r\n print \"U2F. Prepare for step 2. Call FIDO U2F in order to start authentication workflow\"\r\n\r\n try:\r\n authenticationRequestService = FidoU2fClientFactory.instance().createAuthenticationRequestService(self.metaDataConfiguration)\r\n authenticationRequest = authenticationRequestService.startAuthentication(user.getUserId(), None, u2f_application_id, session.getId())\r\n except ClientResponseFailure, ex:\r\n if (ex.getResponse().getResponseStatus() != Response.Status.NOT_FOUND):\r\n print \"U2F. Prepare for step 2. Failed to start authentication workflow. Exception:\", sys.exc_info()[1]\r\n return False\r\n else:\r\n print \"U2F. Prepare for step 2. Call FIDO U2F in order to start registration workflow\"\r\n registrationRequestService = FidoU2fClientFactory.instance().createRegistrationRequestService(self.metaDataConfiguration)\r\n registrationRequest = registrationRequestService.startRegistration(user.getUserId(), u2f_application_id, session.getId())\r\n\r\n identity.setWorkingParameter(\"fido_u2f_authentication_request\", ServerUtil.asJson(authenticationRequest))\r\n identity.setWorkingParameter(\"fido_u2f_registration_request\", ServerUtil.asJson(registrationRequest))\r\n\r\n return True\r\n elif (step == 3):\r\n print \"U2F. Prepare for step 3\"\r\n\r\n return True\r\n else:\r\n return False\r\n\r\n def getExtraParametersForStep(self, configurationAttributes, step):\r\n return None\r\n\r\n def getCountAuthenticationSteps(self, configurationAttributes):\r\n return 2\r\n\r\n def getPageForStep(self, configurationAttributes, step):\r\n if (step == 2):\r\n return \"/auth/u2f/login.xhtml\"\r\n\r\n return \"\"\r\n\r\n def getNextStep(self, configurationAttributes, requestParameters, step):\r\n return -1\r\n\r\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\r\n print \"Get external logout URL call\"\r\n return None\r\n\r\n def logout(self, configurationAttributes, requestParameters):\r\n return True\r\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "u2f", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "https://pujavs4.2.gluu.server", - "value1": "u2f_application_id" - }, - { - "hide": false, - "value2": "https://pujavs4.2.gluu.server", - "value1": "u2f_server_uri" - } - ], - "baseDn": "inum=8BAF-80D6,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 60, - "programmingLanguage": "PYTHON", - "description": "Passport SAML authentication module", - "locationType": "LDAP", - "dn": "inum=D40C-1CA4,ou=scripts,o=gluu", - "inum": "D40C-1CA4", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2019, Gluu\n#\n# Author: Jose Gonzalez\n# Author: Yuriy Movchan\n# Author: Christian Eland\n#\n\nfrom org.gluu.jsf2.service import FacesService\nfrom org.gluu.jsf2.message import FacesMessages\n\nfrom org.gluu.oxauth.model.common import User, WebKeyStorage\nfrom org.gluu.oxauth.model.configuration import AppConfiguration\nfrom org.gluu.oxauth.model.crypto import CryptoProviderFactory\nfrom org.gluu.oxauth.model.jwt import Jwt, JwtClaimName\nfrom org.gluu.oxauth.model.util import Base64Util\nfrom org.gluu.oxauth.service import AppInitializer, AuthenticationService\nfrom org.gluu.oxauth.service.common import UserService, EncryptionService\nfrom org.gluu.oxauth.model.authorize import AuthorizeRequestParam\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.config.oxtrust import LdapOxPassportConfiguration\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.persist import PersistenceEntryManager\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\nfrom java.util import ArrayList, Arrays, Collections, HashSet\nfrom org.gluu.oxauth.model.exception import InvalidJwtException\nfrom javax.faces.application import FacesMessage\nfrom javax.faces.context import FacesContext\n\nimport json\nimport sys\nimport datetime\nimport base64\n\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n\n print \"Passport. init called\"\n\n self.extensionModule = self.loadExternalModule(configurationAttributes.get(\"extension_module\"))\n extensionResult = self.extensionInit(configurationAttributes)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. init. Behaviour is inbound SAML\"\n success = self.processKeyStoreProperties(configurationAttributes)\n\n if success:\n self.providerKey = \"provider\"\n self.customAuthzParameter = self.getCustomAuthzParameter(configurationAttributes.get(\"authz_req_param_provider\"))\n self.passportDN = self.getPassportConfigDN()\n print \"Passport. init. Initialization success\"\n else:\n print \"Passport. init. Initialization failed\"\n return success\n\n\n def destroy(self, configurationAttributes):\n print \"Passport. destroy called\"\n return True\n\n\n def getApiVersion(self):\n return 11\n\n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n\n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n\n extensionResult = self.extensionAuthenticate(configurationAttributes, requestParameters, step)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. authenticate for step %s called\" % str(step)\n identity = CdiUtil.bean(Identity)\n\n # Loading self.registeredProviders in case passport destroyed\n if not hasattr(self,'registeredProviders'):\n print \"Passport. Fetching registered providers.\"\n self.parseProviderConfigs()\n\n if step == 1:\n\n jwt_param = None\n\n if self.isInboundFlow(identity):\n # if is idp-initiated inbound flow\n print \"Passport. authenticate for step 1. Detected idp-initiated inbound Saml flow\"\n # get request from session attributes\n jwt_param = identity.getSessionId().getSessionAttributes().get(AuthorizeRequestParam.STATE)\n print \"Passport. authenticate. step ==1. if self.isInboundFlow(identity):.\"\n print \"jwt_param = %s\" % jwt_param\n # now jwt_param != None\n\n\n\n if jwt_param == None:\n print \"Entered if jwt_param == None\"\n # gets jwt parameter \"user\" sent after authentication by passport (if exists)\n jwt_param = ServerUtil.getFirstValue(requestParameters, \"user\")\n\n\n if jwt_param != None:\n # and now that the jwt_param user exists...\n print \"Entered if jwt_param != None\"\n print \"Passport. authenticate for step 1. JWT user profile token found\"\n\n if self.isInboundFlow(identity):\n jwt_param = base64.urlsafe_b64decode(str(jwt_param+'=='))\n\n # Parse JWT and validate\n jwt = Jwt.parse(jwt_param)\n\n if not self.validSignature(jwt):\n return False\n\n if self.jwtHasExpired(jwt):\n return False\n\n # Gets user profile as string and json using the information on JWT\n (user_profile, jsonp) = self.getUserProfile(jwt)\n\n if user_profile == None:\n return False\n\n sessionAttributes = identity.getSessionId().getSessionAttributes()\n self.skipProfileUpdate = StringHelper.equalsIgnoreCase(sessionAttributes.get(\"skipPassportProfileUpdate\"), \"true\")\n\n return self.attemptAuthentication(identity, user_profile, jsonp)\n\n #See passportlogin.xhtml\n print \"-------------============------------\"\n provider = ServerUtil.getFirstValue(requestParameters, \"loginForm:provider\")\n print \"authenticate() - provider = %s\" % str(provider)\n\n\n print \"authenticate - self.registeredProviders: %s\" % str(self.registeredProviders)\n if StringHelper.isEmpty(provider):\n\n #it's username + passw auth\n print \"Passport. authenticate for step 1. Basic authentication detected\"\n logged_in = False\n\n credentials = identity.getCredentials()\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n authenticationService = CdiUtil.bean(AuthenticationService)\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n print \"Passport. authenticate for step 1. Basic authentication returned: %s\" % logged_in\n return logged_in\n\n\n\n elif provider in self.registeredProviders:\n # user selected provider\n # it's a recognized external IDP\n\n identity.setWorkingParameter(\"selectedProvider\", provider)\n print \"Passport. authenticate for step 1. Retrying step 1\"\n\n #see prepareForStep (step = 1)\n return True\n\n if step == 2:\n mail = ServerUtil.getFirstValue(requestParameters, \"loginForm:email\")\n jsonp = identity.getWorkingParameter(\"passport_user_profile\")\n\n if mail == None:\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email was missing in user profile\")\n elif jsonp != None:\n # Completion of profile takes place\n user_profile = json.loads(jsonp)\n user_profile[\"mail\"] = [ mail ]\n\n return self.attemptAuthentication(identity, user_profile, jsonp)\n\n print \"Passport. authenticate for step 2. Failed: expected mail value in HTTP request and json profile in session\"\n return False\n\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n\n extensionResult = self.extensionPrepareForStep(configurationAttributes, requestParameters, step)\n if extensionResult != None:\n return extensionResult\n\n print \"Passport. prepareForStep called %s\" % str(step)\n identity = CdiUtil.bean(Identity)\n\n if step == 1:\n #re-read the strategies config (for instance to know which strategies have enabled the email account linking)\n self.parseProviderConfigs()\n identity.setWorkingParameter(\"externalProviders\", json.dumps(self.registeredProviders))\n\n providerParam = self.customAuthzParameter\n url = None\n\n sessionAttributes = identity.getSessionId().getSessionAttributes()\n self.skipProfileUpdate = StringHelper.equalsIgnoreCase(sessionAttributes.get(\"skipPassportProfileUpdate\"), \"true\")\n\n #this param could have been set previously in authenticate step if current step is being retried\n provider = identity.getWorkingParameter(\"selectedProvider\")\n print \"prepareForStep %s - provider = %s\" % (str(step), str(provider))\n\n # if there is a selectedProvider\n if provider != None:\n\n # get the redirect URL to use at facesService.redirectToExternalURL() that sends /passport/auth//\n url = self.getPassportRedirectUrl(provider)\n print \"prepareForStep %s - url = %s\" % (str(step), url)\n\n # sets selectedProvider back to None\n identity.setWorkingParameter(\"selectedProvider\", None)\n\n # if there is customAuthzParameter\n elif providerParam != None:\n\n\n # get it from sessionAtributes\n paramValue = sessionAttributes.get(providerParam)\n\n #if exists\n if paramValue != None:\n print \"Passport. prepareForStep. Found value in custom param of authorization request: %s\" % paramValue\n provider = self.getProviderFromJson(paramValue)\n\n if provider == None:\n print \"Passport. prepareForStep. A provider value could not be extracted from custom authorization request parameter\"\n elif not provider in self.registeredProviders:\n print \"Passport. prepareForStep. Provider '%s' not part of known configured IDPs/OPs\" % provider\n else:\n url = self.getPassportRedirectUrl(provider)\n\n\n # if no provider selected yet...\n if url == None:\n print \"Passport. prepareForStep. A page to manually select an identity provider will be shown\"\n\n # else already got the /passport/auth// url...\n else:\n\n facesService = CdiUtil.bean(FacesService)\n\n # redirects to Passport getRedirectURL - sends browser to IDP.\n print \"Passport. Redirecting to external url: %s\" + url\n\n facesService.redirectToExternalURL(url)\n\n return True\n\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n print \"Passport. getExtraParametersForStep called for step %s\" % str(step)\n if step == 1:\n return Arrays.asList(\"selectedProvider\", \"externalProviders\")\n elif step == 2:\n return Arrays.asList(\"passport_user_profile\")\n return None\n\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n print \"Passport. getCountAuthenticationSteps called\"\n identity = CdiUtil.bean(Identity)\n if identity.getWorkingParameter(\"passport_user_profile\") != None:\n return 2\n return 1\n\n\n def getPageForStep(self, configurationAttributes, step):\n print \"Passport. getPageForStep called\"\n\n extensionResult = self.extensionGetPageForStep(configurationAttributes, step)\n if extensionResult != None:\n return extensionResult\n\n if step == 1:\n identity = CdiUtil.bean(Identity)\n print \"Passport. getPageForStep. Entered if step ==1\"\n if self.isInboundFlow(identity):\n print \"Passport. getPageForStep for step 1. Detected inbound Saml flow\"\n return \"/postlogin.xhtml\"\n print \"Passport. getPageForStep 1. NormalFlow, returning passportlogin.xhtml\"\n return \"/auth/passport/passportlogin.xhtml\"\n\n return \"/auth/passport/passportpostlogin.xhtml\"\n\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n if step == 1:\n identity = CdiUtil.bean(Identity)\n provider = identity.getWorkingParameter(\"selectedProvider\")\n if provider != None:\n return 1\n\n return -1\n\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n# Extension module related functions\n\n def extensionInit(self, configurationAttributes):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.init(configurationAttributes)\n\n\n def extensionAuthenticate(self, configurationAttributes, requestParameters, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.authenticate(configurationAttributes, requestParameters, step)\n\n\n def extensionPrepareForStep(self, configurationAttributes, requestParameters, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.prepareForStep(configurationAttributes, requestParameters, step)\n\n\n def extensionGetPageForStep(self, configurationAttributes, step):\n\n if self.extensionModule == None:\n return None\n return self.extensionModule.getPageForStep(configurationAttributes, step)\n\n# Initalization routines\n\n def loadExternalModule(self, simpleCustProperty):\n\n if simpleCustProperty != None:\n print \"Passport. loadExternalModule. Loading passport extension module...\"\n moduleName = simpleCustProperty.getValue2()\n try:\n module = __import__(moduleName)\n return module\n except:\n print \"Passport. loadExternalModule. Failed to load module %s\" % moduleName\n print \"Exception: \", sys.exc_info()[1]\n print \"Passport. loadExternalModule. Flow will be driven entirely by routines of main passport script\"\n return None\n\n\n def processKeyStoreProperties(self, attrs):\n file = attrs.get(\"key_store_file\")\n password = attrs.get(\"key_store_password\")\n\n if file != None and password != None:\n file = file.getValue2()\n password = password.getValue2()\n\n if StringHelper.isNotEmpty(file) and StringHelper.isNotEmpty(password):\n self.keyStoreFile = file\n self.keyStorePassword = password\n return True\n\n print \"Passport. readKeyStoreProperties. Properties key_store_file or key_store_password not found or empty\"\n return False\n\n\n def getCustomAuthzParameter(self, simpleCustProperty):\n\n customAuthzParameter = None\n if simpleCustProperty != None:\n prop = simpleCustProperty.getValue2()\n if StringHelper.isNotEmpty(prop):\n customAuthzParameter = prop\n\n if customAuthzParameter == None:\n print \"Passport. getCustomAuthzParameter. No custom param for OIDC authz request in script properties\"\n print \"Passport. getCustomAuthzParameter. Passport flow cannot be initiated by doing an OpenID connect authorization request\"\n else:\n print \"Passport. getCustomAuthzParameter. Custom param for OIDC authz request in script properties: %s\" % customAuthzParameter\n\n return customAuthzParameter\n\n# Configuration parsing\n\n def getPassportConfigDN(self):\n\n f = open('/etc/gluu/conf/gluu.properties', 'r')\n for line in f:\n prop = line.split(\"=\")\n if prop[0] == \"oxpassport_ConfigurationEntryDN\":\n prop.pop(0)\n break\n\n f.close()\n return \"=\".join(prop).strip()\n\n\n def parseAllProviders(self):\n\n registeredProviders = {}\n print \"Passport. parseAllProviders. Adding providers\"\n entryManager = CdiUtil.bean(PersistenceEntryManager)\n\n config = LdapOxPassportConfiguration()\n config = entryManager.find(config.getClass(), self.passportDN).getPassportConfiguration()\n config = config.getProviders() if config != None else config\n\n if config != None and len(config) > 0:\n for prvdetails in config:\n if prvdetails.isEnabled():\n registeredProviders[prvdetails.getId()] = {\n \"emailLinkingSafe\": prvdetails.isEmailLinkingSafe(),\n \"requestForEmail\" : prvdetails.isRequestForEmail(),\n \"logo_img\": prvdetails.getLogoImg(),\n \"displayName\": prvdetails.getDisplayName(),\n \"type\": prvdetails.getType()\n }\n\n return registeredProviders\n\n\n def parseProviderConfigs(self):\n\n registeredProviders = {}\n try:\n registeredProviders = self.parseAllProviders()\n toRemove = []\n\n for provider in registeredProviders:\n if registeredProviders[provider][\"type\"] != \"saml\":\n toRemove.append(provider)\n else:\n registeredProviders[provider][\"saml\"] = True\n\n for provider in toRemove:\n registeredProviders.pop(provider)\n\n\n if len(registeredProviders.keys()) > 0:\n print \"Passport. parseProviderConfigs. Configured providers:\", registeredProviders\n else:\n print \"Passport. parseProviderConfigs. No providers registered yet\"\n except:\n print \"Passport. parseProviderConfigs. An error occurred while building the list of supported authentication providers\", sys.exc_info()[1]\n\n\n print \"parseProviderConfigs - registeredProviders = %s\" % str(registeredProviders)\n self.registeredProviders = registeredProviders\n print \"parseProviderConfigs - self.registeredProviders = %s\" % str(self.registeredProviders)\n\n# Auxiliary routines\n\n def getProviderFromJson(self, providerJson):\n\n provider = None\n try:\n obj = json.loads(Base64Util.base64urldecodeToString(providerJson))\n provider = obj[self.providerKey]\n except:\n print \"Passport. getProviderFromJson. Could not parse provided Json string. Returning None\"\n\n return provider\n\n\n def getPassportRedirectUrl(self, provider):\n\n # provider is assumed to exist in self.registeredProviders\n url = None\n try:\n facesContext = CdiUtil.bean(FacesContext)\n tokenEndpoint = \"https://%s/passport/token\" % facesContext.getExternalContext().getRequest().getServerName()\n\n httpService = CdiUtil.bean(HttpService)\n httpclient = httpService.getHttpsClient()\n\n print \"Passport. getPassportRedirectUrl. Obtaining token from passport at %s\" % tokenEndpoint\n resultResponse = httpService.executeGet(httpclient, tokenEndpoint, Collections.singletonMap(\"Accept\", \"text/json\"))\n httpResponse = resultResponse.getHttpResponse()\n\n bytes = httpService.getResponseContent(httpResponse)\n\n response = httpService.convertEntityToString(bytes)\n print \"Passport. getPassportRedirectUrl. Response was %s\" % httpResponse.getStatusLine().getStatusCode()\n\n tokenObj = json.loads(response)\n\n url = \"/passport/auth/%s/%s\" % (provider, tokenObj[\"token_\"])\n\n except:\n print \"Passport. getPassportRedirectUrl. Error building redirect URL: \", sys.exc_info()[1]\n\n return url\n\n\n def validSignature(self, jwt):\n\n print \"Passport. validSignature. Checking JWT token signature\"\n valid = False\n\n try:\n\n appConfiguration = AppConfiguration()\n appConfiguration.setWebKeysStorage(WebKeyStorage.KEYSTORE)\n appConfiguration.setKeyStoreFile(self.keyStoreFile)\n appConfiguration.setKeyStoreSecret(self.keyStorePassword)\n appConfiguration.setKeyRegenerationEnabled(False)\n\n cryptoProvider = CryptoProviderFactory.getCryptoProvider(appConfiguration)\n\n\n alg_string = str(jwt.getHeader().getSignatureAlgorithm())\n signature_string = str(jwt.getEncodedSignature())\n\n if alg_string == \"none\" or alg_string == \"None\" or alg_string == \"NoNe\" or alg_string == \"nONE\" or alg_string == \"NONE\" or alg_string == \"NonE\" or alg_string == \"nOnE\":\n # blocks none attack\n\n print \"WARNING: JWT Signature algorithm is none\"\n valid = False\n\n elif alg_string != \"RS512\":\n # blocks anything that's not RS512\n\n print \"WARNING: JWT Signature algorithm is NOT RS512\"\n valid = False\n\n elif signature_string == \"\" :\n # blocks empty signature string\n print \"WARNING: JWT Signature not sent\"\n valid = False\n\n else:\n\n # class extends AbstractCryptoProvider\n ''' on version 4.2 .getAlgorithm() method was renamed to .getSignatureAlgorithm()\n for older versions:\n valid = cryptoProvider.verifySignature(jwt.getSigningInput(), jwt.getEncodedSignature(), jwt.getHeader().getKeyId(),\n None, None, jwt.getHeader().getAlgorithm())\n '''\n\n # working on 4.2:\n valid = cryptoProvider.verifySignature(jwt.getSigningInput(), jwt.getEncodedSignature(), jwt.getHeader().getKeyId(),\n None, None, jwt.getHeader().getSignatureAlgorithm())\n\n except:\n print \"Exception: \", sys.exc_info()[1]\n\n print \"Passport. validSignature. Validation result was %s\" % valid\n\n return valid\n\n\n def jwtHasExpired(self, jwt):\n # Check if jwt has expired\n jwt_claims = jwt.getClaims()\n try:\n exp_date = jwt_claims.getClaimAsDate(JwtClaimName.EXPIRATION_TIME)\n hasExpired = exp_date < datetime.datetime.now()\n except:\n print \"Exception: The JWT does not have '%s' attribute\" % JwtClaimName.EXPIRATION_TIME\n return False\n\n return hasExpired\n\n\n def getUserProfile(self, jwt):\n\n # getClaims method located at org.gluu.oxauth.model.token.JsonWebResponse.java as a org.gluu.oxauth.model.jwt.JwtClaims object\n jwt_claims = jwt.getClaims()\n\n user_profile_json = None\n\n try:\n # public String getClaimAsString(String key)\n user_profile_json = CdiUtil.bean(EncryptionService).decrypt(jwt_claims.getClaimAsString(\"data\"))\n\n user_profile = json.loads(user_profile_json)\n except:\n print \"Passport. getUserProfile. Problem obtaining user profile json representation\"\n\n return (user_profile, user_profile_json)\n\n\n def attemptAuthentication(self, identity, user_profile, user_profile_json):\n\n print \"Entered attemptAuthentication...\"\n uidKey = \"uid\"\n if not self.checkRequiredAttributes(user_profile, [uidKey, self.providerKey]):\n return False\n\n provider = user_profile[self.providerKey]\n print \"user_profile[self.providerKey] = %s\" % str(user_profile[self.providerKey])\n if not provider in self.registeredProviders:\n print \"Entered if note provider in self.registeredProviers:\"\n print \"Passport. attemptAuthentication. Identity Provider %s not recognized\" % provider\n return False\n\n print \"attemptAuthentication. user_profile = %s\" % user_profile\n print \"user_profile[uidKey] = %s\" % user_profile[uidKey]\n uid = user_profile[uidKey][0]\n print \"attemptAuthentication - uid = %s\" % uid\n externalUid = \"passport-%s:%s:%s\" % (\"saml\", provider, uid)\n\n userService = CdiUtil.bean(UserService)\n userByUid = self.getUserByExternalUid(uid, provider, userService)\n\n email = None\n if \"mail\" in user_profile:\n email = user_profile[\"mail\"]\n if len(email) == 0:\n email = None\n else:\n email = email[0]\n user_profile[\"mail\"] = [ email ]\n\n if email == None and self.registeredProviders[provider][\"requestForEmail\"]:\n print \"Passport. attemptAuthentication. Email was not received\"\n\n if userByUid != None:\n # This avoids asking for the email over every login attempt\n email = userByUid.getAttribute(\"mail\")\n if email != None:\n print \"Passport. attemptAuthentication. Filling missing email value with %s\" % email\n user_profile[\"mail\"] = [ email ]\n\n if email == None:\n # Store user profile in session and abort this routine\n identity.setWorkingParameter(\"passport_user_profile\", user_profile_json)\n return True\n\n userByMail = None if email == None else userService.getUserByAttribute(\"mail\", email)\n\n # Determine if we should add entry, update existing, or deny access\n doUpdate = False\n doAdd = False\n if userByUid != None:\n print \"User with externalUid '%s' already exists\" % externalUid\n if userByMail == None:\n doUpdate = True\n else:\n if userByMail.getUserId() == userByUid.getUserId():\n doUpdate = True\n else:\n print \"Users with externalUid '%s' and mail '%s' are different. Access will be denied. Impersonation attempt?\" % (externalUid, email)\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email value corresponds to an already existing provisioned account\")\n else:\n if userByMail == None:\n doAdd = True\n elif self.registeredProviders[provider][\"emailLinkingSafe\"]:\n\n tmpList = userByMail.getAttributeValues(\"oxExternalUid\")\n tmpList = ArrayList() if tmpList == None else ArrayList(tmpList)\n tmpList.add(externalUid)\n userByMail.setAttribute(\"oxExternalUid\", tmpList)\n\n userByUid = userByMail\n print \"External user supplying mail %s will be linked to existing account '%s'\" % (email, userByMail.getUserId())\n doUpdate = True\n else:\n print \"An attempt to supply an email of an existing user was made. Turn on 'emailLinkingSafe' if you want to enable linking\"\n self.setMessageError(FacesMessage.SEVERITY_ERROR, \"Email value corresponds to an already existing account. If you already have a username and password use those instead of an external authentication site to get access.\")\n\n username = None\n try:\n if doUpdate:\n username = userByUid.getUserId()\n print \"Passport. attemptAuthentication. Updating user %s\" % username\n self.updateUser(userByUid, user_profile, userService)\n elif doAdd:\n print \"Passport. attemptAuthentication. Creating user %s\" % externalUid\n newUser = self.addUser(externalUid, user_profile, userService)\n username = newUser.getUserId()\n except:\n print \"Exception: \", sys.exc_info()[1]\n print \"Passport. attemptAuthentication. Authentication failed\"\n return False\n\n if username == None:\n print \"Passport. attemptAuthentication. Authentication attempt was rejected\"\n return False\n else:\n logged_in = CdiUtil.bean(AuthenticationService).authenticate(username)\n print \"Passport. attemptAuthentication. Authentication for %s returned %s\" % (username, logged_in)\n return logged_in\n\n\n def getUserByExternalUid(self, uid, provider, userService):\n newFormat = \"passport-%s:%s:%s\" % (\"saml\", provider, uid)\n user = userService.getUserByAttribute(\"oxExternalUid\", newFormat)\n\n if user == None:\n oldFormat = \"passport-%s:%s\" % (\"saml\", uid)\n user = userService.getUserByAttribute(\"oxExternalUid\", oldFormat)\n\n if user != None:\n # Migrate to newer format\n list = HashSet(user.getAttributeValues(\"oxExternalUid\"))\n list.remove(oldFormat)\n list.add(newFormat)\n user.setAttribute(\"oxExternalUid\", ArrayList(list))\n print \"Migrating user's oxExternalUid to newer format 'passport-saml:provider:uid'\"\n userService.updateUser(user)\n\n return user\n\n\n def setMessageError(self, severity, msg):\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.setKeepMessages()\n facesMessages.clear()\n facesMessages.add(severity, msg)\n\n\n def checkRequiredAttributes(self, profile, attrs):\n\n for attr in attrs:\n if (not attr in profile) or len(profile[attr]) == 0:\n print \"Passport. checkRequiredAttributes. Attribute '%s' is missing in profile\" % attr\n return False\n return True\n\n\n def addUser(self, externalUid, profile, userService):\n print \"Passport. Entered addUser().\"\n print \"Passport. addUser. externalUid = %s\" % externalUid\n print \"Passport. addUser. profile = %s\" % profile\n newUser = User()\n #Fill user attrs\n newUser.setAttribute(\"oxExternalUid\", externalUid)\n self.fillUser(newUser, profile)\n newUser = userService.addUser(newUser, True)\n return newUser\n\n\n def updateUser(self, foundUser, profile, userService):\n # when this is false, there might still some updates taking place (e.g. not related to profile attrs released by external provider)\n if (not self.skipProfileUpdate):\n self.fillUser(foundUser, profile)\n userService.updateUser(foundUser)\n\n\n def fillUser(self, foundUser, profile):\n print\n print \"Passport. Entered fillUser().\"\n print \"Passport. fillUser. foundUser = %s\" % foundUser\n print \"Passport. fillUser. profile = %s\" % profile\n for attr in profile:\n # \"provider\" is disregarded if part of mapping\n if attr != self.providerKey:\n values = profile[attr]\n print \"%s = %s\" % (attr, values)\n foundUser.setAttribute(attr, values)\n\n if attr == \"mail\":\n print \"Passport. fillUser. entered if attr == mail\"\n oxtrustMails = []\n for mail in values:\n oxtrustMails.append('{\"value\":\"%s\",\"primary\":false}' % mail)\n foundUser.setAttribute(\"oxTrustEmail\", oxtrustMails)\n\n# IDP-initiated flow routines\n\n def isInboundFlow(self, identity):\n print \"passport. entered isInboundFlow\"\n\n sessionId = identity.getSessionId()\n print \"passport. isInboundFlow. sessionId = %s\" % sessionId\n if sessionId == None:\n print \"passport. isInboundFlow. sessionId not found yet...\"\n # Detect mode if there is no session yet. It's needed for getPageForStep method\n facesContext = CdiUtil.bean(FacesContext)\n requestParameters = facesContext.getExternalContext().getRequestParameterMap()\n print \"passport. isInboundFlow. requestParameters = %s\" % requestParameters\n\n authz_state = requestParameters.get(AuthorizeRequestParam.STATE)\n print \"passport. isInboundFlow. authz_state = %s\" % authz_state\n else:\n authz_state = identity.getSessionId().getSessionAttributes().get(AuthorizeRequestParam.STATE)\n\n print \"passport. IsInboundFlow. authz_state = %s\" % authz_state\n\n # the replace above is workaround due a problem reported\n # on issue: https://github.com/GluuFederation/gluu-passport/issues/95\n # TODO: Remove after fixed on JSF side\n\n b64url_decoded_auth_state = base64.urlsafe_b64decode(str(authz_state+'=='))\n\n # print \"passport. IsInboundFlow. b64url_decoded_auth_state = %s\" % str(b64url_decoded_auth_state)\n print \"passport. IsInboundFlow. self.isInboundJwt() = %s\" % str(self.isInboundJwt(b64url_decoded_auth_state))\n if self.isInboundJwt(b64url_decoded_auth_state):\n return True\n\n return False\n\n\n def isInboundJwt(self, value):\n if value == None:\n return False\n\n try:\n\n print(\"passport.isInboundJwt. value = %s\" % value)\n # value = value.replace(\"_\", \".\")\n # print(\"passport.isInboundJwt. value = %s\" % value)\n\n jwt = Jwt.parse(value)\n print \"passport.isInboundJwt. jwt = %s\" % jwt\n\n # user_profile_json = jwt.getClaims().getClaimAsString(\"data\")\n\n user_profile_json = CdiUtil.bean(EncryptionService).decrypt(jwt.getClaims().getClaimAsString(\"data\"))\n print \"passport.isInboundJwt. user_profile_json = %s\" % user_profile_json\n if StringHelper.isEmpty(user_profile_json):\n return False\n except InvalidJwtException:\n return False\n\n except:\n print(\"Unexpected error:\", sys.exc_info()[0])\n return False\n\n return True\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "passport_saml", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "/etc/certs/passport-rp.jks", - "value1": "key_store_file" - }, - { - "hide": false, - "value2": "secret", - "value1": "key_store_password" - } - ], - "baseDn": "inum=D40C-1CA4,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 60, - "programmingLanguage": "PYTHON", - "description": "Super Gluu authentication module", - "locationType": "LDAP", - "dn": "inum=92F0-BF9E,ou=scripts,o=gluu", - "inum": "92F0-BF9E", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom com.google.android.gcm.server import Sender, Message\nfrom com.notnoop.apns import APNS\nfrom java.util import Arrays\nfrom org.apache.http.params import CoreConnectionPNames\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.oxauth.model.config import ConfigurationFactory\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.fido.u2f import DeviceRegistrationService\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.util import StringHelper\nfrom org.gluu.oxauth.service.common import EncryptionService, UserService\nfrom org.gluu.service import MailService\nfrom org.gluu.oxauth.service.push.sns import PushPlatform, PushSnsService \nfrom org.gluu.oxnotify.client import NotifyClientFactory \nfrom java.util import Arrays, HashMap, IdentityHashMap, Date\nfrom java.time import ZonedDateTime\nfrom java.time.format import DateTimeFormatter\n\ntry:\n from org.gluu.oxd.license.client.js import Product\n from org.gluu.oxd.license.validator import LicenseValidator\n has_license_api = True\nexcept ImportError:\n print \"Super-Gluu. Load. Failed to load licensing API\"\n has_license_api = False\n\nimport datetime\nimport urllib\n\nimport sys\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Super-Gluu. Initialization\"\n\n if not configurationAttributes.containsKey(\"authentication_mode\"):\n print \"Super-Gluu. Initialization. Property authentication_mode is mandatory\"\n return False\n\n self.applicationId = None\n if configurationAttributes.containsKey(\"application_id\"):\n self.applicationId = configurationAttributes.get(\"application_id\").getValue2()\n\n self.registrationUri = None\n if configurationAttributes.containsKey(\"registration_uri\"):\n self.registrationUri = configurationAttributes.get(\"registration_uri\").getValue2()\n\n authentication_mode = configurationAttributes.get(\"authentication_mode\").getValue2()\n if StringHelper.isEmpty(authentication_mode):\n print \"Super-Gluu. Initialization. Failed to determine authentication_mode. authentication_mode configuration parameter is empty\"\n return False\n \n self.oneStep = StringHelper.equalsIgnoreCase(authentication_mode, \"one_step\")\n self.twoStep = StringHelper.equalsIgnoreCase(authentication_mode, \"two_step\")\n\n if not (self.oneStep or self.twoStep):\n print \"Super-Gluu. Initialization. Valid authentication_mode values are one_step and two_step\"\n return False\n \n self.enabledPushNotifications = self.initPushNotificationService(configurationAttributes)\n\n self.androidUrl = None\n if configurationAttributes.containsKey(\"supergluu_android_download_url\"):\n self.androidUrl = configurationAttributes.get(\"supergluu_android_download_url\").getValue2()\n\n self.IOSUrl = None\n if configurationAttributes.containsKey(\"supergluu_ios_download_url\"):\n self.IOSUrl = configurationAttributes.get(\"supergluu_ios_download_url\").getValue2()\n\n self.customLabel = None\n if configurationAttributes.containsKey(\"label\"):\n self.customLabel = configurationAttributes.get(\"label\").getValue2()\n\n self.customQrOptions = {}\n if configurationAttributes.containsKey(\"qr_options\"):\n self.customQrOptions = configurationAttributes.get(\"qr_options\").getValue2()\n\n self.use_super_gluu_group = False\n if configurationAttributes.containsKey(\"super_gluu_group\"):\n self.super_gluu_group = configurationAttributes.get(\"super_gluu_group\").getValue2()\n self.use_super_gluu_group = True\n print \"Super-Gluu. Initialization. Using super_gluu only if user belong to group: %s\" % self.super_gluu_group\n\n self.use_audit_group = False\n if configurationAttributes.containsKey(\"audit_group\"):\n self.audit_group = configurationAttributes.get(\"audit_group\").getValue2()\n\n if (not configurationAttributes.containsKey(\"audit_group_email\")):\n print \"Super-Gluu. Initialization. Property audit_group_email is not specified\"\n return False\n\n self.audit_email = configurationAttributes.get(\"audit_group_email\").getValue2()\n self.use_audit_group = True\n\n print \"Super-Gluu. Initialization. Using audit group: %s\" % self.audit_group\n \n if self.use_super_gluu_group or self.use_audit_group:\n if not configurationAttributes.containsKey(\"audit_attribute\"):\n print \"Super-Gluu. Initialization. Property audit_attribute is not specified\"\n return False\n else:\n self.audit_attribute = configurationAttributes.get(\"audit_attribute\").getValue2()\n\n self.valid_license = False\n # Removing or altering this block validation is against the terms of the license. \n if has_license_api and configurationAttributes.containsKey(\"license_file\"):\n license_file = configurationAttributes.get(\"license_file\").getValue2()\n\n # Load license from file\n f = open(license_file, 'r')\n try:\n license = json.loads(f.read())\n except:\n print \"Super-Gluu. Initialization. Failed to load license from file: %s\" % license_file\n return False\n finally:\n f.close()\n \n # Validate license\n try:\n self.license_content = LicenseValidator.validate(license[\"public_key\"], license[\"public_password\"], license[\"license_password\"], license[\"license\"],\n Product.SUPER_GLUU, Date())\n self.valid_license = self.license_content.isValid()\n except:\n print \"Super-Gluu. Initialization. Failed to validate license. Exception: \", sys.exc_info()[1]\n return False\n\n print \"Super-Gluu. Initialization. License status: '%s'. License metadata: '%s'\" % (self.valid_license, self.license_content.getMetadata())\n\n print \"Super-Gluu. Initialized successfully. oneStep: '%s', twoStep: '%s', pushNotifications: '%s', customLabel: '%s'\" % (self.oneStep, self.twoStep, self.enabledPushNotifications, self.customLabel)\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Super-Gluu. Destroy\"\n\n self.pushAndroidService = None\n self.pushAppleService = None\n\n print \"Super-Gluu. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n client_redirect_uri = self.getApplicationUri(session_attributes)\n if client_redirect_uri == None:\n print \"Super-Gluu. Authenticate. redirect_uri is not set\"\n return False\n\n self.setRequestScopedParameters(identity, step)\n\n # Validate form result code and initialize QR code regeneration if needed (retry_current_step = True)\n identity.setWorkingParameter(\"retry_current_step\", False)\n form_auth_result = ServerUtil.getFirstValue(requestParameters, \"auth_result\")\n if StringHelper.isNotEmpty(form_auth_result):\n print \"Super-Gluu. Authenticate for step %s. Get auth_result: '%s'\" % (step, form_auth_result)\n if form_auth_result in ['error']:\n return False\n\n if form_auth_result in ['timeout']:\n if ((step == 1) and self.oneStep) or ((step == 2) and self.twoStep): \n print \"Super-Gluu. Authenticate for step %s. Reinitializing current step\" % step\n identity.setWorkingParameter(\"retry_current_step\", True)\n return False\n\n userService = CdiUtil.bean(UserService)\n deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)\n if step == 1:\n print \"Super-Gluu. Authenticate for step 1\"\n\n user_name = credentials.getUsername()\n if self.oneStep:\n session_device_status = self.getSessionDeviceStatus(session_attributes, user_name)\n if session_device_status == None:\n return False\n\n u2f_device_id = session_device_status['device_id']\n\n validation_result = self.validateSessionDeviceStatus(client_redirect_uri, session_device_status)\n if validation_result:\n print \"Super-Gluu. Authenticate for step 1. User successfully authenticated with u2f_device '%s'\" % u2f_device_id\n else:\n return False\n \n if not session_device_status['one_step']:\n print \"Super-Gluu. Authenticate for step 1. u2f_device '%s' is not one step device\" % u2f_device_id\n return False\n \n # There are two steps only in enrollment mode\n if session_device_status['enroll']:\n return validation_result\n\n identity.setWorkingParameter(\"super_gluu_count_login_steps\", 1)\n\n user_inum = session_device_status['user_inum']\n\n u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id, \"oxId\")\n if u2f_device == None:\n print \"Super-Gluu. Authenticate for step 1. Failed to load u2f_device '%s'\" % u2f_device_id\n return False\n\n logged_in = authenticationService.authenticate(user_name)\n if not logged_in:\n print \"Super-Gluu. Authenticate for step 1. Failed to authenticate user '%s'\" % user_name\n return False\n\n print \"Super-Gluu. Authenticate for step 1. User '%s' successfully authenticated with u2f_device '%s'\" % (user_name, u2f_device_id)\n \n return True\n elif self.twoStep:\n authenticated_user = self.processBasicAuthentication(credentials)\n if authenticated_user == None:\n return False\n\n if (self.use_super_gluu_group):\n print \"Super-Gluu. Authenticate for step 1. Checking if user belong to super_gluu group\"\n is_member_super_gluu_group = self.isUserMemberOfGroup(authenticated_user, self.audit_attribute, self.super_gluu_group)\n if (is_member_super_gluu_group):\n print \"Super-Gluu. Authenticate for step 1. User '%s' member of super_gluu group\" % authenticated_user.getUserId()\n super_gluu_count_login_steps = 2\n else:\n if self.use_audit_group:\n self.processAuditGroup(authenticated_user, self.audit_attribute, self.audit_group)\n super_gluu_count_login_steps = 1\n \n identity.setWorkingParameter(\"super_gluu_count_login_steps\", super_gluu_count_login_steps)\n \n if super_gluu_count_login_steps == 1:\n return True\n \n auth_method = 'authenticate'\n enrollment_mode = ServerUtil.getFirstValue(requestParameters, \"loginForm:registerButton\")\n if StringHelper.isNotEmpty(enrollment_mode):\n auth_method = 'enroll'\n \n if auth_method == 'authenticate':\n user_inum = userService.getUserInum(authenticated_user)\n u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, \"oxId\")\n if u2f_devices_list.size() == 0:\n auth_method = 'enroll'\n print \"Super-Gluu. Authenticate for step 1. There is no U2F '%s' user devices associated with application '%s'. Changing auth_method to '%s'\" % (user_name, client_redirect_uri, auth_method)\n \n print \"Super-Gluu. Authenticate for step 1. auth_method: '%s'\" % auth_method\n \n identity.setWorkingParameter(\"super_gluu_auth_method\", auth_method)\n\n return True\n\n return False\n elif step == 2:\n print \"Super-Gluu. Authenticate for step 2\"\n\n user = authenticationService.getAuthenticatedUser()\n if (user == None):\n print \"Super-Gluu. Authenticate for step 2. Failed to determine user name\"\n return False\n user_name = user.getUserId()\n\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n session_device_status = self.getSessionDeviceStatus(session_attributes, user_name)\n if session_device_status == None:\n return False\n\n u2f_device_id = session_device_status['device_id']\n\n # There are two steps only in enrollment mode\n if self.oneStep and session_device_status['enroll']:\n authenticated_user = self.processBasicAuthentication(credentials)\n if authenticated_user == None:\n return False\n\n user_inum = userService.getUserInum(authenticated_user)\n \n attach_result = deviceRegistrationService.attachUserDeviceRegistration(user_inum, u2f_device_id)\n\n print \"Super-Gluu. Authenticate for step 2. Result after attaching u2f_device '%s' to user '%s': '%s'\" % (u2f_device_id, user_name, attach_result) \n\n return attach_result\n elif self.twoStep:\n if user_name == None:\n print \"Super-Gluu. Authenticate for step 2. Failed to determine user name\"\n return False\n\n validation_result = self.validateSessionDeviceStatus(client_redirect_uri, session_device_status, user_name)\n if validation_result:\n print \"Super-Gluu. Authenticate for step 2. User '%s' successfully authenticated with u2f_device '%s'\" % (user_name, u2f_device_id)\n else:\n return False\n \n super_gluu_request = json.loads(session_device_status['super_gluu_request'])\n auth_method = super_gluu_request['method']\n if auth_method in ['enroll', 'authenticate']:\n if validation_result and self.use_audit_group:\n user = authenticationService.getAuthenticatedUser()\n self.processAuditGroup(user, self.audit_attribute, self.audit_group)\n\n return validation_result\n\n print \"Super-Gluu. Authenticate for step 2. U2F auth_method is invalid\"\n\n return False\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n client_redirect_uri = self.getApplicationUri(session_attributes)\n if client_redirect_uri == None:\n print \"Super-Gluu. Prepare for step. redirect_uri is not set\"\n return False\n\n self.setRequestScopedParameters(identity, step)\n\n if step == 1:\n print \"Super-Gluu. Prepare for step 1\"\n if self.oneStep:\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"Super-Gluu. Prepare for step 2. Failed to determine session_id\"\n return False\n\n issuer = CdiUtil.bean(ConfigurationFactory).getConfiguration().getIssuer()\n super_gluu_request_dictionary = {'app': client_redirect_uri,\n 'issuer': issuer,\n 'state': session.getId(),\n 'licensed': self.valid_license,\n 'created': DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().withNano(0))}\n\n self.addGeolocationData(session_attributes, super_gluu_request_dictionary)\n\n super_gluu_request = json.dumps(super_gluu_request_dictionary, separators=(',',':'))\n print \"Super-Gluu. Prepare for step 1. Prepared super_gluu_request:\", super_gluu_request\n \n identity.setWorkingParameter(\"super_gluu_request\", super_gluu_request)\n elif self.twoStep:\n identity.setWorkingParameter(\"display_register_action\", True)\n\n return True\n elif step == 2:\n print \"Super-Gluu. Prepare for step 2\"\n if self.oneStep:\n return True\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"Super-Gluu. Prepare for step 2. Failed to determine user name\"\n return False\n\n if session_attributes.containsKey(\"super_gluu_request\"):\n super_gluu_request = session_attributes.get(\"super_gluu_request\")\n if not StringHelper.equalsIgnoreCase(super_gluu_request, \"timeout\"):\n print \"Super-Gluu. Prepare for step 2. Request was generated already\"\n return True\n \n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"Super-Gluu. Prepare for step 2. Failed to determine session_id\"\n return False\n\n auth_method = session_attributes.get(\"super_gluu_auth_method\")\n if StringHelper.isEmpty(auth_method):\n print \"Super-Gluu. Prepare for step 2. Failed to determine auth_method\"\n return False\n\n print \"Super-Gluu. Prepare for step 2. auth_method: '%s'\" % auth_method\n \n issuer = CdiUtil.bean(ConfigurationFactory).getAppConfiguration().getIssuer()\n super_gluu_request_dictionary = {'username': user.getUserId(),\n 'app': client_redirect_uri,\n 'issuer': issuer,\n 'method': auth_method,\n 'state': session.getId(),\n 'licensed': self.valid_license,\n 'created': DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now().withNano(0))}\n\n self.addGeolocationData(session_attributes, super_gluu_request_dictionary)\n\n super_gluu_request = json.dumps(super_gluu_request_dictionary, separators=(',',':'))\n print \"Super-Gluu. Prepare for step 2. Prepared super_gluu_request:\", super_gluu_request\n\n identity.setWorkingParameter(\"super_gluu_request\", super_gluu_request)\n identity.setWorkingParameter(\"super_gluu_auth_method\", auth_method)\n\n if auth_method in ['authenticate']:\n self.sendPushNotification(client_redirect_uri, user, super_gluu_request)\n\n return True\n else:\n return False\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n # If user not pass current step change step to previous\n identity = CdiUtil.bean(Identity)\n retry_current_step = identity.getWorkingParameter(\"retry_current_step\")\n if retry_current_step:\n print \"Super-Gluu. Get next step. Retrying current step\"\n\n # Remove old QR code\n identity.setWorkingParameter(\"super_gluu_request\", \"timeout\")\n\n resultStep = step\n return resultStep\n\n return -1\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n if step == 1:\n if self.oneStep: \n return Arrays.asList(\"super_gluu_request\")\n elif self.twoStep:\n return Arrays.asList(\"display_register_action\")\n elif step == 2:\n return Arrays.asList(\"super_gluu_auth_method\", \"super_gluu_request\")\n \n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n identity = CdiUtil.bean(Identity)\n if identity.isSetWorkingParameter(\"super_gluu_count_login_steps\"):\n return identity.getWorkingParameter(\"super_gluu_count_login_steps\")\n else:\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 1:\n if self.oneStep: \n return \"/auth/super-gluu/login.xhtml\"\n elif step == 2:\n if self.oneStep:\n return \"/login.xhtml\"\n else:\n identity = CdiUtil.bean(Identity)\n authmethod = identity.getWorkingParameter(\"super_gluu_auth_method\")\n print \"Super-Gluu. authmethod '%s'\" % authmethod\n if authmethod == \"enroll\":\n return \"/auth/super-gluu/login.xhtml\"\n else:\n return \"/auth/super-gluu/login.xhtml\"\n\n return \"\"\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def processBasicAuthentication(self, credentials):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return None\n\n find_user_by_uid = authenticationService.getAuthenticatedUser()\n if find_user_by_uid == None:\n print \"Super-Gluu. Process basic authentication. Failed to find user '%s'\" % user_name\n return None\n \n return find_user_by_uid\n\n def validateSessionDeviceStatus(self, client_redirect_uri, session_device_status, user_name = None):\n userService = CdiUtil.bean(UserService)\n deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)\n\n u2f_device_id = session_device_status['device_id']\n\n u2f_device = None\n if session_device_status['enroll'] and session_device_status['one_step']:\n u2f_device = deviceRegistrationService.findOneStepUserDeviceRegistration(u2f_device_id)\n if u2f_device == None:\n print \"Super-Gluu. Validate session device status. There is no one step u2f_device '%s'\" % u2f_device_id\n return False\n else:\n # Validate if user has specified device_id enrollment\n user_inum = userService.getUserInum(user_name)\n\n if session_device_status['one_step']:\n user_inum = session_device_status['user_inum']\n \n u2f_device = deviceRegistrationService.findUserDeviceRegistration(user_inum, u2f_device_id)\n if u2f_device == None:\n print \"Super-Gluu. Validate session device status. There is no u2f_device '%s' associated with user '%s'\" % (u2f_device_id, user_inum)\n return False\n\n if not StringHelper.equalsIgnoreCase(client_redirect_uri, u2f_device.application):\n print \"Super-Gluu. Validate session device status. u2f_device '%s' associated with other application '%s'\" % (u2f_device_id, u2f_device.application)\n return False\n \n return True\n\n def getSessionDeviceStatus(self, session_attributes, user_name):\n print \"Super-Gluu. Get session device status\"\n\n if not session_attributes.containsKey(\"super_gluu_request\"):\n print \"Super-Gluu. Get session device status. There is no Super-Gluu request in session attributes\"\n return None\n\n # Check session state extended\n if not session_attributes.containsKey(\"session_custom_state\"):\n print \"Super-Gluu. Get session device status. There is no session_custom_state in session attributes\"\n return None\n\n session_custom_state = session_attributes.get(\"session_custom_state\")\n if not StringHelper.equalsIgnoreCase(\"approved\", session_custom_state):\n print \"Super-Gluu. Get session device status. User '%s' not approve or not pass U2F authentication. session_custom_state: '%s'\" % (user_name, session_custom_state)\n return None\n\n # Try to find device_id in session attribute\n if not session_attributes.containsKey(\"oxpush2_u2f_device_id\"):\n print \"Super-Gluu. Get session device status. There is no u2f_device associated with this request\"\n return None\n\n # Try to find user_inum in session attribute\n if not session_attributes.containsKey(\"oxpush2_u2f_device_user_inum\"):\n print \"Super-Gluu. Get session device status. There is no user_inum associated with this request\"\n return None\n \n enroll = False\n if session_attributes.containsKey(\"oxpush2_u2f_device_enroll\"):\n enroll = StringHelper.equalsIgnoreCase(\"true\", session_attributes.get(\"oxpush2_u2f_device_enroll\"))\n\n one_step = False\n if session_attributes.containsKey(\"oxpush2_u2f_device_one_step\"):\n one_step = StringHelper.equalsIgnoreCase(\"true\", session_attributes.get(\"oxpush2_u2f_device_one_step\"))\n \n super_gluu_request = session_attributes.get(\"super_gluu_request\")\n u2f_device_id = session_attributes.get(\"oxpush2_u2f_device_id\")\n user_inum = session_attributes.get(\"oxpush2_u2f_device_user_inum\")\n\n session_device_status = {\"super_gluu_request\": super_gluu_request, \"device_id\": u2f_device_id, \"user_inum\" : user_inum, \"enroll\" : enroll, \"one_step\" : one_step}\n print \"Super-Gluu. Get session device status. session_device_status: '%s'\" % (session_device_status)\n \n return session_device_status\n\n def initPushNotificationService(self, configurationAttributes):\n print \"Super-Gluu. Initialize Native/SNS/Gluu notification services\"\n\n self.pushSnsMode = False\n self.pushGluuMode = False\n if configurationAttributes.containsKey(\"notification_service_mode\"):\n notificationServiceMode = configurationAttributes.get(\"notification_service_mode\").getValue2()\n if StringHelper.equalsIgnoreCase(notificationServiceMode, \"sns\"):\n return self.initSnsPushNotificationService(configurationAttributes)\n elif StringHelper.equalsIgnoreCase(notificationServiceMode, \"gluu\"):\n return self.initGluuPushNotificationService(configurationAttributes)\n\n return self.initNativePushNotificationService(configurationAttributes)\n\n def initNativePushNotificationService(self, configurationAttributes):\n print \"Super-Gluu. Initialize native notification services\"\n \n creds = self.loadPushNotificationCreds(configurationAttributes)\n if creds == None:\n return False\n \n try:\n android_creds = creds[\"android\"][\"gcm\"]\n ios_creds = creds[\"ios\"][\"apns\"]\n except:\n print \"Super-Gluu. Initialize native notification services. Invalid credentials file format\"\n return False\n \n self.pushAndroidService = None\n self.pushAppleService = None\n if android_creds[\"enabled\"]:\n self.pushAndroidService = Sender(android_creds[\"api_key\"]) \n print \"Super-Gluu. Initialize native notification services. Created Android notification service\"\n \n if ios_creds[\"enabled\"]:\n p12_file_path = ios_creds[\"p12_file_path\"]\n p12_password = ios_creds[\"p12_password\"]\n\n try:\n encryptionService = CdiUtil.bean(EncryptionService)\n p12_password = encryptionService.decrypt(p12_password)\n except:\n # Ignore exception. Password is not encrypted\n print \"Super-Gluu. Initialize native notification services. Assuming that 'p12_password' password in not encrypted\"\n\n apnsServiceBuilder = APNS.newService().withCert(p12_file_path, p12_password)\n if ios_creds[\"production\"]:\n self.pushAppleService = apnsServiceBuilder.withProductionDestination().build()\n else:\n self.pushAppleService = apnsServiceBuilder.withSandboxDestination().build()\n\n self.pushAppleServiceProduction = ios_creds[\"production\"]\n\n print \"Super-Gluu. Initialize native notification services. Created iOS notification service\"\n\n enabled = self.pushAndroidService != None or self.pushAppleService != None\n\n return enabled\n\n def initSnsPushNotificationService(self, configurationAttributes):\n print \"Super-Gluu. Initialize SNS notification services\"\n self.pushSnsMode = True\n\n creds = self.loadPushNotificationCreds(configurationAttributes)\n if creds == None:\n return False\n \n try:\n sns_creds = creds[\"sns\"]\n android_creds = creds[\"android\"][\"sns\"]\n ios_creds = creds[\"ios\"][\"sns\"]\n except:\n print \"Super-Gluu. Initialize SNS notification services. Invalid credentials file format\"\n return False\n \n self.pushAndroidService = None\n self.pushAppleService = None\n if not (android_creds[\"enabled\"] or ios_creds[\"enabled\"]):\n print \"Super-Gluu. Initialize SNS notification services. SNS disabled for all platforms\"\n return False\n\n sns_access_key = sns_creds[\"access_key\"]\n sns_secret_access_key = sns_creds[\"secret_access_key\"]\n sns_region = sns_creds[\"region\"]\n\n encryptionService = CdiUtil.bean(EncryptionService)\n\n try:\n sns_secret_access_key = encryptionService.decrypt(sns_secret_access_key)\n except:\n # Ignore exception. Password is not encrypted\n print \"Super-Gluu. Initialize SNS notification services. Assuming that 'sns_secret_access_key' in not encrypted\"\n \n pushSnsService = CdiUtil.bean(PushSnsService)\n pushClient = pushSnsService.createSnsClient(sns_access_key, sns_secret_access_key, sns_region)\n\n if android_creds[\"enabled\"]:\n self.pushAndroidService = pushClient\n self.pushAndroidPlatformArn = android_creds[\"platform_arn\"]\n print \"Super-Gluu. Initialize SNS notification services. Created Android notification service\"\n\n if ios_creds[\"enabled\"]:\n self.pushAppleService = pushClient \n self.pushApplePlatformArn = ios_creds[\"platform_arn\"]\n self.pushAppleServiceProduction = ios_creds[\"production\"]\n print \"Super-Gluu. Initialize SNS notification services. Created iOS notification service\"\n\n enabled = self.pushAndroidService != None or self.pushAppleService != None\n\n return enabled\n\n def initGluuPushNotificationService(self, configurationAttributes):\n print \"Super-Gluu. Initialize Gluu notification services\"\n\n self.pushGluuMode = True\n\n creds = self.loadPushNotificationCreds(configurationAttributes)\n if creds == None:\n return False\n \n try:\n gluu_conf = creds[\"gluu\"]\n android_creds = creds[\"android\"][\"gluu\"]\n ios_creds = creds[\"ios\"][\"gluu\"]\n except:\n print \"Super-Gluu. Initialize Gluu notification services. Invalid credentials file format\"\n return False\n \n self.pushAndroidService = None\n self.pushAppleService = None\n if not (android_creds[\"enabled\"] or ios_creds[\"enabled\"]):\n print \"Super-Gluu. Initialize Gluu notification services. Gluu disabled for all platforms\"\n return False\n\n gluu_server_uri = gluu_conf[\"server_uri\"]\n notifyClientFactory = NotifyClientFactory.instance()\n metadataConfiguration = None\n try:\n metadataConfiguration = notifyClientFactory.createMetaDataConfigurationService(gluu_server_uri).getMetadataConfiguration()\n except:\n print \"Super-Gluu. Initialize Gluu notification services. Failed to load metadata. Exception: \", sys.exc_info()[1]\n return False\n\n gluuClient = notifyClientFactory.createNotifyService(metadataConfiguration)\n encryptionService = CdiUtil.bean(EncryptionService)\n\n if android_creds[\"enabled\"]:\n gluu_access_key = android_creds[\"access_key\"]\n gluu_secret_access_key = android_creds[\"secret_access_key\"]\n \n try:\n gluu_secret_access_key = encryptionService.decrypt(gluu_secret_access_key)\n except:\n # Ignore exception. Password is not encrypted\n print \"Super-Gluu. Initialize Gluu notification services. Assuming that 'gluu_secret_access_key' in not encrypted\"\n \n self.pushAndroidService = gluuClient \n self.pushAndroidServiceAuth = notifyClientFactory.getAuthorization(gluu_access_key, gluu_secret_access_key);\n print \"Super-Gluu. Initialize Gluu notification services. Created Android notification service\"\n\n if ios_creds[\"enabled\"]:\n gluu_access_key = ios_creds[\"access_key\"]\n gluu_secret_access_key = ios_creds[\"secret_access_key\"]\n \n try:\n gluu_secret_access_key = encryptionService.decrypt(gluu_secret_access_key)\n except:\n # Ignore exception. Password is not encrypted\n print \"Super-Gluu. Initialize Gluu notification services. Assuming that 'gluu_secret_access_key' in not encrypted\"\n \n self.pushAppleService = gluuClient \n self.pushAppleServiceAuth = notifyClientFactory.getAuthorization(gluu_access_key, gluu_secret_access_key);\n print \"Super-Gluu. Initialize Gluu notification services. Created iOS notification service\"\n\n enabled = self.pushAndroidService != None or self.pushAppleService != None\n\n return enabled\n\n def loadPushNotificationCreds(self, configurationAttributes):\n print \"Super-Gluu. Initialize notification services\"\n if not configurationAttributes.containsKey(\"credentials_file\"):\n return None\n\n super_gluu_creds_file = configurationAttributes.get(\"credentials_file\").getValue2()\n\n # Load credentials from file\n f = open(super_gluu_creds_file, 'r')\n try:\n creds = json.loads(f.read())\n except:\n print \"Super-Gluu. Initialize notification services. Failed to load credentials from file:\", super_gluu_creds_file\n return None\n finally:\n f.close()\n\n return creds\n\n def sendPushNotification(self, client_redirect_uri, user, super_gluu_request):\n try:\n self.sendPushNotificationImpl(client_redirect_uri, user, super_gluu_request)\n except:\n print \"Super-Gluu. Send push notification. Failed to send push notification: \", sys.exc_info()[1]\n\n def sendPushNotificationImpl(self, client_redirect_uri, user, super_gluu_request):\n if not self.enabledPushNotifications:\n return\n\n user_name = user.getUserId()\n print \"Super-Gluu. Send push notification. Loading user '%s' devices\" % user_name\n\n send_notification = False\n send_notification_result = True\n\n userService = CdiUtil.bean(UserService)\n deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)\n\n user_inum = userService.getUserInum(user_name)\n\n send_android = 0\n send_ios = 0\n u2f_devices_list = deviceRegistrationService.findUserDeviceRegistrations(user_inum, client_redirect_uri, \"oxId\", \"oxDeviceData\", \"oxDeviceNotificationConf\")\n if u2f_devices_list.size() > 0:\n for u2f_device in u2f_devices_list:\n device_data = u2f_device.getDeviceData()\n\n # Device data which Super-Gluu gets during enrollment\n if device_data == None:\n continue\n\n platform = device_data.getPlatform()\n push_token = device_data.getPushToken()\n debug = False\n\n if StringHelper.equalsIgnoreCase(platform, \"ios\") and StringHelper.isNotEmpty(push_token):\n # Sending notification to iOS user's device\n if self.pushAppleService == None:\n print \"Super-Gluu. Send push notification. Apple native push notification service is not enabled\"\n else:\n send_notification = True\n \n title = \"Super Gluu\"\n message = \"Confirm your sign in request to: %s\" % client_redirect_uri\n\n if self.pushSnsMode or self.pushGluuMode:\n pushSnsService = CdiUtil.bean(PushSnsService)\n targetEndpointArn = self.getTargetEndpointArn(deviceRegistrationService, pushSnsService, PushPlatform.APNS, user, u2f_device)\n if targetEndpointArn == None:\n \treturn\n\n send_notification = True\n \n sns_push_request_dictionary = { \"aps\": \n { \"badge\": 0,\n \"alert\" : {\"body\": message, \"title\" : title},\n \"category\": \"ACTIONABLE\",\n \"content-available\": \"1\",\n \"sound\": 'default'\n },\n \"request\" : super_gluu_request\n }\n push_message = json.dumps(sns_push_request_dictionary, separators=(',',':'))\n \n if self.pushSnsMode:\n apple_push_platform = PushPlatform.APNS\n if not self.pushAppleServiceProduction:\n apple_push_platform = PushPlatform.APNS_SANDBOX\n \n send_notification_result = pushSnsService.sendPushMessage(self.pushAppleService, apple_push_platform, targetEndpointArn, push_message, None)\n if debug:\n print \"Super-Gluu. Send iOS SNS push notification. token: '%s', message: '%s', send_notification_result: '%s', apple_push_platform: '%s'\" % (push_token, push_message, send_notification_result, apple_push_platform)\n elif self.pushGluuMode:\n send_notification_result = self.pushAppleService.sendNotification(self.pushAppleServiceAuth, targetEndpointArn, push_message)\n if debug:\n print \"Super-Gluu. Send iOS Gluu push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n else:\n additional_fields = { \"request\" : super_gluu_request }\n \n msgBuilder = APNS.newPayload().alertBody(message).alertTitle(title).sound(\"default\")\n msgBuilder.category('ACTIONABLE').badge(0)\n msgBuilder.forNewsstand()\n msgBuilder.customFields(additional_fields)\n push_message = msgBuilder.build()\n \n send_notification_result = self.pushAppleService.push(push_token, push_message)\n if debug:\n print \"Super-Gluu. Send iOS Native push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n send_ios = send_ios + 1\n\n if StringHelper.equalsIgnoreCase(platform, \"android\") and StringHelper.isNotEmpty(push_token):\n # Sending notification to Android user's device\n if self.pushAndroidService == None:\n print \"Super-Gluu. Send native push notification. Android native push notification service is not enabled\"\n else:\n send_notification = True\n\n title = \"Super-Gluu\"\n if self.pushSnsMode or self.pushGluuMode:\n pushSnsService = CdiUtil.bean(PushSnsService)\n targetEndpointArn = self.getTargetEndpointArn(deviceRegistrationService, pushSnsService, PushPlatform.GCM, user, u2f_device)\n if targetEndpointArn == None:\n \treturn\n\n send_notification = True\n \n sns_push_request_dictionary = { \"collapse_key\": \"single\",\n \"content_available\": True,\n \"time_to_live\": 60,\n \"data\": \n { \"message\" : super_gluu_request,\n \"title\" : title }\n }\n push_message = json.dumps(sns_push_request_dictionary, separators=(',',':'))\n \n if self.pushSnsMode:\n send_notification_result = pushSnsService.sendPushMessage(self.pushAndroidService, PushPlatform.GCM, targetEndpointArn, push_message, None)\n if debug:\n print \"Super-Gluu. Send Android SNS push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n elif self.pushGluuMode:\n send_notification_result = self.pushAndroidService.sendNotification(self.pushAndroidServiceAuth, targetEndpointArn, push_message)\n if debug:\n print \"Super-Gluu. Send Android Gluu push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n else:\n msgBuilder = Message.Builder().addData(\"message\", super_gluu_request).addData(\"title\", title).collapseKey(\"single\").contentAvailable(True)\n push_message = msgBuilder.build()\n \n send_notification_result = self.pushAndroidService.send(push_message, push_token, 3)\n if debug:\n print \"Super-Gluu. Send Android Native push notification. token: '%s', message: '%s', send_notification_result: '%s'\" % (push_token, push_message, send_notification_result)\n send_android = send_android + 1\n\n print \"Super-Gluu. Send push notification. send_android: '%s', send_ios: '%s'\" % (send_android, send_ios)\n\n def getTargetEndpointArn(self, deviceRegistrationService, pushSnsService, platform, user, u2fDevice):\n targetEndpointArn = None\n \n # Return endpoint ARN if it created already\n notificationConf = u2fDevice.getDeviceNotificationConf()\n if StringHelper.isNotEmpty(notificationConf):\n notificationConfJson = json.loads(notificationConf)\n targetEndpointArn = notificationConfJson['sns_endpoint_arn']\n if StringHelper.isNotEmpty(targetEndpointArn):\n print \"Super-Gluu. Get target endpoint ARN. There is already created target endpoint ARN\"\n return targetEndpointArn\n\n # Create endpoint ARN \n pushClient = None\n pushClientAuth = None\n platformApplicationArn = None\n if platform == PushPlatform.GCM:\n pushClient = self.pushAndroidService\n if self.pushSnsMode:\n platformApplicationArn = self.pushAndroidPlatformArn\n if self.pushGluuMode:\n pushClientAuth = self.pushAndroidServiceAuth\n elif platform == PushPlatform.APNS:\n pushClient = self.pushAppleService\n if self.pushSnsMode:\n platformApplicationArn = self.pushApplePlatformArn\n if self.pushGluuMode:\n pushClientAuth = self.pushAppleServiceAuth\n else:\n return None\n\n deviceData = u2fDevice.getDeviceData()\n pushToken = deviceData.getPushToken()\n \n print \"Super-Gluu. Get target endpoint ARN. Attempting to create target endpoint ARN for user: '%s'\" % user.getUserId()\n if self.pushSnsMode:\n targetEndpointArn = pushSnsService.createPlatformArn(pushClient, platformApplicationArn, pushToken, user)\n else:\n customUserData = pushSnsService.getCustomUserData(user)\n registerDeviceResponse = pushClient.registerDevice(pushClientAuth, pushToken, customUserData);\n if registerDeviceResponse != None and registerDeviceResponse.getStatusCode() == 200:\n targetEndpointArn = registerDeviceResponse.getEndpointArn()\n \n if StringHelper.isEmpty(targetEndpointArn):\n\t print \"Super-Gluu. Failed to get endpoint ARN for user: '%s'\" % user.getUserId()\n \treturn None\n\n print \"Super-Gluu. Get target endpoint ARN. Create target endpoint ARN '%s' for user: '%s'\" % (targetEndpointArn, user.getUserId())\n \n # Store created endpoint ARN in device entry\n userInum = user.getAttribute(\"inum\")\n u2fDeviceUpdate = deviceRegistrationService.findUserDeviceRegistration(userInum, u2fDevice.getId())\n u2fDeviceUpdate.setDeviceNotificationConf('{\"sns_endpoint_arn\" : \"%s\"}' % targetEndpointArn)\n deviceRegistrationService.updateDeviceRegistration(userInum, u2fDeviceUpdate)\n\n return targetEndpointArn\n\n def getApplicationUri(self, session_attributes):\n if self.applicationId != None:\n return self.applicationId\n \n if not session_attributes.containsKey(\"redirect_uri\"):\n return None\n\n return session_attributes.get(\"redirect_uri\")\n\n def setRequestScopedParameters(self, identity, step):\n downloadMap = HashMap()\n if self.registrationUri != None:\n identity.setWorkingParameter(\"external_registration_uri\", self.registrationUri)\n\n if self.androidUrl!= None and step == 1:\n downloadMap.put(\"android\", self.androidUrl)\n\n if self.IOSUrl != None and step == 1:\n downloadMap.put(\"ios\", self.IOSUrl)\n \n if self.customLabel != None:\n identity.setWorkingParameter(\"super_gluu_label\", self.customLabel)\n \n identity.setWorkingParameter(\"download_url\", downloadMap)\n identity.setWorkingParameter(\"super_gluu_qr_options\", self.customQrOptions)\n\n def addGeolocationData(self, session_attributes, super_gluu_request_dictionary):\n if session_attributes.containsKey(\"remote_ip\"):\n remote_ip = session_attributes.get(\"remote_ip\")\n if StringHelper.isNotEmpty(remote_ip):\n print \"Super-Gluu. Prepare for step 2. Adding req_ip and req_loc to super_gluu_request\"\n super_gluu_request_dictionary['req_ip'] = remote_ip\n\n remote_loc_dic = self.determineGeolocationData(remote_ip)\n if remote_loc_dic == None:\n print \"Super-Gluu. Prepare for step 2. Failed to determine remote location by remote IP '%s'\" % remote_ip\n return\n\n remote_loc = \"%s, %s, %s\" % ( remote_loc_dic['country'], remote_loc_dic['regionName'], remote_loc_dic['city'] )\n remote_loc_encoded = urllib.quote(remote_loc.encode('utf-8'))\n super_gluu_request_dictionary['req_loc'] = remote_loc_encoded\n\n def determineGeolocationData(self, remote_ip):\n print \"Super-Gluu. Determine remote location. remote_ip: '%s'\" % remote_ip\n httpService = CdiUtil.bean(HttpService)\n\n http_client = httpService.getHttpsClient()\n http_client_params = http_client.getParams()\n http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000)\n \n geolocation_service_url = \"http://ip-api.com/json/%s?fields=49177\" % remote_ip\n geolocation_service_headers = { \"Accept\" : \"application/json\" }\n\n try:\n http_service_response = httpService.executeGet(http_client, geolocation_service_url, geolocation_service_headers)\n http_response = http_service_response.getHttpResponse()\n except:\n print \"Super-Gluu. Determine remote location. Exception: \", sys.exc_info()[1]\n return None\n\n try:\n if not httpService.isResponseStastusCodeOk(http_response):\n print \"Super-Gluu. Determine remote location. Get invalid response from validation server: \", str(http_response.getStatusLine().getStatusCode())\n httpService.consume(http_response)\n return None\n \n response_bytes = httpService.getResponseContent(http_response)\n response_string = httpService.convertEntityToString(response_bytes)\n httpService.consume(http_response)\n finally:\n http_service_response.closeConnection()\n\n if response_string == None:\n print \"Super-Gluu. Determine remote location. Get empty response from location server\"\n return None\n \n response = json.loads(response_string)\n \n if not StringHelper.equalsIgnoreCase(response['status'], \"success\"):\n print \"Super-Gluu. Determine remote location. Get response with status: '%s'\" % response['status']\n return None\n\n return response\n\n def isUserMemberOfGroup(self, user, attribute, group):\n is_member = False\n member_of_list = user.getAttributeValues(attribute)\n if (member_of_list != None):\n for member_of in member_of_list:\n if StringHelper.equalsIgnoreCase(group, member_of) or member_of.endswith(group):\n is_member = True\n break\n\n return is_member\n\n def processAuditGroup(self, user, attribute, group):\n is_member = self.isUserMemberOfGroup(user, attribute, group)\n if (is_member):\n print \"Super-Gluu. Authenticate for processAuditGroup. User '%s' member of audit group\" % user.getUserId()\n print \"Super-Gluu. Authenticate for processAuditGroup. Sending e-mail about user '%s' login to %s\" % (user.getUserId(), self.audit_email)\n \n # Send e-mail to administrator\n user_id = user.getUserId()\n mailService = CdiUtil.bean(MailService)\n subject = \"User log in: %s\" % user_id\n body = \"User log in: %s\" % user_id\n mailService.sendMail(self.audit_email, subject, body)\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - }, - { - "value2": "interactive", - "value1": "usage_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "super_gluu", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "{ size: 500, mSize: 0.05 }", - "value1": "qr_options" - }, - { - "hide": false, - "value2": "Super Gluu", - "value1": "label" - }, - { - "hide": false, - "value2": "https://pujavs4.2.gluu.server/identity/register", - "value1": "registration_uri" - }, - { - "hide": false, - "value2": "two_step", - "value1": "authentication_mode" - }, - { - "hide": false, - "value2": "gluu", - "value1": "notification_service_mode" - }, - { - "hide": false, - "value2": "/etc/certs/super_gluu_creds.json", - "value1": "credentials_file" - }, - { - "hide": false, - "value2": "https://play.google.com/store/apps/details?id=gluu.org.super.gluu&hl=en_US", - "value1": "supergluu_android_download_url" - }, - { - "hide": false, - "value2": "https://itunes.apple.com/us/app/super-gluu/id1093479646", - "value1": "supergluu_ios_download_url" - } - ], - "baseDn": "inum=92F0-BF9E,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 70, - "programmingLanguage": "PYTHON", - "description": "Fido2 authentication module", - "locationType": "LDAP", - "dn": "inum=8BAF-80D7,ou=scripts,o=gluu", - "inum": "8BAF-80D7", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2018, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom javax.ws.rs.core import Response\nfrom org.jboss.resteasy.client import ClientResponseFailure\nfrom org.jboss.resteasy.client.exception import ResteasyClientException\nfrom javax.ws.rs.core import Response\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.fido2.client import Fido2ClientFactory\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper\n\nfrom java.util.concurrent.locks import ReentrantLock\n\nimport java\nimport sys\ntry:\n import json\nexcept ImportError:\n import simplejson as json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Fido2. Initialization\"\n\n if not configurationAttributes.containsKey(\"fido2_server_uri\"):\n print \"fido2_server_uri. Initialization. Property fido2_server_uri is not specified\"\n return False\n\n self.fido2_server_uri = configurationAttributes.get(\"fido2_server_uri\").getValue2()\n\n self.fido2_domain = None\n if configurationAttributes.containsKey(\"fido2_domain\"):\n self.fido2_domain = configurationAttributes.get(\"fido2_domain\").getValue2()\n\n self.metaDataLoaderLock = ReentrantLock()\n self.metaDataConfiguration = None\n \n print \"Fido2. Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"Fido2. Destroy\"\n print \"Fido2. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n user_name = credentials.getUsername()\n\n if step == 1:\n print \"Fido2. Authenticate for step 1\"\n\n user_password = credentials.getPassword()\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n userService = CdiUtil.bean(UserService)\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return False\n\n return True\n elif step == 2:\n print \"Fido2. Authenticate for step 2\"\n\n token_response = ServerUtil.getFirstValue(requestParameters, \"tokenResponse\")\n if token_response == None:\n print \"Fido2. Authenticate for step 2. tokenResponse is empty\"\n return False\n\n auth_method = ServerUtil.getFirstValue(requestParameters, \"authMethod\")\n if auth_method == None:\n print \"Fido2. Authenticate for step 2. authMethod is empty\"\n return False\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"Fido2. Prepare for step 2. Failed to determine user name\"\n return False\n\n if auth_method == 'authenticate':\n print \"Fido2. Prepare for step 2. Call Fido2 in order to finish authentication flow\"\n assertionService = Fido2ClientFactory.instance().createAssertionService(self.metaDataConfiguration)\n assertionStatus = assertionService.verify(token_response)\n authenticationStatusEntity = assertionStatus.readEntity(java.lang.String)\n\n if assertionStatus.getStatus() != Response.Status.OK.getStatusCode():\n print \"Fido2. Authenticate for step 2. Get invalid authentication status from Fido2 server\"\n return False\n\n return True\n elif auth_method == 'enroll':\n print \"Fido2. Prepare for step 2. Call Fido2 in order to finish registration flow\"\n attestationService = Fido2ClientFactory.instance().createAttestationService(self.metaDataConfiguration)\n attestationStatus = attestationService.verify(token_response)\n\n if attestationStatus.getStatus() != Response.Status.OK.getStatusCode():\n print \"Fido2. Authenticate for step 2. Get invalid registration status from Fido2 server\"\n return False\n\n return True\n else:\n print \"Fido2. Prepare for step 2. Authentication method is invalid\"\n return False\n\n return False\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n\n if step == 1:\n return True\n elif step == 2:\n print \"Fido2. Prepare for step 2\"\n\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"Fido2. Prepare for step 2. Failed to determine session_id\"\n return False\n\n authenticationService = CdiUtil.bean(AuthenticationService)\n user = authenticationService.getAuthenticatedUser()\n if user == None:\n print \"Fido2. Prepare for step 2. Failed to determine user name\"\n return False\n\n userName = user.getUserId()\n\n metaDataConfiguration = self.getMetaDataConfiguration()\n \n assertionResponse = None\n attestationResponse = None\n\n # Check if user have registered devices\n userService = CdiUtil.bean(UserService)\n countFido2Devices = userService.countFidoAndFido2Devices(userName, self.fido2_domain)\n if countFido2Devices > 0:\n print \"Fido2. Prepare for step 2. Call Fido2 endpoint in order to start assertion flow\"\n\n try:\n assertionService = Fido2ClientFactory.instance().createAssertionService(metaDataConfiguration)\n assertionRequest = json.dumps({'username': userName}, separators=(',', ':'))\n assertionResponse = assertionService.authenticate(assertionRequest).readEntity(java.lang.String)\n except ClientResponseFailure, ex:\n print \"Fido2. Prepare for step 2. Failed to start assertion flow. Exception:\", sys.exc_info()[1]\n return False\n else:\n print \"Fido2. Prepare for step 2. Call Fido2 endpoint in order to start attestation flow\"\n\n try:\n attestationService = Fido2ClientFactory.instance().createAttestationService(metaDataConfiguration)\n attestationRequest = json.dumps({'username': userName, 'displayName': userName, 'attestation' : 'direct'}, separators=(',', ':'))\n attestationResponse = attestationService.register(attestationRequest).readEntity(java.lang.String)\n except ClientResponseFailure, ex:\n print \"Fido2. Prepare for step 2. Failed to start attestation flow. Exception:\", sys.exc_info()[1]\n return False\n\n identity.setWorkingParameter(\"fido2_assertion_request\", ServerUtil.asJson(assertionResponse))\n identity.setWorkingParameter(\"fido2_attestation_request\", ServerUtil.asJson(attestationResponse))\n print \"Fido2. Prepare for step 2. Successfully start flow with next requests.\\nfido2_assertion_request: '%s'\\nfido2_attestation_request: '%s'\" % ( assertionResponse, attestationResponse )\n\n return True\n elif step == 3:\n print \"Fido2. Prepare for step 3\"\n\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return None\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 2\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getPageForStep(self, configurationAttributes, step):\n if step == 2:\n return \"/auth/fido2/login.xhtml\"\n\n return \"\"\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None \n \n \n def getMetaDataConfiguration(self):\n if self.metaDataConfiguration != None:\n return self.metaDataConfiguration\n \n self.metaDataLoaderLock.lock()\n # Make sure that another thread not loaded configuration already \n if self.metaDataConfiguration != None:\n return self.metaDataConfiguration\n\n try:\n print \"Fido2. Initialization. Downloading Fido2 metadata\"\n self.fido2_server_metadata_uri = self.fido2_server_uri + \"/.well-known/fido2-configuration\"\n #self.fido2_server_metadata_uri = self.fido2_server_uri + \"/fido2/restv1/fido2/configuration\"\n\n metaDataConfigurationService = Fido2ClientFactory.instance().createMetaDataConfigurationService(self.fido2_server_metadata_uri)\n \n max_attempts = 10\n for attempt in range(1, max_attempts + 1):\n try:\n self.metaDataConfiguration = metaDataConfigurationService.getMetadataConfiguration().readEntity(java.lang.String)\n return self.metaDataConfiguration\n except ClientResponseFailure, ex:\n # Detect if last try or we still get Service Unavailable HTTP error\n if (attempt == max_attempts) or (ex.getResponse().getResponseStatus() != Response.Status.SERVICE_UNAVAILABLE):\n raise ex\n \n java.lang.Thread.sleep(3000)\n print \"Attempting to load metadata: %d\" % attempt\n except ResteasyClientException, ex:\n # Detect if last try or we still get Service Unavailable HTTP error\n if attempt == max_attempts:\n raise ex\n \n java.lang.Thread.sleep(3000)\n print \"Attempting to load metadata: %d\" % attempt\n finally:\n self.metaDataLoaderLock.unlock()\n \n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "interactive", - "value1": "usage_type" - }, - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "fido2", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "https://pujavs4.2.gluu.server", - "value1": "fido2_server_uri" - } - ], - "baseDn": "inum=8BAF-80D7,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 70, - "programmingLanguage": "PYTHON", - "description": "UAF authentication module", - "locationType": "LDAP", - "dn": "inum=5018-AF9C,ou=scripts,o=gluu", - "inum": "5018-AF9C", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\n# Requires the following custom properties and values:\n# uaf_server_uri: \n#\n# These are non mandatory custom properties and values:\n# uaf_policy_name: default\n# send_push_notifaction: false\n# registration_uri: https:///identity/register\n# qr_options: { width: 400, height: 400 }\n\nfrom org.gluu.model.custom.script.type.auth import PersonAuthenticationType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.oxauth.service import AuthenticationService, SessionIdService\nfrom org.gluu.oxauth.service.common import UserService\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom org.gluu.oxauth.util import ServerUtil\nfrom org.gluu.oxauth.model.config import Constants\nfrom javax.ws.rs.core import Response\nfrom java.util import Arrays\nfrom org.gluu.oxauth.service.net import HttpService\nfrom org.apache.http.params import CoreConnectionPNames\n\nimport sys\nimport java\nimport json\n\nclass PersonAuthentication(PersonAuthenticationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"UAF. Initialization\"\n\n if not configurationAttributes.containsKey(\"uaf_server_uri\"):\n print \"UAF. Initialization. Property uaf_server_uri is mandatory\"\n return False\n\n self.uaf_server_uri = configurationAttributes.get(\"uaf_server_uri\").getValue2()\n\n self.uaf_policy_name = \"default\"\n if configurationAttributes.containsKey(\"uaf_policy_name\"):\n self.uaf_policy_name = configurationAttributes.get(\"uaf_policy_name\").getValue2()\n\n self.send_push_notifaction = False\n if configurationAttributes.containsKey(\"send_push_notifaction\"):\n self.send_push_notifaction = StringHelper.toBoolean(configurationAttributes.get(\"send_push_notifaction\").getValue2(), False)\n\n self.registration_uri = None\n if configurationAttributes.containsKey(\"registration_uri\"):\n self.registration_uri = configurationAttributes.get(\"registration_uri\").getValue2()\n\n self.customQrOptions = {}\n if configurationAttributes.containsKey(\"qr_options\"):\n self.customQrOptions = configurationAttributes.get(\"qr_options\").getValue2()\n\n print \"UAF. Initializing HTTP client\"\n httpService = CdiUtil.bean(HttpService)\n self.http_client = httpService.getHttpsClient()\n http_client_params = self.http_client.getParams()\n http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000)\n\n print \"UAF. Initialized successfully. uaf_server_uri: '%s', uaf_policy_name: '%s', send_push_notifaction: '%s', registration_uri: '%s', qr_options: '%s'\" % (self.uaf_server_uri, self.uaf_policy_name, self.send_push_notifaction, self.registration_uri, self.customQrOptions)\n \n print \"UAF. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"UAF. Destroy\"\n print \"UAF. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n \n def getAuthenticationMethodClaims(self, requestParameters):\n return None\n \n def isValidAuthenticationMethod(self, usageType, configurationAttributes):\n return True\n\n def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes):\n return None\n\n def authenticate(self, configurationAttributes, requestParameters, step):\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n self.setRequestScopedParameters(identity)\n\n if (step == 1):\n print \"UAF. Authenticate for step 1\"\n\n user_name = credentials.getUsername()\n\n authenticated_user = self.processBasicAuthentication(credentials)\n if authenticated_user == None:\n return False\n\n uaf_auth_method = \"authenticate\"\n # Uncomment this block if you need to allow user second device registration\n #enrollment_mode = ServerUtil.getFirstValue(requestParameters, \"loginForm:registerButton\")\n #if StringHelper.isNotEmpty(enrollment_mode):\n # uaf_auth_method = \"enroll\"\n \n if uaf_auth_method == \"authenticate\":\n user_enrollments = self.findEnrollments(credentials)\n if len(user_enrollments) == 0:\n uaf_auth_method = \"enroll\"\n print \"UAF. Authenticate for step 1. There is no UAF enrollment for user '%s'. Changing uaf_auth_method to '%s'\" % (user_name, uaf_auth_method)\n\n print \"UAF. Authenticate for step 1. uaf_auth_method: '%s'\" % uaf_auth_method\n \n identity.setWorkingParameter(\"uaf_auth_method\", uaf_auth_method)\n\n return True\n elif (step == 2):\n print \"UAF. Authenticate for step 2\"\n\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"UAF. Prepare for step 2. Failed to determine session_id\"\n return False\n\n user = authenticationService.getAuthenticatedUser()\n if (user == None):\n print \"UAF. Authenticate for step 2. Failed to determine user name\"\n return False\n user_name = user.getUserId()\n\n uaf_auth_result = ServerUtil.getFirstValue(requestParameters, \"auth_result\")\n if uaf_auth_result != \"success\":\n print \"UAF. Authenticate for step 2. auth_result is '%s'\" % uaf_auth_result\n return False\n\n # Restore state from session\n uaf_auth_method = session_attributes.get(\"uaf_auth_method\")\n\n if not uaf_auth_method in ['enroll', 'authenticate']:\n print \"UAF. Authenticate for step 2. Failed to authenticate user. uaf_auth_method: '%s'\" % uaf_auth_method\n return False\n\n # Request STATUS_OBB\n if True:\n #TODO: Remove this condition\n # It's workaround becuase it's not possible to call STATUS_OBB 2 times. First time on browser and second ime on server\n uaf_user_device_handle = ServerUtil.getFirstValue(requestParameters, \"auth_handle\")\n else:\n uaf_obb_auth_method = session_attributes.get(\"uaf_obb_auth_method\")\n uaf_obb_server_uri = session_attributes.get(\"uaf_obb_server_uri\")\n uaf_obb_start_response = session_attributes.get(\"uaf_obb_start_response\")\n\n # Prepare STATUS_OBB\n uaf_obb_start_response_json = json.loads(uaf_obb_start_response)\n uaf_obb_status_request_dictionary = { \"operation\": \"STATUS_%s\" % uaf_obb_auth_method,\n \"userName\": user_name,\n \"needDetails\": 1,\n \"oobStatusHandle\": uaf_obb_start_response_json[\"oobStatusHandle\"],\n }\n \n uaf_obb_status_request = json.dumps(uaf_obb_status_request_dictionary, separators=(',',':'))\n print \"UAF. Authenticate for step 2. Prepared STATUS request: '%s' to send to '%s'\" % (uaf_obb_status_request, uaf_obb_server_uri)\n\n uaf_status_obb_response = self.executePost(uaf_obb_server_uri, uaf_obb_status_request)\n if uaf_status_obb_response == None:\n return False\n\n print \"UAF. Authenticate for step 2. Get STATUS response: '%s'\" % uaf_status_obb_response\n uaf_status_obb_response_json = json.loads(uaf_status_obb_response)\n \n if uaf_status_obb_response_json[\"statusCode\"] != 4000:\n print \"UAF. Authenticate for step 2. UAF operation status is invalid. statusCode: '%s'\" % uaf_status_obb_response_json[\"statusCode\"]\n return False\n\n uaf_user_device_handle = uaf_status_obb_response_json[\"additionalInfo\"][\"authenticatorsResult\"][\"handle\"]\n\n if StringHelper.isEmpty(uaf_user_device_handle):\n print \"UAF. Prepare for step 2. Failed to get UAF handle\"\n return False\n\n uaf_user_external_uid = \"uaf:%s\" % uaf_user_device_handle\n print \"UAF. Authenticate for step 2. UAF handle: '%s'\" % uaf_user_external_uid\n\n if uaf_auth_method == \"authenticate\":\n # Validate if user used device with same keYHandle\n user_enrollments = self.findEnrollments(credentials)\n if len(user_enrollments) == 0:\n uaf_auth_method = \"enroll\"\n print \"UAF. Authenticate for step 2. There is no UAF enrollment for user '%s'.\" % user_name\n return False\n \n for user_enrollment in user_enrollments:\n if StringHelper.equalsIgnoreCase(user_enrollment, uaf_user_device_handle):\n print \"UAF. Authenticate for step 2. There is UAF enrollment for user '%s'. User authenticated successfully\" % user_name\n return True\n else:\n userService = CdiUtil.bean(UserService)\n\n # Double check just to make sure. We did checking in previous step\n # Check if there is user which has uaf_user_external_uid\n # Avoid mapping user cert to more than one IDP account\n find_user_by_external_uid = userService.getUserByAttribute(\"oxExternalUid\", uaf_user_external_uid)\n if find_user_by_external_uid == None:\n # Add uaf_user_external_uid to user's external GUID list\n find_user_by_external_uid = userService.addUserAttribute(user_name, \"oxExternalUid\", uaf_user_external_uid)\n if find_user_by_external_uid == None:\n print \"UAF. Authenticate for step 2. Failed to update current user\"\n return False\n \n return True\n\n return False\n else:\n return False\n\n def prepareForStep(self, configurationAttributes, requestParameters, step):\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n identity = CdiUtil.bean(Identity)\n credentials = identity.getCredentials()\n\n session_attributes = identity.getSessionId().getSessionAttributes()\n\n self.setRequestScopedParameters(identity)\n\n if (step == 1):\n return True\n elif (step == 2):\n print \"UAF. Prepare for step 2\"\n\n session = CdiUtil.bean(SessionIdService).getSessionId()\n if session == None:\n print \"UAF. Prepare for step 2. Failed to determine session_id\"\n return False\n\n user = authenticationService.getAuthenticatedUser()\n if (user == None):\n print \"UAF. Prepare for step 2. Failed to determine user name\"\n return False\n\n uaf_auth_method = session_attributes.get(\"uaf_auth_method\")\n if StringHelper.isEmpty(uaf_auth_method):\n print \"UAF. Prepare for step 2. Failed to determine auth_method\"\n return False\n\n print \"UAF. Prepare for step 2. uaf_auth_method: '%s'\" % uaf_auth_method\n\n uaf_obb_auth_method = \"OOB_REG\"\n uaf_obb_server_uri = self.uaf_server_uri + \"/nnl/v2/reg\" \n if StringHelper.equalsIgnoreCase(uaf_auth_method, \"authenticate\"):\n uaf_obb_auth_method = \"OOB_AUTH\"\n uaf_obb_server_uri = self.uaf_server_uri + \"/nnl/v2/auth\" \n\n # Prepare START_OBB\n uaf_obb_start_request_dictionary = { \"operation\": \"START_%s\" % uaf_obb_auth_method,\n \"userName\": user.getUserId(),\n \"policyName\": \"default\",\n \"oobMode\":\n { \"qr\": \"true\", \"rawData\": \"false\", \"push\": \"false\" } \n }\n\n uaf_obb_start_request = json.dumps(uaf_obb_start_request_dictionary, separators=(',',':'))\n print \"UAF. Prepare for step 2. Prepared START request: '%s' to send to '%s'\" % (uaf_obb_start_request, uaf_obb_server_uri)\n\n # Request START_OBB\n uaf_obb_start_response = self.executePost(uaf_obb_server_uri, uaf_obb_start_request)\n if uaf_obb_start_response == None:\n return False\n\n print \"UAF. Prepare for step 2. Get START response: '%s'\" % uaf_obb_start_response\n uaf_obb_start_response_json = json.loads(uaf_obb_start_response)\n\n # Prepare STATUS_OBB\n #TODO: Remove needDetails parameter\n uaf_obb_status_request_dictionary = { \"operation\": \"STATUS_%s\" % uaf_obb_auth_method,\n \"userName\": user.getUserId(),\n \"needDetails\": 1,\n \"oobStatusHandle\": uaf_obb_start_response_json[\"oobStatusHandle\"],\n }\n\n uaf_obb_status_request = json.dumps(uaf_obb_status_request_dictionary, separators=(',',':'))\n print \"UAF. Prepare for step 2. Prepared STATUS request: '%s' to send to '%s'\" % (uaf_obb_status_request, uaf_obb_server_uri)\n\n identity.setWorkingParameter(\"uaf_obb_auth_method\", uaf_obb_auth_method)\n identity.setWorkingParameter(\"uaf_obb_server_uri\", uaf_obb_server_uri)\n identity.setWorkingParameter(\"uaf_obb_start_response\", uaf_obb_start_response)\n identity.setWorkingParameter(\"qr_image\", uaf_obb_start_response_json[\"modeResult\"][\"qrCode\"][\"qrImage\"])\n identity.setWorkingParameter(\"uaf_obb_status_request\", uaf_obb_status_request)\n\n return True\n else:\n return False\n\n def getExtraParametersForStep(self, configurationAttributes, step):\n return Arrays.asList(\"uaf_auth_method\", \"uaf_obb_auth_method\", \"uaf_obb_server_uri\", \"uaf_obb_start_response\")\n\n def getCountAuthenticationSteps(self, configurationAttributes):\n return 2\n\n def getPageForStep(self, configurationAttributes, step):\n if (step == 2):\n return \"/auth/uaf/login.xhtml\"\n\n return \"\"\n\n def getNextStep(self, configurationAttributes, requestParameters, step):\n return -1\n\n def getLogoutExternalUrl(self, configurationAttributes, requestParameters):\n print \"Get external logout URL call\"\n return None\n\n def logout(self, configurationAttributes, requestParameters):\n return True\n\n def setRequestScopedParameters(self, identity):\n if self.registration_uri != None:\n identity.setWorkingParameter(\"external_registration_uri\", self.registration_uri)\n identity.setWorkingParameter(\"qr_options\", self.customQrOptions)\n\n def processBasicAuthentication(self, credentials):\n userService = CdiUtil.bean(UserService)\n authenticationService = CdiUtil.bean(AuthenticationService)\n\n user_name = credentials.getUsername()\n user_password = credentials.getPassword()\n\n logged_in = False\n if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):\n logged_in = authenticationService.authenticate(user_name, user_password)\n\n if not logged_in:\n return None\n\n find_user_by_uid = authenticationService.getAuthenticatedUser()\n if find_user_by_uid == None:\n print \"UAF. Process basic authentication. Failed to find user '%s'\" % user_name\n return None\n \n return find_user_by_uid\n\n def findEnrollments(self, credentials):\n result = []\n\n userService = CdiUtil.bean(UserService)\n user_name = credentials.getUsername()\n user = userService.getUser(user_name, \"oxExternalUid\")\n if user == None:\n print \"UAF. Find enrollments. Failed to find user\"\n return result\n \n user_custom_ext_attribute = userService.getCustomAttribute(user, \"oxExternalUid\")\n if user_custom_ext_attribute == None:\n return result\n \n uaf_prefix = \"uaf:\"\n uaf_prefix_length = len(uaf_prefix) \n for user_external_uid in user_custom_ext_attribute.getValues():\n index = user_external_uid.find(uaf_prefix)\n if index != -1:\n enrollment_uid = user_external_uid[uaf_prefix_length:]\n result.append(enrollment_uid)\n \n return result\n\n def executePost(self, request_uri, request_data):\n httpService = CdiUtil.bean(HttpService)\n\n request_headers = { \"Content-type\" : \"application/json; charset=UTF-8\", \"Accept\" : \"application/json\" }\n\n try:\n http_service_response = httpService.executePost(self.http_client, request_uri, None, request_headers, request_data)\n http_response = http_service_response.getHttpResponse()\n except:\n print \"UAF. Validate POST response. Exception: \", sys.exc_info()[1]\n return None\n\n try:\n if not httpService.isResponseStastusCodeOk(http_response):\n print \"UAF. Validate POST response. Get invalid response from server: %s\" % str(http_response.getStatusLine().getStatusCode())\n httpService.consume(http_response)\n return None\n \n response_bytes = httpService.getResponseContent(http_response)\n response_string = httpService.convertEntityToString(response_bytes)\n httpService.consume(http_response)\n \n return response_string\n finally:\n http_service_response.closeConnection()\n return None\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - }, - { - "value2": "interactive", - "value1": "usage_type" - } - ], - "scriptType": "PERSON_AUTHENTICATION", - "name": "uaf", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "https://pujavs4.2.gluu.server", - "value1": "uaf_server_uri" - }, - { - "hide": false, - "value2": "default", - "value1": "uaf_policy_name" - }, - { - "hide": false, - "value2": "{ width: 400, height: 400 }", - "value1": "qr_options" - }, - { - "hide": false, - "value2": "https://pujavs4.2.gluu.server/identity/register", - "value1": "registration_uri" - }, - { - "hide": false, - "value2": "false", - "value1": "send_push_notifaction" - } - ], - "baseDn": "inum=5018-AF9C,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Client authorization UMA RPT Policy for SCIM and Passport", - "locationType": "LDAP", - "dn": "inum=2DAF-F9A5,ou=scripts,o=gluu", - "inum": "2DAF-F9A5", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2017, Gluu\n#\n# Author: Jose Gonzalez\n# Adapted from previous 3.0.1 script of Yuriy Movchan\n#\n# oxConfigurationProperty required:\n# allowed_clients - comma separated list of dns of allowed clients\n# (i.e. the SCIM RP client)\n\nfrom org.gluu.oxauth.model.uma import UmaConstants\nfrom org.gluu.model.uma import ClaimDefinitionBuilder\nfrom org.gluu.model.custom.script.type.uma import UmaRptPolicyType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList, HashSet\nfrom java.lang import String\n\nclass UmaRptPolicy(UmaRptPolicyType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"RPT Policy. Initializing ...\"\n self.clientsSet = self.prepareClientsSet(configurationAttributes)\n print \"RPT Policy. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"RPT Policy. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def getRequiredClaims(self, context):\n json = \"\"\"[\n ]\"\"\"\n return ClaimDefinitionBuilder.build(json)\n\n def authorize(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\n print \"RPT Policy. Authorizing ...\"\n\n client_id=context.getClient().getClientId()\n print \"UmaRptPolicy. client_id = %s\" % client_id\n\n if (StringHelper.isEmpty(client_id)):\n return False\n \n if (self.clientsSet.contains(client_id)):\n print \"UmaRptPolicy. Authorizing client\"\n return True\n else:\n print \"UmaRptPolicy. Client isn't authorized\"\n return False\n\n def getClaimsGatheringScriptName(self, context):\n return UmaConstants.NO_SCRIPT\n\n def prepareClientsSet(self, configurationAttributes):\n clientsSet = HashSet()\n if (not configurationAttributes.containsKey(\"allowed_clients\")):\n return clientsSet\n\n allowedClientsList = configurationAttributes.get(\"allowed_clients\").getValue2()\n if (StringHelper.isEmpty(allowedClientsList)):\n print \"UmaRptPolicy. The property allowed_clients is empty\"\n return clientsSet \n\n allowedClientsListArray = StringHelper.split(allowedClientsList, \",\")\n if (ArrayHelper.isEmpty(allowedClientsListArray)):\n print \"UmaRptPolicy. No clients specified in allowed_clients property\"\n return clientsSet\n \n # Convert to HashSet to quick search\n i = 0\n count = len(allowedClientsListArray)\n while (i < count):\n client = allowedClientsListArray[i]\n clientsSet.add(client)\n i = i + 1\n\n return clientsSet\n", - "enabled": true, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "UMA_RPT_POLICY", - "name": "scim_access_policy", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "1202.f39fd3df-45b8-412b-a628-13ef5c38d453, None", - "value1": "allowed_clients" - } - ], - "baseDn": "inum=2DAF-F9A5,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Client authorization UMA RPT Policy for oxtrust api", - "locationType": "LDAP", - "dn": "inum=OO11-BAFE,ou=scripts,o=gluu", - "inum": "OO11-BAFE", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2017, Gluu\n#\n# Author: Jose Gonzalez\n# Adapted from previous 3.0.1 script of Yuriy Movchan\n#\n# oxConfigurationProperty required:\n# allowed_clients - comma separated list of dns of allowed clients\n# (i.e. the SCIM RP client)\n\nfrom org.gluu.oxauth.model.uma import UmaConstants\nfrom org.gluu.model.uma import ClaimDefinitionBuilder\nfrom org.gluu.model.custom.script.type.uma import UmaRptPolicyType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList, HashSet\nfrom java.lang import String\n\nclass UmaRptPolicy(UmaRptPolicyType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"RPT Policy. Initializing ...\"\n self.clientsSet = self.prepareClientsSet(configurationAttributes)\n print \"RPT Policy. Initialized successfully\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"RPT Policy. Destroyed successfully\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def getRequiredClaims(self, context):\n json = \"\"\"[\n ]\"\"\"\n return ClaimDefinitionBuilder.build(json)\n\n def authorize(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\n print \"RPT Policy. Authorizing ...\"\n\n client_id=context.getClient().getClientId()\n print \"UmaRptPolicy. client_id = %s\" % client_id\n\n if (StringHelper.isEmpty(client_id)):\n return False\n \n if (self.clientsSet.contains(client_id)):\n print \"UmaRptPolicy. Authorizing client\"\n return True\n else:\n print \"UmaRptPolicy. Client isn't authorized\"\n return False\n\n def getClaimsGatheringScriptName(self, context):\n return UmaConstants.NO_SCRIPT\n\n def prepareClientsSet(self, configurationAttributes):\n clientsSet = HashSet()\n if (not configurationAttributes.containsKey(\"allowed_clients\")):\n return clientsSet\n\n allowedClientsList = configurationAttributes.get(\"allowed_clients\").getValue2()\n if (StringHelper.isEmpty(allowedClientsList)):\n print \"UmaRptPolicy. The property allowed_clients is empty\"\n return clientsSet \n\n allowedClientsListArray = StringHelper.split(allowedClientsList, \",\")\n if (ArrayHelper.isEmpty(allowedClientsListArray)):\n print \"UmaRptPolicy. No clients specified in allowed_clients property\"\n return clientsSet\n \n # Convert to HashSet to quick search\n i = 0\n count = len(allowedClientsListArray)\n while (i < count):\n client = allowedClientsListArray[i]\n clientsSet.add(client)\n i = i + 1\n\n return clientsSet\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "UMA_RPT_POLICY", - "name": "oxtrust_api_access_policy", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "1402.06d4bb9f-b830-44af-bbb2-6bc301448038", - "value1": "allowed_clients" - } - ], - "baseDn": "inum=OO11-BAFE,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Sample Dynamic Scope script for org_name", - "locationType": "LDAP", - "dn": "inum=031C-5621,ou=scripts,o=gluu", - "inum": "031C-5621", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2016, Gluu\r\n#\r\n# Author: Yuriy Movchan\r\n#\r\n\r\nfrom org.gluu.model.custom.script.type.scope import DynamicScopeType\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.util import StringHelper, ArrayHelper\r\nfrom java.util import Arrays, ArrayList\r\n\r\nimport java\r\n\r\nclass DynamicScope(DynamicScopeType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Dynamic scope. Initialization\"\r\n\r\n print \"Dynamic scope. Initialized successfully\"\r\n\r\n return True \r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Dynamic scope. Destroy\"\r\n print \"Dynamic scope. Destroyed successfully\"\r\n return True \r\n\r\n # Update Json Web token before signing/encrypring it\r\n # dynamicScopeContext is org.gluu.oxauth.service.external.context.DynamicScopeExternalContext\r\n # configurationAttributes is java.util.Map\r\n def update(self, dynamicScopeContext, configurationAttributes):\r\n print \"Dynamic scope. Update method\"\r\n\r\n dynamicScopes = dynamicScopeContext.getDynamicScopes()\r\n authorizationGrant = dynamicScopeContext.getAuthorizationGrant()\r\n user = dynamicScopeContext.getUser()\r\n jsonWebResponse = dynamicScopeContext.getJsonWebResponse()\r\n claims = jsonWebResponse.getClaims()\r\n\r\n # Add organization name if there is scope = org_name\r\n claims.setClaim(\"org_name\", \"Gluu, Inc.\")\r\n\r\n return True\r\n\r\n def getSupportedClaims(self, configurationAttributes):\r\n return Arrays.asList(\"org_name\")\r\n\r\n def getApiVersion(self):\r\n return 11\r\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "DYNAMIC_SCOPE", - "name": "org_name", - "modified": false, - "baseDn": "inum=031C-5621,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "locationType": "LDAP", - "dn": "inum=8AF7.D82A,ou=scripts,o=gluu", - "inum": "8AF7.D82A", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2020, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.model.custom.script.type.persistence import PersistenceType\nfrom org.gluu.util import StringHelper\nfrom org.gluu.persist.operation.auth import PasswordEncryptionHelper\nfrom org.gluu.persist.operation.auth import PasswordEncryptionMethod\n\nimport java\n\nclass PersistenceExtension(PersistenceType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Persistence extension. Initialization\"\n return True\n\n def destroy(self, configurationAttributes):\n print \"Persistence extension. Destroy\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def onAfterCreate(self, context, configurationAttributes):\n print \"Persistence extension. Method: onAfterCreate\"\n\n def onAfterDestroy(self, context, configurationAttributes):\n print \"Persistence extension. Method: onAfterDestroy\"\n\n def createHashedPassword(self, credential):\n print \"Persistence extension. Method: createHashedPassword\"\n\n hashed_password= PasswordEncryptionHelper.createStoragePassword(credential, PasswordEncryptionMethod.HASH_METHOD_PKCS5S2)\n\n return hashed_password\n\n def compareHashedPasswords(self, credential, storedCredential):\n print \"Persistence extension. Method: compareHashedPasswords\"\n \n auth_result = PasswordEncryptionHelper.compareCredentials(credential, storedCredential)\n\n return auth_result \n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "PERSISTENCE_EXTENSION", - "name": "persistence_extension", - "modified": false, - "baseDn": "inum=8AF7.D82A,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Sample Cache Refresh script", - "locationType": "LDAP", - "dn": "inum=13D3-E7AD,ou=scripts,o=gluu", - "inum": "13D3-E7AD", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.user import CacheRefreshType\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList\nfrom org.gluu.oxtrust.model import GluuCustomAttribute\nfrom org.gluu.model.custom.script.model.bind import BindCredentials\n\nimport java\n\nclass CacheRefresh(CacheRefreshType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Cache refresh. Initialization\"\n print \"Cache refresh. Initialized successfully\"\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Cache refresh. Destroy\"\n print \"Cache refresh. Destroyed successfully\"\n return True\n\n # Check if this instance conform starting conditions \n # configurationAttributes is java.util.Map\n # return True/False\n def isStartProcess(self, configurationAttributes):\n print \"Cache refresh. Is start process method\"\n\n return False\n \n # Get bind credentials required to access source server \n # configId is the source server\n # configurationAttributes is java.util.Map\n # return None (use password from configuration) or org.gluu.model.custom.script.model.bind.BindCredentials\n def getBindCredentials(self, configId, configurationAttributes):\n print \"Cache refresh. GetBindCredentials method\"\n# if configId == \"source\":\n# return BindCredentials(\"cn=Directory Manager\", \"password\")\n\n return None\n\n # Update user entry before persist it\n # user is org.gluu.oxtrust.model.GluuCustomPerson\n # configurationAttributes is java.util.Map\n def updateUser(self, user, configurationAttributes):\n print \"Cache refresh. UpdateUser method\"\n\n attributes = user.getCustomAttributes()\n\n # Add new attribute preferredLanguage\n attrPrefferedLanguage = GluuCustomAttribute(\"preferredLanguage\", \"en-us\")\n attributes.add(attrPrefferedLanguage)\n\n # Add new attribute userPassword\n attrUserPassword = GluuCustomAttribute(\"userPassword\", \"test\")\n attributes.add(attrUserPassword)\n\n # Update givenName attribute\n for attribute in attributes:\n attrName = attribute.getName()\n if ((\"givenname\" == StringHelper.toLowerCase(attrName)) and StringHelper.isNotEmpty(attribute.getValue())):\n attribute.setValue(StringHelper.removeMultipleSpaces(attribute.getValue()) + \" (updated)\")\n\n return True\n\n def getApiVersion(self):\n return 11\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "CACHE_REFRESH", - "name": "cache_refresh", - "modified": false, - "baseDn": "inum=13D3-E7AD,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Sample Application Session script", - "locationType": "LDAP", - "dn": "inum=DAA9-B789,ou=scripts,o=gluu", - "inum": "DAA9-B789", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.session import ApplicationSessionType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.persist import PersistenceEntryManager\nfrom org.gluu.oxauth.model.config import StaticConfiguration\nfrom org.gluu.oxauth.model.ldap import TokenLdap\nfrom javax.faces.application import FacesMessage\nfrom org.gluu.jsf2.message import FacesMessages\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom org.gluu.oxauth.model.config import Constants\nfrom java.util import Arrays, ArrayList\nfrom org.gluu.oxauth.service.external.session import SessionEventType\n\nimport java\n\nclass ApplicationSession(ApplicationSessionType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Application session. Initialization\"\n\n self.entryManager = CdiUtil.bean(PersistenceEntryManager)\n self.staticConfiguration = CdiUtil.bean(StaticConfiguration)\n\n print \"Application session. Initialized successfully\"\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Application session. Destroy\"\n print \"Application session. Destroyed successfully\"\n return True \n\n def getApiVersion(self):\n return 11\n\n # Called each time specific session event occurs\n # event is org.gluu.oxauth.service.external.session.SessionEvent\n def onEvent(self, event):\n if event.getType() == SessionEventType.AUTHENTICATED:\n print \"Session is authenticated, session: \" + event.getSessionId().getId()\n return\n\n # Application calls it at start session request to allow notify 3rd part systems\n # httpRequest is javax.servlet.http.HttpServletRequest\n # sessionId is org.gluu.oxauth.model.common.SessionId\n # configurationAttributes is java.util.Map\n def startSession(self, httpRequest, sessionId, configurationAttributes):\n print \"Application session. Starting external session\"\n\n user_name = sessionId.getSessionAttributes().get(Constants.AUTHENTICATED_USER)\n\n first_session = self.isFirstSession(user_name)\n if not first_session:\n facesMessages = CdiUtil.bean(FacesMessages)\n facesMessages.add(FacesMessage.SEVERITY_ERROR, \"Please, end active session first!\")\n return False\n\n print \"Application session. External session started successfully\"\n return True\n\n # Application calls it at end session request to allow notify 3rd part systems\n # httpRequest is javax.servlet.http.HttpServletRequest\n # sessionId is org.gluu.oxauth.model.common.SessionId\n # configurationAttributes is java.util.Map\n def endSession(self, httpRequest, sessionId, configurationAttributes):\n print \"Application session. Starting external session end\"\n\n print \"Application session. External session ended successfully\"\n return True\n\n def isFirstSession(self, user_name):\n tokenLdap = TokenLdap()\n tokenLdap.setDn(self.staticConfiguration.getBaseDn().getClients())\n tokenLdap.setUserId(user_name)\n\n tokenLdapList = self.entryManager.findEntries(tokenLdap, 1)\n print \"Application session. isFirstSession. Get result: '%s'\" % tokenLdapList\n\n if (tokenLdapList != None) and (tokenLdapList.size() > 0):\n print \"Application session. isFirstSession: False\"\n return False\n\n print \"Application session. isFirstSession: True\"\n return True\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "APPLICATION_SESSION", - "name": "application_session", - "modified": false, - "baseDn": "inum=DAA9-B789,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Dynamic Scope Script for Super Gluu RO", - "locationType": "LDAP", - "dn": "inum=5866-4202,ou=scripts,o=gluu", - "inum": "5866-4202", - "script": "# Super Gluu Radius Dynamic Scope \n# Copyright (c) 2019 Gluu Inc.\n\nfrom org.gluu.model.custom.script.type.scope import DynamicScopeType\nfrom org.gluu.oxauth.security import Identity\nfrom org.gluu.service.cdi.util import CdiUtil\n\nimport java\n\nclass DynamicScope(DynamicScopeType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Super-Gluu-DynScope init\"\n self.sessionIdClaimName = \"__session_id\"\n if configurationAttributes.containsKey(\"session_id_claim_name\"):\n self.sessionIdClaimName = configurationAttributes.get(\"session_id_claim_name\").getValue2()\n \n print \"Super-Gluu-DynScope init complete\"\n return True\n \n def destroy(self, configurationAttributes):\n print \"Super-Gluu-DynScope destroy\"\n print \"Super-Gluu-DynScope destroy complete\"\n return True\n \n def update(self, dynamicScopeContext, configurationAttributes):\n # Todo implement this\n print \"Super-Gluu-DynScope update\"\n updated = False\n identity = CdiUtil.bean(Identity)\n if (identity is not None) and (identity.getSessionId() is not None):\n session_id = identity.getSessionId().getId()\n jsonWebResponse = dynamicScopeContext.getJsonWebResponse()\n claims = jsonWebResponse.getClaims()\n claims.setClaim(self.sessionIdClaimName,session_id)\n updated = True\n else:\n print \"Super-Gluu-DynScope. No session id found. Skipping\"\n print \"Super-Gluu-DynScope update complete\"\n return updated\n \n def getApiVersion(self):\n return 11\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "DYNAMIC_SCOPE", - "name": "super_gluu_ro_session", - "modified": false, - "baseDn": "inum=5866-4202,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "locationType": "LDAP", - "dn": "inum=8AF7.D82B,ou=scripts,o=gluu", - "inum": "8AF7.D82B", - "script": "# oxShibboleth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2020, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.idp import IdpType\nfrom org.gluu.util import StringHelper\nfrom org.gluu.idp.externalauth import AuthenticatedNameTranslator\nfrom net.shibboleth.idp.authn.principal import UsernamePrincipal, IdPAttributePrincipal\nfrom net.shibboleth.idp.authn import ExternalAuthentication\nfrom net.shibboleth.idp.attribute import IdPAttribute, StringAttributeValue\nfrom net.shibboleth.idp.authn.context import AuthenticationContext, ExternalAuthenticationContext\nfrom net.shibboleth.idp.attribute.context import AttributeContext\nfrom javax.security.auth import Subject\nfrom java.util import Collections, HashSet, ArrayList, Arrays\n\nimport java\n\nclass IdpExtension(IdpType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Idp extension. Initialization\"\n \n self.defaultNameTranslator = AuthenticatedNameTranslator()\n \n return True\n\n def destroy(self, configurationAttributes):\n print \"Idp extension. Destroy\"\n return True\n\n def getApiVersion(self):\n return 11\n\n # Translate attributes from user profile\n # context is org.gluu.idp.externalauth.TranslateAttributesContext (https://github.com/GluuFederation/shib-oxauth-authn3/blob/master/src/main/java/org/gluu/idp/externalauth/TranslateAttributesContext.java)\n # configurationAttributes is java.util.Map\n def translateAttributes(self, context, configurationAttributes):\n print \"Idp extension. Method: translateAttributes\"\n \n # Return False to use default method\n #return False\n \n request = context.getRequest()\n userProfile = context.getUserProfile()\n principalAttributes = self.defaultNameTranslator.produceIdpAttributePrincipal(userProfile.getAttributes())\n print \"Idp extension. Converted user profile: '%s' to attribute principal: '%s'\" % (userProfile, principalAttributes)\n\n if not principalAttributes.isEmpty():\n print \"Idp extension. Found attributes from oxAuth. Processing...\"\n \n # Start: Custom part\n # Add givenName attribute\n givenNameAttribute = IdPAttribute(\"oxEnrollmentCode\")\n givenNameAttribute.setValues(ArrayList(Arrays.asList(StringAttributeValue(\"Dummy\"))))\n principalAttributes.add(IdPAttributePrincipal(givenNameAttribute))\n print \"Idp extension. Updated attribute principal: '%s'\" % principalAttributes\n # End: Custom part\n\n principals = HashSet()\n principals.addAll(principalAttributes)\n principals.add(UsernamePrincipal(userProfile.getId()))\n\n request.setAttribute(ExternalAuthentication.SUBJECT_KEY, Subject(False, Collections.singleton(principals),\n Collections.emptySet(), Collections.emptySet()))\n\n print \"Created an IdP subject instance with principals containing attributes for: '%s'\" % userProfile.getId()\n\n if False:\n idpAttributes = ArrayList()\n for principalAttribute in principalAttributes:\n idpAttributes.add(principalAttribute.getAttribute())\n \n request.setAttribute(ExternalAuthentication.ATTRIBUTES_KEY, idpAttributes)\n \n authenticationKey = context.getAuthenticationKey()\n profileRequestContext = ExternalAuthentication.getProfileRequestContext(authenticationKey, request)\n authContext = profileRequestContext.getSubcontext(AuthenticationContext)\n extContext = authContext.getSubcontext(ExternalAuthenticationContext)\n \n extContext.setSubject(Subject(False, Collections.singleton(principals), Collections.emptySet(), Collections.emptySet()));\n \n extContext.getSubcontext(AttributeContext, True).setUnfilteredIdPAttributes(idpAttributes)\n extContext.getSubcontext(AttributeContext).setIdPAttributes(idpAttributes)\n else:\n print \"No attributes released from oxAuth. Creating an IdP principal for: '%s'\" % userProfile.getId()\n request.setAttribute(ExternalAuthentication.PRINCIPAL_NAME_KEY, userProfile.getId())\n\n #Return True to specify that default method is not needed\n return False\n\n # Update attributes before releasing them\n # context is org.gluu.idp.consent.processor.PostProcessAttributesContext (https://github.com/GluuFederation/shib-oxauth-authn3/blob/master/src/main/java/org/gluu/idp/consent/processor/PostProcessAttributesContext.java)\n # configurationAttributes is java.util.Map\n def updateAttributes(self, context, configurationAttributes):\n print \"Idp extension. Method: updateAttributes\"\n return True\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "IDP", - "name": "idp", - "modified": false, - "baseDn": "inum=8AF7.D82B,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Permission Dynamic Scope script", - "locationType": "LDAP", - "dn": "inum=CB5B-3211,ou=scripts,o=gluu", - "inum": "CB5B-3211", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2016, Gluu\r\n#\r\n# Author: Yuriy Movchan\r\n#\r\n\r\nfrom org.gluu.model.custom.script.type.scope import DynamicScopeType\r\nfrom org.gluu.service.cdi.util import CdiUtil\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.util import StringHelper, ArrayHelper\r\nfrom java.util import Arrays, ArrayList\r\n\r\nimport java\r\n\r\nclass DynamicScope(DynamicScopeType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Permission dynamic scope. Initialization\"\r\n\r\n print \"Permission dynamic scope. Initialized successfully\"\r\n\r\n return True \r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Permission dynamic scope. Destroy\"\r\n print \"Permission dynamic scope. Destroyed successfully\"\r\n return True \r\n\r\n # Update Json Web token before signing/encrypring it\r\n # dynamicScopeContext is org.gluu.oxauth.service.external.context.DynamicScopeExternalContext\r\n # configurationAttributes is java.util.Map\r\n def update(self, dynamicScopeContext, configurationAttributes):\r\n print \"Permission dynamic scope scope. Update method\"\r\n\r\n authorizationGrant = dynamicScopeContext.getAuthorizationGrant()\r\n user = dynamicScopeContext.getUser()\r\n jsonWebResponse = dynamicScopeContext.getJsonWebResponse()\r\n claims = jsonWebResponse.getClaims()\r\n\r\n userService = CdiUtil.bean(UserService)\r\n roles = userService.getCustomAttribute(user, \"role\")\r\n if roles != None:\r\n claims.setClaim(\"role\", roles.getValues())\r\n\r\n return True\r\n\r\n def getSupportedClaims(self, configurationAttributes):\r\n return Arrays.asList(\"role\")\r\n\r\n def getApiVersion(self):\r\n return 11\r\n", - "enabled": true, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "DYNAMIC_SCOPE", - "name": "dynamic_permission", - "modified": false, - "baseDn": "inum=CB5B-3211,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Sample script for SCIM events", - "locationType": "LDAP", - "dn": "inum=A910-56AB,ou=scripts,o=gluu", - "inum": "A910-56AB", - "script": "# oxTrust is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2014, Gluu\n#\n# Author: Jose Gonzalez\n#\nfrom org.gluu.model.custom.script.type.scim import ScimType\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList\nfrom org.gluu.oxtrust.ldap.service import PersonService\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxtrust.model import GluuCustomPerson\n\nimport java\n\nclass ScimEventHandler(ScimType):\n\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"ScimEventHandler (init): Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"ScimEventHandler (destroy): Destroyed successfully\"\n return True \n\n def getApiVersion(self):\n #return 2 if you want the post* scripts being executed\n return 11\n\n def createUser(self, user, configurationAttributes):\n\n print \"ScimEventHandler (createUser): Current id = \" + user.getUid()\n\n testProp1 = configurationAttributes.get(\"testProp1\").getValue2()\n testProp2 = configurationAttributes.get(\"testProp2\").getValue2()\n\n print \"ScimEventHandler (createUser): testProp1 = \" + testProp1\n print \"ScimEventHandler (createUser): testProp2 = \" + testProp2\n\n return True\n\n def updateUser(self, user, configurationAttributes):\n personService = CdiUtil.bean(PersonService)\n oldUser = personService.getPersonByUid(user.getUid())\n print \"ScimEventHandler (updateUser): Old displayName %s\" % oldUser.getDisplayName()\n print \"ScimEventHandler (updateUser): New displayName \" + user.getDisplayName()\n return True\n\n def deleteUser(self, user, configurationAttributes):\n print \"ScimEventHandler (deleteUser): Current id = \" + user.getUid()\n return True\n\n def createGroup(self, group, configurationAttributes):\n print \"ScimEventHandler (createGroup): Current displayName = \" + group.getDisplayName()\n return True\n\n def updateGroup(self, group, configurationAttributes):\n print \"ScimEventHandler (updateGroup): Current displayName = \" + group.getDisplayName()\n return True\n\n def deleteGroup(self, group, configurationAttributes):\n print \"ScimEventHandler (deleteGroup): Current displayName = \" + group.getDisplayName()\n return True\n \n def postCreateUser(self, user, configurationAttributes):\n return True\n\n def postUpdateUser(self, user, configurationAttributes):\n return True\n\n def postDeleteUser(self, user, configurationAttributes):\n return True\n\n def postUpdateGroup(self, group, configurationAttributes):\n return True\n\n def postCreateGroup(self, group, configurationAttributes):\n return True\n\n def postDeleteGroup(self, group, configurationAttributes):\n return True", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "SCIM", - "name": "scim_event_handler", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "Test value 1", - "value1": "testProp1" - }, - { - "hide": false, - "value2": "Test value 2", - "value1": "testProp2" - } - ], - "baseDn": "inum=A910-56AB,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Sample Id Generator script", - "locationType": "LDAP", - "dn": "inum=031C-4A65,ou=scripts,o=gluu", - "inum": "031C-4A65", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.id import IdGeneratorType\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList\n\nimport java\n\nclass IdGenerator(IdGeneratorType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Id generator. Initialization\"\n print \"Id generator. Initialized successfully\"\n\n return True \n\n def destroy(self, configurationAttributes):\n print \"Id generator. Destroy\"\n print \"Id generator. Destroyed successfully\"\n return True \n\n def getApiVersion(self):\n return 11\n\n # Id generator init method\n # appId is application Id\n # idType is Id Type\n # idPrefix is Id Prefix\n # user is org.gluu.oxtrust.model.GluuCustomPerson\n # configurationAttributes is java.util.Map\n def generateId(self, appId, idType, idPrefix, configurationAttributes):\n print \"Id generator. Generate Id\"\n print \"Id generator. Generate Id. AppId: '\", appId, \"', IdType: '\", idType, \"', IdPrefix: '\", idPrefix, \"'\"\n\n # Return None or empty string to trigger default Id generation method\n return None\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "ID_GENERATOR", - "name": "id_generator", - "modified": false, - "baseDn": "inum=031C-4A65,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Sample Client Registration script", - "locationType": "LDAP", - "dn": "inum=DAA9-B788,ou=scripts,o=gluu", - "inum": "DAA9-B788", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\n# Copyright (c) 2016, Gluu\n#\n# Author: Yuriy Movchan\n#\n\nfrom org.gluu.model.custom.script.type.client import ClientRegistrationType\nfrom org.gluu.service.cdi.util import CdiUtil\nfrom org.gluu.oxauth.service import ScopeService\nfrom org.gluu.util import StringHelper, ArrayHelper\nfrom java.util import Arrays, ArrayList, HashSet\n\nimport java\n\nclass ClientRegistration(ClientRegistrationType):\n def __init__(self, currentTimeMillis):\n self.currentTimeMillis = currentTimeMillis\n\n def init(self, customScript, configurationAttributes):\n print \"Client registration. Initialization\"\n \n self.clientRedirectUrisSet = self.prepareClientRedirectUris(configurationAttributes)\n\n print \"Client registration. Initialized successfully\"\n return True \n\n def destroy(self, configurationAttributes):\n print \"Client registration. Destroy\"\n print \"Client registration. Destroyed successfully\"\n return True \n\n # Update client entry before persistent it\n # registerRequest is org.gluu.oxauth.client.RegisterRequest\n # client is org.gluu.oxauth.model.registration.Client\n # configurationAttributes is java.util.Map\n def createClient(self, registerRequest, client, configurationAttributes):\n print \"Client registration. CreateClient method\"\n\n redirectUris = client.getRedirectUris()\n print \"Client registration. Redirect Uris: %s\" % redirectUris\n\n addAddressScope = False\n for redirectUri in redirectUris:\n if (self.clientRedirectUrisSet.contains(redirectUri)):\n addAddressScope = True\n break\n \n print \"Client registration. Is add address scope: %s\" % addAddressScope\n\n if addAddressScope:\n currentScopes = client.getScopes()\n print \"Client registration. Current scopes: %s\" % currentScopes\n \n scopeService = CdiUtil.bean(ScopeService)\n addressScope = scopeService.getScopeByDisplayName(\"address\")\n newScopes = ArrayHelper.addItemToStringArray(currentScopes, addressScope.getDn())\n \n print \"Client registration. Result scopes: %s\" % newScopes\n client.setScopes(newScopes)\n\n return True\n\n # Update client entry before persistent it\n # registerRequest is org.gluu.oxauth.client.RegisterRequest\n # client is org.gluu.oxauth.model.registration.Client\n # configurationAttributes is java.util.Map\n def updateClient(self, registerRequest, client, configurationAttributes):\n print \"Client registration. UpdateClient method\"\n return True\n\n def getApiVersion(self):\n return 11\n\n def prepareClientRedirectUris(self, configurationAttributes):\n clientRedirectUrisSet = HashSet()\n if not configurationAttributes.containsKey(\"client_redirect_uris\"):\n return clientRedirectUrisSet\n\n clientRedirectUrisList = configurationAttributes.get(\"client_redirect_uris\").getValue2()\n if StringHelper.isEmpty(clientRedirectUrisList):\n print \"Client registration. The property client_redirect_uris is empty\"\n return clientRedirectUrisSet \n\n clientRedirectUrisArray = StringHelper.split(clientRedirectUrisList, \",\")\n if ArrayHelper.isEmpty(clientRedirectUrisArray):\n print \"Client registration. No clients specified in client_redirect_uris property\"\n return clientRedirectUrisSet\n \n # Convert to HashSet to quick search\n i = 0\n count = len(clientRedirectUrisArray)\n while i < count:\n uris = clientRedirectUrisArray[i]\n clientRedirectUrisSet.add(uris)\n i = i + 1\n\n return clientRedirectUrisSet\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "CLIENT_REGISTRATION", - "name": "client_registration", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "https://client.example.com/example1, https://client.example.com/example2", - "value1": "client_redirect_uris" - } - ], - "baseDn": "inum=DAA9-B788,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Sample Dynamic Scope script for work_phone", - "locationType": "LDAP", - "dn": "inum=031C-5622,ou=scripts,o=gluu", - "inum": "031C-5622", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2016, Gluu\r\n#\r\n# Author: Yuriy Movchan\r\n#\r\n\r\nfrom org.gluu.model.custom.script.type.scope import DynamicScopeType\r\nfrom org.gluu.service.cdi.util import CdiUtil\r\nfrom org.gluu.oxauth.service.common import UserService\r\nfrom org.gluu.util import StringHelper, ArrayHelper\r\nfrom java.util import Arrays, ArrayList\r\n\r\nimport java\r\n\r\nclass DynamicScope(DynamicScopeType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"Dynamic scope. Initialization\"\r\n\r\n print \"Dynamic scope. Initialized successfully\"\r\n\r\n return True \r\n\r\n def destroy(self, configurationAttributes):\r\n print \"Dynamic scope. Destroy\"\r\n print \"Dynamic scope. Destroyed successfully\"\r\n return True \r\n\r\n # Update Json Web token before signing/encrypring it\r\n # dynamicScopeContext is org.gluu.oxauth.service.external.context.DynamicScopeExternalContext\r\n # configurationAttributes is java.util.Map\r\n def update(self, dynamicScopeContext, configurationAttributes):\r\n print \"Dynamic scope. Update method\"\r\n\r\n dynamicScopes = dynamicScopeContext.getDynamicScopes()\r\n authorizationGrant = dynamicScopeContext.getAuthorizationGrant()\r\n user = dynamicScopeContext.getUser()\r\n jsonWebResponse = dynamicScopeContext.getJsonWebResponse()\r\n claims = jsonWebResponse.getClaims()\r\n\r\n # Add work phone if there is scope = work_phone\r\n userService = CdiUtil.bean(UserService)\r\n workPhone = userService.getCustomAttribute(user, \"telephoneNumber\")\r\n if workPhone != None:\r\n claims.setClaim(\"work_phone\", workPhone.getValues())\r\n\r\n return True\r\n\r\n def getSupportedClaims(self, configurationAttributes):\r\n return Arrays.asList(\"work_phone\")\r\n\r\n def getApiVersion(self):\r\n return 11\r\n", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "DYNAMIC_SCOPE", - "name": "work_phone", - "modified": false, - "baseDn": "inum=031C-5622,ou=scripts,o=gluu" - }, - { - "internal": false, - "level": 100, - "programmingLanguage": "PYTHON", - "description": "Sample UMA RPT Policy", - "locationType": "LDAP", - "dn": "inum=2DAF-F995,ou=scripts,o=gluu", - "inum": "2DAF-F995", - "script": "# jans-auth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.\r\n# Copyright (c) 2017, Gluu\r\n#\r\n# Author: Yuriy Zabrovarnyy\r\n#\r\n# Call sequence\r\n# 1. First is call constructor of the Script __init__\r\n# 2. Next init() method\r\n# 3. Next getRequiredClaims() - method returns required claims, so UMA engine checks whether\r\n# in request RP provided all claims that are required. Pay attention that there can be\r\n# multiple scripts bound to the scopes, means that UMA engine will build set of required claims\r\n# from all scripts. If not all claims are provided need_info error is sent to RP.\r\n# During need_info construction getClaimsGatheringScriptName() method is called\r\n# 4. authorize() method is called if all required claims are provided.\r\n# 5. destroy()\r\n\r\nfrom org.gluu.model.custom.script.type.uma import UmaRptPolicyType\r\nfrom org.gluu.model.uma import ClaimDefinitionBuilder\r\nfrom java.lang import String\r\n\r\nclass UmaRptPolicy(UmaRptPolicyType):\r\n def __init__(self, currentTimeMillis):\r\n self.currentTimeMillis = currentTimeMillis\r\n\r\n def init(self, customScript, configurationAttributes):\r\n print \"RPT Policy. Initializing ...\"\r\n print \"RPT Policy. Initialized successfully\"\r\n\r\n return True\r\n\r\n def destroy(self, configurationAttributes):\r\n print \"RPT Policy. Destroying ...\"\r\n print \"RPT Policy. Destroyed successfully\"\r\n return True\r\n\r\n def getApiVersion(self):\r\n return 11\r\n\r\n # Returns required claims definitions.\r\n # This method must provide definition of all claims that is used in 'authorize' method.\r\n # Note : name in both places must match.\r\n # %1$s - placeholder for issuer. It uses standard Java Formatter, docs : https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html\r\n def getRequiredClaims(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\r\n json = \"\"\"[\r\n {\r\n \"issuer\" : [ \"%1$s\" ],\r\n \"name\" : \"country\",\r\n \"claim_token_format\" : [ \"http://openid.net/specs/openid-connect-core-1_0.html#IDToken\" ],\r\n \"claim_type\" : \"string\",\r\n \"friendly_name\" : \"country\"\r\n },\r\n {\r\n \"issuer\" : [ \"%1$s\" ],\r\n \"name\" : \"city\",\r\n \"claim_token_format\" : [ \"http://openid.net/specs/openid-connect-core-1_0.html#IDToken\" ],\r\n \"claim_type\" : \"string\",\r\n \"friendly_name\" : \"city\"\r\n }\r\n ]\"\"\"\r\n context.addRedirectUserParam(\"customUserParam1\", \"value1\") # pass some custom parameters to need_info uri. It can be removed if you don't need custom parameters.\r\n return ClaimDefinitionBuilder.build(String.format(json, context.getIssuer()))\r\n\r\n # Main authorization method. Must return True or False.\r\n def authorize(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\r\n print \"RPT Policy. Authorizing ...\"\r\n\r\n if context.getClaim(\"country\") == 'US' and context.getClaim(\"city\") == 'NY':\r\n print \"Authorized successfully!\"\r\n return True\r\n\r\n return False\r\n\r\n # Returns name of the Claims-Gathering script which will be invoked if need_info error is returned.\r\n def getClaimsGatheringScriptName(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext\r\n context.addRedirectUserParam(\"customUserParam2\", \"value2\") # pass some custom parameters to need_info uri. It can be removed if you don't need custom parameters.\r\n return \"sampleClaimsGathering\"", - "enabled": false, - "revision": 1, - "moduleProperties": [ - { - "value2": "ldap", - "value1": "location_type" - } - ], - "scriptType": "UMA_RPT_POLICY", - "name": "uma_rpt_policy", - "modified": false, - "configurationProperties": [ - { - "hide": false, - "value2": "1202.f39fd3df-45b8-412b-a628-13ef5c38d453, None", - "value1": "allowed_clients" - } - ], - "baseDn": "inum=2DAF-F995,ou=scripts,o=gluu" - } -] \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/custom.feature b/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/custom.feature deleted file mode 100644 index 2bee94d9729..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/custom.feature +++ /dev/null @@ -1,103 +0,0 @@ -Feature: Verify Custom Script configuration endpoint - - Background: - * def mainUrl = scriptsUrl - - - @scripts-get - Scenario: Retrieve Custom Script configuration without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - - @scripts-get - Scenario: Retrieve Custom Script configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @scripts-get-custom-script-by-name - Scenario: Fetch all custom scripts by name - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.entries[0] - And print 'Script inum = '+response.entries[0].name - And assert response.entries[0].name != null - And print 'Script Name = '+response.entries[0].name - And print 'Fetching script by name' + '-' +response.entries[0].name - Given url mainUrl + '/name' + '/'+response.entries[0].name - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @scripts-get-person-custom-scripts - Scenario: Fetch all person custom script - Given url mainUrl + '/type' - And path 'person_authentication' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @scripts-get-introspection-custom-scripts - Scenario: Fetch all introspection scripts - Given url mainUrl + '/type' - And path 'introspection' - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - Scenario: Patch person custom script by inum - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - And print response.entries[0] - And print 'Script inum = '+response.entries[0].inum - And assert response.entries[0].inum != null - And print 'Script Type = '+response.entries[0].scriptType - And print 'Patching script ' + '-' +response.entries[0].scriptType + '-' +response.entries[0].inum - Given url mainUrl + '/'+response.entries[0].inum - And header Authorization = 'Bearer ' + accessToken - And header Content-Type = 'application/json-patch+json' - And def request_body = "[ {\"op\":\"replace\", \"path\": \"/enabled\", \"value\":"+response.entries[0].enabled+" } ]" - And print 'request_body ='+request_body - And request request_body - When method PATCH - Then status 200 - And print response - And assert response.length !=0 - - - Scenario: Post person custom script by inum - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('post-script.json') - When method POST - Then status 201 - And print response - And print response.inum - And print 'Delete newly created script' - Given url mainUrl + '/' +response.inum - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - And print response \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/post-script.json b/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/post-script.json deleted file mode 100644 index a4c0beea841..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/generic/post-script.json +++ /dev/null @@ -1,17 +0,0 @@ -{ -"internal": false, -"level": 1, -"programmingLanguage": "PYTHON", -"description": "Introspection Custom Parameters Sample Script", -"enabled": false, -"revision": 1, -"moduleProperties": [ - { - "value2": "db", - "value1": "location_type" - } -], -"scriptType": "INTROSPECTION", -"name": "introspection_custom_params", -"modified": false -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/persons/person-script.json b/jans-config-api/server/src/test/resources/feature/config/scripts/custom/persons/person-script.json deleted file mode 100644 index 72b3497b0e1..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/persons/person-script.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "configurationProperties": [], - "description": "QAAdded Person Script description", - "enabled": false, - "internal": false, - "level": 30, - "locationType": "db", - "modified": false, - "moduleProperties": [ - { - "description": "", - "value1": "location_type", - "value2": "db" - }, - { - "description": "", - "value1": "usage_type", - "value2": "interactive" - } - ], - "name": "QAAddedPersonScript", - "programmingLanguage": "python", - "revision": 1, - "script": "QaAdded Person Script Content", - "scriptType": "person_authentication" -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/persons/person-scripts.feature b/jans-config-api/server/src/test/resources/feature/config/scripts/custom/persons/person-scripts.feature deleted file mode 100644 index 47163507930..00000000000 --- a/jans-config-api/server/src/test/resources/feature/config/scripts/custom/persons/person-scripts.feature +++ /dev/null @@ -1,122 +0,0 @@ - -Feature: Person Custom Scripts - -Background: - * def mainUrl = scriptsUrl - -Scenario: Fetch all person custom scripts without bearer token -Given url mainUrl + '/type' -And path 'person_authentication' -When method GET -Then status 401 -And print response - - -Scenario: Fetch all person custom scripts -Given url mainUrl + '/type' -And header Authorization = 'Bearer ' + accessToken -And path 'person_authentication' -When method GET -Then status 200 -And print response -And assert response.length != null -And assert response.entries[0].scriptType == 'person_authentication' - - -Scenario: Fetch the first three person custom scripts -Given url mainUrl + '/type' -And header Authorization = 'Bearer ' + accessToken -And path 'person_authentication' -And params ({ limit: 3}) -When method GET -And print response -Then status 200 -And assert response.entries.length == 3 -And assert response.entries[0].scriptType == 'person_authentication' - - -Scenario: Search person custom scripts given a serach pattern -Given url mainUrl + '/type' -And header Authorization = 'Bearer ' + accessToken -And path 'person_authentication' -And params ({ limit: 3,pattern:'fido2'}) -When method GET -And print response -Then status 200 -And assert response.entries.length <= 3 -And assert response.entries[0].scriptType == 'person_authentication' - -@ignore -@CreateUpdateDelete -Scenario: Create new Person Script -Given url mainUrl + '/type' -And header Authorization = 'Bearer ' + accessToken -And path 'person_authentication' -When method GET -And print response -Then status 200 -And assert response.length != 0 -And assert response.entries[0].scriptType == 'person_authentication' -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And def testScript = response.entries[0] -And print "testScript before = "+testScript -And testScript.inum = null -And testScript.dn = null -And testScript.name = "Test_PERSON_AUTHENTICATION" -And testScript.description = "Test_PERSON_AUTHENTICATION_description" -And print "testScript after = "+testScript -And request testScript -When method POST -And print response -Then status 201 -Then def result = response -Then set result.name = 'UpdatedQAAddedPersonScript' -Then def inum_before = result.inum -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request result -When method PUT -And print response -Then status 200 -And assert response.name == 'UpdatedQAAddedPersonScript' -And assert response.inum == inum_before -Given url mainUrl + '/' +response.inum -And header Authorization = 'Bearer ' + accessToken -And print response -When method DELETE -Then status 204 - - -Scenario: Delete a non-existing person custom script by inum -Given url mainUrl + '/1402.66633-8675-473e-a749' -And header Authorization = 'Bearer ' + accessToken -When method DELETE -And print response -Then status 404 - - -Scenario: Get a person custom script by inum(unexisting person script) -#Given url mainUrl + '/53553532727272772' -Given url mainUrl + '/inum/53553532727272772' -And header Authorization = 'Bearer ' + accessToken -When method GET -And print response -Then status 404 - - -Scenario: Get a person custom script by inum -Given url mainUrl + '/type' -And header Authorization = 'Bearer ' + accessToken -And path 'person_authentication' -When method GET -And print response -Then status 200 -And print response.entries[0].inum -Given url mainUrl + '/inum/'+response.entries[0].inum -And header Authorization = 'Bearer ' + accessToken -And print request -When method GET -And print response -Then status 200 -And assert response.scriptType == 'person_authentication' diff --git a/jans-config-api/server/src/test/resources/feature/defaultAcr/defaultAcr.feature b/jans-config-api/server/src/test/resources/feature/defaultAcr/defaultAcr.feature deleted file mode 100644 index 28ecbbed44a..00000000000 --- a/jans-config-api/server/src/test/resources/feature/defaultAcr/defaultAcr.feature +++ /dev/null @@ -1,59 +0,0 @@ - -Feature: Verify Default ACRS configuration endpoint - - Background: - * def mainUrl = acrsUrl - - @acrs-get-error - Scenario: Retrieve ACRS configuration without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - @acrs-get - Scenario: Retrieve Default ACRS configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - @ignore - @acrs-put - Scenario: Update Default ACRS configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def first_response = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 200 - And print response - And assert response.length != null - - @ignore - @acrs-error - Scenario: Default Authentication Mode configuration cannot be null or blank - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def result = response - Then set result.defaultAcr = null - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 400 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/defaultAcr/defaultAcr.json b/jans-config-api/server/src/test/resources/feature/defaultAcr/defaultAcr.json deleted file mode 100644 index 44b246679fd..00000000000 --- a/jans-config-api/server/src/test/resources/feature/defaultAcr/defaultAcr.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "defaultAcr": "simple_password_auth" -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/health/auth-server-health.feature b/jans-config-api/server/src/test/resources/feature/health/auth-server-health.feature deleted file mode 100644 index 4e993f3ce1e..00000000000 --- a/jans-config-api/server/src/test/resources/feature/health/auth-server-health.feature +++ /dev/null @@ -1,13 +0,0 @@ - -Feature: Verify API HealthCheck - -Background: -* def mainUrl = auth_health_url - - Scenario: Verify all stats of the health - Given url mainUrl - When method GET - Then status 200 - And print response - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/health/config-api-health.feature b/jans-config-api/server/src/test/resources/feature/health/config-api-health.feature deleted file mode 100644 index 66e3e5cc1ea..00000000000 --- a/jans-config-api/server/src/test/resources/feature/health/config-api-health.feature +++ /dev/null @@ -1,32 +0,0 @@ - -Feature: Verify API HealthCheck - -Background: - * def mainUrl = healthUrl - * def health_schema = { name: '#string', status: '#string' } - * def status_str = 'UP' - * def response_str = [{"name": "jans-config-api liveness","status": "UP"},{"name": "jans-config-api readiness","status": "UP"}] - * def live_str = [{"name": "jans-config-api liveness","status": "UP"}] - * def ready_str = [{"name": "jans-config-api readiness","status": "UP"}] - - Scenario: Verify all stats of the health - Given url mainUrl - When method GET - Then status 200 - And print response - - - Scenario: Verify liveness status of API - Given url mainUrl + '/live/' - When method GET - Then status 200 - And print response - - Scenario: Verify readiness status of API - Given url mainUrl + '/ready/' - When method GET - Then status 200 - And print response - - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/health/server-health.feature b/jans-config-api/server/src/test/resources/feature/health/server-health.feature deleted file mode 100644 index 4b7d44306a7..00000000000 --- a/jans-config-api/server/src/test/resources/feature/health/server-health.feature +++ /dev/null @@ -1,14 +0,0 @@ - -Feature: Verify Server stats - -Background: - * def mainUrl = healthUrl + "/server-stat" - - Scenario: Verify Underlying server stats - Given url mainUrl - When method GET - Then status 200 - And print response - - - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/logging/logging.feature b/jans-config-api/server/src/test/resources/feature/logging/logging.feature deleted file mode 100644 index 74ab57b7431..00000000000 --- a/jans-config-api/server/src/test/resources/feature/logging/logging.feature +++ /dev/null @@ -1,37 +0,0 @@ - -Feature: Logging connection configuration - - Background: - * def mainUrl = logging_url - - - Scenario: Retrieve logging configuration without bearer token - Given url mainUrl - When method GET - Then status 401 - And print response - - - Scenario: Retrieve logging configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - Scenario: Update logging configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - Then def first_response = response - And header Authorization = 'Bearer ' + accessToken - And request first_response - When method PUT - Then status 200 - And print response - \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/openid/clients/admin-ui-client.json b/jans-config-api/server/src/test/resources/feature/openid/clients/admin-ui-client.json deleted file mode 100644 index 6d78adbb4d4..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/clients/admin-ui-client.json +++ /dev/null @@ -1 +0,0 @@ -{"displayName":"FinalNewTestClient","clientName":"FinalNewTestClient","applicationType":"web","subjectType":"public","idTokenSignedResponseAlg":"HS256","tokenEndpointAuthMethod":"client_secret_post","accessTokenSigningAlg":"HS256","backchannelUserCodeParameter":false,"policyUri":"https://myclient.com/policy","tlsClientAuthSubjectDn":"tls auth","sectorIdentifierUri":"https://myclient.com/uri","redirectUris":["https://myclient.com/redirecturi"],"claimRedirectUris":["https://myclient.com/clainredirect"],"responseTypes":["code"],"grantTypes":["implicit","authorization_code"],"contacts":["sample@yahoo.fr"],"postLogoutRedirectUris":["https://myclient.com/postlogout"],"scopes":["inum=43F1,ou=scopes,o=jans"],"customAttributes":[{"name":"description","multiValued":false,"values":["MyClient description"]},{"name":"description","multiValued":false,"values":[null]}],"spontaneousScopes":["inum=C4F5,ou=scopes,o=jans"],"introspectionScripts":[],"spontaneousScopeScriptDns":[],"consentGatheringScripts":[],"rptClaimsScripts":[],"backchannelLogoutUri":["https://myclient.com/backchannel"],"postAuthnScripts":[],"additionalAudience":["audiance"],"attributes":{"tlsClientAuthSubjectDn":"tls auth","spontaneousScopes":["inum=C4F5,ou=scopes,o=jans"],"backchannelLogoutUri":["https://myclient.com/backchannel"],"additionalAudience":["audiance"],"introspectionScripts":[],"spontaneousScopeScriptDns":[],"consentGatheringScripts":[],"rptClaimsScripts":[],"postAuthnScripts":[]},"customObjectClasses":["top"],"deletable":false,"frontChannelLogoutSessionRequired":true,"requireAuthTime":true,"trustedClient":true,"persistClientAuthorizations":true,"includeClaimsInIdToken":true,"rptAsJwt":true,"accessTokenAsJwt":true,"disabled":false,"clientUri":"https://myclient.com/clienturi","initiateLoginUri":"https://myclient.com/loginuri","tosUri":"https://myclient.com/tosuri","idTokenTokenBindingCnf":"polling","refreshTokenLifetime":5,"oxdId":"sample","defaultMaxAge":5,"accessTokenLifetime":5,"authorizedOrigins":["https://myclient.com/origins"],"requestUris":["https://myclient.com/requesturi"],"idTokenEncryptedResponseAlg":"RSA-OAEP","idTokenEncryptedResponseEnc":"A256CBC+HS512","requestObjectEncryptionAlg":"RSA1_5","requestObjectSigningAlg":"ES512","requestObjectEncryptionEnc":"A256CBC+HS512","userInfoEncryptedResponseAlg":"RSA1_5","userInfoSignedResponseAlg":"ES384","userInfoEncryptedResponseEnc":"A128CBC+HS256","jwksUri":"https://myclient.com/jwksuri","jwks":"https://myclient.com/jwks","action_message":"savinf spsmslmsls"} diff --git a/jans-config-api/server/src/test/resources/feature/openid/clients/client.json b/jans-config-api/server/src/test/resources/feature/openid/clients/client.json deleted file mode 100644 index e18a1e3e1f0..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/clients/client.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "applicationType": "web", - "description":"Description for test client", - "customObjectClasses":["top"], - "accessTokenAsJwt": false, - "claimRedirectUris": [ - ], - "deletable": false, - "disabled": false, - "requireAuthTime": false, - "clientName": "Jans Config API Test Client", - "clientSecret": "test1234", - "exp": "2130-09-28T23:00:00Z[UTC]", - "grantTypes": [ - "authorization_code", - "implicit", - "refresh_token", - "client_credentials", - "password" - ], - "responseTypes": ["code"], - "idTokenSignedResponseAlg": "RS256", - "accessTokenSigningAlg": "RS256", - "attributes": { - "tlsClientAuthSubjectDn":"", - "runIntrospectionScriptBeforeJwtCreation":false, - "keepClientAuthorizationAfterExpiration":false, - "allowSpontaneousScopes":false, - "spontaneousScopes":[],"spontaneousScopeScriptDns":[], - "backchannelLogoutUri":[],"backchannelLogoutSessionRequired":false, - "additionalAudience":[],"postAuthnScripts":[],"consentGatheringScripts":[], - "introspectionScripts":[],"rptClaimsScripts":[] - }, - "frontChannelLogoutSessionRequired": false, - "logoutUri": [ - ], - "persistClientAuthorizations": true, - "postLogoutRedirectUris": [ - ], - "redirectUris": [ - "http://localhost:8080" - ], - "scopes": [ - ], - "trustedClient": false, - "includeClaimsInIdToken": false, - "rptAsJwt": false, - "subjectType": "pairwise", - "tokenEndpointAuthMethod": "client_secret_basic", - "dynamicRegistrationCustomObjectClass": "MyDynamicRegistrationCustomObject", - "dynamicRegistrationCustomAttributes": [ - "jansTrustedClnt", - "myAttr1" - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/openid/clients/client_custom_attribute_patch.json b/jans-config-api/server/src/test/resources/feature/openid/clients/client_custom_attribute_patch.json deleted file mode 100644 index f0ef5dbec6e..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/clients/client_custom_attribute_patch.json +++ /dev/null @@ -1,13 +0,0 @@ -[ - { - "op": "replace", - "path": "/customAttributes", - "value":[ - { - "name": "customTest", - "multiValued": false, - "value": "ABC_Vaue_Patched" - } - ] - } -] diff --git a/jans-config-api/server/src/test/resources/feature/openid/clients/clients.feature b/jans-config-api/server/src/test/resources/feature/openid/clients/clients.feature deleted file mode 100644 index 9b8c32bdc5c..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/clients/clients.feature +++ /dev/null @@ -1,141 +0,0 @@ - -Feature: Openid connect clients - - Background: - * def mainUrl = openidclients_url - -Scenario: Fetch all openid connect clients without bearer token -Given url mainUrl -When method GET -Then status 401 - - -Scenario: Fetch all openid connect clients -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response -#And assert response.length != null - - -Scenario: Fetch the first three openidconnect clients -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param limit = 3 -When method GET -Then status 200 -And print response -#And assert response.length == 3 - - -Scenario: Search openid connect clients given a serach pattern -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param limit = 1 -When method GET -Then status 200 -And print response -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param pattern = response.entries[0].displayName -And print 'pattern = '+pattern -When method GET -Then status 200 -And print response -#And assert response.length !=0 - -Scenario: Search openid connect clients given a serach pattern and pagination -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param pattern = 'test' -And param limit = 10 -And param startIndex = 1 -When method GET -Then status 200 -And print response - -Scenario: Get an openid connect client by inum(unexisting client) -Given url mainUrl + '/53553532727272772' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 404 - - -Scenario: Get an openid connect client by inum -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -Given url mainUrl + '/' +response.entries[0].inum -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response - -@ignore -@CreateUpdateDelete -Scenario: Create new OpenId Connect Client -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request read('client.json') -When method POST -Then status 201 -And print response -Then def result = response -Then set result.entries[0].displayName = 'UpdatedQAAddedClient' -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request result -When method PUT -Then status 200 -And print response -And assert response.entries[0]displayName == 'UpdatedQAAddedClient' -Given url mainUrl + '/' +response.entries[0].inum -And header Authorization = 'Bearer ' + accessToken -When method DELETE -Then status 204 -And print response - - -Scenario: Delete a non-existion openid connect client by inum -Given url mainUrl + '/1402.66633-8675-473e-a749' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 404 -And print response - -@ignore -Scenario: Patch openid connect client -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param limit = 1 -When method GET -Then status 200 -And print response -Given url mainUrl + '/' +response.entries[0].inum -And header Authorization = 'Bearer ' + accessToken -And header Content-Type = 'application/json-patch+json' -And header Accept = 'application/json' -And def newName = response.entries[0].displayName -And print " newName = "+newName -#And request "[ {\"op\":\"replace\", \"path\": \"/displayName\", \"value\":\""+newName+"\"} ]" -And def request_body = (response.entries[0].displayName == null ? "[ {\"op\":\"add\", \"path\": \"/displayName\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/displayName\", \"value\":"+response.displayName+" } ]") -And print 'request_body ='+request_body -And request request_body -When method PATCH -Then status 200 -And print response -#And assert response.length !=0 - -@ignore -@CreateUpdateDelete -Scenario: Create new OpenId Connect Client -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request read('openid_clients_create.json') -When method POST -Then status 201 -And print response - - diff --git a/jans-config-api/server/src/test/resources/feature/openid/clients/custom-attribute.feature b/jans-config-api/server/src/test/resources/feature/openid/clients/custom-attribute.feature deleted file mode 100644 index 5a42b98b8c7..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/clients/custom-attribute.feature +++ /dev/null @@ -1,43 +0,0 @@ -@ignore -Feature: Openid connect clients to test Custom Attribute for Client Claim Management - -Background: -* def mainUrl = openidclients_url -* def customAttributes_url = attributes_url - - -Scenario: Connect Client with CustomAttribute Testing for Client Claim Management -#Check if custom attribute is present -Given url customAttributes_url -And header Authorization = 'Bearer ' + accessToken -And param pattern = 'customTest' -And param limit = 1 -When method GET -Then status 200 -And print response -Then print response[0].name -Then assert responseStatus == 200 -And eval if( response.length == 0 ||response[0].name != 'customTest' ) karate.abort() -# Create Client with CustomAttribute -Given url openidclients_url -And header Authorization = 'Bearer ' + accessToken -And request read('openid-client.json') -When method POST -Then status 201 -And print response -And print response.inum -# Patch OpenId Connect Client with CustomAttribute -Given url openidclients_url + '/' +response.inum -And header Authorization = 'Bearer ' + accessToken -And header Content-Type = 'application/json-patch+json' -And header Accept = 'application/json' -And request read('client_custom_attribute_patch.json') -When method PATCH -Then status 200 -And print response -# Delete OpenId Connect Client with CustomAttribute -Given url openidclients_url + '/' +response.inum -And header Authorization = 'Bearer ' + accessToken -When method DELETE -Then status 204 - diff --git a/jans-config-api/server/src/test/resources/feature/openid/clients/openid-client.json b/jans-config-api/server/src/test/resources/feature/openid/clients/openid-client.json deleted file mode 100644 index 24da86ddd1f..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/clients/openid-client.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "accessTokenAsJwt": false, - "attributes": { - "additionalAudience": [], - "allowSpontaneousScopes": false, - "backchannelLogoutSessionRequired": false, - "backchannelLogoutUri": [], - "consentGatheringScripts": [], - "introspectionScripts": [], - "keepClientAuthorizationAfterExpiration": false, - "postAuthnScripts": [], - "rptClaimsScripts": [], - "runIntrospectionScriptBeforeJwtCreation": false, - "spontaneousScopeScriptDns": [], - "spontaneousScopes": [] - }, - "claimRedirectURI": [ - "https://gluu.gasmyr.com/jans-auth/restv1/uma/gather_claims" - ], - "deletable": false, - "disabled": false, - "displayName": "Puja_Sharma_Test_Client_3", - "description":"OpenId Client added for testing", - "encodedClientSecret": "qaclientPassword", - "exp": "2120-09-28T23:00:00Z[UTC]", - "grantTypes": [ - "AUTHORIZATION_CODE" - ], - "idTokenSignedResponseAlg": "HS256", - "logoutSessionRequired": true, - "logoutUri": [ - "https://gluu.gasmyr.com/identity/ssologout.htm" - ], - "jansAppTyp": "WEB", - "jansPersistClntAuthzs": false, - "jansPostLogoutRedirectURI": [ - "https://gluu.gasmyr.com/identity/finishlogout.htm" - ], - "jansRedirectURI": [ - "https://gluu.gasmyr.com/identity/uri1" - ], - "jansScope": [ - "inum=F0C4,ou=scopes,o=gluu" - ], - "jansTrustedClnt": true, - "jansInclClaimsInIdTkn": false, - "responseTypes": [ - "CODE" - ], - "rptAsJwt": false, - "subjectType": "PUBLIC", - "tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC", - "customAttributes": [ - { - "name": "customTest", - "multiValued": false, - "value": "To test CustomAttribute for Puja_Sharma_Test_Client_3" - } - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/openid/clients/openid_clients_create.json b/jans-config-api/server/src/test/resources/feature/openid/clients/openid_clients_create.json deleted file mode 100644 index bd5078f8eca..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/clients/openid_clients_create.json +++ /dev/null @@ -1,154 +0,0 @@ -{ - "clientSecret": "test@123", - "clientName": "ABCDE", - "description": "sdjkhfjksdfjksdkfj", - "applicationType": "web", - "subjectType": "pairwise", - "initiateLoginUri": "DFGDFDFG", - "logoUri": "sdfsdfsdf", - "clientUri": "sdfsdf", - "tosUri": "fddfdfgdf", - "jwksUri": "JKHJKHSDHKJSDFH", - "jwks": "JKJKHJKJHK", - "expirable": [ - "on" - ], - "expirationDate": "2022-07-25T09:30:00.656Z", - "softwareStatement": "12", - "softwareVersion": "11", - "softwareId": "123", - "softwareSection": false, - "cibaSection": false, - "idTokenSignedResponseAlg": "HS256", - "idTokenEncryptedResponseAlg": "A128KW", - "tokenEndpointAuthMethod": "client_secret_post", - "accessTokenSigningAlg": "HS384", - "idTokenEncryptedResponseEnc": "A256CBC+HS512", - "requestObjectEncryptionAlg": "RSA-OAEP", - "requestObjectSigningAlg": "HS256", - "requestObjectEncryptionEnc": "A256CBC+HS512", - "userInfoEncryptedResponseAlg": "A128KW", - "userInfoSignedResponseAlg": "RS256", - "userInfoEncryptedResponseEnc": "A128GCM", - "idTokenTokenBindingCnf": "dsfsdfdsf", - "backchannelUserCodeParameter": true, - "refreshTokenLifetime": 2, - "defaultMaxAge": 2, - "accessTokenLifetime": 12, - "backchannelTokenDeliveryMode": "push", - "backchannelClientNotificationEndpoint": "sdhjfjhsdf", - "frontChannelLogoutUri": "dfdsdgsdg", - "policyUri": "sfsdsdf", - "sectorIdentifierUri": "HJKFDJHKHJKDS", - "redirectUris": [ - "sdfsdfsdf" - ], - "claimRedirectUris": [ - "NBMNSMNBSDMV" - ], - "authorizedOrigins": [ - "dgffddfg" - ], - "requestUris": [ - "FDDGDFGG" - ], - "postLogoutRedirectUris": [ - "sdfsdfds" - ], - "responseTypes": [ - "token" - ], - "grantTypes": [ - "implicit" - ], - "contacts": [ - "ashash@ggg.ccc" - ], - "defaultAcrValues": [ - "inum=3000-F75A,ou=scripts,o=jans" - ], - "scopes": [ - "inum=10B2,ou=scopes,o=jans" - ], - "attributes": { - "tlsClientAuthSubjectDn": "123", - "runIntrospectionScriptBeforeJwtCreation": "true", - "keepClientAuthorizationAfterExpiration": false, - "allowSpontaneousScopes": "true", - "backchannelLogoutSessionRequired": "true", - "backchannelLogoutUri": [ - "dsfsdfsdf" - ], - "rptClaimsScripts": [], - "consentGatheringScripts": [], - "spontaneousScopeScriptDns": [], - "introspectionScripts": [ - "inum=A44E-4F3D,ou=scripts,o=jans" - ], - "postAuthnScripts": [], - "additionalAudience": [ - "dsfsdfsdf" - ], - "spontaneousScopes": [ - "inum=1200.6928E4,ou=scopes,o=jans" - ], - "redirectUrisRegex": "sdfsdf", - "parLifetime": 3600, - "requirePar": true, - "jansDefaultPromptLogin": true, - "jansAuthorizedAcr": [ - "inum=3000-F75A,ou=scripts,o=jans" - ], - "updateTokenScriptDns": [], - "ropcScripts": [], - "jansAuthSignedRespAlg": "HS384", - "jansAuthEncRespAlg": "A128KW", - "jansAuthEncRespEnc": "A128GCM" - }, - "tlsClientAuthSubjectDn": "123", - "frontChannelLogoutSessionRequired": true, - "runIntrospectionScriptBeforeJwtCreation": "true", - "backchannelLogoutSessionRequired": "true", - "keepClientAuthorizationAfterExpiration": false, - "allowSpontaneousScopes": "true", - "spontaneousScopes": [ - "inum=1200.6928E4,ou=scopes,o=jans" - ], - "introspectionScripts": [ - "inum=A44E-4F3D,ou=scripts,o=jans" - ], - "spontaneousScopeScriptDns": [], - "consentGatheringScripts": [], - "redirectUrisRegex": "sdfsdf", - "parLifetime": "bnxcbmx", - "requirePar": true, - "updateTokenScriptDns": [], - "ropcScripts": [], - "authorizationSignedResponseAlg": "HS384", - "authorizationEncryptedResponseAlg": "A128KW", - "authorizationEncryptedResponseEnc": "A128GCM", - "postAuthnScripts": [], - "rptClaimsScripts": [], - "additionalAudience": [ - "dsfsdfsdf" - ], - "backchannelLogoutUri": [ - "dsfsdfsdf" - ], - "defaultPromptLogin": true, - "jansAuthorizedAcr": [ - "inum=3000-F75A,ou=scripts,o=jans" - ], - "customObjectClasses": [], - "requireAuthTime": true, - "trustedClient": true, - "persistClientAuthorizations": true, - "includeClaimsInIdToken": true, - "rptAsJwt": true, - "accessTokenAsJwt": true, - "disabled": true, - "claimRedirectURIs": [ - "NBMNSMNBSDMV" - ], - "action_message": "SDN KD KJDK " -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/openid/scopes/generic_scopes.feature b/jans-config-api/server/src/test/resources/feature/openid/scopes/generic_scopes.feature deleted file mode 100644 index 21606bc4204..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/scopes/generic_scopes.feature +++ /dev/null @@ -1,87 +0,0 @@ -@ignore -Feature: Scopes - -Scenario: Fetch all scopes without bearer token -Given url scopes_url -When method GET -Then status 401 - -Scenario: Fetch all scopes -Given url scopes_url -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response -And assert response.length != null - -Scenario: Fetch all scopes -Given url scopes_url -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response -And assert response.length != null - -Scenario: Fetch the first three scopes -Given url scopes_url -And header Authorization = 'Bearer ' + accessToken -And param limit = 3 -When method GET -Then status 200 -And print response -And assert response.length == 3 - -Scenario: Search scopes given a serach pattern -Given url scopes_url -And header Authorization = 'Bearer ' + accessToken -And param pattern = 'View' -When method GET -Then status 200 -And print response - -@CreateUpdateDelete -Scenario: Create new Scope -Given url scopes_url -And header Authorization = 'Bearer ' + accessToken -And request read('classpath:scope.json') -When method POST -Then status 201 -Then def result = response -Then set result.displayName = 'UpdatedQAAddedScope' -Then def inum_before = result.inum -Given url scopes_url -And header Authorization = 'Bearer ' + accessToken -And request result -When method PUT -Then status 200 -And assert response.displayName == 'UpdatedQAAddedScope' -And assert response.inum == inum_before -Given url scopes_url + '/' +response.inum -And header Authorization = 'Bearer ' + accessToken -When method DELETE -Then status 204 - -Scenario: Delete a non-existing scope by inum -Given url scopes_url + '/1402.66633-8675-473e-a749' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 404 - - -Scenario: Get an scope by inum(unexisting scope) -Given url scopes_url + '/53553532727272772' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 404 -And print response - -Scenario: Get an scopes by inum -Given url scopes_url -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -Given url scopes_url + '/' +response[0].inum -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 - diff --git a/jans-config-api/server/src/test/resources/feature/openid/scopes/scope.json b/jans-config-api/server/src/test/resources/feature/openid/scopes/scope.json deleted file mode 100644 index 6890116e051..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/scopes/scope.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "attributes": { - "notShowInDiscovery": false - }, - "defaultScope": false, - "description": "Kudia's basic information.", - "id": "kudia", - "jansClaim": [ - "inum=2B29,ou=attributes,o=gluu", - "inum=0C85,ou=attributes,o=gluu" - ], - "scopeType": "OPENID", - "umaType": false -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes-all.json b/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes-all.json deleted file mode 100644 index 777a31d7d45..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes-all.json +++ /dev/null @@ -1,809 +0,0 @@ -{ - "start": 0, - "totalEntriesCount": 79, - "entriesCount": 50, - "entries": [ - { - "dn": "inum=F0C4,ou=scopes,o=jans", - "inum": "F0C4", - "displayName": "authenticate_openid_connect", - "id": "openid", - "description": "Authenticate using OpenID Connect.", - "scopeType": "openid", - "defaultScope": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=F0C4,ou=scopes,o=jans" - }, - { - "dn": "inum=43F1,ou=scopes,o=jans", - "inum": "43F1", - "displayName": "view_profile", - "id": "profile", - "description": "View your basic profile info.", - "scopeType": "openid", - "claims": [ - "inum=2B29,ou=attributes,o=jans", - "inum=0C85,ou=attributes,o=jans", - "inum=B4B0,ou=attributes,o=jans", - "inum=A0E8,ou=attributes,o=jans", - "inum=5EC6,ou=attributes,o=jans", - "inum=B52A,ou=attributes,o=jans", - "inum=64A0,ou=attributes,o=jans", - "inum=EC3A,ou=attributes,o=jans", - "inum=3B47,ou=attributes,o=jans", - "inum=3692,ou=attributes,o=jans", - "inum=98FC,ou=attributes,o=jans", - "inum=A901,ou=attributes,o=jans", - "inum=36D9,ou=attributes,o=jans", - "inum=BE64,ou=attributes,o=jans", - "inum=6493,ou=attributes,o=jans", - "inum=4CF1,ou=attributes,o=jans", - "inum=29DA,ou=attributes,o=jans" - ], - "defaultScope": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=43F1,ou=scopes,o=jans" - }, - { - "dn": "inum=764C,ou=scopes,o=jans", - "inum": "764C", - "displayName": "view_email_address", - "id": "email", - "description": "View your email address.", - "scopeType": "openid", - "claims": [ - "inum=8F88,ou=attributes,o=jans", - "inum=CAE3,ou=attributes,o=jans" - ], - "defaultScope": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=764C,ou=scopes,o=jans" - }, - { - "dn": "inum=C17A,ou=scopes,o=jans", - "inum": "C17A", - "displayName": "view_address", - "id": "address", - "description": "View your address.", - "scopeType": "openid", - "claims": [ - "inum=27DB,ou=attributes,o=jans", - "inum=2A3D,ou=attributes,o=jans", - "inum=6609,ou=attributes,o=jans", - "inum=6EEB,ou=attributes,o=jans", - "inum=BCE8,ou=attributes,o=jans", - "inum=D90B,ou=attributes,o=jans", - "inum=E6B8,ou=attributes,o=jans", - "inum=E999,ou=attributes,o=jans" - ], - "defaultScope": true, - "groupClaims": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=C17A,ou=scopes,o=jans" - }, - { - "dn": "inum=D491,ou=scopes,o=jans", - "inum": "D491", - "displayName": "view_phone_number", - "id": "phone", - "description": "View your phone number.", - "scopeType": "openid", - "claims": [ - "inum=B17A,ou=attributes,o=jans", - "inum=0C18,ou=attributes,o=jans" - ], - "defaultScope": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=D491,ou=scopes,o=jans" - }, - { - "dn": "inum=341A,ou=scopes,o=jans", - "inum": "341A", - "displayName": "view_client", - "id": "clientinfo", - "description": "View the client info.", - "scopeType": "openid", - "claims": [ - "inum=2B29,ou=attributes,o=jans", - "inum=29DA,ou=attributes,o=jans", - "inum=18CF,ou=attributes,o=jans", - "inum=18CC,ou=attributes,o=jans", - "inum=18CD,ou=attributes,o=jans", - "inum=18CE,ou=attributes,o=jans" - ], - "defaultScope": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=341A,ou=scopes,o=jans" - }, - { - "dn": "inum=10B2,ou=scopes,o=jans", - "inum": "10B2", - "displayName": "view_username", - "id": "user_name", - "description": "View your local username in the Janssen Server.", - "scopeType": "openid", - "claims": [ - "inum=42E0,ou=attributes,o=jans" - ], - "defaultScope": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=10B2,ou=scopes,o=jans" - }, - { - "dn": "inum=6D99,ou=scopes,o=jans", - "inum": "6D99", - "displayName": "UMA Protection", - "id": "uma_protection", - "description": "Obtain UMA PAT.", - "scopeType": "openid", - "defaultScope": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=6D99,ou=scopes,o=jans" - }, - { - "dn": "inum=7D90,ou=scopes,o=jans", - "inum": "7D90", - "displayName": "revoke_session", - "id": "revoke_session", - "description": "revoke_session scope which is required to be able call /revoke_session endpoint", - "scopeType": "openid", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=7D90,ou=scopes,o=jans" - }, - { - "dn": "inum=8A01,ou=scopes,o=jans", - "inum": "8A01", - "displayName": "view_mobile_phone_number", - "id": "mobile_phone", - "description": "View your mobile phone number.", - "scopeType": "openid", - "claims": [ - "inum=6DA6,ou=attributes,o=jans" - ], - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=8A01,ou=scopes,o=jans" - }, - { - "dn": "inum=C4F5,ou=scopes,o=jans", - "inum": "C4F5", - "displayName": "view_user_permissions_roles", - "id": "permission", - "description": "View your user permission and roles.", - "scopeType": "dynamic", - "defaultScope": true, - "dynamicScopeScripts": [ - "inum=CB5B-3211,ou=scripts,o=jans" - ], - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=C4F5,ou=scopes,o=jans" - }, - { - "dn": "inum=C4F6,ou=scopes,o=jans", - "inum": "C4F6", - "displayName": "refresh_token", - "id": "offline_access", - "description": "This scope value requests that an OAuth 2.0 Refresh Token be issued.", - "scopeType": "openid", - "defaultScope": true, - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=C4F6,ou=scopes,o=jans" - }, - { - "dn": "inum=C4F7,ou=scopes,o=jans", - "inum": "C4F7", - "id": "jans_stat", - "description": "This scope is required for calling Statistic Endpoint", - "scopeType": "openid", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=C4F7,ou=scopes,o=jans" - }, - { - "dn": "inum=1200.487800,ou=scopes,o=jans", - "inum": "1200.487800", - "displayName": "Scim users.read", - "id": "https://jans.io/scim/users.read", - "description": "Query user resources", - "scopeType": "oauth", - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=1200.487800,ou=scopes,o=jans" - }, - { - "dn": "inum=1200.9CEE5C,ou=scopes,o=jans", - "inum": "1200.9CEE5C", - "displayName": "Scim users.write", - "id": "https://jans.io/scim/users.write", - "description": "Modify user resources", - "scopeType": "oauth", - "attributes": { - "showInConfigurationEndpoint": true - }, - "creationDate": "2022-10-27T20:51:17", - "umaType": false, - "baseDn": "inum=1200.9CEE5C,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.FFE5C0,ou=scopes,o=jans", - "inum": "1800.FFE5C0", - "displayName": "Config API scope https://jans.io/oauth/jans-auth-server/config/properties.readonly", - "id": "https://jans.io/oauth/jans-auth-server/config/properties.readonly", - "description": "View Auth Server properties related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.FFE5C0,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.472951,ou=scopes,o=jans", - "inum": "1800.472951", - "displayName": "Config API scope https://jans.io/oauth/jans-auth-server/config/properties.write", - "id": "https://jans.io/oauth/jans-auth-server/config/properties.write", - "description": "Manage Auth Server properties related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.472951,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.556F45,ou=scopes,o=jans", - "inum": "1800.556F45", - "displayName": "Config API scope https://jans.io/oauth/config/fido2.readonly", - "id": "https://jans.io/oauth/config/fido2.readonly", - "description": "View FIDO2 related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.556F45,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.77FB4F,ou=scopes,o=jans", - "inum": "1800.77FB4F", - "displayName": "Config API scope https://jans.io/oauth/config/fido2.write", - "id": "https://jans.io/oauth/config/fido2.write", - "description": "Manage FIDO2 related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.77FB4F,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.AA8DFE,ou=scopes,o=jans", - "inum": "1800.AA8DFE", - "displayName": "Config API scope https://jans.io/oauth/config/attributes.readonly", - "id": "https://jans.io/oauth/config/attributes.readonly", - "description": "View attribute related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.AA8DFE,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.CD5B72,ou=scopes,o=jans", - "inum": "1800.CD5B72", - "displayName": "Config API scope https://jans.io/oauth/config/attributes.write", - "id": "https://jans.io/oauth/config/attributes.write", - "description": "Manage attribute related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.CD5B72,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.CBCF52,ou=scopes,o=jans", - "inum": "1800.CBCF52", - "displayName": "Config API scope https://jans.io/oauth/config/attributes.delete", - "id": "https://jans.io/oauth/config/attributes.delete", - "description": "Delete attribute related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.CBCF52,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.12284F,ou=scopes,o=jans", - "inum": "1800.12284F", - "displayName": "Config API scope https://jans.io/oauth/config/acrs.readonly", - "id": "https://jans.io/oauth/config/acrs.readonly", - "description": "View ACRS related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.12284F,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.141B26,ou=scopes,o=jans", - "inum": "1800.141B26", - "displayName": "Config API scope https://jans.io/oauth/config/acrs.write", - "id": "https://jans.io/oauth/config/acrs.write", - "description": "Manage ACRS related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.141B26,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.A018AC,ou=scopes,o=jans", - "inum": "1800.A018AC", - "displayName": "Config API scope https://jans.io/oauth/config/database/ldap.readonly", - "id": "https://jans.io/oauth/config/database/ldap.readonly", - "description": "View LDAP database related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.A018AC,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.6E4456,ou=scopes,o=jans", - "inum": "1800.6E4456", - "displayName": "Config API scope https://jans.io/oauth/config/database/ldap.write", - "id": "https://jans.io/oauth/config/database/ldap.write", - "description": "Manage LDAP database related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.6E4456,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.55499D,ou=scopes,o=jans", - "inum": "1800.55499D", - "displayName": "Config API scope https://jans.io/oauth/config/database/ldap.delete", - "id": "https://jans.io/oauth/config/database/ldap.delete", - "description": "Delete LDAP database related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.55499D,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.E730AA,ou=scopes,o=jans", - "inum": "1800.E730AA", - "displayName": "Config API scope https://jans.io/oauth/config/scripts.readonly", - "id": "https://jans.io/oauth/config/scripts.readonly", - "description": "View cache scripts information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.E730AA,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.097318,ou=scopes,o=jans", - "inum": "1800.097318", - "displayName": "Config API scope https://jans.io/oauth/config/scripts.write", - "id": "https://jans.io/oauth/config/scripts.write", - "description": "Manage scripts related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.097318,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.04CF24,ou=scopes,o=jans", - "inum": "1800.04CF24", - "displayName": "Config API scope https://jans.io/oauth/config/scripts.delete", - "id": "https://jans.io/oauth/config/scripts.delete", - "description": "Delete scripts related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.04CF24,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.F963F9,ou=scopes,o=jans", - "inum": "1800.F963F9", - "displayName": "Config API scope https://jans.io/oauth/config/cache.readonly", - "id": "https://jans.io/oauth/config/cache.readonly", - "description": "View cache related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.F963F9,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.31F580,ou=scopes,o=jans", - "inum": "1800.31F580", - "displayName": "Config API scope https://jans.io/oauth/config/cache.write", - "id": "https://jans.io/oauth/config/cache.write", - "description": "Manage cache related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.31F580,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.E512E3,ou=scopes,o=jans", - "inum": "1800.E512E3", - "displayName": "Config API scope https://jans.io/oauth/config/smtp.readonly", - "id": "https://jans.io/oauth/config/smtp.readonly", - "description": "View SMTP related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.E512E3,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.E65DC6,ou=scopes,o=jans", - "inum": "1800.E65DC6", - "displayName": "Config API scope https://jans.io/oauth/config/smtp.write", - "id": "https://jans.io/oauth/config/smtp.write", - "description": "Manage SMTP related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.E65DC6,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.3C1F46,ou=scopes,o=jans", - "inum": "1800.3C1F46", - "displayName": "Config API scope https://jans.io/oauth/config/smtp.delete", - "id": "https://jans.io/oauth/config/smtp.delete", - "description": "Delete SMTP related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.3C1F46,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.20D48C,ou=scopes,o=jans", - "inum": "1800.20D48C", - "displayName": "Config API scope https://jans.io/oauth/config/logging.readonly", - "id": "https://jans.io/oauth/config/logging.readonly", - "description": "View logging related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.20D48C,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.4601AA,ou=scopes,o=jans", - "inum": "1800.4601AA", - "displayName": "Config API scope https://jans.io/oauth/config/logging.write", - "id": "https://jans.io/oauth/config/logging.write", - "description": "Manage logging related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.4601AA,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.A9B842,ou=scopes,o=jans", - "inum": "1800.A9B842", - "displayName": "Config API scope https://jans.io/oauth/config/jwks.readonly", - "id": "https://jans.io/oauth/config/jwks.readonly", - "description": "View JWKS related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.A9B842,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.864485,ou=scopes,o=jans", - "inum": "1800.864485", - "displayName": "Config API scope https://jans.io/oauth/config/jwks.write", - "id": "https://jans.io/oauth/config/jwks.write", - "description": "Manage JWKS related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.864485,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.F0B654,ou=scopes,o=jans", - "inum": "1800.F0B654", - "displayName": "Config API scope https://jans.io/oauth/config/jwks.delete", - "id": "https://jans.io/oauth/config/jwks.delete", - "description": "Delete JWKS related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.F0B654,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.45F1D7,ou=scopes,o=jans", - "inum": "1800.45F1D7", - "displayName": "Config API scope https://jans.io/oauth/config/openid/clients.readonly", - "id": "https://jans.io/oauth/config/openid/clients.readonly", - "description": "View clients related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.45F1D7,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.B78FA5,ou=scopes,o=jans", - "inum": "1800.B78FA5", - "displayName": "Config API scope https://jans.io/oauth/config/openid/clients.write", - "id": "https://jans.io/oauth/config/openid/clients.write", - "description": "Manage clients related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.B78FA5,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.E3D7E0,ou=scopes,o=jans", - "inum": "1800.E3D7E0", - "displayName": "Config API scope https://jans.io/oauth/config/openid/clients.delete", - "id": "https://jans.io/oauth/config/openid/clients.delete", - "description": "Delete clients related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.E3D7E0,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.E212DC,ou=scopes,o=jans", - "inum": "1800.E212DC", - "displayName": "Config API scope https://jans.io/oauth/config/scopes.readonly", - "id": "https://jans.io/oauth/config/scopes.readonly", - "description": "View scope related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.E212DC,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.94F80F,ou=scopes,o=jans", - "inum": "1800.94F80F", - "displayName": "Config API scope https://jans.io/oauth/config/scopes.write", - "id": "https://jans.io/oauth/config/scopes.write", - "description": "Manage scope related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.94F80F,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.9F96F3,ou=scopes,o=jans", - "inum": "1800.9F96F3", - "displayName": "Config API scope https://jans.io/oauth/config/scopes.delete", - "id": "https://jans.io/oauth/config/scopes.delete", - "description": "Delete scope related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.9F96F3,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.CB50EC,ou=scopes,o=jans", - "inum": "1800.CB50EC", - "displayName": "Config API scope https://jans.io/oauth/config/uma/resources.readonly", - "id": "https://jans.io/oauth/config/uma/resources.readonly", - "description": "View UMA Resource related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.CB50EC,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.1CA946,ou=scopes,o=jans", - "inum": "1800.1CA946", - "displayName": "Config API scope https://jans.io/oauth/config/uma/resources.write", - "id": "https://jans.io/oauth/config/uma/resources.write", - "description": "Manage UMA Resource related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:27", - "umaType": false, - "baseDn": "inum=1800.1CA946,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.18231E,ou=scopes,o=jans", - "inum": "1800.18231E", - "displayName": "Config API scope https://jans.io/oauth/config/uma/resources.delete", - "id": "https://jans.io/oauth/config/uma/resources.delete", - "description": "Delete UMA Resource related information", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:28", - "umaType": false, - "baseDn": "inum=1800.18231E,ou=scopes,o=jans" - }, - { - "dn": "inum=1800.C25D78,ou=scopes,o=jans", - "inum": "1800.C25D78", - "displayName": "Config API scope https://jans.io/oauth/config/stats.readonly", - "id": "https://jans.io/oauth/config/stats.readonly", - "description": "Vew server with basic statistic", - "scopeType": "oauth", - "defaultScope": false, - "attributes": { - "showInConfigurationEndpoint": false - }, - "creationDate": "2022-10-24T14:55:28", - "umaType": false, - "baseDn": "inum=1800.C25D78,ou=scopes,o=jans" - } - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes.feature b/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes.feature deleted file mode 100644 index cc93861fea4..00000000000 --- a/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes.feature +++ /dev/null @@ -1,132 +0,0 @@ - -Feature: Openid connect Scopes - -Background: -* def mainUrl = scopes_url - -Scenario: Fetch all openid connect scopes without bearer token -Given url mainUrl -When method GET -Then status 401 - - -Scenario: Fetch all scopes -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response -And assert response.length != null - - -Scenario: Fetch all openid connect scopes -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param type = 'openid' -When method GET -Then status 200 -And print response -And assert response.length != null - - -Scenario: Fetch the first three openidconnect scopes -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param type = 'openid' -And param limit = 3 -When method GET -Then status 200 -And print response -#And assert response.length == 3 - - -Scenario: Search openid connect scopes given a serach pattern -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param type = 'openid' -And param pattern = 'openid' -When method GET -Then status 200 -And print response -#And assert response.length == 1 - -Scenario: Fetch scopes based on creator -Given url mainUrl + '/creator/abc' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response - -Scenario: Fetch scopes based on type -Given url mainUrl + '/type/uma' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response - - -@CreateUpdateDelete -Scenario: Create new OpenId Connect Scope -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request read('scope.json') -When method POST -Then status 201 -And print response -Then def result = response -Then set result.displayName = 'UpdatedQAAddedScope' -Then def inum_before = result.inum -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request result -When method PUT -Then status 200 -And print response -And assert response.displayName == 'UpdatedQAAddedScope' -And assert response.inum == inum_before -Given url mainUrl + '/' +response.inum -And header Authorization = 'Bearer ' + accessToken -And header Content-Type = 'application/json-patch+json' -And header Accept = 'application/json' -And def newDisplayName = response.displayName -And print " newDisplayName = "+newDisplayName -And request "[ {\"op\":\"replace\", \"path\": \"/displayName\", \"value\":\""+newDisplayName+"\"} ]" -When method PATCH -Then status 200 -And print response -And assert response.length !=0 -Given url mainUrl + '/' +response.inum -And header Authorization = 'Bearer ' + accessToken -When method DELETE -Then status 204 - - -Scenario: Delete a non-existing openid connect scope by inum -Given url mainUrl + '/1402.66633-8675-473e-a749' -And header Authorization = 'Bearer ' + accessToken -And param type = 'openid' -When method GET -Then status 404 -And print response - - -Scenario: Get an openid connect scope by inum(unexisting scope) -Given url mainUrl + '/53553532727272772' -And header Authorization = 'Bearer ' + accessToken -And param type = 'openid' -When method GET -Then status 404 -And print response - - -Scenario: Get an openid connect scopes by inum -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response -Given url mainUrl + '/' +response.entries[0].inum -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response diff --git a/jans-config-api/server/src/test/resources/feature/plugins/plugin-all.json b/jans-config-api/server/src/test/resources/feature/plugins/plugin-all.json deleted file mode 100644 index d2055ab6f4b..00000000000 --- a/jans-config-api/server/src/test/resources/feature/plugins/plugin-all.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "fido2", - "description": "fido2 plugin" - }, - { - "name": "scim", - "description": "scim plugin" - }, - { - "name": "user-management", - "description": "user-management plugin" - } -] \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/plugins/plugin.feature b/jans-config-api/server/src/test/resources/feature/plugins/plugin.feature deleted file mode 100644 index 42d9c06ec02..00000000000 --- a/jans-config-api/server/src/test/resources/feature/plugins/plugin.feature +++ /dev/null @@ -1,30 +0,0 @@ - -Feature: Plugins - -Background: -* def mainUrl = plugin_url - -Scenario: Fetch all plugin without bearer token -Given url mainUrl -When method GET -Then status 401 - - -Scenario: Fetch all plugin_url -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response -And assert response.length != null - - -Scenario: Fetch plugin based on name -Given url mainUrl + '/fido2' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response - - - diff --git a/jans-config-api/server/src/test/resources/feature/session/session.feature b/jans-config-api/server/src/test/resources/feature/session/session.feature deleted file mode 100644 index 12b7e4bfaa0..00000000000 --- a/jans-config-api/server/src/test/resources/feature/session/session.feature +++ /dev/null @@ -1,52 +0,0 @@ - -Feature: Session flow - -Background: -* def mainUrl = session_url - -Scenario: Fetch all session - Given url mainUrl - When method GET - Then status 401 - And print response - -@ignore -Scenario: Fetch all session - Given url mainUrl - And print 'accessToken = '+accessToken - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - -@ignore -Scenario: Fetch all session -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -Given url mainUrl + '/search' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response - - -@ignore -Scenario: Revoke user session - Given url mainUrl - And print 'accessToken = '+accessToken - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - Then def result = response[0] - And print result - And def userDn = result.userDn - Given url mainUrl + '/' +userDn - And header Authorization = 'Bearer ' + accessToken - And request {} - When method POST - Then status 200 - And print response - diff --git a/jans-config-api/server/src/test/resources/feature/smtp/smtp.feature b/jans-config-api/server/src/test/resources/feature/smtp/smtp.feature deleted file mode 100644 index 477d5ad7478..00000000000 --- a/jans-config-api/server/src/test/resources/feature/smtp/smtp.feature +++ /dev/null @@ -1,54 +0,0 @@ - -Feature: Configure SMTP server - - Background: - * def mainUrl = smtp_url - - @get-smtp-config - Scenario: Get SMTP server details - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And assert response.length != null - - - @CreateGetUpdateDelete - Scenario: Setup SMTP configuration - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And def smtpConf = (response.length != null ? response : read('smtp.json')) - And print smtpConf - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request smtpConf - When method POST - Then status 201 - And print response - Then def result = response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - And print response - - @ignore - @test-smtp-config - Scenario: Get SMTP server details - Given url mainUrl +'/test' - And header Authorization = 'Bearer ' + accessToken - And request read('smtp.json') - When method POST - Then status 200 - And print response - And assert response.length != null diff --git a/jans-config-api/server/src/test/resources/feature/smtp/smtp.json b/jans-config-api/server/src/test/resources/feature/smtp/smtp.json deleted file mode 100644 index 2977149bb78..00000000000 --- a/jans-config-api/server/src/test/resources/feature/smtp/smtp.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fromEmailAddress": "test@gmail.com", - "fromName": "QA-TESTER", - "host": "smtp.gmail.com", - "password": "password", - "port": 587, - "requiresAuthentication": true, - "requiresSsl": true, - "serverTrust": true, - "userName": "test@gmail.com", - "valid": true -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/stat/stat.feature b/jans-config-api/server/src/test/resources/feature/stat/stat.feature deleted file mode 100644 index ccbeaeba473..00000000000 --- a/jans-config-api/server/src/test/resources/feature/stat/stat.feature +++ /dev/null @@ -1,24 +0,0 @@ -@ignore - -Feature: Statistics - -Background: -* def mainUrl = statUrl - -Scenario: Fetch all statistics without bearer token - Given url mainUrl - And param month = '202107' - When method GET - Then status 401 - -Scenario: Fetch user statistics - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And param month = '202107' - #And param format = 'openmetrics' - When method GET - Then status 200 - And print response - - - diff --git a/jans-config-api/server/src/test/resources/feature/token/client-token.feature b/jans-config-api/server/src/test/resources/feature/token/client-token.feature deleted file mode 100644 index edb945da958..00000000000 --- a/jans-config-api/server/src/test/resources/feature/token/client-token.feature +++ /dev/null @@ -1,27 +0,0 @@ - -Feature: Token flow - -Background: -* def mainUrl = token_url - - -Scenario: Fetch all client token -Given url mainUrl -When method GET -Then status 401 -And print response - -@ignore -Scenario: Fetch all token -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -Given url mainUrl + '/search' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response - - - diff --git a/jans-config-api/server/src/test/resources/feature/uma/resource/resources.feature b/jans-config-api/server/src/test/resources/feature/uma/resource/resources.feature deleted file mode 100644 index 183feb743cd..00000000000 --- a/jans-config-api/server/src/test/resources/feature/uma/resource/resources.feature +++ /dev/null @@ -1,107 +0,0 @@ - -Feature: Uma Resource - - Background: - * def mainUrl = umaresources_url - -Scenario: Fetch all uma resources without bearer token -Given url mainUrl -When method GET -Then status 401 - - -Scenario: Fetch all uma resources -Given url mainUrl -And print accessToken -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response -#And assert response.length != null - - -Scenario: Fetch the first two uma resources -Given url mainUrl -And print accessToken -And header Authorization = 'Bearer ' + accessToken -And param limit = 2 -When method GET -Then status 200 -Then print response -#And assert response.length == 2 - - -Scenario: Search uma resources given a search pattern -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param pattern = 'Passport Resource' -When method GET -Then status 200 -#And assert response.length == 1 - - -@CreateUpdateDelete -Scenario: Create new Uma Resource -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request read('uma-resource.json') -When method POST -Then status 201 -And print response -Then def result = response -Then set result.name = 'UpdatedQAAddedResource' -Then def id_before = result.id -Given url mainUrl + '/' +response.id -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -And print response -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request result -When method PUT -Then status 200 -And print response -And assert response.name == 'UpdatedQAAddedResource' -And assert response.id == id_before -Given url mainUrl + '/' +response.id -And header Authorization = 'Bearer ' + accessToken -And header Content-Type = 'application/json-patch+json' -And header Accept = 'application/json' -And def newName = response.name -And print " newName = "+newName -And request "[ {\"op\":\"replace\", \"path\": \"/description\", \"value\":\""+newName+"\"} ]" -When method PATCH -Then status 200 -And print response -And assert response.length !=0 -Given url mainUrl + '/' +response.id -And header Authorization = 'Bearer ' + accessToken -When method DELETE -Then status 204 - - -Scenario: Delete a non-existion uma resource by id -Given url mainUrl + '/1402.66633-8675-473e-a749' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 404 - - -Scenario: Get an uma resource by id(unexisting resource) -Given url mainUrl + '/53553532727272772' -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 404 - - -@ignore -Scenario: Get an uma resource by id -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 -Given url mainUrl + '/' +response[0].id -And header Authorization = 'Bearer ' + accessToken -When method GET -Then status 200 diff --git a/jans-config-api/server/src/test/resources/feature/uma/resource/uma-resource.json b/jans-config-api/server/src/test/resources/feature/uma/resource/uma-resource.json deleted file mode 100644 index 39a5a98bb35..00000000000 --- a/jans-config-api/server/src/test/resources/feature/uma/resource/uma-resource.json +++ /dev/null @@ -1,16 +0,0 @@ - { - "clients": [ - ], - "deletable": false, - "expired": false, - "iconUri": "http://www.qa.org/qa_logo.png", - "name": "QAAddedResource", - "description": "QAAdded Resource", - "resources": [ - "https://gluu.gasmyr.com/identity/restv1/passport/config" - ], - "rev": "0", - "scopes": [ - "inum=8CAD-B06E,ou=scopes,o=gluu" - ] -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/uma/scopes/uma-scope.json b/jans-config-api/server/src/test/resources/feature/uma/scopes/uma-scope.json deleted file mode 100644 index c3baf346f20..00000000000 --- a/jans-config-api/server/src/test/resources/feature/uma/scopes/uma-scope.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "attributes": { - "notShowInDiscovery": true - }, - "displayName": "QAAddedUmaScope", - "id": "https://gluu.qa.com/jans-auth/restv1/uma/scopes/qa-scope", - "scopeType": "UMA", - "umaAuthorizationPolicies": [], - "umaType": true -} \ No newline at end of file diff --git a/jans-config-api/server/src/test/resources/feature/uma/scopes/umascopes.feature b/jans-config-api/server/src/test/resources/feature/uma/scopes/umascopes.feature deleted file mode 100644 index 5abf737aa07..00000000000 --- a/jans-config-api/server/src/test/resources/feature/uma/scopes/umascopes.feature +++ /dev/null @@ -1,118 +0,0 @@ - -Feature: Uma Scopes - -Background: -* def mainUrl = scopes_url - - -Scenario: Fetch all uma scopes without bearer token -Given url mainUrl -When method GET -Then status 401 - - -Scenario: Fetch all uma scopes -Given url mainUrl -And print accessToken -And header Authorization = 'Bearer ' + accessToken -And param type = 'uma' -When method GET -Then status 200 -And print response -And assert response.length != null - - -Scenario: Fetch the first three uma scopes -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param type = 'uma' -And param limit = 3 -When method GET -Then status 200 -And print response -#And assert response.length <= 3 - - -Scenario: Search uma scopes given a search pattern -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param type = 'uma' -And param pattern = 'SCIM Access' -When method GET -Then status 200 -And print response -#And assert response.length == 1 - - -@CreateUpdateDelete -Scenario: Create new Uma Scope -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request read('uma-scope.json') -When method POST -Then status 201 -And print response -Then def result = response -Then set result.displayName = 'UpdatedQAAddedUmaScope' -Then def inum_before = result.inum -Given url mainUrl + '/' +result.inum -And header Authorization = 'Bearer ' + accessToken -And param type = 'uma' -When method GET -Then status 200 -And print response -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And request result -When method PUT -Then status 200 -And print response -And assert response.displayName == 'UpdatedQAAddedUmaScope' -And assert response.inum == inum_before -Given url mainUrl + '/' +response.inum -And header Authorization = 'Bearer ' + accessToken -And header Content-Type = 'application/json-patch+json' -And header Accept = 'application/json' -And def newDisplayName = response.displayName -And print " newDisplayName = "+newDisplayName -And request "[ {\"op\":\"replace\", \"path\": \"/displayName\", \"value\":\""+newDisplayName+"\"} ]" -When method PATCH -Then status 200 -And print response -And assert response.length !=0 -Given url mainUrl + '/' +response.inum -And header Authorization = 'Bearer ' + accessToken -When method DELETE -Then status 204 - - -Scenario: Delete a non-existion uma scope by inum -Given url mainUrl + '/1402.66633-8675-473e-a749' -And header Authorization = 'Bearer ' + accessToken -And param type = 'uma' -When method GET -Then status 404 - - -Scenario: Get an uma scope by inum(unexisting scope) -Given url mainUrl + '/53553532727272772' -And header Authorization = 'Bearer ' + accessToken -And param type = 'uma' -When method GET -Then status 404 -And print response - - -@ignore -Scenario: Get an uma scope by inum -Given url mainUrl -And header Authorization = 'Bearer ' + accessToken -And param type = 'uma' -When method GET -Then status 200 -Given url mainUrl + '/' +response[0].inum -And header Authorization = 'Bearer ' + accessToken -And param type = 'uma' -When method GET -Then status 200 - diff --git a/jans-config-api/server/src/test/resources/karate-config.js b/jans-config-api/server/src/test/resources/karate-config.js deleted file mode 100644 index b11ca003aa2..00000000000 --- a/jans-config-api/server/src/test/resources/karate-config.js +++ /dev/null @@ -1,82 +0,0 @@ -function() { - - var stream = read('classpath:karate.properties'); - var props = new java.util.Properties(); - props.load(stream); - - var env = props.get('karate.env'); // get java system property 'karate.env' - karate.configure("ssl", true); - - if (!env) { - env = 'dev'; //env can be anything: dev, qa, staging, etc. - } - - var url = props.get('karate.test.url'); - var port = props.get('karate.test.port'); - var baseUrl = url + (port ? ':' + port : ''); - - karate.log('karate env :', env); - karate.log('karate url :', url); - karate.log('karate port :', port); - karate.log('karate baseUrl :', baseUrl); - - var testStream = read('classpath:test.properties'); - var testProps = new java.util.Properties(); - testProps.load(testStream); - karate.log(' testProps = '+testProps); - var testClientId = testProps.get('test.client.id'); - var testClientSecret = testProps.get('test.client.secret'); - var tokenEndpoint = testProps.get('token.endpoint'); - var testScopes = testProps.get('test.scopes'); - var issuer = testProps.get('test.issuer'); - karate.log(' testClientId = '+testClientId); - karate.log(' testClientSecret = '+testClientSecret); - karate.log(' tokenEndpoint = '+tokenEndpoint); - karate.log(' testScopes = '+testScopes); - karate.log(' issuer = '+issuer); - - - var config = { - env: env, - baseUrl: baseUrl, - testProps: testProps, - issuer: issuer, - accessToken: '123', - - statUrl: baseUrl + '/jans-config-api/api/v1/stat', - healthUrl: baseUrl + '/jans-config-api/api/v1/health', - acrsUrl: baseUrl + '/jans-config-api/api/v1/acrs', - authConfigurationUrl: baseUrl + '/jans-config-api/api/v1/jans-auth-server/config', - scriptsUrl: baseUrl + '/jans-config-api/api/v1/config/scripts', - cacheUrl: baseUrl + '/jans-config-api/api/v1/config/cache', - messageUrl: baseUrl + '/jans-config-api/api/v1/config/message', - jwksUrl: baseUrl + '/jans-config-api/api/v1/config/jwks', - ldapUrl: baseUrl + '/jans-config-api/api/v1/config/database/ldap', - openidclients_url: baseUrl + '/jans-config-api/api/v1/openid/clients', - scopes_url: baseUrl + '/jans-config-api/api/v1/scopes', - umaresources_url: baseUrl + '/jans-config-api/api/v1/uma/resources', - attributes_url: baseUrl + '/jans-config-api/api/v1/attributes', - smtp_url: baseUrl + '/jans-config-api/api/v1/config/smtp', - logging_url: baseUrl + '/jans-config-api/api/v1/logging', - auth_health_url: baseUrl + '/jans-config-api/api/v1/jans-auth-server/health', - org_configuration_url: baseUrl + '/jans-config-api/api/v1/org', - user_url: baseUrl + '/jans-config-api/api/v1/user', - agama_url: baseUrl + '/jans-config-api/api/v1/agama', - session_url: baseUrl + '/jans-config-api/api/v1/jans-auth-server/session', - plugin_url: baseUrl + '/jans-config-api/api/v1/plugin', - api_config_url: baseUrl + '/jans-config-api/api/v1/api-config', - agama_deployment_url: baseUrl + '/jans-config-api/api/v1/agama-deployment', - clients_authorizations_url: baseUrl + '/jans-config-api/api/v1/clients/authorizations', - token_url: baseUrl + '/jans-config-api/api/v1/token', - - }; - - karate.configure('connectTimeout', 30000); - karate.configure('readTimeout', 60000); - - var result = karate.callSingle('classpath:token.feature', config); - print(' result.response = '+result.response); - config.accessToken = result.response.access_token; - - return config; -} \ No newline at end of file From 56641cc9c8885e62d1e80d12939263ec48ed36bf Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 13 Dec 2024 20:54:09 +0530 Subject: [PATCH 38/44] feat(config-api): testNG framework changes Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 14 +-- .../ca/plugin/adminui/AdminUIBaseTest.java | 87 --------------- .../test/AuditLoggingResourceTest.java | 16 +-- .../adminui/test/LicenseResourceTest.java | 17 +-- .../adminui/test/OAuth2ResourceTest.java | 19 +--- .../test/JansKcLinkConfigResourceTest.java | 18 +-- .../configapi/test/JansIdpResourceTest.java | 30 ++--- .../test/JansKcSAMLConfigResourceTest.java | 24 ++-- .../test/JansKcSAMLTrustRelationshipTest.java | 27 ++--- .../configapi/test/LockAuditResourceTest.java | 45 ++++---- .../test/LockConfigResourceTest.java | 31 +++--- .../test/ScimConfigResourceTest.java | 10 +- .../jans/configapi/test/UserResourceTest.java | 9 +- .../configapi/test/auth/AcrsResourceTest.java | 17 +-- .../auth/AgamaDeploymentsResourceTest.java | 8 +- .../test/auth/AuthConfigResourceTest.java | 16 +-- .../test/auth/ClientResourceTest.java | 15 +-- .../test/auth/ConfigResourceTest.java | 24 +--- .../configapi/test/health/ApiHealthTest.java | 17 ++- .../io/jans/configapi/core/test/BaseTest.java | 104 ++---------------- .../test/listener/AlterSuiteListener.java | 25 ++--- .../core/test/listener/PersistenceType.java | 1 - .../core/test/listener/SkipTest.java | 1 - .../core/test/listener/SkipTestsListener.java | 3 - 24 files changed, 162 insertions(+), 416 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 1333a299fde..1731e8c09f5 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9303,20 +9303,20 @@ components: type: string selected: type: boolean - userCanEdit: + whitePagesCanView: type: boolean - userCanView: + adminCanEdit: type: boolean adminCanView: type: boolean - adminCanEdit: + userCanEdit: + type: boolean + userCanView: type: boolean adminCanAccess: type: boolean userCanAccess: type: boolean - whitePagesCanView: - type: boolean baseDn: type: string PatchRequest: @@ -10177,6 +10177,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10186,8 +10188,6 @@ components: - code - token - id_token - fapi: - type: boolean AuthenticationFilter: required: - baseDn diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java index 22b1c494fe9..b6542599213 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -6,97 +6,10 @@ package io.jans.ca.plugin.adminui; -import io.jans.as.client.TokenRequest; -import io.jans.as.client.TokenResponse; import io.jans.as.model.common.GrantType; -import io.jans.as.model.util.Util; -import io.jans.configapi.core.util.Jackson; import io.jans.configapi.core.test.BaseTest; - -import static java.nio.charset.StandardCharsets.UTF_8; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; - -import java.util.Hashtable; -import java.util.Map; -import java.util.Properties; -import java.net.URLEncoder; -import java.io.UnsupportedEncodingException; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.net.URLDecoder; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.*; -import java.util.Map.Entry; - -import jakarta.servlet.http.HttpServletRequest; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang3.StringUtils; - -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CookieStore; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.routing.HttpRoutePlanner; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.entity.ContentType; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.conn.ssl.TrustStrategy; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.client.LaxRedirectStrategy; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.http.ssl.SSLContexts; - -import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; -import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; - -import org.json.JSONObject; -import org.json.JSONException; -import org.testng.ITestContext; -import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeSuite; -import org.testng.annotations.BeforeTest; - -import jakarta.annotation.PostConstruct; -import jakarta.ws.rs.core.UriBuilder; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.client.Invocation.Builder; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; public class AdminUIBaseTest extends BaseTest{ diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java index 259a950bddb..4f90f1b73c6 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java @@ -6,21 +6,14 @@ package io.jans.ca.plugin.adminui.test; -import io.jans.as.common.model.registration.Client; -import static io.restassured.RestAssured.given; import io.jans.ca.plugin.adminui.AdminUIBaseTest; -import io.jans.model.net.HttpServiceResponse; + import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; - -import java.util.Map; -import org.apache.http.entity.ContentType; -import static org.testng.Assert.*; import org.testng.annotations.Parameters; import org.testng.annotations.Test; @@ -33,15 +26,14 @@ public class AuditLoggingResourceTest extends AdminUIBaseTest{ @Parameters({"test.issuer", "auditLoggingURL", "audit_post_1"}) @Test public void postAuditLoggingData(final String issuer, final String auditLoggingURL, final String json) { - log.error("postAuditLoggingData() - accessToken:{}, issuer:{}, auditLoggingURL:{}, json:{}", accessToken, issuer, auditLoggingURL, json); + log.info("postAuditLoggingData() - accessToken:{}, issuer:{}, auditLoggingURL:{}, json:{}", accessToken, issuer, auditLoggingURL, json); Builder request = getResteasyService().getClientBuilder(issuer+auditLoggingURL); //request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); - request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - + request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); // assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("\n\n Response for postAuditLoggingData - response:{}", response); + log.info("\n\n Response for postAuditLoggingData - response:{}", response); } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java index 5d4a12362ea..1b77c7dc705 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java @@ -6,24 +6,15 @@ package io.jans.ca.plugin.adminui.test; -import io.jans.as.common.model.registration.Client; -import static io.restassured.RestAssured.given; import io.jans.ca.plugin.adminui.AdminUIBaseTest; -import io.jans.model.net.HttpServiceResponse; -import jakarta.ws.rs.client.Entity; + import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; -import java.util.Map; - -import org.apache.http.entity.ContentType; import org.testng.annotations.Parameters; import org.testng.annotations.Test; -import static org.testng.Assert.*; - -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; public class LicenseResourceTest extends AdminUIBaseTest { @@ -33,7 +24,7 @@ public class LicenseResourceTest extends AdminUIBaseTest { @Parameters({ "test.issuer", "checkActiveLicenseURL" }) @Test public void getLicenseDetails(final String issuer, final String checkActiveLicenseURL) { - log.error("getLicenseDetails() - accessToken:{}, issuer:{}, checkActiveLicenseURL:{}", accessToken, issuer, + log.info("getLicenseDetails() - accessToken:{}, issuer:{}, checkActiveLicenseURL:{}", accessToken, issuer, checkActiveLicenseURL); Builder request = getResteasyService().getClientBuilder(issuer + checkActiveLicenseURL); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -41,7 +32,7 @@ public void getLicenseDetails(final String issuer, final String checkActiveLicen Response response = request.get(); //assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("\n\n Response for getLicenseDetails - response:{}", response); + log.info("\n\n Response for getLicenseDetails - response:{}", response); } } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java index 4bb2f7c2b04..eb6ae3f7fb3 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/OAuth2ResourceTest.java @@ -6,21 +6,14 @@ package io.jans.ca.plugin.adminui.test; -import io.jans.as.common.model.registration.Client; -import static io.restassured.RestAssured.given; + import io.jans.ca.plugin.adminui.AdminUIBaseTest; -import io.jans.model.net.HttpServiceResponse; -import java.util.Map; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; -import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.MediaType; -import org.apache.http.entity.ContentType; -import static org.testng.Assert.*; import org.testng.annotations.Parameters; import org.testng.annotations.Test; @@ -33,13 +26,13 @@ public class OAuth2ResourceTest extends AdminUIBaseTest{ @Parameters({"test.issuer", "adminUIConfigURL"}) @Test public void getOAuth2Data(final String issuer, final String adminUIConfigURL) { - log.error("getOAuth2Data() - accessToken:{}, issuer:{}, adminUIConfigURL:{}", accessToken, issuer, adminUIConfigURL); + log.info("getOAuth2Data() - accessToken:{}, issuer:{}, adminUIConfigURL:{}", accessToken, issuer, adminUIConfigURL); Builder request = getResteasyService().getClientBuilder(issuer+adminUIConfigURL); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); - log.error("Response for getOAuth2Data() - response:{}", response); + log.info("Response for getOAuth2Data() - response:{}", response); } @@ -49,13 +42,13 @@ public void getOAuth2Data(final String issuer, final String adminUIConfigURL) { @Parameters({"test.issuer", "apiProtectionTokenURL", "ujwt"}) @Test public void getApiProtectionTokenData(final String issuer, final String apiProtectionTokenURL, final String ujwt) { - log.error("\n\n getApiProtectionTokenData() - accessToken:{}, issuer:{}, apiProtectionTokenURL:{}, ujwt:{}", accessToken, issuer, apiProtectionTokenURL, ujwt); + log.info("\n\n getApiProtectionTokenData() - accessToken:{}, issuer:{}, apiProtectionTokenURL:{}, ujwt:{}", accessToken, issuer, apiProtectionTokenURL, ujwt); Builder request = getResteasyService().getClientBuilder(issuer+apiProtectionTokenURL); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); request.property("ujwt", ujwt); Response response = request.get(); - log.error("\n\n Response for getApiProtectionTokenData() - response:{}", response); + log.info("\n\n Response for getApiProtectionTokenData() - response:{}", response); } diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java index d4f1928135d..a3599ee2fd4 100644 --- a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java +++ b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/test/JansKcLinkConfigResourceTest.java @@ -12,12 +12,10 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import org.testng.annotations.Test; - -import static org.testng.Assert.assertEquals; - import java.lang.reflect.Method; +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; import org.testng.SkipException; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; @@ -28,27 +26,23 @@ public class JansKcLinkConfigResourceTest extends BaseTest { @BeforeMethod public void before(Method methodName){ boolean isServiceDeployed = isServiceDeployed("io.jans.configapi.plugin.kc.link.rest.ApiApplication"); - log.error("\n\n\n *** JansKcLinkConfigResourceTest - isServiceDeployed:{}",isServiceDeployed); + log.info("\n\n\n *** JansKcLinkConfigResourceTest - isServiceDeployed:{}",isServiceDeployed); // check condition, note once you condition is met the rest of the tests will be skipped as well if(!isServiceDeployed) { throw new SkipException("KC-LINK Plugin not deployed"); - } - + } } @Parameters({"issuer", "kcLinkConfigUrl"}) @Test public void getKcLinkConfiguration(final String issuer, final String kcLinkConfigUrl) { - log.error("getKcLinkConfiguration() - accessToken:{}, issuer:{}, kcLinkConfigUrl:{}", accessToken, issuer, kcLinkConfigUrl); + log.info("getKcLinkConfiguration() - accessToken:{}, issuer:{}, kcLinkConfigUrl:{}", accessToken, issuer, kcLinkConfigUrl); Builder request = getResteasyService().getClientBuilder(issuer + kcLinkConfigUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getKcLinkConfiguration - response:{}", response); + log.info("Response for getKcLinkConfiguration - response:{}", response); } - - } diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java index ed1154f8f2c..6bf4b9ad08e 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansIdpResourceTest.java @@ -7,49 +7,43 @@ package io.jans.configapi.test; import io.jans.configapi.core.test.BaseTest; -import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; +import java.lang.reflect.Method; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; - -import java.lang.reflect.Method; - import org.testng.SkipException; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; public class JansIdpResourceTest extends BaseTest { - // Execute before each test is run @BeforeMethod - public void before(Method methodName){ + public void before(Method methodName) { boolean isServiceDeployed = isServiceDeployed("io.jans.configapi.plugin.saml.rest.ApiApplication"); - log.error("\n\n\n *** JansIdpResourceTest - isServiceDeployed:{}",isServiceDeployed); - // check condition, note once you condition is met the rest of the tests will be skipped as well - if(!isServiceDeployed) { + log.info("\n\n\n *** JansIdpResourceTest - isServiceDeployed:{}", isServiceDeployed); + // check condition, note once you condition is met the rest of the tests will be + // skipped as well + if (!isServiceDeployed) { throw new SkipException("KC-SAML Plugin not deployed"); } - - } - - @Parameters({"issuer", "samlIdpUrl"}) + } + + @Parameters({ "issuer", "samlIdpUrl" }) @Test public void getKcSAMLIdp(final String issuer, final String samlIdpUrl) { - log.error("getKcSAMLIdp() - accessToken:{}, issuer:{}, samlIdpUrl:{}", accessToken, issuer, samlIdpUrl); + log.info("getKcSAMLIdp() - accessToken:{}, issuer:{}, samlIdpUrl:{}", accessToken, issuer, samlIdpUrl); Builder request = getResteasyService().getClientBuilder(issuer + samlIdpUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); - - //assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getKcSAMLIdp - response:{}", response); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.info("Response for getKcSAMLIdp - response:{}", response); } - } diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java index 9bec6ae628c..72480c7b952 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLConfigResourceTest.java @@ -8,7 +8,6 @@ import java.lang.reflect.Method; import io.jans.configapi.core.test.BaseTest; -import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @@ -25,25 +24,24 @@ public class JansKcSAMLConfigResourceTest extends BaseTest { // Execute before each test is run @BeforeMethod - public void before(Method methodName){ - // check condition, note once you condition is met the rest of the tests will be skipped as well - if(!isServiceDeployed("io.jans.configapi.plugin.saml.rest.ApiApplication")) + public void before(Method methodName) { + // check condition, note once you condition is met the rest of the tests will be + // skipped as well + if (!isServiceDeployed("io.jans.configapi.plugin.saml.rest.ApiApplication")) throw new SkipException("KC-SAML Plugin not deployed"); - } - - @Parameters({"issuer", "samlConfigUrl"}) + } + + @Parameters({ "issuer", "samlConfigUrl" }) @Test public void getKcSAMLConfiguration(final String issuer, final String samlConfigUrl) { - log.error("getKcSAMLConfiguration() - accessToken:{}, issuer:{}, samlConfigUrl:{}", accessToken, issuer, samlConfigUrl); + log.info("getKcSAMLConfiguration() - accessToken:{}, issuer:{}, samlConfigUrl:{}", accessToken, issuer, + samlConfigUrl); Builder request = getResteasyService().getClientBuilder(issuer + samlConfigUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - Response response = request.get(); - //assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getKcSAMLConfiguration - response:{}", response); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.info("Response for getKcSAMLConfiguration - response:{}", response); } - - } diff --git a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java index 65a706706da..607b37e8bab 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/test/java/io/jans/configapi/test/JansKcSAMLTrustRelationshipTest.java @@ -12,10 +12,8 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import org.testng.annotations.Test; - import static org.testng.Assert.assertEquals; - +import org.testng.annotations.Test; import java.lang.reflect.Method; import org.testng.SkipException; @@ -26,25 +24,24 @@ public class JansKcSAMLTrustRelationshipTest extends BaseTest { // Execute before each test is run @BeforeMethod - public void before(Method methodName){ - // check condition, note once you condition is met the rest of the tests will be skipped as well - if(!isServiceDeployed("io.jans.configapi.plugin.saml.rest.ApiApplication")) + public void before(Method methodName) { + // check condition, note once you condition is met the rest of the tests will be + // skipped as well + if (!isServiceDeployed("io.jans.configapi.plugin.saml.rest.ApiApplication")) throw new SkipException("KC-SAML Plugin not deployed"); - } - - @Parameters({"issuer", "samlTrustRelationshipUrl"}) + } + + @Parameters({ "issuer", "samlTrustRelationshipUrl" }) @Test public void getKcSAMLTrustRelationship(final String issuer, final String samlTrustRelationshipUrl) { - log.error("getKcSAMLTrustRelationship() - accessToken:{}, issuer:{}, samlTrustRelationshipUrl:{}", accessToken, issuer, samlTrustRelationshipUrl); + log.info("getKcSAMLTrustRelationship() - accessToken:{}, issuer:{}, samlTrustRelationshipUrl:{}", accessToken, + issuer, samlTrustRelationshipUrl); Builder request = getResteasyService().getClientBuilder(issuer + samlTrustRelationshipUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - Response response = request.get(); - // assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getKcSAMLTrustRelationship - response:{}", response); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); + log.info("Response for getKcSAMLTrustRelationship - response:{}", response); } - - } diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java index 3982dc2a64f..cb5960dad89 100644 --- a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java +++ b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockAuditResourceTest.java @@ -13,58 +13,57 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import org.testng.annotations.Test; +import java.lang.reflect.Method; import static org.testng.Assert.assertEquals; - -import java.lang.reflect.Method; +import org.testng.annotations.Test; import org.testng.SkipException; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; -public class LockAuditResourceTest extends BaseTest{ - +public class LockAuditResourceTest extends BaseTest { + // Execute before each test is run @BeforeMethod - public void before(Method methodName){ + public void before(Method methodName) { boolean isServiceDeployed = isServiceDeployed("io.jans.configapi.plugin.lock.rest.ApiApplication"); - log.error("\n\n\n *** LockAuditResourceTest - isServiceDeployed:{}",isServiceDeployed); - // check condition, note once you condition is met the rest of the tests will be skipped as well - if(!isServiceDeployed) { + log.info("\n\n\n *** LockAuditResourceTest - isServiceDeployed:{}", isServiceDeployed); + // check condition, note once you condition is met the rest of the tests will be + // skipped as well + if (!isServiceDeployed) { throw new SkipException("Lock Plugin not deployed"); } - - } - - @Parameters({"issuer", "lockAuditHealthPostUrl", "audit_health_post_1"}) + + } + + @Parameters({ "issuer", "lockAuditHealthPostUrl", "audit_health_post_1" }) @Test public void getLockAuditData(final String issuer, final String lockAuditHealthPostUrl, final String json) { - log.error("getLockAuditData() - accessToken:{}, issuer:{}, lockAuditHealthPostUrl:{}, json:{}", accessToken, issuer, lockAuditHealthPostUrl, json); + log.info("getLockAuditData() - accessToken:{}, issuer:{}, lockAuditHealthPostUrl:{}, json:{}", accessToken, + issuer, lockAuditHealthPostUrl, json); Builder request = getResteasyService().getClientBuilder(issuer + lockAuditHealthPostUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); - log.error("post lock audit - response:{}", response); + log.info("post lock audit - response:{}", response); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getLockAuditData - response:{}", response); + log.info("Response for getLockAuditData - response:{}", response); } - - - @Parameters({"issuer", "lockAuditHealthSearchUrl"}) - //@Test + @Parameters({ "issuer", "lockAuditHealthSearchUrl" }) + // @Test public void getLockAuditData(final String issuer, final String lockAuditHealthSearchUrl) { - log.error("getLockAuditData() - accessToken:{}, issuer:{}, lockAuditHealthSearchUrl:{}", accessToken, issuer, lockAuditHealthSearchUrl); + log.info("getLockAuditData() - accessToken:{}, issuer:{}, lockAuditHealthSearchUrl:{}", accessToken, issuer, + lockAuditHealthSearchUrl); Builder request = getResteasyService().getClientBuilder(issuer + lockAuditHealthSearchUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getLockAuditData - response:{}", response); + log.info("Response for getLockAuditData - response:{}", response); } - } diff --git a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java index ef91c2f304f..f3273d7c69d 100644 --- a/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java +++ b/jans-config-api/plugins/lock-plugin/src/test/java/io/jans/configapi/test/LockConfigResourceTest.java @@ -12,43 +12,40 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import org.testng.annotations.Test; - import static org.testng.Assert.assertEquals; - +import org.testng.annotations.Test; import java.lang.reflect.Method; - import org.testng.SkipException; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; -public class LockConfigResourceTest extends BaseTest{ +public class LockConfigResourceTest extends BaseTest { // Execute before each test is run @BeforeMethod - public void before(Method methodName){ + public void before(Method methodName) { boolean isServiceDeployed = isServiceDeployed("io.jans.configapi.plugin.lock.rest.ApiApplication"); - log.error("\n\n\n *** LockConfigResourceTest - isServiceDeployed:{}",isServiceDeployed); - // check condition, note once you condition is met the rest of the tests will be skipped as well - if(!isServiceDeployed) { + log.info("\n\n\n *** LockConfigResourceTest - isServiceDeployed:{}", isServiceDeployed); + // check condition, note once you condition is met the rest of the tests will be + // skipped as well + if (!isServiceDeployed) { throw new SkipException("Lock Plugin not deployed"); } - - } - - @Parameters({"issuer", "lockConfigUrl"}) + + } + + @Parameters({ "issuer", "lockConfigUrl" }) @Test public void getLockConfigUrlData(final String issuer, final String lockConfigUrl) { - log.error("getLockConfigUrlData() - accessToken:{}, issuer:{}, lockConfigUrl:{}", accessToken, issuer, lockConfigUrl); + log.info("getLockConfigUrlData() - accessToken:{}, issuer:{}, lockConfigUrl:{}", accessToken, issuer, + lockConfigUrl); Builder request = getResteasyService().getClientBuilder(issuer + lockConfigUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getLockConfigUrlData - response:{}", response); + log.info("Response for getLockConfigUrlData - response:{}", response); } - - } diff --git a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java b/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java index 10d35f4a601..0159f477b1f 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java +++ b/jans-config-api/plugins/scim-plugin/src/test/java/io/jans/configapi/test/ScimConfigResourceTest.java @@ -12,10 +12,8 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import org.testng.annotations.Test; - import static org.testng.Assert.assertEquals; - +import org.testng.annotations.Test; import org.testng.annotations.Parameters; public class ScimConfigResourceTest extends BaseTest { @@ -23,16 +21,14 @@ public class ScimConfigResourceTest extends BaseTest { @Parameters({"issuer", "scimConfigUrl"}) @Test public void getScimConfigData(final String issuer, final String scimConfigUrl) { - log.error("getScimConfigData() - accessToken:{}, issuer:{}, scimConfigUrl:{}", accessToken, issuer, scimConfigUrl); + log.info("getScimConfigData() - accessToken:{}, issuer:{}, scimConfigUrl:{}", accessToken, issuer, scimConfigUrl); Builder request = getResteasyService().getClientBuilder(issuer + scimConfigUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getScimConfigData - response:{}", response); + log.info("Response for getScimConfigData - response:{}", response); } - - } diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java index f6c1e6eee4b..59ba05c526b 100644 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/test/UserResourceTest.java @@ -13,24 +13,23 @@ import jakarta.ws.rs.core.Response.Status; import org.testng.annotations.Test; - +import org.testng.annotations.Parameters; import static org.testng.Assert.assertEquals; -import org.testng.annotations.Parameters; public class UserResourceTest extends BaseTest { @Parameters({"issuer", "userUrl"}) - //@Test + @Test public void getUserResourceData(final String issuer, final String userUrl) { - log.error("\n\n getUserResourceData() - accessToken:{}, issuer:{}, userUrl:{}", accessToken, issuer, userUrl); + log.info("\n\n getUserResourceData() - accessToken:{}, issuer:{}, userUrl:{}", accessToken, issuer, userUrl); Builder request = getResteasyService().getClientBuilder(issuer + userUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("\n\n Response for getUserResourceData() - response:{}", response); + log.info("\n\n Response for getUserResourceData() - response:{}", response); } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java index 5b2e24d08d6..ab1313ec44b 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AcrsResourceTest.java @@ -7,47 +7,42 @@ package io.jans.configapi.test.auth; import io.jans.configapi.ConfigServerBaseTest; + import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import org.testng.annotations.Test; - import static org.testng.Assert.assertEquals; - import org.testng.annotations.Parameters; +import org.testng.annotations.Test; public class AcrsResourceTest extends ConfigServerBaseTest{ @Parameters({"issuer", "acrsUrl"}) @Test public void getDefaultAuthenticationMethod(final String issuer, final String acrsUrl) { - log.error("accessToken:{}, issuer:{}, acrsUrl:{}", accessToken, issuer, acrsUrl); + log.info("accessToken:{}, issuer:{}, acrsUrl:{}", accessToken, issuer, acrsUrl); Builder request = getResteasyService().getClientBuilder(issuer + acrsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getDefaultAuthenticationMethod - response:{}", response); + log.info("Response for getDefaultAuthenticationMethod - response:{}", response); } @Parameters({"issuer", "acrsUrl", "default_acr_1"}) @Test public void postClient(final String issuer, final String acrsUrl, final String json) { - log.error("accessToken:{}, issuer:{}, acrsUrl:{}, json:{}", accessToken, issuer, acrsUrl, json); - + log.info("accessToken:{}, issuer:{}, acrsUrl:{}, json:{}", accessToken, issuer, acrsUrl, json); Builder request = getResteasyService().getClientBuilder(issuer + acrsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - Response response = request.put(Entity.entity(json, MediaType.APPLICATION_JSON)); - assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getApiConfigtion - response:{}", response); + log.info("Response for getApiConfigtion - response:{}", response); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java index 6ee3e9b1b2e..bc86fa52776 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AgamaDeploymentsResourceTest.java @@ -12,18 +12,16 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import org.testng.annotations.Test; - import static org.testng.Assert.assertEquals; - import org.testng.annotations.Parameters; +import org.testng.annotations.Test; public class AgamaDeploymentsResourceTest extends ConfigServerBaseTest { @Parameters({ "issuer", "agamaDeploymentUrl" }) @Test public void getDeployments(final String issuer, final String agamaDeploymentUrl) { - log.error("accessToken:{}, issuer:{}, agamaDeploymentUrl:{}", accessToken, issuer, agamaDeploymentUrl); + log.info("accessToken:{}, issuer:{}, agamaDeploymentUrl:{}", accessToken, issuer, agamaDeploymentUrl); Builder request = getResteasyService().getClientBuilder(issuer + agamaDeploymentUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -31,7 +29,7 @@ public void getDeployments(final String issuer, final String agamaDeploymentUrl) Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getDefaultAuthenticationMethod - response:{}", response); + log.info("Response for getDefaultAuthenticationMethod - response:{}", response); } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java index ce33e0f5f6f..422637338ce 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/AuthConfigResourceTest.java @@ -6,8 +6,9 @@ package io.jans.configapi.test.auth; -import jakarta.ws.rs.HttpMethod; import io.jans.configapi.ConfigServerBaseTest; + +import jakarta.ws.rs.HttpMethod; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.core.MediaType; @@ -18,13 +19,12 @@ import org.testng.annotations.Parameters; import org.testng.annotations.Test; - public class AuthConfigResourceTest extends ConfigServerBaseTest{ @Parameters({"issuer", "authConfigurationUrl"}) @Test public void getAuthConfigurationProperty(final String issuer, final String authConfigurationUrl) { - log.error("getAuthConfigurationProperty() - accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); + log.info("getAuthConfigurationProperty() - accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); Builder request = getResteasyService().getClientBuilder(issuer + authConfigurationUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -32,13 +32,13 @@ public void getAuthConfigurationProperty(final String issuer, final String authC Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getAuthConfigurationProperty() - response:{}", response); + log.info("Response for getAuthConfigurationProperty() - response:{}", response); } @Parameters({"issuer", "authConfigurationUrl"}) @Test public void getPersistenceDetails(final String issuer, final String authConfigurationUrl) { - log.error("getPersistenceDetails() - accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); + log.info("getPersistenceDetails() - accessToken:{}, issuer:{}, authConfigurationUrl:{}", accessToken, issuer, authConfigurationUrl); Builder request = getResteasyService().getClientBuilder(issuer + authConfigurationUrl + "/persistence"); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -46,13 +46,13 @@ public void getPersistenceDetails(final String issuer, final String authConfigur Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getPersistenceDetails() - response:{}", response); + log.info("Response for getPersistenceDetails() - response:{}", response); } @Parameters({"issuer", "authConfigurationUrl", "auth_config_patch_1"}) @Test public void patchAuthConfigurationProperty(final String issuer, final String authConfigurationUrl, final String json) { - log.error("patchAuthConfigurationProperty() - getApiConfigtion() - accessToken:{}, issuer:{}, authConfigurationUrl:{}, json:{}", accessToken, issuer, + log.info("patchAuthConfigurationProperty() - getApiConfigtion() - accessToken:{}, issuer:{}, authConfigurationUrl:{}, json:{}", accessToken, issuer, authConfigurationUrl, json); Builder request = getResteasyService().getClientBuilder(issuer + authConfigurationUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -61,6 +61,6 @@ public void patchAuthConfigurationProperty(final String issuer, final String aut Response response = request.method(HttpMethod.PATCH, Entity.entity(json, MediaType.APPLICATION_JSON_PATCH_JSON)); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response patchAuthConfigurationProperty() - response:{}", response); + log.info("Response patchAuthConfigurationProperty() - response:{}", response); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java index d13eafbeb94..2fb7cd82292 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ClientResourceTest.java @@ -16,16 +16,13 @@ import org.testng.annotations.Parameters; import org.testng.annotations.Test; - - public class ClientResourceTest extends ConfigServerBaseTest { - private String clientId; - + @Parameters({ "issuer", "openidClientsUrl" }) @Test public void getAllClient(final String issuer, final String openidClientsUrl) { - log.error("getAllClient() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, + log.info("getAllClient() - accessToken:{}, issuer:{}, openidClientsUrl:{}", accessToken, issuer, openidClientsUrl); Builder request = getResteasyService().getClientBuilder(issuer + openidClientsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -33,22 +30,20 @@ public void getAllClient(final String issuer, final String openidClientsUrl) { Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getAllClient - response:{}", response); + log.info("Response for getAllClient - response:{}", response); } @Parameters({ "issuer", "openidClientsUrl", "openid_client_1" }) @Test public void postClient(final String issuer, final String openidClientsUrl, final String json) { - log.error("\n\n\n postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, + log.info("\n\n\n postClient2 - accessToken:{}, issuer:{}, openidClientsUrl:{}, json:{}", accessToken, issuer, openidClientsUrl, json); Builder request = getResteasyService().getClientBuilder(issuer + openidClientsUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); - // String jsonStr = decodeFileValue(json); - // log.error("\n\n\n postClient2 - jsonStr:{}", jsonStr); Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); - log.error("post client - response:{}", response); + log.info("post client - response:{}", response); if (response.getStatus() == 201) { log.trace("Response for postClient - response.getEntity():{}, response.getClass():{}", diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java index 9a32484830b..c36391639d6 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java @@ -22,49 +22,33 @@ import static io.restassured.RestAssured.given; -/** - * @author Yuriy Zabrovarnyy - */ public class ConfigResourceTest extends ConfigServerBaseTest { @Parameters({ "issuer", "apiConfigtionUrl" }) @Test public void getApiConfigtion(final String issuer, final String apiConfigtionUrl) { - log.error("getApiConfigtion() - accessToken:{}, issuer:{}, apiConfigtionUrl:{}", accessToken, issuer, + log.info("getApiConfigtion() - accessToken:{}, issuer:{}, apiConfigtionUrl:{}", accessToken, issuer, apiConfigtionUrl); Builder request = getResteasyService().getClientBuilder(issuer + apiConfigtionUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getApiConfigtion - response:{}", response); - - } - - @Parameters({ "issuer", "apiConfigtionUrl", "api_config-patch" }) - // @Test - public void patchgetApiConfigtion1(final String issuer, final String apiConfigtionUrl) { - given().when().contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer 0ea2ce99-b741-4f5a-8fd7-26f52d057c19", null) - .body("[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\": \"DEBUG\" } ]") - .patch("/jans-config-api/api/v1/jans-auth-server/config").then().statusCode(200); + log.info("Response for getApiConfigtion - response:{}", response); } @Parameters({ "issuer", "apiConfigtionUrl", "api_config_patch_1" }) @Test public void patchgetApiConfigtion(final String issuer, final String apiConfigtionUrl, final String json) { - log.error("getApiConfigtion() - accessToken:{}, issuer:{}, apiConfigtionUrl:{}, json:{}", accessToken, issuer, + log.info("getApiConfigtion() - accessToken:{}, issuer:{}, apiConfigtionUrl:{}, json:{}", accessToken, issuer, apiConfigtionUrl, json); Builder request = getResteasyService().getClientBuilder(issuer + apiConfigtionUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_PATCH_JSON); Response response = request.method(HttpMethod.PATCH, Entity.entity(json, MediaType.APPLICATION_JSON_PATCH_JSON)); - assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getApiConfigtion - response:{}", response); - + log.info("Response for getApiConfigtion - response:{}", response); } } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java index 0883bf2ec1e..a90d09f1022 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/health/ApiHealthTest.java @@ -23,21 +23,20 @@ public class ApiHealthTest extends ConfigServerBaseTest { @Parameters({ "issuer", "healthUrl" }) @Test public void getHealthResponse(final String issuer, final String healthUrl) { - log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); - + log.info("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); Builder request = getResteasyService().getClientBuilder(issuer + healthUrl); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getHealthResponse - response:{}", response); + log.info("Response for getHealthResponse - response:{}", response); } @Parameters({ "issuer", "healthUrl" }) @Test public void getServerStat(final String issuer, final String healthUrl) { - log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + log.info("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); Builder request = getResteasyService().getClientBuilder(issuer + healthUrl + "/server-stat"); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -45,13 +44,13 @@ public void getServerStat(final String issuer, final String healthUrl) { Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getServerStat - response:{}", response); + log.info("Response for getServerStat - response:{}", response); } @Parameters({ "issuer", "healthUrl" }) @Test public void getApplicationVersion(final String issuer, final String healthUrl) { - log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + log.info("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); Builder request = getResteasyService().getClientBuilder(issuer + healthUrl + "/app-version"); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -59,13 +58,13 @@ public void getApplicationVersion(final String issuer, final String healthUrl) { Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getApplicationVersion - response:{}", response); + log.info("Response for getApplicationVersion - response:{}", response); } @Parameters({ "issuer", "healthUrl" }) @Test public void getServiceStatus(final String issuer, final String healthUrl) { - log.error("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); + log.info("accessToken:{}, issuer:{}, healthUrl:{}", accessToken, issuer, healthUrl); Builder request = getResteasyService().getClientBuilder(issuer + healthUrl + "/service-status"); request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); @@ -73,6 +72,6 @@ public void getServiceStatus(final String issuer, final String healthUrl) { Response response = request.get(); assertEquals(response.getStatus(), Status.OK.getStatusCode()); - log.error("Response for getServiceStatus - response:{}", response); + log.info("Response for getServiceStatus - response:{}", response); } } diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java index c23b7808e8e..1396087c2f1 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java @@ -6,98 +6,31 @@ package io.jans.configapi.core.test; -import io.jans.as.client.TokenRequest; -import io.jans.as.client.TokenResponse; import io.jans.as.model.common.GrantType; import io.jans.as.model.util.Util; -import io.jans.configapi.core.util.Jackson; import io.jans.configapi.core.test.service.HttpService; import io.jans.configapi.core.test.service.ResteasyService; import io.jans.configapi.core.test.service.TokenService; -import static java.nio.charset.StandardCharsets.UTF_8; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; - -import java.util.Hashtable; import java.util.Map; -import java.util.Properties; import java.net.URLEncoder; -import java.io.UnsupportedEncodingException; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.net.URLDecoder; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.security.*; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.*; -import java.util.Map.Entry; - -import jakarta.servlet.http.HttpServletRequest; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; - import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CookieStore; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.routing.HttpRoutePlanner; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.entity.ContentType; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.conn.ssl.TrustStrategy; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.client.LaxRedirectStrategy; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.http.ssl.SSLContexts; - -import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; -import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; -import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; - -import org.json.JSONObject; -import org.json.JSONException; import org.testng.ITestContext; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeSuite; -import org.testng.annotations.BeforeTest; - -import jakarta.annotation.PostConstruct; -import jakarta.ws.rs.core.UriBuilder; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.client.Invocation.Builder; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.Status; + public class BaseTest { @@ -118,20 +51,10 @@ public class BaseTest { @BeforeSuite public void initTestSuite(ITestContext context) throws Exception { - - //log.error("Invoked initTestSuite of '{}'", context.getCurrentXmlTest().getName()); String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); - log.error("Invoked initTestSuite propertiesFile '{}'", propertiesFile); - - //Properties prop = new Properties(); - // prop.load(Files.newBufferedReader(Paths.get(propertiesFile), UTF_8)); - + log.info("Invoked initTestSuite propertiesFile '{}'", propertiesFile); propertiesMap = context.getSuite().getXmlSuite().getParameters(); - //prop.forEach((key, value) -> propertiesMap.put(key.toString(), value.toString())); - //context.getSuite().getXmlSuite().setParameters(propertiesMap); - - log.error("End initTestSuite propertiesMap: {}", propertiesMap); - + log.info("End initTestSuite propertiesMap: {}", propertiesMap); } @AfterSuite @@ -142,18 +65,15 @@ public void finalize() { @BeforeMethod public void getAccessToken() throws Exception { - log.error("getAccessToken - propertiesMap:{}", propertiesMap); - + log.info("getAccessToken - propertiesMap:{}", propertiesMap); String tokenUrl = propertiesMap.get("tokenEndpoint"); String strGrantType = propertiesMap.get("tokenGrantType"); String clientId = propertiesMap.get("clientId"); String clientSecret = propertiesMap.get("clientSecret"); String scopes = propertiesMap.get("scopes"); - String authStr = clientId + ':' + clientSecret; - GrantType grantType = GrantType.fromString(strGrantType); this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); - log.error("accessToken:{}", accessToken); + log.info("accessToken:{}", accessToken); } protected String getToken(final String tokenUrl, final String clientId, final String clientSecret, GrantType grantType, @@ -199,7 +119,7 @@ protected String getEncodedCredentials() { } protected String decodeFileValue(String value) { - log.error("\n\n decodeFileValue"); + log.info("\n\n decodeFileValue"); String decoded = value; if (value.startsWith(FILE_PREFIX)) { value = value.substring(FILE_PREFIX.length()); // remove the prefix @@ -215,12 +135,12 @@ protected String decodeFileValue(String value) { } } - log.error("\n\n decodeFileValue - decoded:{}", decoded); + log.info("\n\n decodeFileValue - decoded:{}", decoded); return decoded; } protected boolean isServiceDeployed(String serviceName) { - log.error("\n\n\n *** Check if service is deployed - serviceName:{}", serviceName+" *** \n\n\n"); + log.info("\n\n\n *** Check if service is deployed - serviceName:{}", serviceName+" *** \n\n\n"); boolean isDeployed = false; try { Class.forName(serviceName); diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/AlterSuiteListener.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/AlterSuiteListener.java index 583b3c8efc2..da2fbe6db19 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/AlterSuiteListener.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/AlterSuiteListener.java @@ -1,12 +1,7 @@ package io.jans.configapi.core.test.listener; -import io.jans.util.StringHelper; -import io.jans.util.security.SecurityProviderUtility; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.testng.IAlterSuiteListener; -import org.testng.xml.XmlSuite; +import io.jans.util.security.SecurityProviderUtility; import java.io.BufferedReader; import java.io.IOException; @@ -18,6 +13,11 @@ import java.util.List; import java.util.Properties; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.testng.IAlterSuiteListener; +import org.testng.xml.XmlSuite; + public class AlterSuiteListener implements IAlterSuiteListener { static PersistenceType persistenceType; @@ -32,22 +32,19 @@ public void alter(List suites) { try { SecurityProviderUtility.installBCProvider(); - logger.error("\n\n Parsing XML suite"); + logger.info("\n\n Parsing XML suite"); XmlSuite suite = suites.get(0); //Properties with the file: preffix will point to real .json files stored under src/test/resources folder String propertiesFile = suite.getParameter("propertiesFile"); - Properties prop = new Properties(); - prop.load(Files.newBufferedReader(Paths.get(propertiesFile), DEFAULT_CHARSET)); //do not bother about IO issues here + prop.load(Files.newBufferedReader(Paths.get(propertiesFile), DEFAULT_CHARSET)); persistenceType = PersistenceType.fromString(prop.getProperty("persistenceType")); - logger.error("Using persistence type = {}", persistenceType); + logger.info("Using persistence type = {}", persistenceType); Map parameters = new Hashtable<>(); - //do not bother about empty keys... but - //If a value is found null, this will throw a NPE since we are using a Hashtable prop.forEach((Object key, Object value) -> parameters.put(key.toString(), decodeFileValue(value.toString()))); // Override test parameters suite.setParameters(parameters); @@ -59,7 +56,7 @@ public void alter(List suites) { } private String decodeFileValue(String value) { - logger.error("\n\n decodeFileValue"); + logger.debug("\n\n decodeFileValue"); String decoded = value; if (value.startsWith(FILE_PREFIX)) { value = value.substring(FILE_PREFIX.length()); //remove the prefix @@ -75,7 +72,7 @@ private String decodeFileValue(String value) { } } - logger.error("\n\n decodeFileValue - decoded:{}",decoded); + logger.debug("\n\n decodeFileValue - decoded:{}",decoded); return decoded; } diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/PersistenceType.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/PersistenceType.java index d6f57caa828..3b235c6b130 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/PersistenceType.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/PersistenceType.java @@ -1,7 +1,6 @@ package io.jans.configapi.core.test.listener; import io.jans.util.StringHelper; - import java.util.stream.Stream; public enum PersistenceType { diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTest.java index 20571b1816c..cd8ef5e2aea 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTest.java @@ -5,7 +5,6 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface SkipTest { diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTestsListener.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTestsListener.java index 3d6f46c734e..cad279b4863 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTestsListener.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/listener/SkipTestsListener.java @@ -1,10 +1,8 @@ package io.jans.configapi.core.test.listener; -import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.stream.Stream; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.testng.IAnnotationTransformer; @@ -36,7 +34,6 @@ public void transform(ITestAnnotation annotation, Class testClass, } } } - } } From b6bf0d67f33dec1a06a4ecdcc26978708728b61c Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 13 Dec 2024 22:11:12 +0530 Subject: [PATCH 39/44] feat(config-api): testNG framework changes Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 16 ++-- .../ca/plugin/adminui/AdminUIBaseTest.java | 8 +- .../test/AuditLoggingResourceTest.java | 7 +- .../adminui/test/LicenseResourceTest.java | 5 +- .../test/auth/ConfigResourceTest.java | 2 - .../io/jans/configapi/core/test/BaseTest.java | 12 +-- .../core/test/service/HttpService.java | 76 ++++++++----------- 7 files changed, 53 insertions(+), 73 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 1731e8c09f5..886be60f448 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9313,10 +9313,10 @@ components: type: boolean userCanView: type: boolean - adminCanAccess: - type: boolean userCanAccess: type: boolean + adminCanAccess: + type: boolean baseDn: type: string PatchRequest: @@ -10177,8 +10177,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10188,6 +10186,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -11297,14 +11297,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: @@ -11733,10 +11733,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java index b6542599213..1186f9f05e1 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/AdminUIBaseTest.java @@ -18,22 +18,18 @@ public class AdminUIBaseTest extends BaseTest{ @BeforeMethod @Override public void getAccessToken() throws Exception { - log.error("AdminUI - getAccessToken - propertiesMap:{}", propertiesMap); + log.info("AdminUI - getAccessToken - propertiesMap:{}", propertiesMap); String tokenUrl = propertiesMap.get("test.authzurl"); String strGrantType = propertiesMap.get("test.grant.type"); String clientId = propertiesMap.get("test.client.id"); String clientSecret = propertiesMap.get("test.client.secret"); String scopes = propertiesMap.get("test.scopes"); - String authStr = clientId + ':' + clientSecret; GrantType grantType = GrantType.fromString(strGrantType); this.accessToken = getToken(tokenUrl, clientId, clientSecret, grantType, scopes); - log.error("\n\n\n\n AdminUI- accessToken:{}", accessToken); + log.info("\n\n\n\n AdminUI- accessToken:{}", accessToken); } - - - } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java index 4f90f1b73c6..e0fe81dff0a 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/AuditLoggingResourceTest.java @@ -14,6 +14,9 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import static org.testng.Assert.assertEquals; import org.testng.annotations.Parameters; import org.testng.annotations.Test; @@ -28,11 +31,11 @@ public class AuditLoggingResourceTest extends AdminUIBaseTest{ public void postAuditLoggingData(final String issuer, final String auditLoggingURL, final String json) { log.info("postAuditLoggingData() - accessToken:{}, issuer:{}, auditLoggingURL:{}, json:{}", accessToken, issuer, auditLoggingURL, json); Builder request = getResteasyService().getClientBuilder(issuer+auditLoggingURL); - //request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); + request.header(AUTHORIZATION, AUTHORIZATION_TYPE + " " + accessToken); request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.post(Entity.entity(json, MediaType.APPLICATION_JSON)); - // assertEquals(response.getStatus(), Status.OK.getStatusCode()); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); log.info("\n\n Response for postAuditLoggingData - response:{}", response); } diff --git a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java index 1b77c7dc705..8176121bc52 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/test/java/io/jans/ca/plugin/adminui/test/LicenseResourceTest.java @@ -13,6 +13,9 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; + +import static org.testng.Assert.assertEquals; import org.testng.annotations.Parameters; import org.testng.annotations.Test; @@ -31,7 +34,7 @@ public void getLicenseDetails(final String issuer, final String checkActiveLicen request.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); Response response = request.get(); - //assertEquals(response.getStatus(), Status.OK.getStatusCode()); + assertEquals(response.getStatus(), Status.OK.getStatusCode()); log.info("\n\n Response for getLicenseDetails - response:{}", response); } diff --git a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java index c36391639d6..03a66ddd1af 100644 --- a/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java +++ b/jans-config-api/server/src/test/java/io/jans/configapi/test/auth/ConfigResourceTest.java @@ -20,8 +20,6 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; -import static io.restassured.RestAssured.given; - public class ConfigResourceTest extends ConfigServerBaseTest { @Parameters({ "issuer", "apiConfigtionUrl" }) diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java index 1396087c2f1..f5a296575e4 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/BaseTest.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Map; @@ -35,7 +36,7 @@ public class BaseTest { private static final String FILE_PREFIX = "file:"; - private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; private static final String NEW_LINE = System.getProperty("line.separator"); protected static final String CONTENT_TYPE = "Content-Type"; protected static final String AUTHORIZATION = "Authorization"; @@ -50,21 +51,16 @@ public class BaseTest { protected String accessToken; @BeforeSuite - public void initTestSuite(ITestContext context) throws Exception { + public void initTestSuite(ITestContext context) { String propertiesFile = context.getCurrentXmlTest().getParameter("propertiesFile"); log.info("Invoked initTestSuite propertiesFile '{}'", propertiesFile); propertiesMap = context.getSuite().getXmlSuite().getParameters(); log.info("End initTestSuite propertiesMap: {}", propertiesMap); } - @AfterSuite - public void finalize() { - // cleanup - log.info("After Suite finalize'"); - } @BeforeMethod - public void getAccessToken() throws Exception { + public void getAccessToken() { log.info("getAccessToken - propertiesMap:{}", propertiesMap); String tokenUrl = propertiesMap.get("tokenEndpoint"); String strGrantType = propertiesMap.get("tokenGrantType"); diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java index 8980a02aaff..43b2bcad8fe 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/test/service/HttpService.java @@ -6,12 +6,16 @@ package io.jans.configapi.core.test.service; +import io.jans.model.net.HttpServiceResponse; +import io.jans.util.StringHelper; + import java.io.File; import java.io.IOException; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -22,6 +26,9 @@ import javax.net.ssl.SSLContext; +import jakarta.annotation.PostConstruct; +import jakarta.servlet.http.HttpServletRequest; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -31,7 +38,6 @@ import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; @@ -50,23 +56,14 @@ import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; -import io.jans.model.net.HttpServiceResponse; -import io.jans.util.StringHelper; -import io.jans.util.Util; -import jakarta.annotation.PostConstruct; -import jakarta.inject.Inject; -import jakarta.servlet.http.HttpServletRequest; -import org.apache.commons.lang3.StringUtils; -import org.json.JSONObject; - public class HttpService implements Serializable { private static final long serialVersionUID = -2398422090669045605L; - protected Logger log = LogManager.getLogger(getClass()); + protected transient Logger log = LogManager.getLogger(getClass()); + private static final String CON_STATS_STR = "Connection manager stats: {}"; + private transient Base64 base64; - private Base64 base64; - - private PoolingHttpClientConnectionManager connectionManager; + private transient PoolingHttpClientConnectionManager connectionManager; @PostConstruct public void init() { @@ -79,7 +76,7 @@ public void init() { public CloseableHttpClient getHttpsClientTrustAll() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); @@ -96,7 +93,7 @@ public CloseableHttpClient getHttpsClient() { } public CloseableHttpClient getHttpsClient(RequestConfig requestConfig) { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); return HttpClients.custom() .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) @@ -104,23 +101,23 @@ public CloseableHttpClient getHttpsClient(RequestConfig requestConfig) { } public CloseableHttpClient getHttpsClient(HttpRoutePlanner routerPlanner) { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); return getHttpsClient(RequestConfig.custom().build(), routerPlanner); } public CloseableHttpClient getHttpsClient(RequestConfig requestConfig, HttpRoutePlanner routerPlanner) { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); return HttpClients.custom() .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) .setConnectionManager(connectionManager).setRoutePlanner(routerPlanner).build(); } - public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword) + public CloseableHttpClient getHttpsClient(String trustStorePath, String trustStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()).build(); @@ -131,10 +128,10 @@ public CloseableHttpClient getHttpsClient(String trustStoreType, String trustSto .setConnectionManager(connectionManager).build(); } - public CloseableHttpClient getHttpsClient(String trustStoreType, String trustStorePath, String trustStorePassword, - String keyStoreType, String keyStorePath, String keyStorePassword) throws KeyManagementException, - NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { - log.trace("Connection manager stats: {}", connectionManager.getTotalStats()); + public CloseableHttpClient getHttpsClient(String trustStorePath, String trustStorePassword, String keyStorePath, + String keyStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, + CertificateException, IOException, UnrecoverableKeyException { + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()) @@ -160,8 +157,8 @@ public HttpServiceResponse executePost(HttpClient httpClient, String uri, String if (StringHelper.isNotEmpty(authCode)) { httpPost.setHeader("Authorization", authType + authCode); } - - if(contentType==null) { + + if (contentType == null) { contentType = ContentType.APPLICATION_JSON; } @@ -201,23 +198,11 @@ public HttpServiceResponse executePost(String uri, String authCode, Map headers) { @@ -245,8 +230,7 @@ public HttpServiceResponse executeGet(String requestUri, Map hea return executeGet(httpClient, requestUri, headers); } - public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri) - throws ClientProtocolException, IOException { + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri) { return executeGet(httpClient, requestUri, null); } @@ -315,9 +299,9 @@ public boolean isResponseStastusCodeOk(HttpResponse httpResponse) { || (responseStastusCode == HttpStatus.SC_PARTIAL_CONTENT) || (responseStastusCode == HttpStatus.SC_MULTI_STATUS)) { return true; + } else { + return false; } - - return false; } public boolean isResponseStatusCodeOk(HttpResponse httpResponse) { @@ -334,9 +318,9 @@ public boolean isContentTypeXml(HttpResponse httpResponse) { if (StringHelper.equals(contentTypeValue, ContentType.APPLICATION_XML.getMimeType()) || StringHelper.equals(contentTypeValue, ContentType.TEXT_XML.getMimeType())) { return true; + } else { + return false; } - - return false; } public String constructServerUrl(final HttpServletRequest request) { From 5ee080f1292ab4bb37e8216f932a6ce35ebae83f Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Fri, 13 Dec 2024 21:28:56 +0300 Subject: [PATCH 40/44] feat(jans-config-api): update surefire plugin Signed-off-by: Yuriy Movchan --- jans-config-api/server/src/test/resources/testng.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jans-config-api/server/src/test/resources/testng.xml b/jans-config-api/server/src/test/resources/testng.xml index ff0a012a9bb..3c98a2f3c30 100644 --- a/jans-config-api/server/src/test/resources/testng.xml +++ b/jans-config-api/server/src/test/resources/testng.xml @@ -2,7 +2,7 @@ - + From 55a789667f22b19130e7ecaf86e59fb06bc9b633 Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Fri, 13 Dec 2024 21:30:52 +0300 Subject: [PATCH 41/44] feat(jans-config-api): update surefire plugin Signed-off-by: Yuriy Movchan --- jans-config-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jans-config-api/pom.xml b/jans-config-api/pom.xml index eacd0e0c372..d577ab6526f 100644 --- a/jans-config-api/pom.xml +++ b/jans-config-api/pom.xml @@ -23,7 +23,7 @@ 11 UTF-8 UTF-8 - 3.0.0-M5 + 3.5.2 ${project.version} From 68cf3fc0d50cbcf48d348357b4043910f71c0b3b Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Fri, 13 Dec 2024 21:33:55 +0300 Subject: [PATCH 42/44] feat(jans-config-api): remote test data Signed-off-by: Yuriy Movchan --- .../Default suite/Default test.html | 215 -------------- .../Default suite/Default test.xml | 46 --- .../Default suite/testng-failed.xml | 19 -- .../server/test-output/emailable-report.html | 71 ----- jans-config-api/server/test-output/index.html | 280 ------------------ ...configapi.test.auth.ClientResourceTest.xml | 37 --- .../old/Default suite/classes.html | 40 --- .../Default suite/methods-alphabetical.html | 6 - .../old/Default suite/methods-not-run.html | 4 - .../old/Default suite/methods.html | 6 - .../old/Default suite/testng.xml.html | 1 - .../test-output/old/Default suite/toc.html | 30 -- .../server/test-output/old/index.html | 9 - .../server/test-output/testng-failed.xml | 19 -- .../server/test-output/testng-results.xml | 113 ------- 15 files changed, 896 deletions(-) delete mode 100644 jans-config-api/server/test-output/Default suite/Default test.html delete mode 100644 jans-config-api/server/test-output/Default suite/Default test.xml delete mode 100644 jans-config-api/server/test-output/Default suite/testng-failed.xml delete mode 100644 jans-config-api/server/test-output/emailable-report.html delete mode 100644 jans-config-api/server/test-output/index.html delete mode 100644 jans-config-api/server/test-output/junitreports/TEST-io.jans.configapi.test.auth.ClientResourceTest.xml delete mode 100644 jans-config-api/server/test-output/old/Default suite/classes.html delete mode 100644 jans-config-api/server/test-output/old/Default suite/methods-alphabetical.html delete mode 100644 jans-config-api/server/test-output/old/Default suite/methods-not-run.html delete mode 100644 jans-config-api/server/test-output/old/Default suite/methods.html delete mode 100644 jans-config-api/server/test-output/old/Default suite/testng.xml.html delete mode 100644 jans-config-api/server/test-output/old/Default suite/toc.html delete mode 100644 jans-config-api/server/test-output/old/index.html delete mode 100644 jans-config-api/server/test-output/testng-failed.xml delete mode 100644 jans-config-api/server/test-output/testng-results.xml diff --git a/jans-config-api/server/test-output/Default suite/Default test.html b/jans-config-api/server/test-output/Default suite/Default test.html deleted file mode 100644 index 0e9ca400b42..00000000000 --- a/jans-config-api/server/test-output/Default suite/Default test.html +++ /dev/null @@ -1,215 +0,0 @@ - - -TestNG: Default test - - - - - - - - -

Default test

- - - - - - - - - - - -
Tests passed/Failed/Skipped:0/0/1
Started on:Tue Nov 19 17:09:20 IST 2024
Total time:0 seconds (49 ms)
Included groups:
Excluded groups:

-(Hover the method name to see the test class name)

- - - - - - - - - - - - - -
FAILED CONFIGURATIONS
Test methodAttribute(s)ExceptionTime (seconds)Instance
initTestSuite
Test class: io.jans.configapi.test.auth.ClientResourceTest
Parameters: org.testng.TestRunner@74518890
java.lang.NullPointerException
-	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
-	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
-	at java.base/java.nio.file.Path.of(Path.java:147)
-	at java.base/java.nio.file.Paths.get(Paths.java:69)
-	at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
-	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
-	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
-	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
-	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
-	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
-	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
-	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382)
-	at org.testng.SuiteRunner.run(SuiteRunner.java:336)
-	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
-	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
-	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
-	at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
-	at org.testng.TestNG.runSuites(TestNG.java:1114)
-	at org.testng.TestNG.run(TestNG.java:1082)
-	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
-	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
-	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)
-
Click to show all stack frames -
java.lang.NullPointerException
-	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
-	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
-	at java.base/java.nio.file.Path.of(Path.java:147)
-	at java.base/java.nio.file.Paths.get(Paths.java:69)
-	at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
-	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
-	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
-	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
-	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
-	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
-	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
-	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382)
-	at org.testng.SuiteRunner.run(SuiteRunner.java:336)
-	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
-	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
-	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
-	at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
-	at org.testng.TestNG.runSuites(TestNG.java:1114)
-	at org.testng.TestNG.run(TestNG.java:1082)
-	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
-	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
-	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)
-
0io.jans.configapi.test.auth.ClientResourceTest@3e2fc448

- - - - - - - - - - - - - -
SKIPPED CONFIGURATIONS
Test methodAttribute(s)ExceptionTime (seconds)Instance
getAccessToken
Test class: io.jans.configapi.test.auth.ClientResourceTest
0io.jans.configapi.test.auth.ClientResourceTest@3e2fc448

- - - - - - - - - - - - - -
SKIPPED TESTS
Test methodAttribute(s)ExceptionTime (seconds)Instance
postClient2
Test class: io.jans.configapi.test.auth.ClientResourceTest
Parameters: param-val-not-found, param-val-not-found, param-val-not-found
java.lang.NullPointerException
-	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
-	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
-	at java.base/java.nio.file.Path.of(Path.java:147)
-	at java.base/java.nio.file.Paths.get(Paths.java:69)
-	at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
-	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
-	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
-	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
-	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
-	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
-	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
-	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382)
-	at org.testng.SuiteRunner.run(SuiteRunner.java:336)
-	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
-	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
-	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
-	at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
-	at org.testng.TestNG.runSuites(TestNG.java:1114)
-	at org.testng.TestNG.run(TestNG.java:1082)
-	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
-	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
-	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)
-
Click to show all stack frames -
java.lang.NullPointerException
-	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
-	at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
-	at java.base/java.nio.file.Path.of(Path.java:147)
-	at java.base/java.nio.file.Paths.get(Paths.java:69)
-	at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
-	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
-	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
-	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
-	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69)
-	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390)
-	at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325)
-	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382)
-	at org.testng.SuiteRunner.run(SuiteRunner.java:336)
-	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
-	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
-	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280)
-	at org.testng.TestNG.runSuitesLocally(TestNG.java:1200)
-	at org.testng.TestNG.runSuites(TestNG.java:1114)
-	at org.testng.TestNG.run(TestNG.java:1082)
-	at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
-	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293)
-	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91)
-
0io.jans.configapi.test.auth.ClientResourceTest@3e2fc448

- - \ No newline at end of file diff --git a/jans-config-api/server/test-output/Default suite/Default test.xml b/jans-config-api/server/test-output/Default suite/Default test.xml deleted file mode 100644 index bd4a13d62ca..00000000000 --- a/jans-config-api/server/test-output/Default suite/Default test.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/jans-config-api/server/test-output/Default suite/testng-failed.xml b/jans-config-api/server/test-output/Default suite/testng-failed.xml deleted file mode 100644 index c7b78234715..00000000000 --- a/jans-config-api/server/test-output/Default suite/testng-failed.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/jans-config-api/server/test-output/emailable-report.html b/jans-config-api/server/test-output/emailable-report.html deleted file mode 100644 index dd54ca5a72b..00000000000 --- a/jans-config-api/server/test-output/emailable-report.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - -TestNG Report - - - - - - - -
Test# Passed# Skipped# Retried# FailedTime (ms)Included GroupsExcluded Groups
Default suite
Default test010049
- -
ClassMethodStartTime (ms)
Default suite
Default test — failed (configuration methods)
io.jans.configapi.test.auth.ClientResourceTestinitTestSuite173201636014436
Default test — skipped (configuration methods)
io.jans.configapi.test.auth.ClientResourceTestfinalize17320163602760
getAccessToken17320163602280
Default test — skipped
io.jans.configapi.test.auth.ClientResourceTestpostClient217320163602320
-

Default test

io.jans.configapi.test.auth.ClientResourceTest#initTestSuite

Parameter #1
org.testng.TestRunner@74518890
Exception
java.lang.NullPointerException - at java.base/java.util.Objects.requireNonNull(Objects.java:208) - at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216) - at java.base/java.nio.file.Path.of(Path.java:147) - at java.base/java.nio.file.Paths.get(Paths.java:69) - at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:568) - at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139) - at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69) - at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390) - at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325) - at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382) - at org.testng.SuiteRunner.run(SuiteRunner.java:336) - at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) - at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95) - at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280) - at org.testng.TestNG.runSuitesLocally(TestNG.java:1200) - at org.testng.TestNG.runSuites(TestNG.java:1114) - at org.testng.TestNG.run(TestNG.java:1082) - at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) - at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293) - at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91) -

back to summary

-

io.jans.configapi.test.auth.ClientResourceTest#finalize

back to summary

-

io.jans.configapi.test.auth.ClientResourceTest#getAccessToken

back to summary

-

io.jans.configapi.test.auth.ClientResourceTest#postClient2

Parameter #1Parameter #2Parameter #3
param-val-not-foundparam-val-not-foundparam-val-not-found
Exception
java.lang.NullPointerException - at java.base/java.util.Objects.requireNonNull(Objects.java:208) - at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216) - at java.base/java.nio.file.Path.of(Path.java:147) - at java.base/java.nio.file.Paths.get(Paths.java:69) - at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:568) - at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139) - at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69) - at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390) - at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325) - at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382) - at org.testng.SuiteRunner.run(SuiteRunner.java:336) - at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) - at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95) - at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280) - at org.testng.TestNG.runSuitesLocally(TestNG.java:1200) - at org.testng.TestNG.runSuites(TestNG.java:1114) - at org.testng.TestNG.run(TestNG.java:1082) - at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) - at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293) - at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91) -

back to summary

- - diff --git a/jans-config-api/server/test-output/index.html b/jans-config-api/server/test-output/index.html deleted file mode 100644 index 2dc98a6ad3a..00000000000 --- a/jans-config-api/server/test-output/index.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - TestNG reports - - - - - - - - - - -
- Test results - -
- 1 suite -
- -
-
-
-
-
- - io.jans.configapi.test.auth.ClientResourceTest -
-
-
-
- - - postClient2 - (param-val-not-found,param-val-not-found,param-val-not-found) -
java.lang.NullPointerException - at java.base/java.util.Objects.requireNonNull(Objects.java:208) - at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216) - at java.base/java.nio.file.Path.of(Path.java:147) - at java.base/java.nio.file.Paths.get(Paths.java:69) - at io.jans.configapi.BaseTest.initTestSuite(BaseTest.java:122) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:568) - at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139) - at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69) - at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390) - at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325) - at org.testng.SuiteRunner.privateRun(SuiteRunner.java:382) - at org.testng.SuiteRunner.run(SuiteRunner.java:336) - at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) - at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95) - at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280) - at org.testng.TestNG.runSuitesLocally(TestNG.java:1200) - at org.testng.TestNG.runSuites(TestNG.java:1114) - at org.testng.TestNG.run(TestNG.java:1082) - at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) - at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:293) - at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:91) - -
-
-
-
-
-
-
-
- C:\Users\pujavs\AppData\Local\Temp\testng-eclipse-1646905561\testng-customsuite.xml -
-
-
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
-<suite name="Default suite" guice-stage="DEVELOPMENT">
-  <parameter name="openid_client2" value="param-val-not-found"/>
-  <parameter name="issuer" value="param-val-not-found"/>
-  <parameter name="openidClientsUrl" value="param-val-not-found"/>
-  <test thread-count="5" name="Default test" verbose="2">
-    <classes>
-      <class name="io.jans.configapi.test.auth.ClientResourceTest">
-        <methods>
-          <include name="postClient2"/>
-        </methods>
-      </class> <!-- io.jans.configapi.test.auth.ClientResourceTest -->
-    </classes>
-  </test> <!-- Default test -->
-</suite> <!-- Default suite -->
-            
-
-
-
-
- Tests for Default suite -
-
-
    -
  • - Default test (1 class) -
  • -
-
-
-
-
- Groups for Default suite -
-
-
-
-
-
- Times for Default suite -
-
-
- - Total running time: 0 ms -
-
-
-
-
-
-
- Reporter output for Default suite -
-
-
-
-
-
- 2 ignored methods -
-
-
- io.jans.configapi.test.auth.ClientResourceTest -
- postClient -
- getClients -
-
-
-
-
-
-
- Methods in chronological order -
-
-
-
io.jans.configapi.test.auth.ClientResourceTest
-
- - - initTestSuite(org.testng.TestRunner@74518890) - 0 ms -
-
-
-
-
- - - diff --git a/jans-config-api/server/test-output/junitreports/TEST-io.jans.configapi.test.auth.ClientResourceTest.xml b/jans-config-api/server/test-output/junitreports/TEST-io.jans.configapi.test.auth.ClientResourceTest.xml deleted file mode 100644 index a6e14231153..00000000000 --- a/jans-config-api/server/test-output/junitreports/TEST-io.jans.configapi.test.auth.ClientResourceTest.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - diff --git a/jans-config-api/server/test-output/old/Default suite/classes.html b/jans-config-api/server/test-output/old/Default suite/classes.html deleted file mode 100644 index 86fae6277d2..00000000000 --- a/jans-config-api/server/test-output/old/Default suite/classes.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Class nameMethod nameGroups
io.jans.configapi.test.auth.ClientResourceTest  
@Test
 getClients 
 postClient2 
 postClient 
@BeforeClass
@BeforeMethod
 getAccessToken 
@AfterMethod
@AfterClass
diff --git a/jans-config-api/server/test-output/old/Default suite/methods-alphabetical.html b/jans-config-api/server/test-output/old/Default suite/methods-alphabetical.html deleted file mode 100644 index 115a3fab23e..00000000000 --- a/jans-config-api/server/test-output/old/Default suite/methods-alphabetical.html +++ /dev/null @@ -1,6 +0,0 @@ -

Methods run, sorted chronologically

>> means before, << means after


Default suite

(Hover the method name to see the test class name)

- - - - -
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
24/11/19 17:09:20 0 >>initTestSuite      main@651235118
diff --git a/jans-config-api/server/test-output/old/Default suite/methods-not-run.html b/jans-config-api/server/test-output/old/Default suite/methods-not-run.html deleted file mode 100644 index df2dbaa2f45..00000000000 --- a/jans-config-api/server/test-output/old/Default suite/methods-not-run.html +++ /dev/null @@ -1,4 +0,0 @@ -

Methods that were not run

- - -
io.jans.configapi.test.auth.ClientResourceTest.postClient
io.jans.configapi.test.auth.ClientResourceTest.getClients
\ No newline at end of file diff --git a/jans-config-api/server/test-output/old/Default suite/methods.html b/jans-config-api/server/test-output/old/Default suite/methods.html deleted file mode 100644 index 115a3fab23e..00000000000 --- a/jans-config-api/server/test-output/old/Default suite/methods.html +++ /dev/null @@ -1,6 +0,0 @@ -

Methods run, sorted chronologically

>> means before, << means after


Default suite

(Hover the method name to see the test class name)

- - - - -
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
24/11/19 17:09:20 0 >>initTestSuite      main@651235118
diff --git a/jans-config-api/server/test-output/old/Default suite/testng.xml.html b/jans-config-api/server/test-output/old/Default suite/testng.xml.html deleted file mode 100644 index 9f47c3a20ba..00000000000 --- a/jans-config-api/server/test-output/old/Default suite/testng.xml.html +++ /dev/null @@ -1 +0,0 @@ -testng.xml for Default suite<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Default suite" guice-stage="DEVELOPMENT">
  <parameter name="openid_client2" value="param-val-not-found"/>
  <parameter name="issuer" value="param-val-not-found"/>
  <parameter name="openidClientsUrl" value="param-val-not-found"/>
  <test thread-count="5" name="Default test" verbose="2">
    <classes>
      <class name="io.jans.configapi.test.auth.ClientResourceTest">
        <methods>
          <include name="postClient2"/>
        </methods>
      </class> <!-- io.jans.configapi.test.auth.ClientResourceTest -->
    </classes>
  </test> <!-- Default test -->
</suite> <!-- Default suite -->
\ No newline at end of file diff --git a/jans-config-api/server/test-output/old/Default suite/toc.html b/jans-config-api/server/test-output/old/Default suite/toc.html deleted file mode 100644 index 1bd1225486a..00000000000 --- a/jans-config-api/server/test-output/old/Default suite/toc.html +++ /dev/null @@ -1,30 +0,0 @@ - - -Results for Default suite - - - - -

Results for
Default suite

- - - - - - - - - - -
1 test1 class1 method:
-  chronological
-  alphabetical
-  not run (2)
0 groupreporter outputtestng.xml
- -

-

-
Default test (0/0/1) - Results -
-
- \ No newline at end of file diff --git a/jans-config-api/server/test-output/old/index.html b/jans-config-api/server/test-output/old/index.html deleted file mode 100644 index 1335d5818da..00000000000 --- a/jans-config-api/server/test-output/old/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - -

Test results

- - - -
SuitePassedFailedSkippedtestng.xml
Total001 
Default suite001Link
diff --git a/jans-config-api/server/test-output/testng-failed.xml b/jans-config-api/server/test-output/testng-failed.xml deleted file mode 100644 index c7b78234715..00000000000 --- a/jans-config-api/server/test-output/testng-failed.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/jans-config-api/server/test-output/testng-results.xml b/jans-config-api/server/test-output/testng-results.xml deleted file mode 100644 index 1d5bef92530..00000000000 --- a/jans-config-api/server/test-output/testng-results.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From da53b9c66c5c5576b3b574b9fb50f3e80ccda11f Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Fri, 13 Dec 2024 21:37:19 +0300 Subject: [PATCH 43/44] feat(jans-config-api): udpate exclude Signed-off-by: Yuriy Movchan --- jans-config-api/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/jans-config-api/.gitignore b/jans-config-api/.gitignore index c53194b720c..51ac95769dc 100644 --- a/jans-config-api/.gitignore +++ b/jans-config-api/.gitignore @@ -34,3 +34,4 @@ pom.xml.tag pom.xml.releaseBackup pom.xml.versionsBackup release.properties +test-output/ From 71436b4df37553b54e65e34745c3359a51ede79a Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 17 Dec 2024 21:31:08 +0530 Subject: [PATCH 44/44] feat(config-api): sync with main Signed-off-by: pujavs --- jans-config-api/docs/jans-config-api-swagger.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 886be60f448..44c68f3f67c 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9303,19 +9303,19 @@ components: type: string selected: type: boolean - whitePagesCanView: + adminCanAccess: type: boolean - adminCanEdit: + userCanAccess: type: boolean adminCanView: type: boolean + adminCanEdit: + type: boolean userCanEdit: type: boolean userCanView: type: boolean - userCanAccess: - type: boolean - adminCanAccess: + whitePagesCanView: type: boolean baseDn: type: string @@ -11297,14 +11297,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: