From a6e9a0435a30816fd738b9287a4842fe03321a6c Mon Sep 17 00:00:00 2001 From: pujavs <43700552+pujavs@users.noreply.github.com> Date: Wed, 2 Feb 2022 14:34:11 +0530 Subject: [PATCH] feat(jans-config-api): scim config endpoint issue #271 (#665) * feat: scim config service * feat: scim config service * feat: scim config service * feat: scim config endpoint * feat: scim config endpoint * feat: scim config endpoint * feat: scim config endpoint * feat: scim config endpoint * feat: scim config endpoint * feat: scim config endpoint issue#271 * feat: scim config endpoint issue#271 * feat: scim config endpoint issue#271 * feat: scim config endpoint issue#271 * feat: sonar fixes * feat: scim config endpoint * feat: sonar issue * feat: sonar issue * feat: sonar issue * feat: scim config endpoint changes to resolve sonar issue * feat: scim config endpoint changes to resolve sonar issue * feat: scim config endpoint changes to resolve sonar issue * feat: scim config endpoint * feat: scim config endpoint sonar issue * feat: scim config endpoint sonar issue * feat: scim config endpoint sonar issue * feat: scim config endpoint sonar issue --- jans-config-api/common/pom.xml | 5 + .../model/configuration/ApiConf.java | 30 +++ .../docs/jans-config-api-swagger.yaml | 123 +++++++++- .../adminui/rest/auth/OAuth2Resource.java | 2 +- .../adminui/rest/license/LicenseResource.java | 2 +- .../rest/user/UserManagementResource.java | 2 +- jans-config-api/plugins/scim-plugin/pom.xml | 34 ++- .../src/main/assembly/assembly.xml | 1 + .../ScimConfigurationFactory.java | 31 +++ .../model/config/ScimAppConfiguration.java | 211 ++++++++++++++++++ .../plugin/scim/model/config/ScimConf.java | 36 +++ .../plugin/scim/rest/ApiApplication.java | 3 +- .../plugin/scim/rest/ScimConfigResource.java | 61 +++++ .../plugin/scim/rest/ScimResource.java | 2 +- .../scim/service/ScimConfigService.java | 44 ++++ .../plugin/scim/service/ScimService.java | 1 - .../configapi/plugin/scim/util/Constants.java | 19 ++ .../services/javax.ws.rs.ext.Providers | 3 + .../feature/scim/config/scim-config.feature | 82 +++++++ .../feature/scim/user/scim-user-patch.json | 49 ++-- .../feature/scim/user/scim-user.feature | 2 +- .../feature/scim/user/scim-user.json | 4 +- .../test/resources/karate-config-jenkins.js | 3 +- .../src/test/resources/karate-config.js | 3 +- jans-config-api/pom.xml | 10 + .../default/config-api-test.properties | 2 +- .../profiles/jans-ui.jans.io/test.properties | 2 +- .../test.properties | 2 +- .../profiles/local/test.properties | 13 +- jans-config-api/server/pom.xml | 4 + .../configuration/ConfigurationFactory.java | 83 +++---- .../filters/AuthorizationFilter.java | 1 + .../jans/configapi/filters/ProtectedApi.java | 29 --- .../rest/resource/auth/AcrsResource.java | 2 +- .../resource/auth/AttributesResource.java | 4 +- .../auth/CacheConfigurationResource.java | 4 +- .../rest/resource/auth/ClientsResource.java | 4 +- .../rest/resource/auth/ConfigResource.java | 4 +- .../resource/auth/ConfigSmtpResource.java | 2 +- .../auth/CouchbaseConfigurationResource.java | 4 +- .../resource/auth/CustomScriptResource.java | 2 +- .../resource/auth/Fido2ConfigResource.java | 4 +- .../rest/resource/auth/JwksResource.java | 4 +- .../auth/LdapConfigurationResource.java | 4 +- .../rest/resource/auth/LoggingResource.java | 2 +- .../rest/resource/auth/ScopesResource.java | 4 +- .../auth/SqlConfigurationResource.java | 4 +- .../rest/resource/auth/StatResource.java | 2 +- .../resource/auth/UmaResourcesResource.java | 4 +- .../security/api/ApiProtectionService.java | 2 +- .../security/client/AuthClientFactory.java | 2 +- .../java/io/jans/configapi/util/AuthUtil.java | 2 +- .../main/resources/config-api-rs-protect.json | 17 ++ jans-config-api/shared/pom.xml | 5 +- .../io/jans/configapi/core/model}/Conf.java | 30 +-- .../io/jans/configapi/core}/util/Jackson.java | 18 +- 56 files changed, 849 insertions(+), 180 deletions(-) create mode 100644 jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiConf.java create mode 100644 jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/configuration/ScimConfigurationFactory.java create mode 100644 jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/model/config/ScimAppConfiguration.java create mode 100644 jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/model/config/ScimConf.java create mode 100644 jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimConfigResource.java create mode 100644 jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/service/ScimConfigService.java create mode 100644 jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/util/Constants.java create mode 100644 jans-config-api/plugins/scim-plugin/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers create mode 100644 jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/config/scim-config.feature delete mode 100644 jans-config-api/server/src/main/java/io/jans/configapi/filters/ProtectedApi.java rename jans-config-api/{common/src/main/java/io/jans/configapi/model/configuration => shared/src/main/java/io/jans/configapi/core/model}/Conf.java (57%) rename jans-config-api/{common/src/main/java/io/jans/configapi => shared/src/main/java/io/jans/configapi/core}/util/Jackson.java (86%) diff --git a/jans-config-api/common/pom.xml b/jans-config-api/common/pom.xml index 7935c90830a..9ecba1e7ab8 100644 --- a/jans-config-api/common/pom.xml +++ b/jans-config-api/common/pom.xml @@ -21,6 +21,10 @@ + + io.jans + jans-config-api-shared + io.jans jans-core-util @@ -34,6 +38,7 @@ jans-auth-common + org.jboss.resteasy diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiConf.java b/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiConf.java new file mode 100644 index 00000000000..e3f82fe15a0 --- /dev/null +++ b/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiConf.java @@ -0,0 +1,30 @@ +package io.jans.configapi.model.configuration; + +import io.jans.configapi.core.model.Conf; +import io.jans.orm.annotation.AttributeName; +import io.jans.orm.annotation.DataEntry; +import io.jans.orm.annotation.JsonObject; +import io.jans.orm.annotation.ObjectClass; + +@DataEntry +@ObjectClass(value = "jansAppConf") +public class ApiConf extends Conf { + + @JsonObject + @AttributeName(name = "jansConfDyn") + private ApiAppConfiguration dynamicConf; + + public ApiAppConfiguration getDynamicConf() { + return dynamicConf; + } + + public void setDynamicConf(ApiAppConfiguration dynamicConf) { + this.dynamicConf = dynamicConf; + } + + @Override + public String toString() { + return "ApiConf [dn=" + dn + ", dynamicConf=" + dynamicConf + ", staticConf=" + staticConf + ", revision=" + + revision + "]"; + } +} \ No newline at end of file diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index c07f96a42e7..02b8a114be8 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -34,6 +34,7 @@ tags: - name: Statistics - User - name: Health - Check - name: SCIM - User Management + - name: SCIM - Config Management - name: Auth Server Health - Check - name: Admin UI - Role - name: Admin UI - Permission @@ -2805,6 +2806,60 @@ paths: $ref: '#/components/schemas/ErrorResponse' security: - oauth2: [https://jans.io/oauth/config/scim/users.read https://jans.io/scim/users.read] + + /jans-config-api/scim/config: + get: + summary: Retrieves SCIM App configuration. + description: Retrieves SCIM configuration. + operationId: get-scim-config + security: + - oauth2: [https://jans.io/scim/config.readonly] + tags: + - SCIM - Config Management + responses: + '200': + description: OK + content: + application/json: + schema: + title: ScimAppConfiguration + description: SCIM App configuration. + $ref: '#/components/schemas/ScimAppConfiguration' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + patch: + summary: Partially modifies SCIM App configuration. + description: Partially modifies SCIM App configuration. + operationId: patch-scim-config + security: + - oauth2: [https://jans.io/scim/config.write] + tags: + - SCIM - Config Management + requestBody: + content: + application/json-patch+json: + schema: + type: array + items: + $ref: '#/components/schemas/PatchRequest' + description: String representing patch-document. + example: '[ {op:replace, path: loggingLevel, value: DEBUG } ]' + responses: + '200': + description: OK + content: + application/json: + schema: + title: ScimAppConfiguration + description: SCIM App configuration. + $ref: '#/components/schemas/ScimAppConfiguration' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + /jans-config-api/api/v1/jans-auth-server/health: get: summary: Returns auth server health status. @@ -3279,6 +3334,8 @@ components: https://jans.io/oauth/config/stats.readonly: Vew server with basic statistic https://jans.io/oauth/config/scim/users.read: Vew scim user related information https://jans.io/oauth/config/scim/users.write: Manage scim user related information + https://jans.io/scim/config.readonly: Vew SCIM App configuration + https://jans.io/scim/config.write: Manage SCIM App configuration responses: Found: @@ -6422,4 +6479,68 @@ components: description: The customer first name. customerLastName: type: string - description: The customer last name. \ No newline at end of file + description: The customer last name. + ScimAppConfiguration: + type: object + properties: + baseDN: + type: string + description: Application config Base DN + applicationUrl: + type: string + description: Application base URL + baseEndpoint: + type: string + description: SCIM base endpoint URL + personCustomObjectClass: + type: string + description: Person Object Class + oxAuthIssuer: + type: string + description: Jans Auth - Issuer identifier. + protectionMode: + type: string + enum: + - OAUTH + - BYPASS + description: SCIM Protection Mode + maxCount: + type: integer + example: Maximum number of results per page + userExtensionSchemaURI: + type: string + description: User Extension Schema URI + loggingLevel: + type: string + description: Logging level for scim logger. + enum: + - TRACE + - DEBUG + - INFO + - WARN + - ERROR + - FATAL + - OFF + loggingLayout: + type: string + description: Logging layout used for Server loggers. + externalLoggerConfiguration: + type: string + description: Path to external log4j2 logging configuration. + metricReporterInterval: + type: integer + description: The interval for metric reporter in seconds. + metricReporterKeepDataDays: + type: integer + description: The days to keep metric reported data. + metricReporterEnabled: + type: boolean + description: Metric reported data enabled flag. + disableJdkLogger: + type: boolean + description: Boolean value specifying whether to enable JDK Loggers. + useLocalCache: + type: boolean + description: Boolean value specifying whether to enable local in-memory cache. + + \ No newline at end of file diff --git a/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/auth/OAuth2Resource.java b/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/auth/OAuth2Resource.java index b05dba28a8b..c3098146444 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/auth/OAuth2Resource.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/auth/OAuth2Resource.java @@ -9,7 +9,7 @@ import io.jans.ca.plugin.adminui.service.auth.OAuth2Service; import io.jans.ca.plugin.adminui.service.config.AUIConfigurationService; import io.jans.ca.plugin.adminui.utils.ErrorResponse; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import org.slf4j.Logger; import javax.inject.Inject; diff --git a/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/license/LicenseResource.java b/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/license/LicenseResource.java index 5b44a33c08b..54c4affb7fb 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/license/LicenseResource.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/license/LicenseResource.java @@ -5,7 +5,7 @@ import io.jans.ca.plugin.adminui.model.auth.LicenseResponse; import io.jans.ca.plugin.adminui.service.license.LicenseDetailsService; import io.jans.ca.plugin.adminui.utils.ErrorResponse; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import org.slf4j.Logger; import javax.inject.Inject; diff --git a/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/user/UserManagementResource.java b/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/user/UserManagementResource.java index 3464dcf5c9f..9fbfdd7ceaf 100644 --- a/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/user/UserManagementResource.java +++ b/jans-config-api/plugins/admin-ui-plugin/src/main/java/io/jans/ca/plugin/adminui/rest/user/UserManagementResource.java @@ -3,7 +3,7 @@ import io.jans.as.model.config.adminui.AdminPermission; import io.jans.as.model.config.adminui.AdminRole; import io.jans.as.model.config.adminui.RolePermissionMapping; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.ca.plugin.adminui.model.exception.ApplicationException; import io.jans.ca.plugin.adminui.service.user.UserManagementService; import io.jans.ca.plugin.adminui.utils.ErrorResponse; diff --git a/jans-config-api/plugins/scim-plugin/pom.xml b/jans-config-api/plugins/scim-plugin/pom.xml index 13bebd9389c..5ad1ba1549a 100644 --- a/jans-config-api/plugins/scim-plugin/pom.xml +++ b/jans-config-api/plugins/scim-plugin/pom.xml @@ -14,7 +14,6 @@ 4.5.13 - @@ -28,6 +27,11 @@ jans-config-api-server ${jans.version} + + io.jans + jans-orm-annotation + ${jans.version} + io.jans jans-scim-model @@ -46,7 +50,6 @@ 1.5.0 - commons-collections @@ -177,6 +180,31 @@ + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + deploy-to-local-folder + package + + copy-resources + + + ../target/plugins + + + ${project.build.directory} + *-distribution.jar + false + + + + + + - \ No newline at end of file + diff --git a/jans-config-api/plugins/scim-plugin/src/main/assembly/assembly.xml b/jans-config-api/plugins/scim-plugin/src/main/assembly/assembly.xml index b0926380f6a..6d916563516 100644 --- a/jans-config-api/plugins/scim-plugin/src/main/assembly/assembly.xml +++ b/jans-config-api/plugins/scim-plugin/src/main/assembly/assembly.xml @@ -15,6 +15,7 @@ io.jans:jans-scim-model io.jans:jans-scim-client + io.jans:jans-config-api-shared runtime diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/configuration/ScimConfigurationFactory.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/configuration/ScimConfigurationFactory.java new file mode 100644 index 00000000000..c8948290682 --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/configuration/ScimConfigurationFactory.java @@ -0,0 +1,31 @@ +/* + * 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.plugin.scim.configuration; + +import io.jans.configapi.configuration.ConfigurationFactory; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.slf4j.Logger; + +@ApplicationScoped +public class ScimConfigurationFactory { + + public static final String CONFIGURATION_ENTRY_DN = "scim_ConfigurationEntryDN"; + + @Inject + private Logger log; + + @Inject + ConfigurationFactory configurationFactory; + + public String getScimConfigurationDn() { + return configurationFactory.getConfigurationDn(CONFIGURATION_ENTRY_DN); + } + +} diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/model/config/ScimAppConfiguration.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/model/config/ScimAppConfiguration.java new file mode 100644 index 00000000000..c700a62de78 --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/model/config/ScimAppConfiguration.java @@ -0,0 +1,211 @@ +package io.jans.configapi.plugin.scim.model.config; + +import io.jans.config.oxtrust.Configuration; +import io.jans.orm.annotation.AttributeName; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ScimAppConfiguration implements Configuration, Serializable { + + private static final long serialVersionUID = 1244429172476500948L; + + @JsonProperty("baseDN") + @AttributeName(name = "baseDN") + private String baseDn; + + @JsonProperty("applicationUrl") + @AttributeName(name = "applicationUrl") + private String appUrl; + + @JsonProperty("baseEndpoint") + @AttributeName(name = "baseEndpoint") + private String baseUrl; + + @JsonProperty("personCustomObjectClass") + @AttributeName(name = "personCustomObjectClass") + private String personCustomObjClass; + + @JsonProperty("oxAuthIssuer") + @AttributeName(name = "oxAuthIssuer") + private String authIssuer; + + @JsonProperty("protectionMode") + @AttributeName(name = "protectionMode") + private String protectionScimMode; + + private int maxCount; + + @JsonProperty("userExtensionSchemaURI") + @AttributeName(name = "userExtensionSchemaURI") + private String userExtSchemaURI; + + @JsonProperty("loggingLevel") + @AttributeName(name = "loggingLevel") + private String logLevel; + + @JsonProperty("loggingLayout") + @AttributeName(name = "loggingLayout") + private String logLayout; + + @JsonProperty("externalLoggerConfiguration") + @AttributeName(name = "externalLoggerConfiguration") + private String externalLoggerConfig; + + @JsonProperty("metricReporterInterval") + @AttributeName(name = "metricReporterInterval") + private int metricReportInterval; + + @JsonProperty("metricReporterKeepDataDays") + @AttributeName(name = "metricReporterKeepDataDays") + private int metricReportKeepDataDays; + + @JsonProperty("metricReporterEnabled") + @AttributeName(name = "metricReporterEnabled") + private Boolean metricReportEnabled; + + private Boolean disableJdkLogger = true; + private Boolean useLocalCache = false; + + public String getBaseDn() { + return baseDn; + } + + public void setBaseDn(String baseDn) { + this.baseDn = baseDn; + } + + public String getAppUrl() { + return appUrl; + } + + public void setAppUrl(String appUrl) { + this.appUrl = appUrl; + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public String getPersonCustomObjClass() { + return personCustomObjClass; + } + + public void setPersonCustomObjClass(String personCustomObjClass) { + this.personCustomObjClass = personCustomObjClass; + } + + public String getAuthIssuer() { + return authIssuer; + } + + public void setAuthIssuer(String authIssuer) { + this.authIssuer = authIssuer; + } + + public String getProtectionScimMode() { + return protectionScimMode; + } + + public void setProtectionScimMode(String protectionScimMode) { + this.protectionScimMode = protectionScimMode; + } + + public int getMaxCount() { + return maxCount; + } + + public void setMaxCount(int maxCount) { + this.maxCount = maxCount; + } + + public String getUserExtSchemaURI() { + return userExtSchemaURI; + } + + public void setUserExtSchemaURI(String userExtSchemaURI) { + this.userExtSchemaURI = userExtSchemaURI; + } + + public String getLogLevel() { + return logLevel; + } + + public void setLogLevel(String logLevel) { + this.logLevel = logLevel; + } + + public String getLogLayout() { + return logLayout; + } + + public void setLogLayout(String logLayout) { + this.logLayout = logLayout; + } + + public String getExternalLoggerConfig() { + return externalLoggerConfig; + } + + public void setExternalLoggerConfig(String externalLoggerConfig) { + this.externalLoggerConfig = externalLoggerConfig; + } + + public int getMetricReportInterval() { + return metricReportInterval; + } + + public void setMetricReportInterval(int metricReportInterval) { + this.metricReportInterval = metricReportInterval; + } + + public int getMetricReportKeepDataDays() { + return metricReportKeepDataDays; + } + + public void setMetricReportKeepDataDays(int metricReportKeepDataDays) { + this.metricReportKeepDataDays = metricReportKeepDataDays; + } + + public Boolean getMetricReportEnabled() { + return metricReportEnabled; + } + + public void setMetricReportEnabled(Boolean metricReportEnabled) { + this.metricReportEnabled = metricReportEnabled; + } + + public Boolean getDisableJdkLogger() { + return disableJdkLogger; + } + + public void setDisableJdkLogger(Boolean disableJdkLogger) { + this.disableJdkLogger = disableJdkLogger; + } + + public Boolean getUseLocalCache() { + return useLocalCache; + } + + public void setUseLocalCache(Boolean useLocalCache) { + this.useLocalCache = useLocalCache; + } + + @Override + public String toString() { + return "ScimAppConfiguration [baseDn=" + baseDn + ", appUrl=" + appUrl + ", baseUrl=" + baseUrl + + ", personCustomObjClass=" + personCustomObjClass + ", authIssuer=" + authIssuer + + ", protectionScimMode=" + protectionScimMode + ", maxCount=" + maxCount + ", userExtSchemaURI=" + + userExtSchemaURI + ", logLevel=" + logLevel + ", logLayout=" + logLayout + ", externalLoggerConfig=" + + externalLoggerConfig + ", metricReportInterval=" + metricReportInterval + + ", metricReportKeepDataDays=" + metricReportKeepDataDays + ", metricReportEnabled=" + + metricReportEnabled + ", disableJdkLogger=" + disableJdkLogger + ", useLocalCache=" + useLocalCache + + "]"; + } + +} diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/model/config/ScimConf.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/model/config/ScimConf.java new file mode 100644 index 00000000000..f624b696ab4 --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/model/config/ScimConf.java @@ -0,0 +1,36 @@ +/* + * 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.plugin.scim.model.config; + +import io.jans.configapi.core.model.Conf; +import io.jans.orm.annotation.AttributeName; +import io.jans.orm.annotation.DataEntry; +import io.jans.orm.annotation.JsonObject; +import io.jans.orm.annotation.ObjectClass; + +@DataEntry +@ObjectClass(value = "jansAppConf") +public class ScimConf extends Conf { + + @JsonObject + @AttributeName(name = "jansConfDyn") + protected ScimAppConfiguration dynamicConf; + + public ScimAppConfiguration getDynamicConf() { + return dynamicConf; + } + + public void setDynamicConf(ScimAppConfiguration dynamicConf) { + this.dynamicConf = dynamicConf; + } + + @Override + public String toString() { + return "ScimConf [dn=" + dn + ", dynamicConf=" + dynamicConf + ", staticConf=" + staticConf + ", revision=" + + revision + "]"; + } +} \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ApiApplication.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ApiApplication.java index 173034cd29c..0f3eec22eb0 100644 --- a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ApiApplication.java +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ApiApplication.java @@ -14,7 +14,8 @@ public Set> getClasses() { // General classes.add(ScimResource.class); - + classes.add(ScimConfigResource.class); + return classes; } } diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimConfigResource.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimConfigResource.java new file mode 100644 index 00000000000..730e80c6c37 --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimConfigResource.java @@ -0,0 +1,61 @@ +package io.jans.configapi.plugin.scim.rest; + +import com.github.fge.jsonpatch.JsonPatchException; + +import io.jans.configapi.core.rest.ProtectedApi; +import io.jans.configapi.plugin.scim.service.ScimConfigService; +import io.jans.configapi.plugin.scim.model.config.ScimAppConfiguration; +import io.jans.configapi.plugin.scim.model.config.ScimConf; +import io.jans.configapi.core.util.Jackson; +import io.jans.configapi.plugin.scim.util.Constants; + +import org.slf4j.Logger; + +import java.io.IOException; +import javax.inject.Inject; +import javax.validation.constraints.NotNull; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + + +@Path(Constants.CONFIG) +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class ScimConfigResource { + + @Inject + Logger log; + + @Inject + ScimConfigService scimConfigService; + + @GET + @ProtectedApi(scopes = { "https://jans.io/scim/config.readonly" }) + public Response getAppConfiguration() { + ScimAppConfiguration appConfiguration = scimConfigService.find(); + log.debug("SCIM appConfiguration:{}", appConfiguration); + return Response.ok(appConfiguration).build(); + } + + @PATCH + @Consumes(MediaType.APPLICATION_JSON_PATCH_JSON) + @ProtectedApi(scopes = { "https://jans.io/scim/config.write" }) + public Response patchAppConfigurationProperty(@NotNull String requestString) throws IOException,JsonPatchException { + log.debug("AUTH CONF details to patch - requestString:{}", requestString); + ScimConf conf = scimConfigService.findConf(); + ScimAppConfiguration appConfiguration = conf.getDynamicConf(); + log.trace("AUTH CONF details BEFORE patch - conf:{}, appConfiguration:{}", conf, appConfiguration); + + appConfiguration = Jackson.applyPatch(requestString, appConfiguration); + log.trace("AUTH CONF details BEFORE patch merge - appConfiguration:{}" ,appConfiguration); + conf.setDynamicConf(appConfiguration); + + scimConfigService.merge(conf); + appConfiguration = scimConfigService.find(); + log.debug("AUTH CONF details AFTER patch merge - appConfiguration:{}", appConfiguration); + return Response.ok(appConfiguration).build(); + } + + +} diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimResource.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimResource.java index 0a3ed0e3c0e..cdaa7e2f518 100644 --- a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimResource.java +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimResource.java @@ -1,7 +1,7 @@ package io.jans.configapi.plugin.scim.rest; import static io.jans.as.model.util.Util.escapeLog; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.plugin.scim.service.ScimService; import io.jans.scim.model.scim2.SearchRequest; import io.jans.scim.model.scim2.patch.PatchRequest; diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/service/ScimConfigService.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/service/ScimConfigService.java new file mode 100644 index 00000000000..29de2e5149a --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/service/ScimConfigService.java @@ -0,0 +1,44 @@ +package io.jans.configapi.plugin.scim.service; + +import io.jans.configapi.plugin.scim.configuration.ScimConfigurationFactory; +import io.jans.configapi.plugin.scim.model.config.ScimAppConfiguration; +import io.jans.configapi.plugin.scim.model.config.ScimConf; +import io.jans.orm.PersistenceEntryManager; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.slf4j.Logger; + +@ApplicationScoped +public class ScimConfigService { + + @Inject + Logger log; + + @Inject + PersistenceEntryManager persistenceManager; + + @Inject + ScimConfigurationFactory scimConfigurationFactory; + + public ScimConf findConf() { + final String dn = scimConfigurationFactory.getScimConfigurationDn(); + log.debug("\n\n ScimConfigService::findConf() - dn:{} ", dn); + return persistenceManager.find(dn, ScimConf.class, null); + } + + public void merge(ScimConf conf) { + conf.setRevision(conf.getRevision() + 1); + persistenceManager.merge(conf); + } + + public ScimAppConfiguration find() { + final ScimConf conf = findConf(); + log.debug( + "\n\n ScimConfigService::find() - new - conf.getDn:{}, conf.getDynamicConf:{}, conf.getStaticConf:{}, conf.getRevision:{}", + conf.getDn(), conf.getDynamicConf(), conf.getStaticConf(), conf.getRevision()); + return conf.getDynamicConf(); + } + +} diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/service/ScimService.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/service/ScimService.java index 94a5737989d..caf19b6e826 100644 --- a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/service/ScimService.java +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/service/ScimService.java @@ -1,6 +1,5 @@ package io.jans.configapi.plugin.scim.service; -import static io.jans.configapi.core.util.Util.escapeLog; import io.jans.configapi.util.AuthUtil; import io.jans.configapi.plugin.scim.model.config.ScimConfiguration; diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/util/Constants.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/util/Constants.java new file mode 100644 index 00000000000..33cdf7808b5 --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/util/Constants.java @@ -0,0 +1,19 @@ +/* + * 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.plugin.scim.util; + +public class Constants { + + private Constants() {} + + public static final String SCIM_CONFIGURATION_ENTRY = "scim_ConfigurationEntryDN"; + public static final String BASE_API_URL = "/"; + public static final String SCIM = "/scim"; + public static final String CONFIG = "/config"; + public static final String USER = "/user"; + +} \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers b/jans-config-api/plugins/scim-plugin/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers new file mode 100644 index 00000000000..b2c9664d366 --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers @@ -0,0 +1,3 @@ +io.jans.configapi.filters.AuthorizationFilter +io.jans.configapi.filters.LoggingFilter + 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/feature/scim/config/scim-config.feature new file mode 100644 index 00000000000..5873b6d0770 --- /dev/null +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/config/scim-config.feature @@ -0,0 +1,82 @@ + +Feature: Scim config + +Background: +* def mainUrl = scim_config_url + + +Scenario: Fetch scim config without bearer token + Given url mainUrl + When method GET + Then status 401 + + +@Get-all +Scenario: Fetch config by filter + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + + +@patch-config-maxCount +Scenario: Patch config properties + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And print response.maxCount + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And def request_body = (response.maxCount == null ? "[ {\"op\":\"add\", \"path\": \"/maxCount\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/maxCount\", \"value\":\""+response.maxCount+"\" } ]") + And print request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + And print 'SCIM App configuration' + + +@patch-config-loggingLevel +Scenario: Patch loggingLevel properties + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And print response.loggingLevel + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And def request_body = (response.loggingLevel == null ? "[ {\"op\":\"add\", \"path\": \"/loggingLevel\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/loggingLevel\", \"value\":\""+response.loggingLevel+"\" } ]") + And print request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + And print 'SCIM App configuration' + +@patch-config-userExtensionSchemaURI +Scenario: Patch userExtensionSchemaURI properties + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And print response.userExtensionSchemaURI + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And header Content-Type = 'application/json-patch+json' + And def request_body = (response.userExtensionSchemaURI == null ? "[ {\"op\":\"add\", \"path\": \"/userExtensionSchemaURI\", \"value\":null } ]" : "[ {\"op\":\"replace\", \"path\": \"/userExtensionSchemaURI\", \"value\":\""+response.userExtensionSchemaURI+"\" } ]") + And print request_body + And request request_body + Then print request + When method PATCH + Then status 200 + And print response + And print 'SCIM App configuration' \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user-patch.json b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user-patch.json index 5724784f072..2b287584397 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user-patch.json +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user-patch.json @@ -2,26 +2,33 @@ "schemas": [ "urn:ietf:params:scim:api:messages:2.0:PatchOp" ], - "Operations": [ - - { - "op": "add", - "path": "emails", - "value": { - "value": "test2@gluu.org", - "type": "other", - "primary": false - } - }, - { - "op": "add", - "path": "phoneNumbers", - "value": [ - { - "value": "555 123 8901", - "type": "other" - } - ] - } + "Operations": [ + { + "op": "replace", + "path": "name", + "value": { + "familyName": "re-patched Jensen", + "givenName": "re-patched Barbara", + "middleName": "re-patched Jane" + } + }, + { + "op": "replace", + "path": "phoneNumbers", + "value": [ + { + "value": "re-patch 555 123 4567", + "type": "other" + }, + { + "value": "re-patch 666 000 1234", + "type": "work" + } + ] + }, + { + "op": "remove", + "path": "name.middleName" + } ] } \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.feature b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.feature index 2ac262007f9..52d2066d593 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.feature +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.feature @@ -2,7 +2,7 @@ Feature: Scim Users Background: -* def mainUrl = scim_url +* def mainUrl = scim_user_url Scenario: Fetch scim users without bearer token diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.json b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.json index 6874d89464b..af970542d3b 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.json +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.json @@ -6,7 +6,7 @@ "resourceType": "User", "location": "https://jans.server1/jans-scim/restv1/v2/Users/48b44f61-ef93-40ff-b1e1-bc00be97225d" }, - "userName": "test-admin", + "userName": "test-admin-test1", "name": { "familyName": "User", "givenName": "TestAdmin", @@ -18,7 +18,7 @@ "active": true, "emails": [ { - "value": "test.admin@jans.server1", + "value": "test.admin@jans.server", "primary": false } ], 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 index 2e35953a9b5..bf39ae8c4f2 100644 --- 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 @@ -44,7 +44,8 @@ function() { accessToken: '123', //scim - scim_url: baseUrl + '/jans-config-api/scim/user', + scim_user_url: baseUrl + '/jans-config-api/scim/user', + scim_config_url: baseUrl + '/jans-config-api/scim/config', }; karate.configure('connectTimeout', 30000); 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 index 0111ad31c0d..85eae142b75 100644 --- 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 @@ -45,7 +45,8 @@ function() { //scim - scim_url: baseUrl + '/jans-config-api/scim/user', + scim_user_url: baseUrl + '/jans-config-api/scim/user', + scim_config_url: baseUrl + '/jans-config-api/scim/config', }; karate.configure('connectTimeout', 30000); diff --git a/jans-config-api/pom.xml b/jans-config-api/pom.xml index 810cd8a0314..80b83cdc702 100644 --- a/jans-config-api/pom.xml +++ b/jans-config-api/pom.xml @@ -119,6 +119,11 @@ jans-config-api-server ${project.version} + + io.jans + jans-config-api-shared + ${jans.version} + io.jans jans-core-util @@ -197,6 +202,11 @@ + + io.jans + jans-orm-annotation + ${jans.version} + diff --git a/jans-config-api/profiles/default/config-api-test.properties b/jans-config-api/profiles/default/config-api-test.properties index ed39d253c7f..f31843b0563 100644 --- a/jans-config-api/profiles/default/config-api-test.properties +++ b/jans-config-api/profiles/default/config-api-test.properties @@ -1,7 +1,7 @@ # The URL of your Jans installation test.server=https://jenkins-config-api.gluu.org -test.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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/jwks.readonly https://jans.io/oauth/config/jwks.write 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 +test.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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/jwks.readonly https://jans.io/oauth/config/jwks.write 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 token.endpoint=https://jenkins-config-api.gluu.org/jans-auth/restv1/token token.grant.type=client_credentials diff --git a/jans-config-api/profiles/jans-ui.jans.io/test.properties b/jans-config-api/profiles/jans-ui.jans.io/test.properties index 0ff17c27878..d2d4915e074 100644 --- a/jans-config-api/profiles/jans-ui.jans.io/test.properties +++ b/jans-config-api/profiles/jans-ui.jans.io/test.properties @@ -1,4 +1,4 @@ -test.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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/jwks.readonly https://jans.io/oauth/config/jwks.write 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 +test.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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/jwks.readonly https://jans.io/oauth/config/jwks.write 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 # Test env Setting token.endpoint=https://jans-ui.jans.io/jans-auth/restv1/token diff --git a/jans-config-api/profiles/jenkins-config-api.gluu.org/test.properties b/jans-config-api/profiles/jenkins-config-api.gluu.org/test.properties index 24e0a6c778e..b8bc8b1581d 100644 --- a/jans-config-api/profiles/jenkins-config-api.gluu.org/test.properties +++ b/jans-config-api/profiles/jenkins-config-api.gluu.org/test.properties @@ -1,6 +1,6 @@ test.server=https://jenkins-config-api.gluu.org -test.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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/jwks.readonly https://jans.io/oauth/config/jwks.write 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 +test.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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/jwks.readonly https://jans.io/oauth/config/jwks.write 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 token.endpoint=https://jenkins-config-api.gluu.org/jans-auth/restv1/token token.grant.type=client_credentials diff --git a/jans-config-api/profiles/local/test.properties b/jans-config-api/profiles/local/test.properties index 1490f1c37dc..aded38d060b 100644 --- a/jans-config-api/profiles/local/test.properties +++ b/jans-config-api/profiles/local/test.properties @@ -1,5 +1,5 @@ #LOCAL -test.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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/jwks.readonly https://jans.io/oauth/config/jwks.write 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 +test.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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/jwks.readonly https://jans.io/oauth/config/jwks.write 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 # Test env Setting #token.endpoint=https://jenkins-config-api.gluu.org/jans-auth/restv1/token @@ -41,8 +41,8 @@ test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/con # jans.server1 token.endpoint=https://jans.server1/jans-auth/restv1/token token.grant.type=client_credentials -test.client.id=1800.4ce06d8b-97f0-4dfb-91be-bc9b66029f8d -test.client.secret=8jh513753567 +test.client.id=1800.ba5c72a0-733c-44e9-82fb-9c710e4e7408 +test.client.secret=EcBbZAVoH8gr test.issuer=https://jans.server1 # jans.server2 @@ -52,5 +52,10 @@ test.issuer=https://jans.server1 #test.client.secret=9ZW2HaDakqD4 #test.issuer=https://jans.server2 - +# jans.server3 +#token.endpoint=https://jans.server3/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1800.1adcb34a-e1a5-4b4d-86d0-f92c62aab52b +#test.client.secret=aDiH4IuuGddZ +#test.issuer=https://jans.server3 diff --git a/jans-config-api/server/pom.xml b/jans-config-api/server/pom.xml index cccab88f887..cac37a65a17 100644 --- a/jans-config-api/server/pom.xml +++ b/jans-config-api/server/pom.xml @@ -50,6 +50,10 @@ io.jans jans-config-api-common + + io.jans + jans-config-api-shared + io.jans jans-core-timer-weld diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/configuration/ConfigurationFactory.java b/jans-config-api/server/src/main/java/io/jans/configapi/configuration/ConfigurationFactory.java index 0a7b201ca1a..5a154f68bd9 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/configuration/ConfigurationFactory.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/configuration/ConfigurationFactory.java @@ -14,6 +14,7 @@ import io.jans.as.model.configuration.AppConfiguration; import io.jans.as.model.error.ErrorResponseFactory; import io.jans.as.model.util.SecurityProviderUtility; +import io.jans.configapi.model.configuration.ApiConf; import io.jans.configapi.model.configuration.ApiAppConfiguration; import io.jans.configapi.model.configuration.CorsConfiguration; import io.jans.configapi.model.configuration.CorsConfigurationFilter; @@ -89,7 +90,6 @@ public class ConfigurationFactory { private ApiAppConfiguration apiAppConfiguration; private CorsConfigurationFilter corsConfigurationFilter; - private StaticConfiguration apiAppStaticConf; private long loadedRevision = -1; private String apiProtectionType; @@ -130,7 +130,7 @@ public CorsConfiguration getCorsConfiguration() { this.corsConfigurationFilter.getCorsSupportCredentials().toString(), Long.toString(this.corsConfigurationFilter.getCorsPreflightMaxAge()), this.corsConfigurationFilter.getCorsRequestDecorate().toString()); - log.debug("\n\n Initializing CorsConfiguration = " + corsConfiguration); + log.debug("\n\n Initializing CorsConfiguration:{} ", corsConfiguration); return corsConfiguration; } @@ -194,6 +194,7 @@ public void create() { } loadApiAppConfigurationFromDb(); + log.info("Configuration loadedRevision:{}", this.loadedRevision); installSecurityProvider(); @@ -218,6 +219,10 @@ public String getConfigurationDn() { return this.baseConfiguration.getString(Constants.SERVER_KEY_OF_CONFIGURATION_ENTRY); } + public String getConfigurationDn(String key) { + return this.baseConfiguration.getString(key); + } + private Conf loadAuthConfigurationFromDb() { log.info("loading Auth Server Configuration From DB...."); return this.loadConfigurationFromDb(this.getConfigurationDn()); @@ -225,29 +230,28 @@ private Conf loadAuthConfigurationFromDb() { private void loadApiAppConfigurationFromDb() { log.info("loading Api App Configuration From DB...."); - io.jans.configapi.model.configuration.Conf conf = null; + ApiConf apiConf = null; final PersistenceEntryManager persistenceEntryManager = persistenceEntryManagerInstance.get(); try { - conf = persistenceEntryManager.find(io.jans.configapi.model.configuration.Conf.class, + apiConf = persistenceEntryManager.find(ApiConf.class, this.baseConfiguration.getString("configApi_ConfigurationEntryDN")); } catch (BasePersistenceException ex) { log.error(ex.getMessage()); } - if (conf == null) { - throw new ConfigurationException("Failed to Api App Configuration From DB " + conf); + if (apiConf == null) { + throw new ConfigurationException("Failed to Api App Configuration From DB " + apiConf); } log.info("ApiAppConfigurationFromDb = ...."); - if (conf.getDynamicConf() != null) { - this.apiAppConfiguration = conf.getDynamicConf(); - } - if (conf.getStaticConf() != null) { - this.apiAppStaticConf = conf.getStaticConf(); + if (apiConf.getDynamicConf() != null) { + this.apiAppConfiguration = apiConf.getDynamicConf(); } - this.loadedRevision = conf.getRevision(); - log.debug("\n\n\n *** ConfigurationFactory::loadApiAppConfigurationFromDb() - this.apiAppConfiguration = " - + this.apiAppConfiguration + " *** \n\n\n"); + this.loadedRevision = apiConf.getRevision(); + + log.debug( + "\n\n\n *** ConfigurationFactory::loadApiAppConfigurationFromDb() - apiAppConfiguration:{}, loadedRevision:{} ", + this.apiAppConfiguration, loadedRevision); this.setApiConfigurationProperties(); } @@ -257,8 +261,8 @@ private void setApiConfigurationProperties() { throw new ConfigurationException("Failed to load Configuration properties " + this.apiAppConfiguration); } - log.debug("\n\n\n *** ConfigurationFactory::setApiConfigurationProperties() - this.apiAppConfiguration = " - + this.apiAppConfiguration + " *** \n\n\n"); + log.debug("\n\n\n *** ConfigurationFactory::setApiConfigurationProperties() - this.apiAppConfiguration:{}", + this.apiAppConfiguration); this.apiApprovedIssuer = this.apiAppConfiguration.getApiApprovedIssuer(); this.apiProtectionType = this.apiAppConfiguration.getApiProtectionType(); this.apiClientId = this.apiAppConfiguration.getApiClientId(); @@ -266,24 +270,24 @@ private void setApiConfigurationProperties() { this.configOauthEnabled = this.apiAppConfiguration.isConfigOauthEnabled(); if (this.apiAppConfiguration.getCorsConfigurationFilters() != null - && this.apiAppConfiguration.getCorsConfigurationFilters().size() > 0) { + && !this.apiAppConfiguration.getCorsConfigurationFilters().isEmpty()) { this.corsConfigurationFilter = this.apiAppConfiguration.getCorsConfigurationFilters().stream() .filter(x -> "CorsFilter".equals(x.getFilterName())).findAny().orElse(null); } - log.debug("Properties set, this.apiApprovedIssuer = " + this.apiApprovedIssuer + " , this.apiProtectionType = " - + this.apiProtectionType + " , this.apiClientId = " + this.apiClientId + " , this.apiClientPassword = " - + this.apiClientPassword + " , this.corsConfigurationFilter = " + this.corsConfigurationFilter - + " , this.configOauthEnabled =" + this.configOauthEnabled); + log.debug( + "Properties set, this.apiApprovedIssuer:{}, , this.apiProtectionType:{}, this.apiClientId :{}, this.apiClientPassword:{}, this.corsConfigurationFilter:{}, this.configOauthEnabled:{} ", + this.apiApprovedIssuer, this.apiProtectionType, this.apiClientId, this.apiClientPassword, + this.corsConfigurationFilter, this.configOauthEnabled); // Populate corsConfigurationFilter object CorsConfiguration corsConfiguration = this.getCorsConfiguration(); - log.debug("CorsConfiguration Produced " + corsConfiguration); + log.debug("CorsConfiguration Produced :{} ", corsConfiguration); getCorsConfigurationFilters(); } private Conf loadConfigurationFromDb(String returnAttribute) { - log.info("loadConfigurationFromDb " + returnAttribute); + log.info("loadConfigurationFromDb returnAttribute:{}", returnAttribute); final PersistenceEntryManager persistenceEntryManager = persistenceEntryManagerInstance.get(); try { return persistenceEntryManager.find(Conf.class, returnAttribute); @@ -294,9 +298,9 @@ private Conf loadConfigurationFromDb(String returnAttribute) { } private void loadBaseConfiguration() { - log.info("Loading base configuration " + BASE_PROPERTIES_FILE); + log.info("Loading base configuration - BASE_PROPERTIES_FILE:{}", BASE_PROPERTIES_FILE); this.baseConfiguration = createFileConfiguration(BASE_PROPERTIES_FILE); - log.info("Loaded base configuration:" + baseConfiguration.getProperties()); + log.info("Loaded base configuration:{}", baseConfiguration.getProperties()); } private String confDir() { @@ -312,27 +316,29 @@ private FileConfiguration createFileConfiguration(String fileName) { try { return new FileConfiguration(fileName); } catch (Exception ex) { - log.error("Failed to load configuration from {}", fileName, ex); + if (log.isErrorEnabled()) { + log.error("Failed to load configuration from {}", fileName, ex); + } throw new ConfigurationException("Failed to load configuration from " + fileName, ex); } } - private void init(Conf p_conf) { - initConfigurationConf(p_conf); + private void init(Conf conf) { + initConfigurationConf(conf); } - private void initConfigurationConf(Conf p_conf) { - if (p_conf.getDynamic() != null) { - appConfiguration = p_conf.getDynamic(); + private void initConfigurationConf(Conf conf) { + if (conf.getDynamic() != null) { + appConfiguration = conf.getDynamic(); } - if (p_conf.getStatics() != null) { - staticConf = p_conf.getStatics(); + if (conf.getStatics() != null) { + staticConf = conf.getStatics(); } - if (p_conf.getWebKeys() != null) { - jwks = p_conf.getWebKeys(); + if (conf.getWebKeys() != null) { + jwks = conf.getWebKeys(); } - if (p_conf.getErrors() != null) { - errorResponseFactory = new ErrorResponseFactory(p_conf.getErrors(), p_conf.getDynamic()); + if (conf.getErrors() != null) { + errorResponseFactory = new ErrorResponseFactory(conf.getErrors(), conf.getDynamic()); } } @@ -342,7 +348,8 @@ private void loadCryptoConfigurationSalt() { this.cryptoConfigurationSalt = cryptoConfiguration.getString("encodeSalt"); } catch (Exception ex) { - log.error("Failed to load configuration from {}", saltFilePath, ex); + if (log.isErrorEnabled()) + log.error("Failed to load configuration from {}", saltFilePath, ex); throw new ConfigurationException("Failed to load configuration from " + saltFilePath, ex); } } diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/filters/AuthorizationFilter.java b/jans-config-api/server/src/main/java/io/jans/configapi/filters/AuthorizationFilter.java index c3143197cb1..0ccafced878 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/filters/AuthorizationFilter.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/filters/AuthorizationFilter.java @@ -6,6 +6,7 @@ package io.jans.configapi.filters; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.security.service.AuthorizationService; import io.jans.configapi.util.ApiConstants; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/filters/ProtectedApi.java b/jans-config-api/server/src/main/java/io/jans/configapi/filters/ProtectedApi.java deleted file mode 100644 index 78d39c7e85d..00000000000 --- a/jans-config-api/server/src/main/java/io/jans/configapi/filters/ProtectedApi.java +++ /dev/null @@ -1,29 +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.filters; - -import javax.ws.rs.NameBinding; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Mougang T.Gasmyr - * - */ -@NameBinding -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.METHOD }) -public @interface ProtectedApi { - - /** - * @return UMA scopes which application should have to access jans-config-api. - */ - String[] scopes() default {}; - -} diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AcrsResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AcrsResource.java index 1c69104cc4e..4cd2fe3894e 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AcrsResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AcrsResource.java @@ -7,7 +7,7 @@ package io.jans.configapi.rest.resource.auth; import io.jans.as.persistence.model.configuration.GluuConfiguration; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.rest.model.AuthenticationMethod; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.util.ApiAccessConstants; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AttributesResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AttributesResource.java index 932dc5ddee1..bba38615068 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AttributesResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AttributesResource.java @@ -7,12 +7,12 @@ package io.jans.configapi.rest.resource.auth; import com.github.fge.jsonpatch.JsonPatchException; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.AttributeService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.configapi.util.AttributeNames; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import io.jans.model.GluuAttribute; import javax.inject.Inject; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CacheConfigurationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CacheConfigurationResource.java index ec477a75e99..daa2ea9c03a 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CacheConfigurationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CacheConfigurationResource.java @@ -9,11 +9,11 @@ import com.github.fge.jsonpatch.JsonPatchException; import io.jans.as.common.service.common.ApplicationFactory; import io.jans.as.persistence.model.configuration.GluuConfiguration; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import io.jans.orm.PersistenceEntryManager; import io.jans.service.cache.*; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ClientsResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ClientsResource.java index e2fdeb57b14..cda92c32a25 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ClientsResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ClientsResource.java @@ -10,13 +10,13 @@ import static io.jans.as.model.util.Util.escapeLog; import io.jans.as.common.model.registration.Client; import io.jans.as.common.service.common.EncryptionService; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.rest.model.SearchRequest; import io.jans.configapi.service.auth.ClientService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.configapi.util.AttributeNames; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import io.jans.orm.model.PagedResult; import io.jans.util.StringHelper; import io.jans.util.security.StringEncrypter.EncryptionException; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigResource.java index 4ef89079500..4d891f7eb01 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigResource.java @@ -8,11 +8,11 @@ import io.jans.as.model.config.Conf; import io.jans.as.model.configuration.AppConfiguration; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import javax.inject.Inject; import javax.validation.constraints.NotNull; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigSmtpResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigSmtpResource.java index fc6876a8e75..629252494e5 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigSmtpResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigSmtpResource.java @@ -9,7 +9,7 @@ import io.jans.as.common.service.common.ConfigurationService; import io.jans.as.common.service.common.EncryptionService; import io.jans.as.persistence.model.configuration.GluuConfiguration; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.model.SmtpConfiguration; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CouchbaseConfigurationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CouchbaseConfigurationResource.java index b006396064e..5824d380b60 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CouchbaseConfigurationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CouchbaseConfigurationResource.java @@ -8,11 +8,11 @@ import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; import com.google.common.base.Joiner; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.CouchbaseConfService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import io.jans.orm.couchbase.model.CouchbaseConnectionConfiguration; import io.jans.orm.couchbase.operation.impl.CouchbaseConnectionProvider; import org.slf4j.Logger; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CustomScriptResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CustomScriptResource.java index c6d988eb0bc..f01c3640059 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CustomScriptResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CustomScriptResource.java @@ -6,7 +6,7 @@ package io.jans.configapi.rest.resource.auth; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.model.custom.script.CustomScriptType; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/Fido2ConfigResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/Fido2ConfigResource.java index 39bd0f068d6..87418bb73b9 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/Fido2ConfigResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/Fido2ConfigResource.java @@ -7,11 +7,11 @@ package io.jans.configapi.rest.resource.auth; import io.jans.config.oxtrust.DbApplicationConfiguration; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.Fido2Service; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import javax.inject.Inject; import javax.validation.constraints.NotNull; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/JwksResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/JwksResource.java index 70e394bdb9f..1af0b161350 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/JwksResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/JwksResource.java @@ -10,11 +10,11 @@ import io.jans.as.model.config.Conf; import io.jans.as.model.config.WebKeysConfiguration; import io.jans.as.model.jwk.JSONWebKey; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import javax.inject.Inject; import javax.validation.constraints.NotNull; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LdapConfigurationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LdapConfigurationResource.java index 484b4a95363..fc1a229a298 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LdapConfigurationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LdapConfigurationResource.java @@ -7,12 +7,12 @@ package io.jans.configapi.rest.resource.auth; import com.github.fge.jsonpatch.JsonPatchException; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.LdapConfigurationService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.configapi.util.ConnectionStatus; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import io.jans.model.ldap.GluuLdapConfiguration; import org.slf4j.Logger; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LoggingResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LoggingResource.java index 549c226780a..153514af4eb 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LoggingResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LoggingResource.java @@ -8,7 +8,7 @@ import io.jans.as.model.config.Conf; import io.jans.as.model.configuration.AppConfiguration; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.rest.model.Logging; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.util.ApiAccessConstants; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ScopesResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ScopesResource.java index 2e906c453ac..374a5e29bd4 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ScopesResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ScopesResource.java @@ -9,12 +9,12 @@ import com.github.fge.jsonpatch.JsonPatchException; import io.jans.as.model.common.ScopeType; import io.jans.as.persistence.model.Scope; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.ScopeService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.configapi.util.AttributeNames; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import io.jans.util.StringHelper; import javax.inject.Inject; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/SqlConfigurationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/SqlConfigurationResource.java index 014a3b15a2e..b5e1cff7fc0 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/SqlConfigurationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/SqlConfigurationResource.java @@ -8,11 +8,11 @@ import com.google.common.base.Joiner; import io.jans.orm.sql.model.SqlConnectionConfiguration; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.SqlConfService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import io.jans.orm.sql.operation.impl.SqlConnectionProvider; import org.slf4j.Logger; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/StatResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/StatResource.java index 9dd58f81784..5815dfa8957 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/StatResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/StatResource.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.service.auth.AuthService; import io.jans.configapi.util.ApiAccessConstants; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UmaResourcesResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UmaResourcesResource.java index dba4f712a3c..aef74692e9d 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UmaResourcesResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UmaResourcesResource.java @@ -8,12 +8,12 @@ import com.github.fge.jsonpatch.JsonPatchException; import io.jans.as.model.uma.persistence.UmaResource; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.UmaResourceService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.configapi.util.AttributeNames; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import io.jans.orm.exception.EntryPersistenceException; import javax.inject.Inject; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/security/api/ApiProtectionService.java b/jans-config-api/server/src/main/java/io/jans/configapi/security/api/ApiProtectionService.java index 42d0c97fef4..1e52870b332 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/security/api/ApiProtectionService.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/security/api/ApiProtectionService.java @@ -10,7 +10,7 @@ import io.jans.configapi.configuration.ConfigurationFactory; import io.jans.configapi.service.auth.ClientService; import io.jans.configapi.service.auth.ScopeService; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import java.io.IOException; import java.io.InputStream; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/security/client/AuthClientFactory.java b/jans-config-api/server/src/main/java/io/jans/configapi/security/client/AuthClientFactory.java index abff58d1dbe..b7e8dd147ee 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/security/client/AuthClientFactory.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/security/client/AuthClientFactory.java @@ -19,7 +19,7 @@ import io.jans.as.model.common.IntrospectionResponse; import io.jans.as.model.jwk.JSONWebKeySet; import static io.jans.as.model.jwk.JWKParameter.JSON_WEB_KEY_SET; -import io.jans.configapi.util.Jackson; +import io.jans.configapi.core.util.Jackson; import org.apache.commons.lang.StringUtils; import org.json.JSONObject; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java b/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java index 1d6ac29af3d..77561a72f51 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java @@ -10,7 +10,7 @@ import io.jans.configapi.security.api.ApiProtectionCache; import io.jans.configapi.security.client.AuthClientFactory; import io.jans.configapi.configuration.ConfigurationFactory; -import io.jans.configapi.filters.ProtectedApi; +import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.service.auth.ClientService; import io.jans.configapi.service.auth.ScopeService; diff --git a/jans-config-api/server/src/main/resources/config-api-rs-protect.json b/jans-config-api/server/src/main/resources/config-api-rs-protect.json index 96b1048fdc9..f3d1f1ca15c 100644 --- a/jans-config-api/server/src/main/resources/config-api-rs-protect.json +++ b/jans-config-api/server/src/main/resources/config-api-rs-protect.json @@ -656,6 +656,23 @@ ] } ] + }, + { + "path":"/jans-config-api/scim/config", + "conditions":[ + { + "httpMethods":["GET"], + "scopes":[ + "https://jans.io/scim/config.readonly" + ] + }, + { + "httpMethods":["PATCH"], + "scopes":[ + "https://jans.io/scim/config.write" + ] + } + ] } ] } \ No newline at end of file diff --git a/jans-config-api/shared/pom.xml b/jans-config-api/shared/pom.xml index f3d6276cea3..9d53ef7c477 100644 --- a/jans-config-api/shared/pom.xml +++ b/jans-config-api/shared/pom.xml @@ -39,10 +39,7 @@ io.jans jans-client-api - - io.jans - jans-config-api-common - + diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/Conf.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/model/Conf.java similarity index 57% rename from jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/Conf.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/model/Conf.java index 3ec48a9b332..57c69f0093d 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/Conf.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/model/Conf.java @@ -1,4 +1,4 @@ -package io.jans.configapi.model.configuration; +package io.jans.configapi.core.model; import io.jans.as.model.config.StaticConfiguration; import io.jans.orm.annotation.AttributeName; @@ -12,36 +12,21 @@ public class Conf { @DN - private String dn; - - @JsonObject - @AttributeName(name = "jansConfDyn") - private ApiAppConfiguration dynamicConf; + protected String dn; @JsonObject @AttributeName(name = "jansConfStatic") - private StaticConfiguration staticConf; + protected StaticConfiguration staticConf; @AttributeName(name = "jansRevision") - private long revision; - - public Conf() { - } + protected long revision; public String getDn() { return dn; } - public void setDn(String p_dn) { - dn = p_dn; - } - - public ApiAppConfiguration getDynamicConf() { - return dynamicConf; - } - - public void setDynamicConf(ApiAppConfiguration dynamicConf) { - this.dynamicConf = dynamicConf; + public void setDn(String dn) { + this.dn = dn; } public StaticConfiguration getStaticConf() { @@ -62,7 +47,6 @@ public void setRevision(long revision) { @Override public String toString() { - return "Conf [dn=" + dn + ", dynamicConf=" + dynamicConf + ", staticConf=" + staticConf + ", revision=" - + revision + "]"; + return "Conf [dn=" + dn + ", staticConf=" + staticConf + ", revision=" + revision + "]"; } } \ No newline at end of file diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/util/Jackson.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/Jackson.java similarity index 86% rename from jans-config-api/common/src/main/java/io/jans/configapi/util/Jackson.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/util/Jackson.java index 0d403781142..50378bb2daf 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/util/Jackson.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/util/Jackson.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.util; +package io.jans.configapi.core.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.AnnotationIntrospector; @@ -57,20 +57,12 @@ public static T applyPatch(JsonPatch jsonPatch, T obj) throws JsonPatchExcep @SuppressWarnings("unchecked") public static T read(InputStream inputStream, T obj) throws IOException { - try { - - Preconditions.checkNotNull(inputStream); - ObjectMapper objectMapper = JacksonUtils.newMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return (T) JacksonUtils.newMapper().readValue(inputStream, obj.getClass()); - } catch (Exception ex) { - ex.printStackTrace(); - throw ex; - } + Preconditions.checkNotNull(inputStream); + return (T) JacksonUtils.newMapper().readValue(inputStream, obj.getClass()); } @SuppressWarnings("unchecked") - public static T getObject(String jsonString, T obj) throws JsonPatchException, IOException { + public static T getObject(String jsonString, T obj) throws IOException { ObjectMapper objectMapper = JacksonUtils.newMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return (T) objectMapper.readValue(jsonString, obj.getClass()); @@ -96,7 +88,7 @@ public static ObjectMapper jsonMapper() { } } - public String getJsonString(T obj) throws JsonPatchException, IOException { + public String getJsonString(T obj) throws IOException { ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(obj); }