diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index f95731d352c..d60e1364af3 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -7888,22 +7888,22 @@ components: $ref: '#/components/schemas/AttributeValidation' tooltip: type: string - selected: - type: boolean whitePagesCanView: type: boolean + selected: + type: boolean adminCanEdit: type: boolean + adminCanView: + type: boolean userCanView: type: boolean userCanEdit: type: boolean - adminCanView: + userCanAccess: type: boolean adminCanAccess: type: boolean - userCanAccess: - type: boolean baseDn: type: string PatchRequest: @@ -8716,8 +8716,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -8727,6 +8725,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn diff --git a/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml b/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml index ce9edff7121..941e2813ac9 100644 --- a/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml @@ -269,7 +269,8 @@ components: challange: type: string challengeHash: - type: string + type: integer + format: int32 creationDate: type: string format: date-time diff --git a/jans-config-api/plugins/docs/kc-link-plugin-swagger.yaml b/jans-config-api/plugins/docs/kc-link-plugin-swagger.yaml new file mode 100644 index 00000000000..7e5898c9f56 --- /dev/null +++ b/jans-config-api/plugins/docs/kc-link-plugin-swagger.yaml @@ -0,0 +1,274 @@ +openapi: 3.0.1 +info: + title: Jans Config API - Keycloak Link + contact: + name: Gluu Support + url: https://support.gluu.org + email: xxx@gluu.org + license: + name: Apache 2.0 + url: https://github.com/JanssenProject/jans/blob/main/LICENSE + version: 1.0.0 +servers: +- url: https://jans.io/ + description: The Jans server +tags: +- name: Keycloak Link - Configuration +paths: + /kc-link/kcLinkConfig: + get: + tags: + - KC Link - Configuration + summary: Gets KC Link configuration properties + description: Gets KC Link configuration properties + operationId: get-kc-link-properties + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/AppConfiguration' + "401": + description: Unauthorized + "500": + description: InternalServerError + security: + - oauth2: + - https://jans.io/oauth/kc-link-config.readonly + put: + tags: + - KC Link - Configuration + summary: Update KC Link configuration properties + description: Update KC Link configuration properties + operationId: put-kc-link-properties + requestBody: + description: GluuAttribute object + content: + application/json: + schema: + $ref: '#/components/schemas/AppConfiguration' + examples: + Request example: + description: Request example + value: "" + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/AppConfiguration' + "401": + description: Unauthorized + "500": + description: InternalServerError + security: + - oauth2: + - https://jans.io/oauth/kc-link-config.write + patch: + tags: + - KC Link - Configuration + summary: Partially modifies KC Link configuration properties. + description: Partially modifies KC Link configuration properties. + operationId: patch-kc-link-properties + requestBody: + description: String representing patch-document. + content: + application/json-patch+json: + schema: + type: array + items: + $ref: '#/components/schemas/JsonPatch' + examples: + Request json example: + description: Request json example + value: "" + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/AppConfiguration' + "401": + description: Unauthorized + "500": + description: InternalServerError + security: + - oauth2: + - https://jans.io/oauth/kc-link-config.write +components: + schemas: + AppConfiguration: + type: object + properties: + sourceConfigs: + type: array + items: + $ref: '#/components/schemas/GluuLdapConfiguration' + inumConfig: + $ref: '#/components/schemas/GluuLdapConfiguration' + targetConfig: + $ref: '#/components/schemas/GluuLdapConfiguration' + ldapSearchSizeLimit: + type: integer + format: int32 + keyAttributes: + type: array + items: + type: string + keyObjectClasses: + type: array + items: + type: string + sourceAttributes: + type: array + items: + type: string + customLdapFilter: + type: string + updateMethod: + type: string + defaultInumServer: + type: boolean + keepExternalPerson: + type: boolean + useSearchLimit: + type: boolean + attributeMapping: + type: array + items: + $ref: '#/components/schemas/CacheRefreshAttributeMapping' + snapshotFolder: + type: string + snapshotMaxCount: + type: integer + format: int32 + keycloakConfiguration: + $ref: '#/components/schemas/KeycloakConfiguration' + baseDN: + type: string + personObjectClassTypes: + type: array + items: + type: string + personCustomObjectClass: + type: string + contactObjectClassTypes: + type: array + items: + type: string + allowPersonModification: + type: boolean + supportedUserStatus: + type: array + items: + type: string + loggingLevel: + type: string + loggingLayout: + type: string + externalLoggerConfiguration: + type: string + metricReporterInterval: + type: integer + format: int32 + metricReporterKeepDataDays: + type: integer + format: int32 + metricReporterEnabled: + type: boolean + disableJdkLogger: + type: boolean + cleanServiceInterval: + type: integer + format: int32 + keycloakLinkEnabled: + type: boolean + keycloakLinkServerIpAddress: + type: string + keycloakLinkPollingInterval: + type: string + keycloakLinkLastUpdate: + type: string + format: date-time + keycloakLinkLastUpdateCount: + type: string + keycloakLinkProblemCount: + type: string + useLocalCache: + type: boolean + CacheRefreshAttributeMapping: + type: object + properties: + source: + type: string + destination: + type: string + GluuLdapConfiguration: + type: object + properties: + configId: + type: string + bindDN: + type: string + bindPassword: + type: string + servers: + type: array + items: + type: string + maxConnections: + type: integer + format: int32 + useSSL: + type: boolean + baseDNs: + type: array + items: + type: string + primaryKey: + type: string + localPrimaryKey: + type: string + useAnonymousBind: + type: boolean + enabled: + type: boolean + version: + type: integer + format: int32 + level: + type: integer + format: int32 + KeycloakConfiguration: + type: object + properties: + serverUrl: + type: string + realm: + type: string + clientId: + type: string + clientSecret: + type: string + grantType: + type: string + username: + type: string + password: + type: string + JsonPatch: + type: object + securitySchemes: + oauth2: + type: oauth2 + flows: + clientCredentials: + tokenUrl: "https://{op-hostname}/.../token" + scopes: + https://jans.io/oauth/kc-link-config.readonly: View Keycloak Link configuration + related information + https://jans.io/oauth/kc-link-config.write: Manage Keycloak Link configuration + related information diff --git a/jans-config-api/plugins/docs/kc-saml-plugin-swagger.yaml b/jans-config-api/plugins/docs/kc-saml-plugin-swagger.yaml index b1e6328bfc2..a668b352de6 100644 --- a/jans-config-api/plugins/docs/kc-saml-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/kc-saml-plugin-swagger.yaml @@ -1009,6 +1009,7 @@ components: type: string TrustRelationship: required: + - clientId - description - displayName - spMetaDataSourceType @@ -1021,6 +1022,8 @@ components: owner: type: string clientId: + maxLength: 60 + minLength: 0 type: string displayName: maxLength: 60 @@ -1058,14 +1061,20 @@ components: - federation - manual - mdq - spMetaDataURL: + nameIDPolicyFormat: type: string - metaLocation: + entityId: type: string - jansEntityId: + singleLogoutServiceUrl: + type: string + redirectUris: type: array items: type: string + spMetaDataURL: + type: string + metaLocation: + type: string releasedAttributes: type: array items: diff --git a/jans-config-api/plugins/kc-link-plugin/pom.xml b/jans-config-api/plugins/kc-link-plugin/pom.xml new file mode 100644 index 00000000000..7398ae84043 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/pom.xml @@ -0,0 +1,298 @@ + + + + plugins + io.jans.jans-config-api.plugins + 1.1.0-SNAPSHOT + + + 4.0.0 + kc-link-plugin + + + 4.4.14 + 4.5.13 + ${project.version} + + + + + + + + io.jans + jans-config-api-shared + ${jans.version} + + + io.jans + jans-config-api-server + ${jans.version} + + + io.jans + jans-orm-annotation + ${jans.version} + + + io.jans + jans-core-document-store + ${jans.version} + + + io.jans + jans-keycloak-link-model + ${jans.version} + + + io.jans + jans-link-model + ${jans.version} + + + + + + org.quartz-scheduler + quartz + + + + io.smallrye + smallrye-config + 1.5.0 + + + + + commons-collections + commons-collections + + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpcore + + + org.apache.httpcomponents + httpcore-nio + ${httpcore.version} + + + + + jakarta.enterprise + jakarta.enterprise.cdi-api + + + jakarta.inject + jakarta.inject-api + + + jakarta.validation + jakarta.validation-api + + + jakarta.ws.rs + jakarta.ws.rs-api + + + org.jboss.resteasy + resteasy-multipart-provider + ${resteasy.version} + + + + + org.apache.james + apache-mime4j-dom + + + org.apache.james + apache-mime4j-storage + + + org.apache.james + apache-mime4j-core + + + + + io.rest-assured + rest-assured + test + + + com.intuit.karate + karate-junit5 + test + + + com.intuit.karate + karate-apache + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + net.masterthought + cucumber-reporting + test + + + + + io.swagger.core.v3 + swagger-core-jakarta + + + + + + + + + ../../profiles/${cfg}/config-build.properties + ../../profiles/${cfg}/config-api-test.properties + + + + + src/test/resources + true + + karate.properties + karate_jenkins.properties + test.properties + *.* + + + + + + + src/main/resources + true + + **/*.xml + **/*.properties + **/*.json + META-INF/services/*.* + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + src/main/assembly/assembly.xml + + + + + + + + maven-surefire-plugin + + + + integration + + --tags ~@ignore + + + + + integration-tests + integration-test + + test + + + false + !integration + integration + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + deploy-to-local-folder + package + + copy-resources + + + ../target/plugins + + + ${project.build.directory} + *-distribution.jar + false + + + + + + + + + + io.swagger.core.v3 + swagger-maven-plugin-jakarta + ${swagger-maven-plugin-jakarta} + + + + true + kc-link-plugin-swagger + ${project.artifactId} + true + + io.jans.configapi.plugin.kc.link.rest + + + + + + + io.swagger.core.v3 + swagger-models-jakarta + ${swagger-models-jakarta} + + + + + + + + \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/assembly/assembly.xml b/jans-config-api/plugins/kc-link-plugin/src/main/assembly/assembly.xml new file mode 100644 index 00000000000..691b7c57b9f --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/assembly/assembly.xml @@ -0,0 +1,31 @@ + + + distribution + + jar + + false + + + true + / + false + + io.jans:jans-keycloak-link-model + io.jans:jans-link-model + + runtime + + + + + ${project.build.directory}/classes + / + + **/* + + + + \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/extensions/KcLinkExtension.java b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/extensions/KcLinkExtension.java new file mode 100644 index 00000000000..11973723678 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/extensions/KcLinkExtension.java @@ -0,0 +1,6 @@ +package io.jans.configapi.plugin.kc.link.extensions; + +import jakarta.enterprise.inject.spi.Extension; + +public class KcLinkExtension implements Extension { +} diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/model/config/KcLinkConfigSource.java b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/model/config/KcLinkConfigSource.java new file mode 100644 index 00000000000..95d7f51b7ae --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/model/config/KcLinkConfigSource.java @@ -0,0 +1,81 @@ +package io.jans.configapi.plugin.kc.link.model.config; + +import io.jans.exception.ConfigurationException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import jakarta.enterprise.context.ApplicationScoped; + +import org.eclipse.microprofile.config.spi.ConfigSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class KcLinkConfigSource implements ConfigSource { + + private static Logger log = LoggerFactory.getLogger(KcLinkConfigSource.class); + private static final String FILE_CONFIG = "kc-link.properties"; + private Properties properties = null; + Map propertiesMap = new HashMap<>(); + + public KcLinkConfigSource() { + this.loadProperties(); + } + + @Override + public Map getProperties() { + log.debug("Getting properties"); + return propertiesMap; + } + + @Override + public Set getPropertyNames() { + log.debug("Getting Property Names"); + try { + return properties.stringPropertyNames(); + + } catch (Exception e) { + log.error("Unable to read properties from file: " + FILE_CONFIG, e); + } + return Collections.emptySet(); + } + + @Override + public int getOrdinal() { + return 800; + } + + @Override + public String getValue(String name) { + log.debug("KcLinkConfigSource()::getValue() - name:{}", name); + try { + return properties.getProperty(name); + } catch (Exception e) { + log.error("Unable to read properties from file: " + FILE_CONFIG, e); + } + + return null; + } + + @Override + public String getName() { + return FILE_CONFIG; + } + + private Properties loadProperties() { + // Load the properties file + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + try ( InputStream inputStream = loader.getResourceAsStream(FILE_CONFIG)) { + properties = new Properties(); + properties.load(inputStream); + properties.stringPropertyNames().stream().forEach(key -> propertiesMap.put(key, properties.getProperty(key))); + return properties; + } catch (Exception e) { + throw new ConfigurationException("Failed to load configuration from "+ FILE_CONFIG, e); + } + } + +} diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/rest/ApiApplication.java b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/rest/ApiApplication.java new file mode 100644 index 00000000000..66e709aecde --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/rest/ApiApplication.java @@ -0,0 +1,39 @@ +package io.jans.configapi.plugin.kc.link.rest; + +import io.jans.configapi.plugin.kc.link.util.Constants; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; +import io.swagger.v3.oas.annotations.info.*; +import io.swagger.v3.oas.annotations.tags.*; +import io.swagger.v3.oas.annotations.security.*; +import io.swagger.v3.oas.annotations.servers.*; + +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; +import java.util.HashSet; +import java.util.Set; + +@ApplicationPath("/kc-link") +@OpenAPIDefinition(info = @Info(title = "Jans Config API - Keycloak Link", version = "1.0.0", contact = @Contact(name = "Gluu Support", url = "https://support.gluu.org", email = "xxx@gluu.org"), + +license = @License(name = "Apache 2.0", url = "https://github.com/JanssenProject/jans/blob/main/LICENSE")), + +tags = { @Tag(name = "Keycloak Link - Configuration")}, + +servers = { @Server(url = "https://jans.io/", description = "The Jans server") }) + +@SecurityScheme(name = "oauth2", type = SecuritySchemeType.OAUTH2, flows = @OAuthFlows(clientCredentials = @OAuthFlow(tokenUrl = "https://{op-hostname}/.../token", scopes = { +@OAuthScope(name = Constants.KC_LINK_CONFIG_READ_ACCESS, description = "View Keycloak Link configuration related information"), +@OAuthScope(name = Constants.KC_LINK_CONFIG_WRITE_ACCESS, description = "Manage Keycloak Link configuration related information")} +))) +public class ApiApplication extends Application { + + @Override + public Set> getClasses() { + HashSet> classes = new HashSet<>(); + + classes.add(KcLinkConfigResource.class); + + return classes; + } +} diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/rest/KcLinkConfigResource.java b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/rest/KcLinkConfigResource.java new file mode 100644 index 00000000000..0a7cdc947fc --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/rest/KcLinkConfigResource.java @@ -0,0 +1,131 @@ +/* + * 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.kc.link.rest; + + +import io.jans.configapi.core.rest.BaseResource; +import io.jans.configapi.core.rest.ProtectedApi; +import io.jans.configapi.core.util.Jackson; +import io.jans.keycloak.link.model.config.AppConfiguration; +import io.jans.keycloak.link.model.config.Conf; +import io.jans.configapi.plugin.kc.link.service.KcLinkConfigService; +import io.jans.configapi.plugin.kc.link.util.Constants; +import io.jans.configapi.util.ApiAccessConstants; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.*; + +import jakarta.inject.Inject; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import java.io.IOException; + +import org.slf4j.Logger; + +import com.github.fge.jsonpatch.JsonPatch; +import com.github.fge.jsonpatch.JsonPatchException; + +@Path(Constants.KC_LINK_CONFIG) +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class KcLinkConfigResource extends BaseResource { + + @Inject + Logger logger; + + @Inject + KcLinkConfigService kcLinkConfigService; + + @Operation(summary = "Gets KC Link configuration properties", description = "Gets KC Link configuration properties", operationId = "get-kc-link-properties", tags = { + "KC Link - Configuration" }, security = @SecurityRequirement(name = "oauth2", scopes = { + Constants.KC_LINK_CONFIG_READ_ACCESS })) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Ok", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppConfiguration.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "500", description = "InternalServerError") }) + @GET + @ProtectedApi(scopes = { Constants.KC_LINK_CONFIG_READ_ACCESS }, groupScopes = { + Constants.KC_LINK_CONFIG_WRITE_ACCESS }, superScopes = { ApiAccessConstants.SUPER_ADMIN_READ_ACCESS, + ApiAccessConstants.SUPER_ADMIN_WRITE_ACCESS }) + public Response getkcLinkConf() { + + AppConfiguration kcLinkConfiguration = kcLinkConfigService.find(); + logger.info("KC Link details kcLinkConfiguration():{}", kcLinkConfiguration); + if(kcLinkConfiguration==null) { + throwInternalServerException("It seems Kc Link module is not setup, kindly check."); + } + return Response.ok(kcLinkConfiguration).build(); + + } + + @Operation(summary = "Update KC Link configuration properties", description = "Update KC Link configuration properties", operationId = "put-kc-link-properties", tags = { + "KC Link - Configuration" }, security = @SecurityRequirement(name = "oauth2", scopes = { + Constants.KC_LINK_CONFIG_WRITE_ACCESS })) + @RequestBody(description = "GluuAttribute object", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppConfiguration.class), examples = @ExampleObject(name = "Request example", value = "example/kc-link/config/kc-link-put.json"))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Ok", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppConfiguration.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "500", description = "InternalServerError") }) + @PUT @ProtectedApi(scopes = { Constants.KC_LINK_CONFIG_WRITE_ACCESS }, groupScopes = {}, superScopes = { + ApiAccessConstants.SUPER_ADMIN_WRITE_ACCESS }) + public Response updatekcLinkConf(@Valid AppConfiguration kcLinkAppConf) { + logger.info("Update KC Link conf details kcLinkAppConf():{}", kcLinkAppConf); + Conf conf = kcLinkConfigService.findKcLinkConf(); + logger.info("KC Link conf:{} ", conf); + if(conf==null) { + throwInternalServerException("It seems Kc Link module is not setup, kindly check."); + } + + conf.setDynamic(kcLinkAppConf); + kcLinkConfigService.mergeKcLinkConfig(conf); + kcLinkAppConf = kcLinkConfigService.find(); + logger.info("KC Link conf, post update - kcLinkAppConf:{}", kcLinkAppConf); + return Response.ok(kcLinkAppConf).build(); + + } + + @Operation(summary = "Partially modifies KC Link configuration properties.", description = "Partially modifies KC Link configuration properties.", operationId = "patch-kc-link-properties", tags = { + "KC Link - Configuration" }, security = @SecurityRequirement(name = "oauth2", scopes = { + Constants.KC_LINK_CONFIG_WRITE_ACCESS })) + @RequestBody(description = "String representing patch-document.", content = @Content(mediaType = MediaType.APPLICATION_JSON_PATCH_JSON, array = @ArraySchema(schema = @Schema(implementation = JsonPatch.class)), examples = @ExampleObject(name = "Request json example", value = "example/kc-link/config/kc-link-patch.json"))) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Ok", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppConfiguration.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "500", description = "InternalServerError") }) + @PATCH + @Consumes(MediaType.APPLICATION_JSON_PATCH_JSON) + @ProtectedApi(scopes = { Constants.KC_LINK_CONFIG_WRITE_ACCESS }, groupScopes = {}, superScopes = { + ApiAccessConstants.SUPER_ADMIN_WRITE_ACCESS }) + public Response patchkcLinkConf(@NotNull String jsonPatchString) throws JsonPatchException, IOException { + logger.info("KC Link Config - jsonPatchString:{} ", jsonPatchString); + Conf conf = kcLinkConfigService.findKcLinkConf(); + logger.info("KC Link conf:{} ", conf); + if(conf==null) { + throwInternalServerException("It seems Kc Link module is not setup, kindly check."); + } + + AppConfiguration kcLinkAppConf = Jackson.applyPatch(jsonPatchString, conf.getDynamic()); + logger.info("KC Link conf details kcLinkAppConf():{}", kcLinkAppConf); + + conf.setDynamic(kcLinkAppConf); + kcLinkConfigService.mergeKcLinkConfig(conf); + kcLinkAppConf = kcLinkConfigService.find(); + logger.info("KC KC Link post patch - kcLinkAppConf:{}", kcLinkAppConf); + return Response.ok(kcLinkAppConf).build(); + } +} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/service/KcLinkConfigService.java b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/service/KcLinkConfigService.java new file mode 100644 index 00000000000..b4fa24a33eb --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/service/KcLinkConfigService.java @@ -0,0 +1,67 @@ +package io.jans.configapi.plugin.kc.link.service; + +import io.jans.as.common.service.common.ApplicationFactory; +import io.jans.configapi.configuration.ConfigurationFactory; +import io.jans.keycloak.link.model.config.AppConfiguration; +import io.jans.keycloak.link.model.config.Conf; +import io.jans.orm.PersistenceEntryManager; +import io.jans.orm.util.properties.FileConfiguration; +import io.jans.util.exception.InvalidConfigurationException; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.inject.Named; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; + +@ApplicationScoped +public class KcLinkConfigService { + + @Inject + Logger logger; + + @Inject + @Named(ApplicationFactory.PERSISTENCE_ENTRY_MANAGER_NAME) + PersistenceEntryManager persistenceManager; + + @Inject + ConfigurationFactory configurationFactory; + + + public FileConfiguration getBaseConfiguration() { + logger.info(" configurationFactory.getBaseConfiguration():{}", configurationFactory.getBaseConfiguration()); + return configurationFactory.getBaseConfiguration(); + } + + public String getKcLinkDn() { + String dn = this.getBaseConfiguration().getString("keycloakLink_ConfigurationEntryDN"); + logger.info(" kcLinkDn:{}", dn); + return dn; + } + + // Config handling methods + public Conf findKcLinkConf() { + final String dn = getKcLinkDn(); + logger.info(" dn:{}", dn); + if (StringUtils.isBlank(dn)) { + throw new InvalidConfigurationException("Kc Link Configuration DN is undefined!"); + } + + Conf kcLinkconf = persistenceManager.find(dn, Conf.class, null); + logger.info(" kcLinkconf:{}", kcLinkconf); + + return kcLinkconf; + } + + public void mergeKcLinkConfig(Conf kcLinkconf) { + kcLinkconf.setRevision(kcLinkconf.getRevision() + 1); + persistenceManager.merge(kcLinkconf); + } + + public AppConfiguration find() { + return findKcLinkConf().getDynamic(); + } + + +} diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/util/Constants.java b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/util/Constants.java new file mode 100644 index 00000000000..4f422f34e70 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/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.kc.link.util; + +public class Constants { + + private Constants() {} + + public static final String KC_LINK_CONFIG = "/kcLinkConfig"; + + + public static final String KC_LINK_CONFIG_READ_ACCESS = "https://jans.io/oauth/kc-link-config.readonly"; + public static final String KC_LINK_CONFIG_WRITE_ACCESS = "https://jans.io/oauth/kc-link-config.write"; + +} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/util/KcLinkUtil.java b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/util/KcLinkUtil.java new file mode 100644 index 00000000000..02c3b805533 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/java/io/jans/configapi/plugin/kc/link/util/KcLinkUtil.java @@ -0,0 +1,37 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.plugin.kc.link.util; + +import io.jans.configapi.plugin.kc.link.model.config.KcLinkConfigSource; + +import java.util.Map; +import java.util.Set; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import org.slf4j.Logger; + +@ApplicationScoped +public class KcLinkUtil { + + @Inject + Logger logger; + + @Inject + KcLinkConfigSource kcLinkConfigSource; + + public Map getProperties() { + logger.debug(" KcLinkUtil - kcLinkConfigSource.getProperties():{}", kcLinkConfigSource.getProperties()); + return kcLinkConfigSource.getProperties(); + } + + public Set getPropertyNames() { + logger.debug(" KcLinkUtil - kcLinkConfigSource.getPropertyNames():{}", kcLinkConfigSource.getPropertyNames()); + return kcLinkConfigSource.getPropertyNames(); + } +} diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/beans.xml b/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/beans.xml new file mode 100644 index 00000000000..bf2ab180c1c --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/beans.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 00000000000..89e970c3e1a --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1 @@ +io.jans.configapi.plugin.kc.link.extensions.KcLinkExtension \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers b/jans-config-api/plugins/kc-link-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/kc-link-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/kc-link-plugin/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource b/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource new file mode 100644 index 00000000000..d6248b5cbdc --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource @@ -0,0 +1 @@ +io.jans.configapi.plugin.kc.link.model.config.KcLinkConfigSource \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/main/resources/kc-link.properties b/jans-config-api/plugins/kc-link-plugin/src/main/resources/kc-link.properties new file mode 100644 index 00000000000..6c5c08a213b --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/main/resources/kc-link.properties @@ -0,0 +1,3 @@ +default.max.count=200 +default.list.size = "50"; +default.list.start.index = "1"; diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java new file mode 100644 index 00000000000..34da4586ef9 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java @@ -0,0 +1,18 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi; + +import com.intuit.karate.junit5.Karate; + +public class KarateTestRunner { + + @Karate.Test + Karate testFullPath() throws Exception { + return Karate.run("src/test/resources/feature"); + } + +} diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java new file mode 100644 index 00000000000..a7f7d2d80c2 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/java/io/jans/configapi/TestJenkinsRunner.java @@ -0,0 +1,44 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi; + +import com.intuit.karate.Results; +import com.intuit.karate.Runner; + +import io.jans.as.common.model.registration.Client; +import net.masterthought.cucumber.Configuration; +import net.masterthought.cucumber.ReportBuilder; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class TestJenkinsRunner { + + @Test + void testParallel() { + System.setProperty("karate.env", "jenkins"); + Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); + generateReport(results.getReportDir()); + Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); + } + + public static void generateReport(String karateOutputPath) { + Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); + List jsonPaths = new ArrayList(jsonFiles.size()); + jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); + Configuration config = new Configuration(new File("target"), "karateTesting"); + ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); + reportBuilder.generateReports(); + } +} diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/feature/kc-link/kc-link-config.feature b/jans-config-api/plugins/kc-link-plugin/src/test/resources/feature/kc-link/kc-link-config.feature new file mode 100644 index 00000000000..dd837aaa6ff --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/feature/kc-link/kc-link-config.feature @@ -0,0 +1,41 @@ +@ignore +Feature: Verify KC Link configuration endpoint + + Background:kcLinkUrl + * def mainUrl = kcLinkUrl + + @kc-link-config-get + Scenario: Retrieve KC Link configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + + + @kc-link-config-put + Scenario: Update KC Link configuration + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + When method GET + Then status 200 + And print response + And assert response.length != null + Given url mainUrl + And header Authorization = 'Bearer ' + accessToken + And request response + When method PUT + Then status 200 + And print response + + + @kc-link-config-get-error + Scenario: Retrieve KC Link configuration without bearer token + Given url mainUrl + When method GET + Then status 401 + And print response + + + \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config-jenkins.js new file mode 100644 index 00000000000..f17ade676db --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config-jenkins.js @@ -0,0 +1,58 @@ +function() { + + var stream = read('classpath:karate_jenkins.properties'); + var props = new java.util.Properties(); + props.load(stream); + + var env = props.get('karate.env'); // get java system property 'karate.env' + karate.configure("ssl", true); + + if (!env) { + env = 'dev'; //env can be anything: dev, qa, staging, etc. + } + + var url = props.get('karate.test.url'); + var port = props.get('karate.test.port'); + var baseUrl = url + (port ? ':' + port : ''); + + karate.log('karate_jenkins env :', env); + karate.log('karate_jenkins url :', url); + karate.log('karate_jenkins port :', port); + karate.log('karate_jenkins baseUrl :', baseUrl); + + var testStream = read('classpath:test.properties'); + var testProps = new java.util.Properties(); + testProps.load(testStream); + karate.log(' testProps = '+testProps); + var testClientId = testProps.get('test.client.id'); + var testClientSecret = testProps.get('test.client.secret'); + var tokenEndpoint = testProps.get('token.endpoint'); + var testScopes = testProps.get('test.scopes'); + var issuer = testProps.get('test.issuer'); + karate.log(' testClientId = '+testClientId); + karate.log(' testClientSecret = '+testClientSecret); + karate.log(' tokenEndpoint = '+tokenEndpoint); + karate.log(' testScopes = '+testScopes); + karate.log(' issuer = '+issuer); + + + var config = { + env: env, + baseUrl: baseUrl, + testProps: testProps, + issuer: issuer, + accessToken: '123', + + kcLinkUrl: baseUrl + '/jans-config-api/kc-link/kc-link-config', + + }; + + karate.configure('connectTimeout', 30000); + karate.configure('readTimeout', 60000); + + var result = karate.callSingle('classpath:token.feature', config); + print(' result.response = '+result.response); + config.accessToken = result.response.access_token; + + return config; +} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config.js new file mode 100644 index 00000000000..41958588071 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate-config.js @@ -0,0 +1,57 @@ +function() { + + var stream = read('classpath:karate.properties'); + var props = new java.util.Properties(); + props.load(stream); + + var env = props.get('karate.env'); // get java system property 'karate.env' + karate.configure("ssl", true); + + if (!env) { + env = 'dev'; //env can be anything: dev, qa, staging, etc. + } + + var url = props.get('karate.test.url'); + var port = props.get('karate.test.port'); + var baseUrl = url + (port ? ':' + port : ''); + + karate.log('karate env :', env); + karate.log('karate url :', url); + karate.log('karate port :', port); + karate.log('karate baseUrl :', baseUrl); + + var testStream = read('classpath:test.properties'); + var testProps = new java.util.Properties(); + testProps.load(testStream); + karate.log(' testProps = '+testProps); + var testClientId = testProps.get('test.client.id'); + var testClientSecret = testProps.get('test.client.secret'); + var tokenEndpoint = testProps.get('token.endpoint'); + var testScopes = testProps.get('test.scopes'); + var issuer = testProps.get('test.issuer'); + karate.log(' testClientId = '+testClientId); + karate.log(' testClientSecret = '+testClientSecret); + karate.log(' tokenEndpoint = '+tokenEndpoint); + karate.log(' testScopes = '+testScopes); + karate.log(' issuer = '+issuer); + + + var config = { + env: env, + baseUrl: baseUrl, + testProps: testProps, + issuer: issuer, + accessToken: '123', + + kcLinkUrl: baseUrl + '/jans-config-api/kc-link/kc-link-config', + }; + + karate.configure('connectTimeout', 30000); + karate.configure('readTimeout', 60000); + + var result = karate.callSingle('classpath:token.feature', config); + print(' result.response = '+result.response); + config.accessToken = result.response.access_token; + + return config; +} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate.properties new file mode 100644 index 00000000000..41c0d369aff --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate.properties @@ -0,0 +1,5 @@ +#karate.test.url=http://localhost +#karate.test.port=8080 +#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api +#karate.test.port=443 +karate.test.url=${test.server} diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate_jenkins.properties new file mode 100644 index 00000000000..0b44a8d7b13 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/karate_jenkins.properties @@ -0,0 +1,2 @@ +karate.test.url=${test.server} +#karate.test.port=443 diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/logback-test.xml b/jans-config-api/plugins/kc-link-plugin/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..fea195eb039 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/logback-test.xml @@ -0,0 +1,24 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + target/karate.log + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties b/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties new file mode 100644 index 00000000000..4257f297907 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/test.properties @@ -0,0 +1,8 @@ +test.scopes=${test.scopes} + +# Test env Setting +token.endpoint=${token.endpoint} +token.grant.type=${token.grant.type} +test.client.id=${test.client.id} +test.client.secret=${test.client.secret} +test.issuer=${test.issuer} \ No newline at end of file diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/kc-link-plugin/src/test/resources/testClient.feature new file mode 100644 index 00000000000..34cfdffc438 --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/testClient.feature @@ -0,0 +1,13 @@ +@ignore +Feature: This Feature is to get token to test the test cases + +Background: +* def mainUrl = test_url + +Scenario: Get Token +Given url mainUrl +And print url +And request '' +When method POST +Then status 204 +And print response diff --git a/jans-config-api/plugins/kc-link-plugin/src/test/resources/token.feature b/jans-config-api/plugins/kc-link-plugin/src/test/resources/token.feature new file mode 100644 index 00000000000..ef0ad0d262d --- /dev/null +++ b/jans-config-api/plugins/kc-link-plugin/src/test/resources/token.feature @@ -0,0 +1,45 @@ +@ignore +Feature: This Feature is to get token to test the test cases - Do not remove ignore tag + +Background: +* def mainUrl = testProps.get('token.endpoint'); +* def grantType = testProps.get('token.grant.type'); +* def clientId = testProps.get('test.client.id'); +* def clientSecret = testProps.get('test.client.secret'); +* def scopes = testProps.get('test.scopes'); +* def authStr = clientId+':'+clientSecret +* def Base64 = Java.type('java.util.Base64') +* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) +* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') + + +Scenario: Get Token +Given url mainUrl +And print 'mainUrl = '+mainUrl +And print 'grantType = '+grantType +And print 'clientId = '+clientId +And print 'clientSecret = '+clientSecret +And print 'scopes = '+scopes +And print 'authStr = '+authStr +And print 'encodedAuth = '+encodedAuth +And print 'encodedScopes = '+encodedScopes +And header Accept = 'application/json' +And header Authorization = 'Basic '+encodedAuth +And form field grant_type = grantType +And form field scope = scopes +When method POST +Then status 200 +And print 'token response = '+response + + + + +#Scenario: Get Token +#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' +#And header Accept = 'application/json' +#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' +#And form field grant_type = 'client_credentials' +#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' +#When method POST +#Then status 200 +#And print 'token response = '+response diff --git a/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/IdentityProvider.java b/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/IdentityProvider.java index 024d000dc40..80b1ca7b75a 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/IdentityProvider.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/IdentityProvider.java @@ -68,7 +68,7 @@ public class IdentityProvider extends Entry implements Serializable { @AttributeName(name = "nameIDPolicyFormat") private String nameIDPolicyFormat; - @AttributeName(name = "idpEntityId") + @AttributeName(name = "entityId") private String idpEntityId; @AttributeName(name = "singleSignOnServiceUrl") diff --git a/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/TrustRelationship.java b/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/TrustRelationship.java index 7518f1057e6..974c72bf8a9 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/TrustRelationship.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/TrustRelationship.java @@ -16,6 +16,7 @@ import io.jans.orm.model.base.Entry; import io.swagger.v3.oas.annotations.Hidden; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Comparator; @@ -42,6 +43,8 @@ public class TrustRelationship extends Entry implements Serializable { private String owner; @AttributeName(name = "jansClntId") + @NotNull + @Size(min = 0, max = 60, message = "Length of the Client Id should not exceed 60") private String clientId; @NotNull @@ -107,6 +110,18 @@ public class TrustRelationship extends Entry implements Serializable { @AttributeName(name = "jansSAMLspMetaDataSourceTyp") private MetadataSourceType spMetaDataSourceType; + @AttributeName(name = "nameIDPolicyFormat") + private String nameIDPolicyFormat; + + @AttributeName(name = "entityId") + private String entityId; + + @AttributeName(name = "singleLogoutServiceUrl") + private String singleLogoutServiceUrl; + + @AttributeName(name = "jansRedirectURI") + private String[] redirectUris; + /** * Trust Relationship file location of metadata */ @@ -120,9 +135,6 @@ public class TrustRelationship extends Entry implements Serializable { @AttributeName(name = "jansMetaLocation") private String metaLocation; - @AttributeName(name = "jansEntityId") - private List jansEntityId; - @AttributeName(name = "jansReleasedAttr") private List releasedAttributes; @@ -144,7 +156,7 @@ public class TrustRelationship extends Entry implements Serializable { private List validationLog; private Map profileConfigurations = new HashMap(); - + public String getInum() { return inum; } @@ -273,6 +285,38 @@ public void setSpMetaDataSourceType(MetadataSourceType spMetaDataSourceType) { this.spMetaDataSourceType = spMetaDataSourceType; } + public String getNameIDPolicyFormat() { + return nameIDPolicyFormat; + } + + public void setNameIDPolicyFormat(String nameIDPolicyFormat) { + this.nameIDPolicyFormat = nameIDPolicyFormat; + } + + public String getEntityId() { + return entityId; + } + + public void setEntityId(String entityId) { + this.entityId = entityId; + } + + public String getSingleLogoutServiceUrl() { + return singleLogoutServiceUrl; + } + + public void setSingleLogoutServiceUrl(String singleLogoutServiceUrl) { + this.singleLogoutServiceUrl = singleLogoutServiceUrl; + } + + public String[] getRedirectUris() { + return redirectUris; + } + + public void setRedirectUris(String[] redirectUris) { + this.redirectUris = redirectUris; + } + public String getSpMetaDataFN() { return spMetaDataFN; } @@ -297,14 +341,6 @@ public void setMetaLocation(String metaLocation) { this.metaLocation = metaLocation; } - public List getJansEntityId() { - return jansEntityId; - } - - public void setJansEntityId(List jansEntityId) { - this.jansEntityId = jansEntityId; - } - public List getReleasedAttributes() { return releasedAttributes; } @@ -372,7 +408,6 @@ public int compare(TrustRelationship first, TrustRelationship second) { public static void sortByDataSourceType(List trustRelationships) { Collections.sort(trustRelationships, new SortByDatasourceTypeComparator()); } - @Override public String toString() { @@ -382,11 +417,12 @@ public String toString() { + ", alwaysDisplayInConsole=" + alwaysDisplayInConsole + ", clientAuthenticatorType=" + clientAuthenticatorType + ", secret=" + secret + ", registrationAccessToken=" + registrationAccessToken + ", consentRequired=" + consentRequired + ", spMetaDataSourceType=" - + spMetaDataSourceType + ", spMetaDataFN=" + spMetaDataFN + ", spMetaDataURL=" + spMetaDataURL - + ", metaLocation=" + metaLocation + ", jansEntityId=" + jansEntityId + ", releasedAttributes=" - + releasedAttributes + ", url=" + url + ", spLogoutURL=" + spLogoutURL + ", status=" + status - + ", validationStatus=" + validationStatus + ", validationLog=" + validationLog - + ", profileConfigurations=" + profileConfigurations + "]"; - } - + + spMetaDataSourceType + ", nameIDPolicyFormat=" + nameIDPolicyFormat + ", entityId=" + entityId + + ", singleLogoutServiceUrl=" + singleLogoutServiceUrl + ", redirectUris=" + + Arrays.toString(redirectUris) + ", spMetaDataFN=" + spMetaDataFN + ", spMetaDataURL=" + spMetaDataURL + + ", metaLocation=" + metaLocation + ", releasedAttributes=" + releasedAttributes + ", url=" + url + + ", spLogoutURL=" + spLogoutURL + ", status=" + status + ", validationStatus=" + validationStatus + + ", validationLog=" + validationLog + ", profileConfigurations=" + profileConfigurations + "]"; + } + } diff --git a/jans-config-api/plugins/pom.xml b/jans-config-api/plugins/pom.xml index 65e0db6b244..5d4dba29b18 100644 --- a/jans-config-api/plugins/pom.xml +++ b/jans-config-api/plugins/pom.xml @@ -22,7 +22,8 @@ user-mgt-plugin fido2-plugin kc-saml-plugin - + kc-link-plugin + 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 7a447d00146..8d0da16c6f7 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 @@ -2303,7 +2303,9 @@ }, { "httpMethods": [ - "POST","PUT","DELETE" + "POST", + "PUT", + "DELETE" ], "scopes": [ { @@ -2349,7 +2351,9 @@ }, { "httpMethods": [ - "POST","PUT","DELETE" + "POST", + "PUT", + "DELETE" ], "scopes": [ { @@ -2395,7 +2399,9 @@ }, { "httpMethods": [ - "POST","PUT","DELETE" + "POST", + "PUT", + "DELETE" ], "scopes": [ { @@ -2441,7 +2447,9 @@ }, { "httpMethods": [ - "POST","PUT","PATCH" + "POST", + "PUT", + "PATCH" ], "scopes": [ { @@ -2487,7 +2495,10 @@ }, { "httpMethods": [ - "POST","PUT","PATCH","DELETE" + "POST", + "PUT", + "PATCH", + "DELETE" ], "scopes": [ { @@ -2533,7 +2544,10 @@ }, { "httpMethods": [ - "POST","PUT","PATCH","DELETE" + "POST", + "PUT", + "PATCH", + "DELETE" ], "scopes": [ { @@ -2725,7 +2739,7 @@ } ] }, - { + { "path": "/jans-config-api/api/v1/health/app-version", "conditions": [ { @@ -2747,6 +2761,53 @@ ] } ] + }, + { + "path": "/jans-config-api/kc-link/kcLinkConfig", + "conditions": [ + { + "httpMethods": [ + "GET" + ], + "scopes": [ + { + "inum": "1800.01.71", + "name": "https://jans.io/oauth/config/saml-config.readonly" + } + ], + "groupScopes": [ + { + "inum": "1800.01.72", + "name": "https://jans.io/oauth/config/saml-config.write" + } + ], + "superScopes": [ + { + "inum": "1800.03.1", + "name": "https://jans.io/oauth/config/read-all" + } + ] + }, + { + "httpMethods": [ + "PUT", + "PATCH" + ], + "scopes": [ + { + "inum": "1800.01.72", + "name": "https://jans.io/oauth/config/saml-config.write" + } + ], + "groupScopes": [], + "superScopes": [ + { + "inum": "1800.03.2", + "name": "https://jans.io/oauth/config/write-all" + } + ] + } + ] } ] } \ No newline at end of file diff --git a/jans-linux-setup/jans_setup/schema/jans_schema.json b/jans-linux-setup/jans_setup/schema/jans_schema.json index 877a9d4d1f4..cbed32cf8d5 100644 --- a/jans-linux-setup/jans_setup/schema/jans_schema.json +++ b/jans-linux-setup/jans_setup/schema/jans_schema.json @@ -3688,10 +3688,10 @@ "x_origin":"Jans created attribute" }, { - "desc":"idpEntityId", + "desc":"entityId", "equality":"caseIgnoreMatch", "names":[ - "idpEntityId" + "entityId" ], "oid":"jansAttr", "substr":"caseIgnoreSubstringsMatch", @@ -5010,19 +5010,21 @@ "jansRedirectURI", "jansWebOrigins", "consentRequired", + "nameIDPolicyFormat", + "entityId", + "singleLogoutServiceUrl", "jansSAMLMetaDataFilter", "jansSAMLspMetaDataSourceTyp", "jansSAMLspMetaDataFN", "jansSAMLspMetaDataURL", "jansMetaLocation", "jansIsFed", - "jansEntityId", "jansEntityTyp", "jansProfileConf", "jansReleasedAttr", "url", "jansPostLogoutRedirectURI", - "protocol", + "protocol", "jansStatus", "jansValidationStatus", "jansValidationLog" @@ -5049,14 +5051,14 @@ "description", "realm", "jansEnabled", - "providerId", - "signingCertificate", - "validateSignature", - "singleLogoutServiceUrl", - "nameIDPolicyFormat", - "idpEntityId", - "singleSignOnServiceUrl", - "encryptionPublicKey", + "providerId", + "signingCertificate", + "validateSignature", + "singleLogoutServiceUrl", + "nameIDPolicyFormat", + "entityId", + "singleSignOnServiceUrl", + "encryptionPublicKey", "trustEmail", "storeToken", "addReadTokenRoleOnCreate",