From 73a2f5188ea0f66f923fbb7e9cc5d7b33357a79b Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 31 Dec 2024 13:58:18 +0530 Subject: [PATCH 01/20] feat(config-api): default ACR methods issue#10511 Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 22 ++++++++++--------- .../plugins/docs/user-mgt-plugin-swagger.yaml | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index c1a1c82474a..ff5d97d4003 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9335,21 +9335,21 @@ components: $ref: '#/components/schemas/AttributeValidation' tooltip: type: string - selected: - type: boolean whitePagesCanView: type: boolean - adminCanAccess: + selected: type: boolean - userCanAccess: + adminCanEdit: type: boolean adminCanView: type: boolean + userCanEdit: + type: boolean userCanView: type: boolean - userCanEdit: + adminCanAccess: type: boolean - adminCanEdit: + userCanAccess: type: boolean baseDn: type: string @@ -10988,10 +10988,10 @@ components: type: array items: type: object - displayValue: - type: string value: type: object + displayValue: + type: string LocalizedString: type: object properties: @@ -11331,14 +11331,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: @@ -11861,6 +11861,8 @@ components: type: string online_access: type: boolean + authorization_challenge: + type: boolean attributes: type: object additionalProperties: diff --git a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml index 9113a738b01..a23d9c4e828 100644 --- a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml @@ -863,10 +863,10 @@ components: type: array items: type: object - displayValue: - type: string value: type: object + displayValue: + type: string CustomUser: type: object properties: From f128244eff7c08ff58d42de4774f41f3e39a7838 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 2 Jan 2025 13:41:18 +0530 Subject: [PATCH 02/20] feat(config-api): agama flow acr method --- .../docs/jans-config-api-swagger.yaml | 16 ++++++++-------- .../plugins/docs/user-mgt-plugin-swagger.yaml | 4 ++-- .../rest/resource/auth/AcrsResource.java | 11 ++++++----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index ff5d97d4003..edce4fcc440 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9339,18 +9339,18 @@ components: type: boolean selected: type: boolean - adminCanEdit: - type: boolean adminCanView: type: boolean - userCanEdit: + adminCanEdit: type: boolean userCanView: type: boolean - adminCanAccess: + userCanEdit: type: boolean userCanAccess: type: boolean + adminCanAccess: + type: boolean baseDn: type: string PatchRequest: @@ -10211,8 +10211,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10222,6 +10220,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -10988,10 +10988,10 @@ components: type: array items: type: object - value: - type: object displayValue: type: string + value: + type: object LocalizedString: type: object properties: diff --git a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml index a23d9c4e828..9113a738b01 100644 --- a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml @@ -863,10 +863,10 @@ components: type: array items: type: object - value: - type: object displayValue: type: string + value: + type: object CustomUser: type: object properties: 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 ba92e2a1efd..cf2272686ca 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 @@ -30,6 +30,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.*; +import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.Optional; @@ -214,22 +215,22 @@ public boolean isValidAgamaDeployment(String authenticationMode) { private Set getDirectLaunchFlows(List agamaDeploymentList) { log.info(" agamaDeploymentList:{}", agamaDeploymentList); Set keys = null; - List noDirectLaunchFlows = null; + List noDirectLaunchFlows = new ArrayList<>(); if (agamaDeploymentList == null || agamaDeploymentList.isEmpty()) { return keys; } for (Deployment deployment : agamaDeploymentList) { - log.debug("Agama deployment:{},", deployment); + log.info("Agama deployment:{},", deployment); if (deployment.getDetails() != null && deployment.getDetails().getFlowsError() != null) { keys = deployment.getDetails().getFlowsError().keySet(); - log.debug(" Agama flow keys:{},", keys); + log.info(" Agama flow keys:{},", keys); if (deployment.getDetails().getProjectMetadata() != null) { - noDirectLaunchFlows = deployment.getDetails().getProjectMetadata().getNoDirectLaunchFlows(); + noDirectLaunchFlows.addAll(deployment.getDetails().getProjectMetadata().getNoDirectLaunchFlows()); } } } - log.debug("All deployed agama keys:{}, noDirectLaunchFlows:{}", keys, noDirectLaunchFlows); + log.info("All deployed agama keys:{}, noDirectLaunchFlows:{}", keys, noDirectLaunchFlows); if (keys != null && !keys.isEmpty() && noDirectLaunchFlows != null) { keys.removeAll(noDirectLaunchFlows); } From 80760061ef811f93d118062f6a70d9eb88b80d2f Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 2 Jan 2025 19:01:22 +0530 Subject: [PATCH 03/20] fix(config-api): setting agama flow as auth method Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 18 +++++++++--------- .../plugins/docs/user-mgt-plugin-swagger.yaml | 4 ++-- .../rest/resource/auth/AcrsResource.java | 17 +++++++++-------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index edce4fcc440..69e873ce172 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9335,13 +9335,9 @@ components: $ref: '#/components/schemas/AttributeValidation' tooltip: type: string - whitePagesCanView: - type: boolean selected: type: boolean - adminCanView: - type: boolean - adminCanEdit: + whitePagesCanView: type: boolean userCanView: type: boolean @@ -9351,6 +9347,10 @@ components: type: boolean adminCanAccess: type: boolean + adminCanEdit: + type: boolean + adminCanView: + type: boolean baseDn: type: string PatchRequest: @@ -10988,10 +10988,10 @@ components: type: array items: type: object - displayValue: - type: string value: type: object + displayValue: + type: string LocalizedString: type: object properties: @@ -11331,14 +11331,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: diff --git a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml index 9113a738b01..a23d9c4e828 100644 --- a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml @@ -863,10 +863,10 @@ components: type: array items: type: object - displayValue: - type: string value: type: object + displayValue: + type: string CustomUser: type: object properties: diff --git a/jans-config-api/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 cf2272686ca..58d556e9a28 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 @@ -31,6 +31,7 @@ import io.swagger.v3.oas.annotations.security.*; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Optional; @@ -203,7 +204,7 @@ public boolean isValidAgamaDeployment(String authenticationMode) { } log.info(" agamaAcr:{},", agamaAcr); - if (keys != null && !keys.isEmpty() && keys.contains(agamaAcr)) { + if (!keys.isEmpty() && keys.contains(agamaAcr)) { log.debug(" keys.contains(agamaAcr):{},", keys.contains(agamaAcr)); isValid = true; } @@ -214,24 +215,24 @@ public boolean isValidAgamaDeployment(String authenticationMode) { private Set getDirectLaunchFlows(List agamaDeploymentList) { log.info(" agamaDeploymentList:{}", agamaDeploymentList); - Set keys = null; + Set keys = new HashSet<>(); List noDirectLaunchFlows = new ArrayList<>(); if (agamaDeploymentList == null || agamaDeploymentList.isEmpty()) { return keys; } for (Deployment deployment : agamaDeploymentList) { - log.info("Agama deployment:{},", deployment); + log.info("Agama deployment:{}, deployment.getId():{},", deployment, deployment.getId()); if (deployment.getDetails() != null && deployment.getDetails().getFlowsError() != null) { - keys = deployment.getDetails().getFlowsError().keySet(); - log.info(" Agama flow keys:{},", keys); + keys.addAll(deployment.getDetails().getFlowsError().keySet()); + log.info("\n Agama flow keys:{},", keys); - if (deployment.getDetails().getProjectMetadata() != null) { + if (deployment.getDetails().getProjectMetadata() != null && deployment.getDetails().getProjectMetadata().getNoDirectLaunchFlows()!=null) { noDirectLaunchFlows.addAll(deployment.getDetails().getProjectMetadata().getNoDirectLaunchFlows()); } } } - log.info("All deployed agama keys:{}, noDirectLaunchFlows:{}", keys, noDirectLaunchFlows); - if (keys != null && !keys.isEmpty() && noDirectLaunchFlows != null) { + log.info("\n All deployed agama keys:{}, noDirectLaunchFlows:{}", keys, noDirectLaunchFlows); + if (!keys.isEmpty() && !noDirectLaunchFlows.isEmpty()) { keys.removeAll(noDirectLaunchFlows); } log.info("Final agama main flow keys:{}", keys); From 3aae4f028ef0f6aca584d70c3d305d2a57eeb7cd Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 14 Jan 2025 20:10:26 +0530 Subject: [PATCH 04/20] test(config-api) token test case failure #10619 Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 14 +++--- .../plugins/docs/fido2-plugin-swagger.yaml | 45 ++++++++++++------- .../feature/token/client-token.feature | 2 +- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 69e873ce172..cd7007ba939 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,19 +9337,19 @@ components: type: string selected: type: boolean - whitePagesCanView: + adminCanEdit: + type: boolean + adminCanView: type: boolean userCanView: type: boolean userCanEdit: type: boolean - userCanAccess: - type: boolean adminCanAccess: type: boolean - adminCanEdit: + userCanAccess: type: boolean - adminCanView: + whitePagesCanView: type: boolean baseDn: type: string @@ -10211,6 +10211,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10220,8 +10222,6 @@ 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 0859f6b93a1..5384db0df26 100644 --- a/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml @@ -560,12 +560,8 @@ components: type: array items: type: string - superGluuEnabled: - type: boolean sessionIdPersistInCache: type: boolean - oldU2fMigrationEnabled: - type: boolean errorReasonEnabled: type: boolean fido2Configuration: @@ -583,38 +579,53 @@ components: type: string checkU2fAttestations: type: boolean - userAutoEnrollment: + debugUserAutoEnrollment: type: boolean unfinishedRequestExpiration: type: integer format: int32 - authenticationHistoryExpiration: + metadataRefreshInterval: type: integer format: int32 serverMetadataFolder: type: string - requestedCredentialTypes: + enabledFidoAlgorithms: type: array items: type: string - requestedParties: + metadataServers: type: array items: - $ref: '#/components/schemas/RequestedParty' - metadataUrlsProvider: - type: string - skipDownloadMdsEnabled: - type: boolean - skipValidateMdsInAttestationEnabled: + $ref: '#/components/schemas/MetadataServer' + disableMetadataService: type: boolean - assertionOptionsGenerateEndpointEnabled: + hints: + type: array + items: + type: string + enterpriseAttestation: type: boolean + attestationMode: + type: string + rp: + type: array + items: + $ref: '#/components/schemas/RequestedParty' + MetadataServer: + type: object + properties: + url: + type: string + certificateDocumentInum: + type: array + items: + type: string RequestedParty: type: object properties: - name: + id: type: string - domains: + origins: type: array items: type: string diff --git a/jans-config-api/server/src/test/resources/feature/token/client-token.feature b/jans-config-api/server/src/test/resources/feature/token/client-token.feature index edb945da958..01539195a80 100644 --- a/jans-config-api/server/src/test/resources/feature/token/client-token.feature +++ b/jans-config-api/server/src/test/resources/feature/token/client-token.feature @@ -8,7 +8,7 @@ Background: Scenario: Fetch all client token Given url mainUrl When method GET -Then status 401 +Then status 404 And print response @ignore From ba6a158223a2ab58384c018fff1c5372413ba8a9 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 14 Jan 2025 21:17:47 +0530 Subject: [PATCH 05/20] test(config-api) token test case failure #10619 Signed-off-by: pujavs --- .../feature/mgt/user/user-patch.json | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-patch.json b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-patch.json index eef49548448..bb5db8eb5db 100644 --- a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-patch.json +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-patch.json @@ -8,33 +8,6 @@ ], "value": true, "displayValue": true - }, - { - "name": "secretAnswer", - "multiValued": false, - "values": [ - "james-bond@123" - ], - "value": "james-bond@123", - "displayValue": "james-bond@123" - }, - { - "name": "jansImsValue", - "multiValued": true, - "values": [{ - "value": "123456", - "display": "Home phone", - "type": "home", - "primary": true - }, - { - "value": "9821789", - "display": "Work phone", - "type": "work", - "primary": false - } - - ] } ] } \ No newline at end of file From 1bf47e03dd85c7d3f0b1b11a064f19fcbcedfe75 Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 17 Jan 2025 23:00:36 +0530 Subject: [PATCH 06/20] feat(config-api): lock stat endpoint Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 16 +- .../plugins/docs/lock-plugin-swagger.yaml | 64 +++ .../plugin/lock/rest/ApiApplication.java | 6 +- .../plugin/lock/rest/LockStatResource.java | 91 +++++ .../plugin/lock/service/LockService.java | 98 +++++ .../configapi/plugin/lock/util/Constants.java | 1 + .../feature/openid/scopes/scopes.feature | 1 + .../core/service/ConfigHttpService.java | 373 ++++++++++++++++++ 8 files changed, 641 insertions(+), 9 deletions(-) create mode 100644 jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java create mode 100644 jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java create mode 100644 jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index cd7007ba939..0f8084638d4 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,6 +9337,12 @@ components: type: string selected: type: boolean + whitePagesCanView: + type: boolean + adminCanAccess: + type: boolean + userCanAccess: + type: boolean adminCanEdit: type: boolean adminCanView: @@ -9345,12 +9351,6 @@ components: type: boolean userCanEdit: type: boolean - adminCanAccess: - type: boolean - userCanAccess: - type: boolean - whitePagesCanView: - type: boolean baseDn: type: string PatchRequest: @@ -11767,10 +11767,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/docs/lock-plugin-swagger.yaml b/jans-config-api/plugins/docs/lock-plugin-swagger.yaml index 2d846528f26..fcabed560ba 100644 --- a/jans-config-api/plugins/docs/lock-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/lock-plugin-swagger.yaml @@ -15,6 +15,7 @@ servers: tags: - name: Lock - Configuration - name: Lock - Audit +- name: Lock - Statistics paths: /lock/audit/health/search: get: @@ -468,6 +469,58 @@ paths: security: - oauth2: - https://jans.io/oauth/lock-config.write + /lock/stat: + get: + tags: + - Statistics + summary: Provides basic statistic + description: Provides basic statistic + operationId: get-lock-stat + parameters: + - name: Authorization + in: header + description: Authorization code + schema: + type: string + - name: month + in: query + description: Month for which the stat report is to be fetched. The parameter + is mandatory if start_month and end_month parameters are not present. + schema: + type: string + example: 202012 + - name: start_month + in: query + description: Start-Month for which the stat report is to be fetched + schema: + type: string + - name: end_month + in: query + description: End-Month for which the stat report is to be fetched + schema: + type: string + - name: format + in: query + description: Report format + schema: + type: string + responses: + "200": + description: Stats + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/JsonNode' + "401": + description: Unauthorized + "500": + description: InternalServerError + security: + - oauth2: + - https://jans.io/oauth/lock/read-all + - jans_stat components: schemas: HealthEntry: @@ -597,6 +650,13 @@ components: openIdIssuer: type: string description: OpenID issuer URL + statEnabled: + type: boolean + description: Active stat enabled + statTimerIntervalInSeconds: + type: integer + description: Statistical data capture time interval + format: int32 tokenChannels: type: array description: List of token channel names @@ -689,6 +749,8 @@ components: items: type: string description: List of Zip Uris with policies + errorReasonEnabled: + type: boolean OpaConfiguration: type: object properties: @@ -701,6 +763,8 @@ components: description: Opa Configuration JsonPatch: type: object + JsonNode: + type: object securitySchemes: oauth2: type: oauth2 diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java index 5432433ade7..84b2c47a6a9 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java @@ -18,7 +18,10 @@ license = @License(name = "Apache 2.0", url = "https://github.com/JanssenProject/jans/blob/main/LICENSE")), - tags = { @Tag(name = "Lock - Configuration"), @Tag(name = "Lock - Audit") }, + tags = { @Tag(name = "Lock - Configuration"), + @Tag(name = "Lock - Audit"), + @Tag(name = "Lock - Statistics") + }, servers = { @Server(url = "https://jans.io/", description = "The Jans server") }) @@ -45,6 +48,7 @@ public Set> getClasses() { classes.add(LockConfigResource.class); classes.add(AuditResource.class); + classes.add(LockStatResource.class); return classes; } diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java new file mode 100644 index 00000000000..f1a563663e2 --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -0,0 +1,91 @@ +/* + * 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.lock.rest; + +import io.jans.configapi.plugin.lock.service.LockService; + +import com.fasterxml.jackson.databind.JsonNode; + +import io.jans.configapi.core.rest.BaseResource; +import io.jans.configapi.core.rest.ProtectedApi; +import io.jans.configapi.plugin.lock.util.Constants; +import io.jans.configapi.service.auth.ConfigurationService; +import io.jans.configapi.util.ApiAccessConstants; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +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.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; + +@Path(Constants.LOCK_STAT) +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class LockStatResource extends BaseResource { + + private static final String STAT_URL = "/jans-lock/v1/internal/stat"; + + @Inject + Logger logger; + + @Inject + ConfigurationService configurationService; + + @Inject + LockService lockService; + + @Inject + + @Operation(summary = "Provides basic statistic", description = "Provides basic statistic", operationId = "get-lock-stat", tags = { + "Statistics" }, security = @SecurityRequirement(name = "oauth2", scopes = { + Constants.LOCK_READ_ACCESS, ApiAccessConstants.JANS_STAT })) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Stats", content = @Content(mediaType = MediaType.APPLICATION_JSON, array = @ArraySchema(schema = @Schema(implementation = JsonNode.class)))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "500", description = "InternalServerError") }) + @GET + @ProtectedApi(scopes = { Constants.LOCK_READ_ACCESS, + ApiAccessConstants.JANS_STAT }, groupScopes = {}, superScopes = { + ApiAccessConstants.SUPER_ADMIN_READ_ACCESS }) + @Produces(MediaType.APPLICATION_JSON) + public Response getStatistics( + @Parameter(description = "Authorization code") @HeaderParam("Authorization") String authorization, + @Parameter(description = "Month for which the stat report is to be fetched. The parameter is mandatory if start_month and end_month parameters are not present.") @QueryParam(value = "month") String month, + @Parameter(description = "Start-Month for which the stat report is to be fetched") @QueryParam(value = "start_month") String startMonth, + @Parameter(description = "End-Month for which the stat report is to be fetched") @QueryParam(value = "end_month") String endMonth, + @Parameter(description = "Report format") @QueryParam(value = "format") String format) { + if (StringUtils.isBlank(format)) { + format = ""; + } + JsonNode jsonNode = null; + try { + String url = getIssuer() + STAT_URL; + jsonNode = this.lockService.getStat(url, authorization, month, startMonth, endMonth, format); + logger.trace("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); + } catch (Exception ex) { + logger.error(" Error while fetching lock stat is", ex); + throwBadRequestException(ex); + } + return Response.ok(jsonNode).build(); + } + + private String getIssuer() { + return configurationService.find().getIssuer(); + } + +} \ No newline at end of file diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java new file mode 100644 index 00000000000..7efbf841b7d --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -0,0 +1,98 @@ +package io.jans.configapi.plugin.lock.service; + +import io.jans.configapi.core.util.Jackson; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import io.jans.configapi.core.service.ConfigHttpService; +import io.jans.model.net.HttpServiceResponse; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response.Status; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpEntity; +import org.slf4j.Logger; + +@ApplicationScoped +public class LockService { + private static final String CONTENT_TYPE = "Content-Type"; + private static final String AUTHORIZATION = "Authorization"; + private static final String AUTHORIZATION_BEARER = "Bearer"; + + @Inject + Logger logger; + + @Inject + ConfigHttpService configHttpService; + + public JsonNode getStat(String url, String token, String month, String startMonth, String endMonth, String format) + throws JsonProcessingException { + JsonNode jsonNode = null; + Map headers = new HashMap<>(); + headers.put(CONTENT_TYPE, MediaType.APPLICATION_JSON); + if (StringUtils.isNotBlank(token)) { + headers.put(AUTHORIZATION, AUTHORIZATION_BEARER + "" + token); + } + + // Query Param + Map data = new HashMap<>(); + data.put("month", month); + data.put("start-month", startMonth); + data.put("end-month", endMonth); + data.put("format", format); + HttpServiceResponse httpServiceResponse = configHttpService.executeGet(url, headers, data); + logger.info(" stat httpServiceResponse:{}", httpServiceResponse); + if (httpServiceResponse != null) { + jsonNode = getResponseJsonNode(httpServiceResponse, Status.OK); + } + logger.info(" stat jsonNode:{}", jsonNode); + return jsonNode; + } + + public String getResponseEntityString(HttpServiceResponse serviceResponse, Status status) { + String jsonString = null; + + if (serviceResponse == null) { + return jsonString; + } + + if (serviceResponse.getHttpResponse() != null && serviceResponse.getHttpResponse().getStatusLine() != null + && serviceResponse.getHttpResponse().getStatusLine().getStatusCode() == status.getStatusCode()) { + HttpEntity entity = serviceResponse.getHttpResponse().getEntity(); + if (entity == null) { + return jsonString; + } + jsonString = entity.toString(); + + } + logger.info(" stat jsonString:{}", jsonString); + return jsonString; + } + + public JsonNode getResponseJsonNode(HttpServiceResponse serviceResponse, Status status) + throws JsonProcessingException { + JsonNode jsonNode = null; + + if (serviceResponse == null) { + return jsonNode; + } + + return getResponseJsonNode(getResponseEntityString(serviceResponse, status)); + } + + public JsonNode getResponseJsonNode(String jsonSring) throws JsonProcessingException { + JsonNode jsonNode = null; + + if (StringUtils.isNotBlank(jsonSring)) { + return jsonNode; + } + + return Jackson.asJsonNode(jsonSring); + } + +} diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/Constants.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/Constants.java index 221bd3ece54..c3f50d4e373 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/Constants.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/Constants.java @@ -14,6 +14,7 @@ private Constants() { public static final String LOCK = "/lock"; public static final String LOCK_CONFIG = "/lockConfig"; public static final String AUDIT = "/audit"; + public static final String LOCK_STAT = "/stat"; public static final String HEALTH = "/health"; public static final String LOG = "/log"; public static final String TELEMETRY = "/telemetry"; diff --git a/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes.feature b/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes.feature index cc93861fea4..4ab40d28a80 100644 --- a/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes.feature +++ b/jans-config-api/server/src/test/resources/feature/openid/scopes/scopes.feature @@ -122,6 +122,7 @@ And print response Scenario: Get an openid connect scopes by inum Given url mainUrl And header Authorization = 'Bearer ' + accessToken +And param pattern = '1800' When method GET Then status 200 And print response diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java new file mode 100644 index 00000000000..00c00b57dd3 --- /dev/null +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java @@ -0,0 +1,373 @@ +/* + * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.core.service; + +import io.jans.model.net.HttpServiceResponse; +import io.jans.util.StringHelper; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.Map; +import java.util.Map.Entry; + +import javax.net.ssl.SSLContext; + +import jakarta.annotation.PostConstruct; +import jakarta.servlet.http.HttpServletRequest; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.apache.commons.codec.binary.Base64; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.DefaultProxyRoutePlanner; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.ssl.TrustStrategy; +import org.apache.http.util.EntityUtils; + +public class ConfigHttpService implements Serializable { + + private static final long serialVersionUID = -2398422090669045605L; + protected transient Logger log = LogManager.getLogger(getClass()); + private static final String CON_STATS_STR = "Connection manager stats: {}"; + private transient Base64 base64; + + private transient PoolingHttpClientConnectionManager connectionManager; + + @PostConstruct + public void init() { + connectionManager = new PoolingHttpClientConnectionManager(); + connectionManager.setMaxTotal(200); // Increase max total connection to 200 + connectionManager.setDefaultMaxPerRoute(50); // Increase default max connection per route to 50 + + this.base64 = new Base64(); + } + + public CloseableHttpClient getHttpsClientTrustAll() + throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException { + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); + + TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext, + NoopHostnameVerifier.INSTANCE); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient() { + return getHttpsClient(RequestConfig.custom().build()); + } + + public CloseableHttpClient getHttpsClient(RequestConfig requestConfig) { + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); + + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient(HttpRoutePlanner routerPlanner) { + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); + + return getHttpsClient(RequestConfig.custom().build(), routerPlanner); + } + + public CloseableHttpClient getHttpsClient(RequestConfig requestConfig, HttpRoutePlanner routerPlanner) { + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); + + return HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.copy(requestConfig).setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).setRoutePlanner(routerPlanner).build(); + } + + public CloseableHttpClient getHttpsClient(String trustStorePath, String trustStorePassword) + throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, + IOException { + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); + + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()).build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public CloseableHttpClient getHttpsClient(String trustStorePath, String trustStorePassword, String keyStorePath, + String keyStorePassword) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, + CertificateException, IOException, UnrecoverableKeyException { + log.trace(CON_STATS_STR, connectionManager.getTotalStats()); + + SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(new File(trustStorePath), trustStorePassword.toCharArray()) + .loadKeyMaterial(new File(keyStorePath), keyStorePassword.toCharArray(), keyStorePassword.toCharArray()) + .build(); + SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslContext); + + return HttpClients.custom().setSSLSocketFactory(sslConSocFactory) + .setDefaultRequestConfig(RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build()) + .setConnectionManager(connectionManager).build(); + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authCode, + Map headers, String postData, ContentType contentType, String authType) { + + HttpPost httpPost = new HttpPost(uri); + + if (StringHelper.isEmpty(authType)) { + authType = "Basic "; + } else { + authType = authType + " "; + } + if (StringHelper.isNotEmpty(authCode)) { + httpPost.setHeader("Authorization", authType + authCode); + } + + if (contentType == null) { + contentType = ContentType.APPLICATION_JSON; + } + + if (headers != null) { + for (Entry headerEntry : headers.entrySet()) { + httpPost.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } + } + + StringEntity stringEntity = new StringEntity(postData, contentType); + httpPost.setEntity(stringEntity); + + try { + HttpResponse httpResponse = httpClient.execute(httpPost); + + return new HttpServiceResponse(httpPost, httpResponse); + } catch (IOException ex) { + log.error("Failed to execute post request", ex); + } + + return null; + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authCode, + Map headers, String postData) { + return executePost(httpClient, uri, authCode, headers, postData, null, null); + } + + public HttpServiceResponse executePost(HttpClient httpClient, String uri, String authCode, String postData, + ContentType contentType) { + return executePost(httpClient, uri, authCode, null, postData, contentType, null); + } + + public HttpServiceResponse executePost(String uri, String authCode, String postData, + ContentType contentType, String authType) { + return executePost(this.getHttpsClient(), uri, authCode, null, postData, contentType, authType); + } + + public String encodeBase64(String value) { + return new String(base64.encode((value).getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); + } + + public String encodeUrl(String value) { + return URLEncoder.encode(value, StandardCharsets.UTF_8); + } + + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, Map headers, + Map parameters) { + HttpGet httpGet = new HttpGet(requestUri); + + if (headers != null) { + for (Entry headerEntry : headers.entrySet()) { + httpGet.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } + } + + if (parameters != null && !parameters.isEmpty()) { + StringBuilder query = new StringBuilder(""); + for (String key : parameters.keySet()) { + + String value = parameters.get(key); + if (value != null && value.length() > 0) { + + String delim = "&" + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="; + query.append(delim.substring(1)); + query.append(URLEncoder.encode(value, StandardCharsets.UTF_8)); + } + } + httpGet = new HttpGet(requestUri + query.toString()); + } + + try { + HttpResponse httpResponse = httpClient.execute(httpGet); + + return new HttpServiceResponse(httpGet, httpResponse); + } catch (IOException ex) { + log.error("Failed to execute get request", ex); + } + + return null; + } + + public HttpServiceResponse executeGet(String requestUri, Map headers, Map data) { + HttpClient httpClient = this.getHttpsClient(); + return executeGet(httpClient, requestUri, headers, data); + } + + public HttpServiceResponse executeGet(String requestUri, Map headers) { + HttpClient httpClient = this.getHttpsClient(); + return executeGet(httpClient, requestUri, headers, null); + } + + public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri) { + return executeGet(httpClient, requestUri, null, null); + } + + public byte[] getResponseContent(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { + return null; + } + + HttpEntity entity = httpResponse.getEntity(); + byte[] responseBytes = new byte[0]; + if (entity != null) { + responseBytes = EntityUtils.toByteArray(entity); + } + + // Consume response content + if (entity != null) { + EntityUtils.consume(entity); + } + + return responseBytes; + } + + public void consume(HttpResponse httpResponse) throws IOException { + if ((httpResponse == null) || !isResponseStastusCodeOk(httpResponse)) { + return; + } + + // Consume response content + HttpEntity entity = httpResponse.getEntity(); + if (entity != null) { + EntityUtils.consume(entity); + } + } + + public String convertEntityToString(byte[] responseBytes) { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes); + } + + public String convertEntityToString(byte[] responseBytes, Charset charset) { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes, charset); + } + + public String convertEntityToString(byte[] responseBytes, String charsetName) throws UnsupportedEncodingException { + if (responseBytes == null) { + return null; + } + + return new String(responseBytes, charsetName); + } + + public boolean isResponseStastusCodeOk(HttpResponse httpResponse) { + int responseStastusCode = httpResponse.getStatusLine().getStatusCode(); + if ((responseStastusCode == HttpStatus.SC_OK) || (responseStastusCode == HttpStatus.SC_CREATED) + || (responseStastusCode == HttpStatus.SC_ACCEPTED) + || (responseStastusCode == HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION) + || (responseStastusCode == HttpStatus.SC_NO_CONTENT) + || (responseStastusCode == HttpStatus.SC_RESET_CONTENT) + || (responseStastusCode == HttpStatus.SC_PARTIAL_CONTENT) + || (responseStastusCode == HttpStatus.SC_MULTI_STATUS)) { + return true; + } else { + return false; + } + } + + public boolean isResponseStatusCodeOk(HttpResponse httpResponse) { + return isResponseStastusCodeOk(httpResponse); + } + + public boolean isContentTypeXml(HttpResponse httpResponse) { + Header contentType = httpResponse.getEntity().getContentType(); + if (contentType == null) { + return false; + } + + String contentTypeValue = contentType.getValue(); + if (StringHelper.equals(contentTypeValue, ContentType.APPLICATION_XML.getMimeType()) + || StringHelper.equals(contentTypeValue, ContentType.TEXT_XML.getMimeType())) { + return true; + } else { + return false; + } + } + + public String constructServerUrl(final HttpServletRequest request) { + int serverPort = request.getServerPort(); + + String redirectUrl; + if ((serverPort == 80) || (serverPort == 443)) { + redirectUrl = String.format("%s://%s%s", request.getScheme(), request.getServerName(), + request.getContextPath()); + } else { + redirectUrl = String.format("%s://%s:%s%s", request.getScheme(), request.getServerName(), + request.getServerPort(), request.getContextPath()); + } + + return redirectUrl.toLowerCase(); + } + + public HttpRoutePlanner buildDefaultRoutePlanner(final String hostname, final int port, final String scheme) { + // Creating an HttpHost object for proxy + HttpHost proxyHost = new HttpHost(hostname, port, scheme); + + return new DefaultProxyRoutePlanner(proxyHost); + } + + public HttpRoutePlanner buildDefaultRoutePlanner(final String proxy) { + return buildDefaultRoutePlanner(proxy, -1, null); + } + +} From 1f1b4fa798098cb4f2e6b06d33f6a811ddb84d2a Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 20 Jan 2025 12:02:35 +0530 Subject: [PATCH 07/20] feat(config-api): lock stat endpoint Signed-off-by: pujavs --- .../io/jans/configapi/plugin/lock/rest/LockStatResource.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java index f1a563663e2..39ae0338137 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -49,8 +49,6 @@ public class LockStatResource extends BaseResource { @Inject LockService lockService; - @Inject - @Operation(summary = "Provides basic statistic", description = "Provides basic statistic", operationId = "get-lock-stat", tags = { "Statistics" }, security = @SecurityRequirement(name = "oauth2", scopes = { Constants.LOCK_READ_ACCESS, ApiAccessConstants.JANS_STAT })) From dfae7c54b01a2064e9a3aa2b28adff8618d5079b Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 20 Jan 2025 13:25:48 +0530 Subject: [PATCH 08/20] feat(config-api): scope test case update Signed-off-by: pujavs --- jans-config-api/docs/jans-config-api-swagger.yaml | 12 ++++++------ .../plugins/docs/lock-plugin-swagger.yaml | 1 - .../configapi/plugin/lock/rest/ApiApplication.java | 1 - .../configapi/plugin/lock/rest/LockStatResource.java | 3 ++- .../configapi/plugin/lock/service/LockService.java | 4 ++-- .../configapi/core/service/ConfigHttpService.java | 2 ++ 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 0f8084638d4..f15f5ff5cb2 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,19 +9337,19 @@ components: type: string selected: type: boolean - whitePagesCanView: - type: boolean adminCanAccess: type: boolean userCanAccess: type: boolean - adminCanEdit: + whitePagesCanView: type: boolean adminCanView: type: boolean + userCanEdit: + type: boolean userCanView: type: boolean - userCanEdit: + adminCanEdit: type: boolean baseDn: type: string @@ -11767,10 +11767,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/docs/lock-plugin-swagger.yaml b/jans-config-api/plugins/docs/lock-plugin-swagger.yaml index fcabed560ba..b75b56adade 100644 --- a/jans-config-api/plugins/docs/lock-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/lock-plugin-swagger.yaml @@ -488,7 +488,6 @@ paths: is mandatory if start_month and end_month parameters are not present. schema: type: string - example: 202012 - name: start_month in: query description: Start-Month for which the stat report is to be fetched diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java index 84b2c47a6a9..fec8a36af05 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java @@ -48,7 +48,6 @@ public Set> getClasses() { classes.add(LockConfigResource.class); classes.add(AuditResource.class); - classes.add(LockStatResource.class); return classes; } diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java index 39ae0338137..fe34e979abb 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -72,9 +72,10 @@ public Response getStatistics( } JsonNode jsonNode = null; try { + logger.info("LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", authorization, month, startMonth, endMonth, format); String url = getIssuer() + STAT_URL; jsonNode = this.lockService.getStat(url, authorization, month, startMonth, endMonth, format); - logger.trace("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); + logger.info("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); } catch (Exception ex) { logger.error(" Error while fetching lock stat is", ex); throwBadRequestException(ex); diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java index 7efbf841b7d..a8a74809db5 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -22,7 +22,6 @@ public class LockService { private static final String CONTENT_TYPE = "Content-Type"; private static final String AUTHORIZATION = "Authorization"; - private static final String AUTHORIZATION_BEARER = "Bearer"; @Inject Logger logger; @@ -32,11 +31,12 @@ public class LockService { public JsonNode getStat(String url, String token, String month, String startMonth, String endMonth, String format) throws JsonProcessingException { + logger.info("LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", url, token, month, startMonth, endMonth, format); JsonNode jsonNode = null; Map headers = new HashMap<>(); headers.put(CONTENT_TYPE, MediaType.APPLICATION_JSON); if (StringUtils.isNotBlank(token)) { - headers.put(AUTHORIZATION, AUTHORIZATION_BEARER + "" + token); + headers.put(AUTHORIZATION, token); } // Query Param diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java index 00c00b57dd3..ada7abc8609 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java @@ -27,6 +27,7 @@ import javax.net.ssl.SSLContext; import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; import jakarta.servlet.http.HttpServletRequest; import org.apache.logging.log4j.LogManager; @@ -56,6 +57,7 @@ import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; +@ApplicationScoped public class ConfigHttpService implements Serializable { private static final long serialVersionUID = -2398422090669045605L; From 605d1b5b451948f8f6e3978166435a2636e71e6c Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 20 Jan 2025 14:12:29 +0530 Subject: [PATCH 09/20] feat(config-api): scope test case update Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 22 +++++++++---------- .../plugin/lock/rest/LockStatResource.java | 10 ++++++--- .../plugin/lock/service/LockService.java | 6 ++++- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index f15f5ff5cb2..2d18cd9c0b7 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,19 +9337,19 @@ components: type: string selected: type: boolean - adminCanAccess: - type: boolean - userCanAccess: + adminCanEdit: type: boolean - whitePagesCanView: + userCanEdit: type: boolean adminCanView: type: boolean - userCanEdit: - type: boolean userCanView: type: boolean - adminCanEdit: + adminCanAccess: + type: boolean + userCanAccess: + type: boolean + whitePagesCanView: type: boolean baseDn: type: string @@ -11331,14 +11331,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: @@ -11767,10 +11767,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java index fe34e979abb..bc45d275688 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -50,8 +50,8 @@ public class LockStatResource extends BaseResource { LockService lockService; @Operation(summary = "Provides basic statistic", description = "Provides basic statistic", operationId = "get-lock-stat", tags = { - "Statistics" }, security = @SecurityRequirement(name = "oauth2", scopes = { - Constants.LOCK_READ_ACCESS, ApiAccessConstants.JANS_STAT })) + "Statistics" }, security = @SecurityRequirement(name = "oauth2", scopes = { Constants.LOCK_READ_ACCESS, + ApiAccessConstants.JANS_STAT })) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Stats", content = @Content(mediaType = MediaType.APPLICATION_JSON, array = @ArraySchema(schema = @Schema(implementation = JsonNode.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @@ -72,7 +72,11 @@ public Response getStatistics( } JsonNode jsonNode = null; try { - logger.info("LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", authorization, month, startMonth, endMonth, format); + if (logger.isInfoEnabled()) { + logger.info( + "LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + authorization, month, startMonth, endMonth, format); + } String url = getIssuer() + STAT_URL; jsonNode = this.lockService.getStat(url, authorization, month, startMonth, endMonth, format); logger.info("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java index a8a74809db5..42cb2b44710 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -31,7 +31,11 @@ public class LockService { public JsonNode getStat(String url, String token, String month, String startMonth, String endMonth, String format) throws JsonProcessingException { - logger.info("LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", url, token, month, startMonth, endMonth, format); + if (logger.isInfoEnabled()) { + logger.info( + "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + url, token, month, startMonth, endMonth, format); + } JsonNode jsonNode = null; Map headers = new HashMap<>(); headers.put(CONTENT_TYPE, MediaType.APPLICATION_JSON); From faed1bf0f49dde109fc8e123eb33ae9a0366a611 Mon Sep 17 00:00:00 2001 From: pujavs Date: Mon, 20 Jan 2025 14:31:31 +0530 Subject: [PATCH 10/20] feat(config-api): scope test case update Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 18 +++++++++--------- .../plugin/lock/rest/LockStatResource.java | 6 ++++-- .../plugin/lock/service/LockService.java | 3 ++- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 2d18cd9c0b7..d46e4c60864 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,19 +9337,19 @@ components: type: string selected: type: boolean - adminCanEdit: + userCanAccess: type: boolean - userCanEdit: + adminCanAccess: type: boolean - adminCanView: + whitePagesCanView: type: boolean - userCanView: + adminCanView: type: boolean - adminCanAccess: + userCanEdit: type: boolean - userCanAccess: + adminCanEdit: type: boolean - whitePagesCanView: + userCanView: type: boolean baseDn: type: string @@ -11331,14 +11331,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java index bc45d275688..86223909970 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -6,12 +6,14 @@ package io.jans.configapi.plugin.lock.rest; -import io.jans.configapi.plugin.lock.service.LockService; + import com.fasterxml.jackson.databind.JsonNode; +import static io.jans.as.model.util.Util.escapeLog; import io.jans.configapi.core.rest.BaseResource; import io.jans.configapi.core.rest.ProtectedApi; +import io.jans.configapi.plugin.lock.service.LockService; import io.jans.configapi.plugin.lock.util.Constants; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.util.ApiAccessConstants; @@ -75,7 +77,7 @@ public Response getStatistics( if (logger.isInfoEnabled()) { logger.info( "LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - authorization, month, startMonth, endMonth, format); + escapeLog(authorization), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); } String url = getIssuer() + STAT_URL; jsonNode = this.lockService.getStat(url, authorization, month, startMonth, endMonth, format); diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java index 42cb2b44710..3293d795b67 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; +import static io.jans.as.model.util.Util.escapeLog; import io.jans.configapi.core.service.ConfigHttpService; import io.jans.model.net.HttpServiceResponse; @@ -34,7 +35,7 @@ public JsonNode getStat(String url, String token, String month, String startMont if (logger.isInfoEnabled()) { logger.info( "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - url, token, month, startMonth, endMonth, format); + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); } JsonNode jsonNode = null; Map headers = new HashMap<>(); From e64b0f81a174a24e4662bd62998c0d830beabe23 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 21 Jan 2025 11:44:06 +0530 Subject: [PATCH 11/20] feat(config-api): sync with main Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 12 ++++++------ .../plugins/docs/lock-plugin-swagger.yaml | 2 +- .../plugin/lock/rest/ApiApplication.java | 1 + .../plugin/lock/rest/LockStatResource.java | 6 +++++- .../plugin/lock/service/LockService.java | 10 +++++++--- .../configapi/plugin/lock/util/Constants.java | 2 +- .../core/service/ConfigHttpService.java | 18 ++++++++++-------- 7 files changed, 31 insertions(+), 20 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index d46e4c60864..24263e978b5 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,20 +9337,20 @@ components: type: string selected: type: boolean - userCanAccess: - type: boolean - adminCanAccess: - type: boolean whitePagesCanView: type: boolean adminCanView: type: boolean - userCanEdit: - type: boolean adminCanEdit: type: boolean + userCanEdit: + type: boolean userCanView: type: boolean + userCanAccess: + type: boolean + adminCanAccess: + type: boolean baseDn: type: string PatchRequest: diff --git a/jans-config-api/plugins/docs/lock-plugin-swagger.yaml b/jans-config-api/plugins/docs/lock-plugin-swagger.yaml index b75b56adade..e21e952b110 100644 --- a/jans-config-api/plugins/docs/lock-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/lock-plugin-swagger.yaml @@ -469,7 +469,7 @@ paths: security: - oauth2: - https://jans.io/oauth/lock-config.write - /lock/stat: + /lock/lockStat: get: tags: - Statistics diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java index fec8a36af05..84b2c47a6a9 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/ApiApplication.java @@ -48,6 +48,7 @@ public Set> getClasses() { classes.add(LockConfigResource.class); classes.add(AuditResource.class); + classes.add(LockStatResource.class); return classes; } diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java index 86223909970..90b5553458d 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -79,9 +79,13 @@ public Response getStatistics( "LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", escapeLog(authorization), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); } + + logger.error( + "LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + authorization, month, startMonth, endMonth, format); String url = getIssuer() + STAT_URL; jsonNode = this.lockService.getStat(url, authorization, month, startMonth, endMonth, format); - logger.info("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); + logger.error("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); } catch (Exception ex) { logger.error(" Error while fetching lock stat is", ex); throwBadRequestException(ex); diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java index 3293d795b67..628b1bcd699 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -37,6 +37,9 @@ public JsonNode getStat(String url, String token, String month, String startMont "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); } + logger.error( + "LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + url, month, startMonth, endMonth, format); JsonNode jsonNode = null; Map headers = new HashMap<>(); headers.put(CONTENT_TYPE, MediaType.APPLICATION_JSON); @@ -51,11 +54,12 @@ public JsonNode getStat(String url, String token, String month, String startMont data.put("end-month", endMonth); data.put("format", format); HttpServiceResponse httpServiceResponse = configHttpService.executeGet(url, headers, data); - logger.info(" stat httpServiceResponse:{}", httpServiceResponse); + logger.error(" stat httpServiceResponse:{}", httpServiceResponse); if (httpServiceResponse != null) { + logger.error(" stat httpServiceResponse.getHttpResponse():{}, httpServiceResponse.getHttpResponse().getStatusLine():{}, httpServiceResponse.getHttpResponse().getEntity():{}", httpServiceResponse.getHttpResponse(), httpServiceResponse.getHttpResponse().getStatusLine(), httpServiceResponse.getHttpResponse().getEntity()); jsonNode = getResponseJsonNode(httpServiceResponse, Status.OK); } - logger.info(" stat jsonNode:{}", jsonNode); + logger.error(" stat jsonNode:{}", jsonNode); return jsonNode; } @@ -75,7 +79,7 @@ public String getResponseEntityString(HttpServiceResponse serviceResponse, Statu jsonString = entity.toString(); } - logger.info(" stat jsonString:{}", jsonString); + logger.error(" stat jsonString:{}", jsonString); return jsonString; } diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/Constants.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/Constants.java index c3f50d4e373..80d102fcad9 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/Constants.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/Constants.java @@ -14,7 +14,7 @@ private Constants() { public static final String LOCK = "/lock"; public static final String LOCK_CONFIG = "/lockConfig"; public static final String AUDIT = "/audit"; - public static final String LOCK_STAT = "/stat"; + public static final String LOCK_STAT = "/lockStat"; public static final String HEALTH = "/health"; public static final String LOG = "/log"; public static final String TELEMETRY = "/telemetry"; diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java index ada7abc8609..c4ed07bb133 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java @@ -194,8 +194,8 @@ public HttpServiceResponse executePost(HttpClient httpClient, String uri, String return executePost(httpClient, uri, authCode, null, postData, contentType, null); } - public HttpServiceResponse executePost(String uri, String authCode, String postData, - ContentType contentType, String authType) { + public HttpServiceResponse executePost(String uri, String authCode, String postData, ContentType contentType, + String authType) { return executePost(this.getHttpsClient(), uri, authCode, null, postData, contentType, authType); } @@ -210,7 +210,7 @@ public String encodeUrl(String value) { public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, Map headers, Map parameters) { HttpGet httpGet = new HttpGet(requestUri); - + log.error("requestUri{}, headers:{}, parameters:{}", requestUri, headers, parameters); if (headers != null) { for (Entry headerEntry : headers.entrySet()) { httpGet.setHeader(headerEntry.getKey(), headerEntry.getValue()); @@ -218,23 +218,25 @@ public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, } if (parameters != null && !parameters.isEmpty()) { - StringBuilder query = new StringBuilder(""); + StringBuilder query = new StringBuilder(); + int i = 0; for (String key : parameters.keySet()) { String value = parameters.get(key); if (value != null && value.length() > 0) { - - String delim = "&" + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="; - query.append(delim.substring(1)); + String delim = (i == 0) ? "?" : "&" + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="; + query.append(delim); query.append(URLEncoder.encode(value, StandardCharsets.UTF_8)); } } + requestUri = requestUri + query.toString(); + log.error("\n\n\n Final requestUri:{}", requestUri); httpGet = new HttpGet(requestUri + query.toString()); } try { HttpResponse httpResponse = httpClient.execute(httpGet); - + log.error("httpResponse:{}", httpResponse); return new HttpServiceResponse(httpGet, httpResponse); } catch (IOException ex) { log.error("Failed to execute get request", ex); From 3f08ab43717c6db61cd7f361b8d6345c8bd11f83 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 21 Jan 2025 20:17:52 +0530 Subject: [PATCH 12/20] feat(config-api): lock stat endpoint Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 14 +++++----- .../plugin/lock/rest/LockStatResource.java | 3 +-- .../service/OpenIdAuthorizationService.java | 12 ++++----- .../main/resources/config-api-rs-protect.json | 27 +++++++++++++++++++ .../core/service/ConfigHttpService.java | 18 +++++++++---- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 24263e978b5..41a1b023dd7 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9343,14 +9343,14 @@ components: type: boolean adminCanEdit: type: boolean - userCanEdit: - type: boolean userCanView: type: boolean - userCanAccess: + userCanEdit: type: boolean adminCanAccess: type: boolean + userCanAccess: + type: boolean baseDn: type: string PatchRequest: @@ -10211,8 +10211,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10222,6 +10220,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -11767,10 +11767,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java index 90b5553458d..396b31333c0 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -59,8 +59,7 @@ public class LockStatResource extends BaseResource { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "500", description = "InternalServerError") }) @GET - @ProtectedApi(scopes = { Constants.LOCK_READ_ACCESS, - ApiAccessConstants.JANS_STAT }, groupScopes = {}, superScopes = { + @ProtectedApi(scopes = { Constants.LOCK_READ_ACCESS, ApiAccessConstants.JANS_STAT }, groupScopes = {}, superScopes = { ApiAccessConstants.SUPER_ADMIN_READ_ACCESS }) @Produces(MediaType.APPLICATION_JSON) public Response getStatistics( diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java b/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java index 30bbe9fcbbb..828e90e73e5 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java @@ -120,26 +120,26 @@ public String processAuthorization(String token, String issuer, ResourceInfo res private String validateScope(String accessToken, List tokenScopes, ResourceInfo resourceInfo, String issuer) throws WebApplicationException { - logger.debug("Validate scope, accessToken:{}, tokenScopes:{}, resourceInfo: {}, issuer: {}", accessToken, + logger.error("Validate scope, accessToken:{}, tokenScopes:{}, resourceInfo: {}, issuer: {}", accessToken, tokenScopes, resourceInfo, issuer); try { // Get resource scope Map> resourceScopesByType = getRequestedScopes(resourceInfo); List resourceScopes = getAllScopeList(resourceScopesByType); - logger.debug("Validate scope, resourceScopesByType: {}, resourceScopes: {}", resourceScopesByType, + logger.error("Validate scope, resourceScopesByType: {}, resourceScopes: {}", resourceScopesByType, resourceScopes); // find missing scopes List missingScopes = findMissingScopes(resourceScopesByType, tokenScopes); - logger.debug("missingScopes:{}", missingScopes); + logger.error("missingScopes:{}", missingScopes); // Check if resource requires auth server specific scope List authSpecificScope = getAuthSpecificScopeRequired(resourceInfo); - logger.debug(" resourceScopes:{}, authSpecificScope:{} ", resourceScopes, authSpecificScope); + logger.error(" resourceScopes:{}, authSpecificScope:{} ", resourceScopes, authSpecificScope); // If No auth scope required OR if token contains the authSpecificScope if ((authSpecificScope == null || authSpecificScope.isEmpty())) { - logger.debug("Validating token scopes as no authSpecificScope required"); + logger.error("Validating token scopes as no authSpecificScope required"); if ((missingScopes != null && !missingScopes.isEmpty())) { logger.error("Insufficient scopes! Required scope:{} - however token scopes:{}", resourceScopes, tokenScopes); @@ -180,7 +180,7 @@ private String validateScope(String accessToken, List tokenScopes, Resou Response.status(Response.Status.UNAUTHORIZED).build()); } - logger.info("Token scopes Valid Returning accessToken:{}", accessToken); + logger.error("Token scopes Valid Returning accessToken:{}", accessToken); return AUTHENTICATION_SCHEME + accessToken; } catch (Exception ex) { if (logger.isErrorEnabled()) { 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 71e6189a377..f4c277e38f2 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 @@ -3318,6 +3318,33 @@ ] } ] + }, + { + "path": "/jans-config-api/lock/lockStat", + "conditions": [ + { + "httpMethods": [ + "GET" + ], + "scopes": [ + { + "inum": "1800.03.4", + "name": "https://jans.io/oauth/lock/read-all" + }, + { + "inum": "", + "name": "jans_stat" + } + ], + "groupScopes": [], + "superScopes": [ + { + "inum": "1800.03.1", + "name": "https://jans.io/oauth/config/read-all" + } + ] + } + ] } ] } \ No newline at end of file diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java index c4ed07bb133..76305a4533f 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java @@ -21,6 +21,7 @@ import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; @@ -30,10 +31,12 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.commons.codec.binary.Base64; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; @@ -57,6 +60,8 @@ import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; + + @ApplicationScoped public class ConfigHttpService implements Serializable { @@ -220,18 +225,21 @@ public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, if (parameters != null && !parameters.isEmpty()) { StringBuilder query = new StringBuilder(); int i = 0; - for (String key : parameters.keySet()) { - + for (Iterator iterator = parameters.keySet().iterator(); iterator.hasNext(); ) { + String key = iterator.next(); String value = parameters.get(key); - if (value != null && value.length() > 0) { + log.error("\n\n\n Final key:{}, value:{}", key, value); + if (StringUtils.isNotBlank(value)) { String delim = (i == 0) ? "?" : "&" + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="; query.append(delim); query.append(URLEncoder.encode(value, StandardCharsets.UTF_8)); + i++; + log.error("\n\n\n Final i:{}, query:{}", i, query); } } requestUri = requestUri + query.toString(); log.error("\n\n\n Final requestUri:{}", requestUri); - httpGet = new HttpGet(requestUri + query.toString()); + httpGet = new HttpGet(requestUri); } try { From ac8ca671e60a76eadc30a01ab5f6bcdcb1754858 Mon Sep 17 00:00:00 2001 From: pujavs Date: Tue, 21 Jan 2025 22:23:32 +0530 Subject: [PATCH 13/20] feat(config-api): lock endpoint for stat Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 10 +++--- .../plugin/lock/service/LockService.java | 35 ++++++++++--------- .../service/OpenIdAuthorizationService.java | 11 ++++-- .../openid/OpenIdProtectionService.java | 8 ++--- 4 files changed, 37 insertions(+), 27 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 41a1b023dd7..cd7007ba939 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,12 +9337,10 @@ components: type: string selected: type: boolean - whitePagesCanView: + adminCanEdit: type: boolean adminCanView: type: boolean - adminCanEdit: - type: boolean userCanView: type: boolean userCanEdit: @@ -9351,6 +9349,8 @@ components: type: boolean userCanAccess: type: boolean + whitePagesCanView: + type: boolean baseDn: type: string PatchRequest: @@ -10211,6 +10211,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10220,8 +10222,6 @@ components: - code - token - id_token - fapi: - type: boolean AuthenticationFilter: required: - baseDn diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java index 628b1bcd699..a60ca5628f4 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -35,10 +35,10 @@ public JsonNode getStat(String url, String token, String month, String startMont if (logger.isInfoEnabled()) { logger.info( "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), + escapeLog(format)); } - logger.error( - "LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + logger.error("LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", url, month, startMonth, endMonth, format); JsonNode jsonNode = null; Map headers = new HashMap<>(); @@ -56,13 +56,27 @@ public JsonNode getStat(String url, String token, String month, String startMont HttpServiceResponse httpServiceResponse = configHttpService.executeGet(url, headers, data); logger.error(" stat httpServiceResponse:{}", httpServiceResponse); if (httpServiceResponse != null) { - logger.error(" stat httpServiceResponse.getHttpResponse():{}, httpServiceResponse.getHttpResponse().getStatusLine():{}, httpServiceResponse.getHttpResponse().getEntity():{}", httpServiceResponse.getHttpResponse(), httpServiceResponse.getHttpResponse().getStatusLine(), httpServiceResponse.getHttpResponse().getEntity()); + logger.error( + " stat httpServiceResponse.getHttpResponse():{}, httpServiceResponse.getHttpResponse().getStatusLine():{}, httpServiceResponse.getHttpResponse().getEntity():{}", + httpServiceResponse.getHttpResponse(), httpServiceResponse.getHttpResponse().getStatusLine(), + httpServiceResponse.getHttpResponse().getEntity()); jsonNode = getResponseJsonNode(httpServiceResponse, Status.OK); } logger.error(" stat jsonNode:{}", jsonNode); return jsonNode; } + public JsonNode getResponseJsonNode(HttpServiceResponse serviceResponse, Status status) + throws JsonProcessingException { + JsonNode jsonNode = null; + + if (serviceResponse == null) { + return jsonNode; + } + + return getResponseJsonNode(getResponseEntityString(serviceResponse, status)); + } + public String getResponseEntityString(HttpServiceResponse serviceResponse, Status status) { String jsonString = null; @@ -83,21 +97,10 @@ public String getResponseEntityString(HttpServiceResponse serviceResponse, Statu return jsonString; } - public JsonNode getResponseJsonNode(HttpServiceResponse serviceResponse, Status status) - throws JsonProcessingException { - JsonNode jsonNode = null; - - if (serviceResponse == null) { - return jsonNode; - } - - return getResponseJsonNode(getResponseEntityString(serviceResponse, status)); - } - public JsonNode getResponseJsonNode(String jsonSring) throws JsonProcessingException { JsonNode jsonNode = null; - if (StringUtils.isNotBlank(jsonSring)) { + if (StringUtils.isBlank(jsonSring)) { return jsonNode; } diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java b/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java index 828e90e73e5..6de5d9648e8 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java @@ -113,7 +113,7 @@ public String processAuthorization(String token, String issuer, ResourceInfo res acccessToken = validateScope(acccessToken, tokenScopes, resourceInfo, issuer); boolean isAuthorized = externalAuthorization(token, issuer, method, path); - logger.debug("Custom authorization - isAuthorized:{}", isAuthorized); + logger.error("Custom authorization - isAuthorized:{}", isAuthorized); return acccessToken; } @@ -160,11 +160,18 @@ private String validateScope(String accessToken, List tokenScopes, Resou + ", however token scopes: " + tokenScopes, Response.status(Response.Status.UNAUTHORIZED).build()); } + + //If no scope is missing + if (missingScopes == null || missingScopes.isEmpty()) { + logger.error(" No missing scopes and hence returning original accessToken"); + return accessToken; + } + logger.error("Generating new token with authSpecificScope"); // Generate token with required resourceScopes resourceScopes.addAll(authSpecificScope); accessToken = openIdService.requestAccessToken(authUtil.getClientId(), resourceScopes); - logger.debug("Introspecting new accessToken:{}", accessToken); + logger.error("Introspecting new accessToken:{}", accessToken); // Introspect IntrospectionResponse introspectionResponse = openIdService diff --git a/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java b/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java index 39cbc12c1f4..227a4d003da 100644 --- a/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java +++ b/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java @@ -61,19 +61,19 @@ public Response processAuthorization(HttpHeaders headers, ResourceInfo resourceI try { String token = headers.getHeaderString(HttpHeaders.AUTHORIZATION); boolean authFound = StringUtils.isNotEmpty(token); - log.info("Authorization header {} found", authFound ? "" : "not"); + log.error("Authorization header {} found", authFound ? "" : "not"); if (!authFound) { - log.info("Request is missing authorization header"); + log.error("Request is missing authorization header"); // See section 3.12 RFC 7644 return simpleResponse(UNAUTHORIZED, "No authorization header found"); } token = token.replaceFirst("Bearer\\s+",""); - log.debug("Validating token {}", token); + log.error("Validating token {}", token); List scopes = getRequestedScopes(resourceInfo); - log.info("Call requires scopes: {}", scopes); + log.error("Call requires scopes: {}", scopes); Jwt jwt = tokenAsJwt(token); if (jwt == null) { From 58f278a1c25acef5282613429e6774862ae2d265 Mon Sep 17 00:00:00 2001 From: pujavs Date: Wed, 22 Jan 2025 13:31:32 +0530 Subject: [PATCH 14/20] feat(config-api): sync with main Signed-off-by: pujavs --- jans-config-api/docs/jans-config-api-swagger.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index cd7007ba939..013c5571640 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,20 +9337,20 @@ components: type: string selected: type: boolean + whitePagesCanView: + type: boolean + userCanView: + type: boolean adminCanEdit: type: boolean adminCanView: type: boolean - userCanView: - type: boolean userCanEdit: type: boolean adminCanAccess: type: boolean userCanAccess: type: boolean - whitePagesCanView: - type: boolean baseDn: type: string PatchRequest: @@ -10211,8 +10211,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10222,6 +10220,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn From 7cdc3f89678d43f0cb6331d3992dfead184ea868 Mon Sep 17 00:00:00 2001 From: pujavs Date: Wed, 22 Jan 2025 22:48:00 +0530 Subject: [PATCH 15/20] feat(config-api): lock endpoint wip Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 14 +- .../plugin/lock/service/LockService.java | 45 ++++- .../plugin/lock/util/LockClientFactory.java | 155 ++++++++++++++++++ .../core/service/ConfigHttpService.java | 21 +-- .../openid/OpenIdProtectionService.java | 6 +- 5 files changed, 213 insertions(+), 28 deletions(-) create mode 100644 jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/LockClientFactory.java diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 013c5571640..4caec218f7b 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9335,18 +9335,18 @@ components: $ref: '#/components/schemas/AttributeValidation' tooltip: type: string - selected: - type: boolean whitePagesCanView: type: boolean - userCanView: - type: boolean - adminCanEdit: + selected: type: boolean adminCanView: type: boolean + adminCanEdit: + type: boolean userCanEdit: type: boolean + userCanView: + type: boolean adminCanAccess: type: boolean userCanAccess: @@ -11767,10 +11767,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java index a60ca5628f4..f24f0a5fc96 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -4,13 +4,16 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; + import static io.jans.as.model.util.Util.escapeLog; +import io.jans.configapi.plugin.lock.util.LockClientFactory; import io.jans.configapi.core.service.ConfigHttpService; import io.jans.model.net.HttpServiceResponse; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import java.util.HashMap; import java.util.Map; @@ -21,24 +24,28 @@ @ApplicationScoped public class LockService { + private static final String CONTENT_TYPE = "Content-Type"; private static final String AUTHORIZATION = "Authorization"; - + @Inject Logger logger; @Inject ConfigHttpService configHttpService; + @Inject + LockClientFactory lockClientFactory; + public JsonNode getStat(String url, String token, String month, String startMonth, String endMonth, String format) throws JsonProcessingException { if (logger.isInfoEnabled()) { logger.info( "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), - escapeLog(format)); + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); } - logger.error("LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + logger.error( + "LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", url, month, startMonth, endMonth, format); JsonNode jsonNode = null; Map headers = new HashMap<>(); @@ -56,16 +63,38 @@ public JsonNode getStat(String url, String token, String month, String startMont HttpServiceResponse httpServiceResponse = configHttpService.executeGet(url, headers, data); logger.error(" stat httpServiceResponse:{}", httpServiceResponse); if (httpServiceResponse != null) { - logger.error( - " stat httpServiceResponse.getHttpResponse():{}, httpServiceResponse.getHttpResponse().getStatusLine():{}, httpServiceResponse.getHttpResponse().getEntity():{}", - httpServiceResponse.getHttpResponse(), httpServiceResponse.getHttpResponse().getStatusLine(), - httpServiceResponse.getHttpResponse().getEntity()); + logger.error(" stat httpServiceResponse.getHttpResponse():{}, httpServiceResponse.getHttpResponse().getStatusLine():{}, httpServiceResponse.getHttpResponse().getEntity():{}", httpServiceResponse.getHttpResponse(), httpServiceResponse.getHttpResponse().getStatusLine(), httpServiceResponse.getHttpResponse().getEntity()); jsonNode = getResponseJsonNode(httpServiceResponse, Status.OK); } logger.error(" stat jsonNode:{}", jsonNode); return jsonNode; } + + public JsonNode getStatData(String url, String token, String month, String startMonth, String endMonth, String format) + throws JsonProcessingException { + if (logger.isInfoEnabled()) { + logger.info( + "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), + escapeLog(format)); + } + logger.error("LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + url, month, startMonth, endMonth, format); + JsonNode jsonNode = null; + + Response response = LockClientFactory.getStat(url, token, month, startMonth, endMonth, format); + logger.error(" stat response:{}", response); + if (response != null) { + logger.error(" stat response.getStatus():{}, response.getEntity():{}", response.getStatus(), + response.getEntity()); + String jsonString = response.getEntity().toString(); + jsonNode = getResponseJsonNode(jsonString); + } + logger.error(" stat jsonNode:{}", jsonNode); + return jsonNode; + } + public JsonNode getResponseJsonNode(HttpServiceResponse serviceResponse, Status status) throws JsonProcessingException { JsonNode jsonNode = null; diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/LockClientFactory.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/LockClientFactory.java new file mode 100644 index 00000000000..6e693b1c7d4 --- /dev/null +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/LockClientFactory.java @@ -0,0 +1,155 @@ +/* + * 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.lock.util; + +import static io.jans.as.model.util.Util.escapeLog; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; + +import io.jans.as.client.JwkResponse; +import io.jans.as.client.RevokeSessionResponse; +import io.jans.as.client.RevokeSessionRequest; +import io.jans.as.client.TokenRequest; +import io.jans.as.client.TokenResponse; +import io.jans.as.client.service.IntrospectionService; +import io.jans.as.model.common.GrantType; +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.core.util.Jackson; + + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.Invocation.Builder; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedHashMap; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.core.Response; + + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + + +import org.apache.commons.lang3.StringUtils; +import org.json.JSONObject; +import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; +import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; +import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class LockClientFactory { + + private static final String CONTENT_TYPE = "Content-Type"; + private static final String AUTHORIZATION = "Authorization"; + private static Logger log = LoggerFactory.getLogger(LockClientFactory.class); + + public static Response getStatResponse(String url, String token, String month, String startMonth, String endMonth, + String format) { + if (log.isDebugEnabled()) { + log.debug("Stat Response Token - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{} ", + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), + escapeLog(format)); + } + log.error("Stat Response Token - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{} ", + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), + escapeLog(format)); + ResteasyWebTarget webTarget = (ResteasyWebTarget) ClientBuilder.newClient().target(url); + webTarget.property(CONTENT_TYPE, MediaType.APPLICATION_JSON); + webTarget.property(AUTHORIZATION, token); + + MultivaluedMap params = new MultivaluedHashMap<>(); + if (StringUtils.isNotBlank(month)) { + webTarget.queryParam("month", month); + } + if (StringUtils.isNotBlank(month)) { + webTarget.queryParam("start-month", startMonth); + } + if (StringUtils.isNotBlank(month)) { + webTarget.queryParam("end-month", endMonth); + } + if (StringUtils.isNotBlank(month)) { + webTarget.queryParam("format", format); + } + + + Response response = webTarget.request().accept(MediaType.APPLICATION_JSON).get(); + log.error("response:{}",response); + return response; + } + + + public static Response getStat(String url, String token, String month, String startMonth, String endMonth, + String format) { + if (log.isDebugEnabled()) { + log.debug("Stat Response Token - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{} ", + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), + escapeLog(format)); + } + log.error("Stat Response Token - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{} ", + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), + escapeLog(format)); + + + + Map parameters = new HashMap<>(); + if (StringUtils.isNotBlank(month)) { + parameters.put("month", month); + } + if (StringUtils.isNotBlank(month)) { + parameters.put("start-month", startMonth); + } + if (StringUtils.isNotBlank(month)) { + parameters.put("end-month", endMonth); + } + if (StringUtils.isNotBlank(month)) { + parameters.put("format", format); + } + + if (!parameters.isEmpty()) { + StringBuilder query = new StringBuilder(); + int i = 0; + for (String key : parameters.keySet()) { + + String value = parameters.get(key); + if (value != null && value.length() > 0) { + String delim = (i == 0) ? "?" : "&" + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="; + query.append(delim); + query.append(URLEncoder.encode(value, StandardCharsets.UTF_8)); + } + } + url = url + query.toString(); + log.error("\n\n ******** Final url:{}", url); + + } + Builder clientRequest = getClientBuilder(url); + clientRequest.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); + clientRequest.header(AUTHORIZATION, token); + clientRequest.accept(CONTENT_TYPE, MediaType.APPLICATION_JSON); + + Response response = clientRequest.get(); + log.error("response:{}",response); + return response; + } + + + private static Builder getClientBuilder(String url) { + return ClientBuilder.newClient().target(url).request(); + } + +} diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java index 76305a4533f..72ea751ad5d 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java @@ -214,14 +214,10 @@ public String encodeUrl(String value) { public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, Map headers, Map parameters) { - HttpGet httpGet = new HttpGet(requestUri); + + log.error("\n\n requestUri{}, headers:{}, parameters:{}", requestUri, headers, parameters); + log.error("requestUri{}, headers:{}, parameters:{}", requestUri, headers, parameters); - if (headers != null) { - for (Entry headerEntry : headers.entrySet()) { - httpGet.setHeader(headerEntry.getKey(), headerEntry.getValue()); - } - } - if (parameters != null && !parameters.isEmpty()) { StringBuilder query = new StringBuilder(); int i = 0; @@ -238,10 +234,15 @@ public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, } } requestUri = requestUri + query.toString(); - log.error("\n\n\n Final requestUri:{}", requestUri); - httpGet = new HttpGet(requestUri); + log.error("\n\n\n Final requestUri:{}", requestUri); + } + + HttpGet httpGet = new HttpGet(requestUri); + if (headers != null) { + for (Entry headerEntry : headers.entrySet()) { + httpGet.setHeader(headerEntry.getKey(), headerEntry.getValue()); + } } - try { HttpResponse httpResponse = httpClient.execute(httpGet); log.error("httpResponse:{}", httpResponse); diff --git a/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java b/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java index 227a4d003da..36933186f8b 100644 --- a/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java +++ b/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java @@ -61,7 +61,7 @@ public Response processAuthorization(HttpHeaders headers, ResourceInfo resourceI try { String token = headers.getHeaderString(HttpHeaders.AUTHORIZATION); boolean authFound = StringUtils.isNotEmpty(token); - log.error("Authorization header {} found", authFound ? "" : "not"); + log.error("\n\n\n\n Authorization header {} found", authFound ? "" : "not"); if (!authFound) { log.error("Request is missing authorization header"); @@ -73,7 +73,7 @@ public Response processAuthorization(HttpHeaders headers, ResourceInfo resourceI log.error("Validating token {}", token); List scopes = getRequestedScopes(resourceInfo); - log.error("Call requires scopes: {}", scopes); + log.error("\n Call requires scopes: {}", scopes); Jwt jwt = tokenAsJwt(token); if (jwt == null) { @@ -136,7 +136,7 @@ public Response processIntrospectionResponse(IntrospectionResponse iresponse, Li if (tokenScopes == null || !iresponse.isActive() || !tokenScopes.containsAll(scopes)) { String msg = "Invalid token or insufficient scopes"; - log.error("{}. Token scopes: {}", msg, tokenScopes); + log.error("\n\n\n {}. Token scopes: {}", msg, tokenScopes); // See section 3.12 RFC 7644 response = simpleResponse(Response.Status.FORBIDDEN, msg); } From 9b97d97802d5e3013b3480fb6d47f70f6ea5e21a Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 23 Jan 2025 15:43:39 +0530 Subject: [PATCH 16/20] feat(config-api): lock stats endpoint Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 14 ++--- .../plugin/lock/rest/LockStatResource.java | 14 +++-- .../plugin/lock/service/LockService.java | 61 ++++++++++++------- .../core/service/ConfigHttpService.java | 4 +- 4 files changed, 57 insertions(+), 36 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 4caec218f7b..073734174f6 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9335,22 +9335,22 @@ components: $ref: '#/components/schemas/AttributeValidation' tooltip: type: string - whitePagesCanView: - type: boolean selected: type: boolean adminCanView: type: boolean - adminCanEdit: - type: boolean userCanEdit: type: boolean userCanView: type: boolean - adminCanAccess: + adminCanEdit: type: boolean userCanAccess: type: boolean + adminCanAccess: + type: boolean + whitePagesCanView: + type: boolean baseDn: type: string PatchRequest: @@ -10211,6 +10211,8 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' + fapi: + type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10220,8 +10222,6 @@ components: - code - token - id_token - fapi: - type: boolean AuthenticationFilter: required: - baseDn diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java index 396b31333c0..6b8b7af4baf 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -6,11 +6,10 @@ package io.jans.configapi.plugin.lock.rest; - - import com.fasterxml.jackson.databind.JsonNode; import static io.jans.as.model.util.Util.escapeLog; +import io.jans.configapi.core.model.exception.ApiApplicationException; import io.jans.configapi.core.rest.BaseResource; import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.plugin.lock.service.LockService; @@ -59,7 +58,8 @@ public class LockStatResource extends BaseResource { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "500", description = "InternalServerError") }) @GET - @ProtectedApi(scopes = { Constants.LOCK_READ_ACCESS, ApiAccessConstants.JANS_STAT }, groupScopes = {}, superScopes = { + @ProtectedApi(scopes = { Constants.LOCK_READ_ACCESS, + ApiAccessConstants.JANS_STAT }, groupScopes = {}, superScopes = { ApiAccessConstants.SUPER_ADMIN_READ_ACCESS }) @Produces(MediaType.APPLICATION_JSON) public Response getStatistics( @@ -76,15 +76,19 @@ public Response getStatistics( if (logger.isInfoEnabled()) { logger.info( "LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - escapeLog(authorization), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); + escapeLog(authorization), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), + escapeLog(format)); } - + logger.error( "LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", authorization, month, startMonth, endMonth, format); String url = getIssuer() + STAT_URL; jsonNode = this.lockService.getStat(url, authorization, month, startMonth, endMonth, format); logger.error("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); + } catch (ApiApplicationException aex) { + logger.error(" ApiApplicationException while fetching lock stat is", aex); + throwInternalServerException("Stat Error", aex); } catch (Exception ex) { logger.error(" Error while fetching lock stat is", ex); throwBadRequestException(ex); diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java index f24f0a5fc96..b6a620dc9ac 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -6,8 +6,9 @@ import com.fasterxml.jackson.databind.JsonNode; import static io.jans.as.model.util.Util.escapeLog; -import io.jans.configapi.plugin.lock.util.LockClientFactory; +import io.jans.configapi.core.model.exception.ApiApplicationException; import io.jans.configapi.core.service.ConfigHttpService; +import io.jans.configapi.plugin.lock.util.LockClientFactory; import io.jans.model.net.HttpServiceResponse; import jakarta.enterprise.context.ApplicationScoped; @@ -20,6 +21,8 @@ import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; import org.slf4j.Logger; @ApplicationScoped @@ -27,7 +30,7 @@ public class LockService { private static final String CONTENT_TYPE = "Content-Type"; private static final String AUTHORIZATION = "Authorization"; - + @Inject Logger logger; @@ -38,14 +41,14 @@ public class LockService { LockClientFactory lockClientFactory; public JsonNode getStat(String url, String token, String month, String startMonth, String endMonth, String format) - throws JsonProcessingException { + throws ApiApplicationException, JsonProcessingException { if (logger.isInfoEnabled()) { logger.info( "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); + escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), + escapeLog(format)); } - logger.error( - "LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", + logger.error("LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", url, month, startMonth, endMonth, format); JsonNode jsonNode = null; Map headers = new HashMap<>(); @@ -63,16 +66,18 @@ public JsonNode getStat(String url, String token, String month, String startMont HttpServiceResponse httpServiceResponse = configHttpService.executeGet(url, headers, data); logger.error(" stat httpServiceResponse:{}", httpServiceResponse); if (httpServiceResponse != null) { - logger.error(" stat httpServiceResponse.getHttpResponse():{}, httpServiceResponse.getHttpResponse().getStatusLine():{}, httpServiceResponse.getHttpResponse().getEntity():{}", httpServiceResponse.getHttpResponse(), httpServiceResponse.getHttpResponse().getStatusLine(), httpServiceResponse.getHttpResponse().getEntity()); - jsonNode = getResponseJsonNode(httpServiceResponse, Status.OK); + logger.error( + " stat httpServiceResponse.getHttpResponse():{}, httpServiceResponse.getHttpResponse().getStatusLine():{}, httpServiceResponse.getHttpResponse().getEntity():{}", + httpServiceResponse.getHttpResponse(), httpServiceResponse.getHttpResponse().getStatusLine(), + httpServiceResponse.getHttpResponse().getEntity()); + jsonNode = getResponseJsonNode(httpServiceResponse); } logger.error(" stat jsonNode:{}", jsonNode); return jsonNode; } - - public JsonNode getStatData(String url, String token, String month, String startMonth, String endMonth, String format) - throws JsonProcessingException { + public JsonNode getStatData(String url, String token, String month, String startMonth, String endMonth, + String format) throws JsonProcessingException { if (logger.isInfoEnabled()) { logger.info( "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", @@ -95,35 +100,47 @@ public JsonNode getStatData(String url, String token, String month, String start return jsonNode; } - public JsonNode getResponseJsonNode(HttpServiceResponse serviceResponse, Status status) - throws JsonProcessingException { + public JsonNode getResponseJsonNode(HttpServiceResponse serviceResponse) + throws ApiApplicationException, JsonProcessingException { JsonNode jsonNode = null; if (serviceResponse == null) { return jsonNode; } - return getResponseJsonNode(getResponseEntityString(serviceResponse, status)); + return getResponseJsonNode(getResponseEntityString(serviceResponse)); } - public String getResponseEntityString(HttpServiceResponse serviceResponse, Status status) { + public String getResponseEntityString(HttpServiceResponse serviceResponse) throws ApiApplicationException { String jsonString = null; if (serviceResponse == null) { return jsonString; } - - if (serviceResponse.getHttpResponse() != null && serviceResponse.getHttpResponse().getStatusLine() != null - && serviceResponse.getHttpResponse().getStatusLine().getStatusCode() == status.getStatusCode()) { - HttpEntity entity = serviceResponse.getHttpResponse().getEntity(); + HttpResponse httpResponse = serviceResponse.getHttpResponse(); + if (httpResponse != null) { + HttpEntity entity = httpResponse.getEntity(); + logger.debug("entity:{}, httpResponse.getStatusLine().getStatusCode():{}", entity, + httpResponse.getStatusLine().getStatusCode()); if (entity == null) { return jsonString; } - jsonString = entity.toString(); + try { + jsonString = entity.toString(); + logger.error(" stat jsonString:{}", jsonString); + + jsonString = EntityUtils.toString(entity, "UTF-8"); + logger.error("\n\n New jsonString:{}", jsonString); + } catch (Exception ex) { + logger.error("Error while getting entity using EntityUtils is ", ex); + } + } + if (httpResponse.getStatusLine().getStatusCode() == Status.OK.getStatusCode()) { + return jsonString; + } else { + throw new ApiApplicationException(httpResponse.getStatusLine().getStatusCode(), jsonString); } - logger.error(" stat jsonString:{}", jsonString); - return jsonString; } public JsonNode getResponseJsonNode(String jsonSring) throws JsonProcessingException { diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java index 72ea751ad5d..0129470f569 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java @@ -226,8 +226,8 @@ public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, String value = parameters.get(key); log.error("\n\n\n Final key:{}, value:{}", key, value); if (StringUtils.isNotBlank(value)) { - String delim = (i == 0) ? "?" : "&" + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="; - query.append(delim); + String delim = (i == 0) ? "?" : "&"; + query.append(delim + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="); query.append(URLEncoder.encode(value, StandardCharsets.UTF_8)); i++; log.error("\n\n\n Final i:{}, query:{}", i, query); From 671aa7dd284eca7922615b58fd01f4ea64da4be6 Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 23 Jan 2025 19:18:22 +0530 Subject: [PATCH 17/20] feat(config-api): lock stat endpoint Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 6 +- .../plugins/docs/lock-plugin-swagger.yaml | 31 +--- .../plugin/lock/rest/LockStatResource.java | 12 +- .../plugin/lock/service/LockService.java | 71 +++----- .../plugin/lock/util/LockClientFactory.java | 155 ------------------ .../service/OpenIdAuthorizationService.java | 20 +-- .../core/service/ConfigHttpService.java | 21 +-- .../openid/OpenIdProtectionService.java | 10 +- 8 files changed, 61 insertions(+), 265 deletions(-) delete mode 100644 jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/LockClientFactory.java diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 073734174f6..b6c7bf72095 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9341,14 +9341,14 @@ components: type: boolean userCanEdit: type: boolean - userCanView: - type: boolean adminCanEdit: type: boolean - userCanAccess: + userCanView: type: boolean adminCanAccess: type: boolean + userCanAccess: + type: boolean whitePagesCanView: type: boolean baseDn: diff --git a/jans-config-api/plugins/docs/lock-plugin-swagger.yaml b/jans-config-api/plugins/docs/lock-plugin-swagger.yaml index e21e952b110..dda647c3d48 100644 --- a/jans-config-api/plugins/docs/lock-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/lock-plugin-swagger.yaml @@ -488,12 +488,12 @@ paths: is mandatory if start_month and end_month parameters are not present. schema: type: string - - name: start_month + - name: start-month in: query description: Start-Month for which the stat report is to be fetched schema: type: string - - name: end_month + - name: end-month in: query description: End-Month for which the stat report is to be fetched schema: @@ -671,9 +671,6 @@ components: tokenUrl: type: string description: Jans URL of the OpenID Connect Provider's OAuth 2.0 Token Endpoint - groupScopeEnabled: - type: boolean - description: Group scope enabled endpointGroups: type: object additionalProperties: @@ -707,9 +704,6 @@ components: externalLoggerConfiguration: type: string description: The path to the external log4j2 logging configuration - metricChannel: - type: string - description: Channel for metric reports metricReporterInterval: type: integer description: The interval for metric reporter in seconds @@ -725,11 +719,6 @@ components: type: integer description: Time interval for the Clean Service in seconds format: int32 - opaConfiguration: - $ref: '#/components/schemas/OpaConfiguration' - pdpType: - type: string - description: PDP type policiesJsonUrisAuthorizationToken: type: string description: Authorization token to access Json Uris @@ -748,18 +737,14 @@ components: items: type: string description: List of Zip Uris with policies - errorReasonEnabled: - type: boolean - OpaConfiguration: - type: object - properties: - baseUrl: + messageConsumerType: type: string - description: Base OPA URL - accessToken: + description: PubSub consumer service + policyConsumerType: type: string - description: OPA access token - description: Opa Configuration + description: Policy consumer service + errorReasonEnabled: + type: boolean JsonPatch: type: object JsonNode: diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java index 6b8b7af4baf..c19ea60ebcb 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/rest/LockStatResource.java @@ -65,8 +65,8 @@ public class LockStatResource extends BaseResource { public Response getStatistics( @Parameter(description = "Authorization code") @HeaderParam("Authorization") String authorization, @Parameter(description = "Month for which the stat report is to be fetched. The parameter is mandatory if start_month and end_month parameters are not present.") @QueryParam(value = "month") String month, - @Parameter(description = "Start-Month for which the stat report is to be fetched") @QueryParam(value = "start_month") String startMonth, - @Parameter(description = "End-Month for which the stat report is to be fetched") @QueryParam(value = "end_month") String endMonth, + @Parameter(description = "Start-Month for which the stat report is to be fetched") @QueryParam(value = "start-month") String startMonth, + @Parameter(description = "End-Month for which the stat report is to be fetched") @QueryParam(value = "end-month") String endMonth, @Parameter(description = "Report format") @QueryParam(value = "format") String format) { if (StringUtils.isBlank(format)) { format = ""; @@ -79,18 +79,14 @@ public Response getStatistics( escapeLog(authorization), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); } - - logger.error( - "LockStatResource::getStatistics() - authorization:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - authorization, month, startMonth, endMonth, format); String url = getIssuer() + STAT_URL; jsonNode = this.lockService.getStat(url, authorization, month, startMonth, endMonth, format); - logger.error("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); + logger.info("StatResource::getUserStatistics() - jsonNode:{} ", jsonNode); } catch (ApiApplicationException aex) { logger.error(" ApiApplicationException while fetching lock stat is", aex); throwInternalServerException("Stat Error", aex); } catch (Exception ex) { - logger.error(" Error while fetching lock stat is", ex); + logger.error(" Exception while fetching lock stat is", ex); throwBadRequestException(ex); } return Response.ok(jsonNode).build(); diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java index b6a620dc9ac..e61366f813e 100644 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java +++ b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/service/LockService.java @@ -8,13 +8,12 @@ import static io.jans.as.model.util.Util.escapeLog; import io.jans.configapi.core.model.exception.ApiApplicationException; import io.jans.configapi.core.service.ConfigHttpService; -import io.jans.configapi.plugin.lock.util.LockClientFactory; import io.jans.model.net.HttpServiceResponse; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; + import jakarta.ws.rs.core.Response.Status; import java.util.HashMap; import java.util.Map; @@ -37,9 +36,6 @@ public class LockService { @Inject ConfigHttpService configHttpService; - @Inject - LockClientFactory lockClientFactory; - public JsonNode getStat(String url, String token, String month, String startMonth, String endMonth, String format) throws ApiApplicationException, JsonProcessingException { if (logger.isInfoEnabled()) { @@ -48,55 +44,33 @@ public JsonNode getStat(String url, String token, String month, String startMont escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), escapeLog(format)); } - logger.error("LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - url, month, startMonth, endMonth, format); + JsonNode jsonNode = null; + + // Request headers Map headers = new HashMap<>(); headers.put(CONTENT_TYPE, MediaType.APPLICATION_JSON); if (StringUtils.isNotBlank(token)) { headers.put(AUTHORIZATION, token); } - // Query Param + // Query Parameter Map data = new HashMap<>(); data.put("month", month); data.put("start-month", startMonth); data.put("end-month", endMonth); data.put("format", format); HttpServiceResponse httpServiceResponse = configHttpService.executeGet(url, headers, data); - logger.error(" stat httpServiceResponse:{}", httpServiceResponse); + + logger.info(" stat httpServiceResponse:{}", httpServiceResponse); if (httpServiceResponse != null) { - logger.error( + logger.info( " stat httpServiceResponse.getHttpResponse():{}, httpServiceResponse.getHttpResponse().getStatusLine():{}, httpServiceResponse.getHttpResponse().getEntity():{}", httpServiceResponse.getHttpResponse(), httpServiceResponse.getHttpResponse().getStatusLine(), httpServiceResponse.getHttpResponse().getEntity()); jsonNode = getResponseJsonNode(httpServiceResponse); } - logger.error(" stat jsonNode:{}", jsonNode); - return jsonNode; - } - - public JsonNode getStatData(String url, String token, String month, String startMonth, String endMonth, - String format) throws JsonProcessingException { - if (logger.isInfoEnabled()) { - logger.info( - "LockStatResource::getStatistics() - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), - escapeLog(format)); - } - logger.error("LockStatResource::getStatistics() - url:{}, month:{}, startMonth:{}, endMonth:{}, format:{}", - url, month, startMonth, endMonth, format); - JsonNode jsonNode = null; - - Response response = LockClientFactory.getStat(url, token, month, startMonth, endMonth, format); - logger.error(" stat response:{}", response); - if (response != null) { - logger.error(" stat response.getStatus():{}, response.getEntity():{}", response.getStatus(), - response.getEntity()); - String jsonString = response.getEntity().toString(); - jsonNode = getResponseJsonNode(jsonString); - } - logger.error(" stat jsonNode:{}", jsonNode); + logger.info(" stat jsonNode:{}", jsonNode); return jsonNode; } @@ -108,7 +82,7 @@ public JsonNode getResponseJsonNode(HttpServiceResponse serviceResponse) return jsonNode; } - return getResponseJsonNode(getResponseEntityString(serviceResponse)); + return getResponseJsonNode(getResponseEntityString(serviceResponse), "response"); } public String getResponseEntityString(HttpServiceResponse serviceResponse) throws ApiApplicationException { @@ -126,31 +100,32 @@ public String getResponseEntityString(HttpServiceResponse serviceResponse) throw return jsonString; } try { - jsonString = entity.toString(); - logger.error(" stat jsonString:{}", jsonString); - jsonString = EntityUtils.toString(entity, "UTF-8"); - logger.error("\n\n New jsonString:{}", jsonString); } catch (Exception ex) { logger.error("Error while getting entity using EntityUtils is ", ex); } - } - if (httpResponse.getStatusLine().getStatusCode() == Status.OK.getStatusCode()) { - return jsonString; - } else { - throw new ApiApplicationException(httpResponse.getStatusLine().getStatusCode(), jsonString); + if (httpResponse.getStatusLine() != null + && httpResponse.getStatusLine().getStatusCode() == Status.OK.getStatusCode()) { + return jsonString; + } else { + throw new ApiApplicationException(httpResponse.getStatusLine().getStatusCode(), jsonString); + } } + return jsonString; } - public JsonNode getResponseJsonNode(String jsonSring) throws JsonProcessingException { + public JsonNode getResponseJsonNode(String jsonSring, String nodeName) throws JsonProcessingException { JsonNode jsonNode = null; if (StringUtils.isBlank(jsonSring)) { return jsonNode; } - - return Jackson.asJsonNode(jsonSring); + jsonNode = Jackson.asJsonNode(jsonSring); + if (StringUtils.isNotBlank(nodeName) && jsonNode != null && jsonNode.get(nodeName) != null) { + jsonNode = jsonNode.get("response"); + } + return jsonNode; } } diff --git a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/LockClientFactory.java b/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/LockClientFactory.java deleted file mode 100644 index 6e693b1c7d4..00000000000 --- a/jans-config-api/plugins/lock-plugin/src/main/java/io/jans/configapi/plugin/lock/util/LockClientFactory.java +++ /dev/null @@ -1,155 +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.plugin.lock.util; - -import static io.jans.as.model.util.Util.escapeLog; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; - -import io.jans.as.client.JwkResponse; -import io.jans.as.client.RevokeSessionResponse; -import io.jans.as.client.RevokeSessionRequest; -import io.jans.as.client.TokenRequest; -import io.jans.as.client.TokenResponse; -import io.jans.as.client.service.IntrospectionService; -import io.jans.as.model.common.GrantType; -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.core.util.Jackson; - - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.client.Invocation.Builder; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.MultivaluedHashMap; -import jakarta.ws.rs.core.MultivaluedMap; -import jakarta.ws.rs.core.Response; - - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; - - -import org.apache.commons.lang3.StringUtils; -import org.json.JSONObject; -import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; -import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@ApplicationScoped -public class LockClientFactory { - - private static final String CONTENT_TYPE = "Content-Type"; - private static final String AUTHORIZATION = "Authorization"; - private static Logger log = LoggerFactory.getLogger(LockClientFactory.class); - - public static Response getStatResponse(String url, String token, String month, String startMonth, String endMonth, - String format) { - if (log.isDebugEnabled()) { - log.debug("Stat Response Token - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{} ", - escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), - escapeLog(format)); - } - log.error("Stat Response Token - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{} ", - escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), - escapeLog(format)); - ResteasyWebTarget webTarget = (ResteasyWebTarget) ClientBuilder.newClient().target(url); - webTarget.property(CONTENT_TYPE, MediaType.APPLICATION_JSON); - webTarget.property(AUTHORIZATION, token); - - MultivaluedMap params = new MultivaluedHashMap<>(); - if (StringUtils.isNotBlank(month)) { - webTarget.queryParam("month", month); - } - if (StringUtils.isNotBlank(month)) { - webTarget.queryParam("start-month", startMonth); - } - if (StringUtils.isNotBlank(month)) { - webTarget.queryParam("end-month", endMonth); - } - if (StringUtils.isNotBlank(month)) { - webTarget.queryParam("format", format); - } - - - Response response = webTarget.request().accept(MediaType.APPLICATION_JSON).get(); - log.error("response:{}",response); - return response; - } - - - public static Response getStat(String url, String token, String month, String startMonth, String endMonth, - String format) { - if (log.isDebugEnabled()) { - log.debug("Stat Response Token - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{} ", - escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), - escapeLog(format)); - } - log.error("Stat Response Token - url:{}, token:{}, month:{}, startMonth:{}, endMonth:{}, format:{} ", - escapeLog(url), escapeLog(token), escapeLog(month), escapeLog(startMonth), escapeLog(endMonth), - escapeLog(format)); - - - - Map parameters = new HashMap<>(); - if (StringUtils.isNotBlank(month)) { - parameters.put("month", month); - } - if (StringUtils.isNotBlank(month)) { - parameters.put("start-month", startMonth); - } - if (StringUtils.isNotBlank(month)) { - parameters.put("end-month", endMonth); - } - if (StringUtils.isNotBlank(month)) { - parameters.put("format", format); - } - - if (!parameters.isEmpty()) { - StringBuilder query = new StringBuilder(); - int i = 0; - for (String key : parameters.keySet()) { - - String value = parameters.get(key); - if (value != null && value.length() > 0) { - String delim = (i == 0) ? "?" : "&" + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="; - query.append(delim); - query.append(URLEncoder.encode(value, StandardCharsets.UTF_8)); - } - } - url = url + query.toString(); - log.error("\n\n ******** Final url:{}", url); - - } - Builder clientRequest = getClientBuilder(url); - clientRequest.header(CONTENT_TYPE, MediaType.APPLICATION_JSON); - clientRequest.header(AUTHORIZATION, token); - clientRequest.accept(CONTENT_TYPE, MediaType.APPLICATION_JSON); - - Response response = clientRequest.get(); - log.error("response:{}",response); - return response; - } - - - private static Builder getClientBuilder(String url) { - return ClientBuilder.newClient().target(url).request(); - } - -} diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java b/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java index 6de5d9648e8..b93bd743b9c 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/security/service/OpenIdAuthorizationService.java @@ -113,33 +113,33 @@ public String processAuthorization(String token, String issuer, ResourceInfo res acccessToken = validateScope(acccessToken, tokenScopes, resourceInfo, issuer); boolean isAuthorized = externalAuthorization(token, issuer, method, path); - logger.error("Custom authorization - isAuthorized:{}", isAuthorized); + logger.debug("Custom authorization - isAuthorized:{}", isAuthorized); return acccessToken; } private String validateScope(String accessToken, List tokenScopes, ResourceInfo resourceInfo, String issuer) throws WebApplicationException { - logger.error("Validate scope, accessToken:{}, tokenScopes:{}, resourceInfo: {}, issuer: {}", accessToken, + logger.info("Validate scope, accessToken:{}, tokenScopes:{}, resourceInfo: {}, issuer: {}", accessToken, tokenScopes, resourceInfo, issuer); try { // Get resource scope Map> resourceScopesByType = getRequestedScopes(resourceInfo); List resourceScopes = getAllScopeList(resourceScopesByType); - logger.error("Validate scope, resourceScopesByType: {}, resourceScopes: {}", resourceScopesByType, + logger.debug("Validate scope, resourceScopesByType: {}, resourceScopes: {}", resourceScopesByType, resourceScopes); // find missing scopes List missingScopes = findMissingScopes(resourceScopesByType, tokenScopes); - logger.error("missingScopes:{}", missingScopes); + logger.info("missingScopes:{}", missingScopes); // Check if resource requires auth server specific scope List authSpecificScope = getAuthSpecificScopeRequired(resourceInfo); - logger.error(" resourceScopes:{}, authSpecificScope:{} ", resourceScopes, authSpecificScope); + logger.info(" resourceScopes:{}, authSpecificScope:{} ", resourceScopes, authSpecificScope); // If No auth scope required OR if token contains the authSpecificScope if ((authSpecificScope == null || authSpecificScope.isEmpty())) { - logger.error("Validating token scopes as no authSpecificScope required"); + logger.info("Validating token scopes as no authSpecificScope required"); if ((missingScopes != null && !missingScopes.isEmpty())) { logger.error("Insufficient scopes! Required scope:{} - however token scopes:{}", resourceScopes, tokenScopes); @@ -163,15 +163,15 @@ private String validateScope(String accessToken, List tokenScopes, Resou //If no scope is missing if (missingScopes == null || missingScopes.isEmpty()) { - logger.error(" No missing scopes and hence returning original accessToken"); + logger.info(" No missing scopes and hence returning original accessToken"); return accessToken; } - logger.error("Generating new token with authSpecificScope"); + logger.info("Generating new token with authSpecificScope"); // Generate token with required resourceScopes resourceScopes.addAll(authSpecificScope); accessToken = openIdService.requestAccessToken(authUtil.getClientId(), resourceScopes); - logger.error("Introspecting new accessToken:{}", accessToken); + logger.debug("Introspecting new accessToken:{}", accessToken); // Introspect IntrospectionResponse introspectionResponse = openIdService @@ -187,7 +187,7 @@ private String validateScope(String accessToken, List tokenScopes, Resou Response.status(Response.Status.UNAUTHORIZED).build()); } - logger.error("Token scopes Valid Returning accessToken:{}", accessToken); + logger.info("Token scopes Valid Returning accessToken:{}", accessToken); return AUTHENTICATION_SCHEME + accessToken; } catch (Exception ex) { if (logger.isErrorEnabled()) { diff --git a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java index 0129470f569..d7489ae3df7 100644 --- a/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/service/ConfigHttpService.java @@ -60,8 +60,6 @@ import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; - - @ApplicationScoped public class ConfigHttpService implements Serializable { @@ -214,29 +212,26 @@ public String encodeUrl(String value) { public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, Map headers, Map parameters) { - - log.error("\n\n requestUri{}, headers:{}, parameters:{}", requestUri, headers, parameters); - - log.error("requestUri{}, headers:{}, parameters:{}", requestUri, headers, parameters); + + log.info("\n\n requestUri{}, headers:{}, parameters:{}", requestUri, headers, parameters); + if (parameters != null && !parameters.isEmpty()) { StringBuilder query = new StringBuilder(); int i = 0; - for (Iterator iterator = parameters.keySet().iterator(); iterator.hasNext(); ) { + for (Iterator iterator = parameters.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); String value = parameters.get(key); - log.error("\n\n\n Final key:{}, value:{}", key, value); if (StringUtils.isNotBlank(value)) { - String delim = (i == 0) ? "?" : "&"; + String delim = (i == 0) ? "?" : "&"; query.append(delim + URLEncoder.encode(key, StandardCharsets.UTF_8) + "="); query.append(URLEncoder.encode(value, StandardCharsets.UTF_8)); i++; - log.error("\n\n\n Final i:{}, query:{}", i, query); } } requestUri = requestUri + query.toString(); - log.error("\n\n\n Final requestUri:{}", requestUri); + log.info("\n\n\n Final requestUri:{}", requestUri); } - + HttpGet httpGet = new HttpGet(requestUri); if (headers != null) { for (Entry headerEntry : headers.entrySet()) { @@ -245,7 +240,7 @@ public HttpServiceResponse executeGet(HttpClient httpClient, String requestUri, } try { HttpResponse httpResponse = httpClient.execute(httpGet); - log.error("httpResponse:{}", httpResponse); + log.info("httpResponse:{}", httpResponse); return new HttpServiceResponse(httpGet, httpResponse); } catch (IOException ex) { log.error("Failed to execute get request", ex); diff --git a/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java b/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java index 36933186f8b..39cbc12c1f4 100644 --- a/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java +++ b/jans-lock/lock-server/service/src/main/java/io/jans/lock/service/filter/openid/OpenIdProtectionService.java @@ -61,19 +61,19 @@ public Response processAuthorization(HttpHeaders headers, ResourceInfo resourceI try { String token = headers.getHeaderString(HttpHeaders.AUTHORIZATION); boolean authFound = StringUtils.isNotEmpty(token); - log.error("\n\n\n\n Authorization header {} found", authFound ? "" : "not"); + log.info("Authorization header {} found", authFound ? "" : "not"); if (!authFound) { - log.error("Request is missing authorization header"); + log.info("Request is missing authorization header"); // See section 3.12 RFC 7644 return simpleResponse(UNAUTHORIZED, "No authorization header found"); } token = token.replaceFirst("Bearer\\s+",""); - log.error("Validating token {}", token); + log.debug("Validating token {}", token); List scopes = getRequestedScopes(resourceInfo); - log.error("\n Call requires scopes: {}", scopes); + log.info("Call requires scopes: {}", scopes); Jwt jwt = tokenAsJwt(token); if (jwt == null) { @@ -136,7 +136,7 @@ public Response processIntrospectionResponse(IntrospectionResponse iresponse, Li if (tokenScopes == null || !iresponse.isActive() || !tokenScopes.containsAll(scopes)) { String msg = "Invalid token or insufficient scopes"; - log.error("\n\n\n {}. Token scopes: {}", msg, tokenScopes); + log.error("{}. Token scopes: {}", msg, tokenScopes); // See section 3.12 RFC 7644 response = simpleResponse(Response.Status.FORBIDDEN, msg); } From 2a8bf8642ca6a334e0eba6649a3543727ac27fdf Mon Sep 17 00:00:00 2001 From: pujavs Date: Thu, 23 Jan 2025 21:13:14 +0530 Subject: [PATCH 18/20] feat(config-api): lock stat endpoint Signed-off-by: pujavs --- jans-config-api/docs/jans-config-api-swagger.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index b6c7bf72095..5d9c8373cf1 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9339,12 +9339,12 @@ components: type: boolean adminCanView: type: boolean + userCanView: + type: boolean userCanEdit: type: boolean adminCanEdit: type: boolean - userCanView: - type: boolean adminCanAccess: type: boolean userCanAccess: @@ -10211,8 +10211,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -10222,6 +10220,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn From 6135564655fc07ecc6907d3861bf40003c3cbafa Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 24 Jan 2025 13:59:16 +0530 Subject: [PATCH 19/20] fix(config-api): asset upload config and saml document store changes Signed-off-by: pujavs --- .../customization/customize-web-pages.md | 4 +-- .../docs/jans-config-api-swagger.yaml | 16 ++++----- .../plugin/saml/service/SamlIdpService.java | 36 +++++++++---------- .../configapi/service/auth/AssetService.java | 6 ---- .../jans-config-api/dynamic-conf.json | 15 ++------ 5 files changed, 29 insertions(+), 48 deletions(-) diff --git a/docs/janssen-server/developer/customization/customize-web-pages.md b/docs/janssen-server/developer/customization/customize-web-pages.md index a6598e08801..a0ddad6c271 100644 --- a/docs/janssen-server/developer/customization/customize-web-pages.md +++ b/docs/janssen-server/developer/customization/customize-web-pages.md @@ -81,7 +81,7 @@ Listing of custom asset types that each Janssen Server module accepts: | Path | Asset Type | |----------------|-------------| -| /opt/jans/jetty/jans-lock/custom-libs | *.jar +| /opt/jans/jetty/jans-lock/custom/libs | *.jar ### KeyCloak-link @@ -96,7 +96,7 @@ Listing of custom asset types that each Janssen Server module accepts: | Path | Asset Type | |----------------|-------------| -| /opt/jans/jetty/jans-link/custom-libs | *.jar +| /opt/jans/jetty/jans-link/custom/libs | *.jar | /var/jans/link-snapshots/ | *.txt diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 5d9c8373cf1..c38befde24a 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9339,16 +9339,16 @@ components: type: boolean adminCanView: type: boolean - userCanView: + adminCanEdit: type: boolean userCanEdit: type: boolean - adminCanEdit: - type: boolean - adminCanAccess: + userCanView: type: boolean userCanAccess: type: boolean + adminCanAccess: + type: boolean whitePagesCanView: type: boolean baseDn: @@ -11331,14 +11331,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: @@ -11767,10 +11767,10 @@ components: ttl: type: integer format: int32 - opbrowserState: - type: string persisted: type: boolean + opbrowserState: + type: string SessionIdAccessMap: type: object properties: diff --git a/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/service/SamlIdpService.java b/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/service/SamlIdpService.java index 0b7a16077c5..b0b33b2c532 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/service/SamlIdpService.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/service/SamlIdpService.java @@ -6,7 +6,6 @@ package io.jans.configapi.plugin.saml.service; -import io.jans.service.document.store.service.DocumentStoreService; import io.jans.service.document.store.conf.DocumentStoreType; import io.jans.service.document.store.service.LocalDocumentStoreService; import io.jans.util.exception.InvalidConfigurationException; @@ -38,8 +37,6 @@ public class SamlIdpService { @Inject Logger logger; - @Inject - private DocumentStoreService documentStoreService; @Inject private LocalDocumentStoreService localDocumentStoreService; @@ -58,7 +55,7 @@ public void create() { } public boolean isLocalDocumentStoreType() { - return documentStoreService.getProviderType() == DocumentStoreType.LOCAL; + return localDocumentStoreService.getProviderType() == DocumentStoreType.LOCAL; } public String saveMetadataFile(String metadataDir, String metadataFileName, String documentStoreModuleName, @@ -83,14 +80,13 @@ public String saveMetadataFile(String metadataDir, String metadataFileName, Stri } String metadataFile = metadataDir + File.separator + metadataFileName; - logger.info("documentStoreService:{}, metadataFile:{}, localDocumentStoreService:{} ", documentStoreService, - metadataFile, localDocumentStoreService); + logger.info("metadataFile:{}, localDocumentStoreService:{} ", metadataFile, localDocumentStoreService); try { - String result = documentStoreService.saveDocumentStream(metadataFile, null, - stream, documentStoreModuleName); + String result = localDocumentStoreService.saveDocumentStream(metadataFile, null, stream, + documentStoreModuleName); logger.info("SAML file saving result:{}", result); - InputStream newFile = documentStoreService.readDocumentAsStream(metadataFile); + InputStream newFile = localDocumentStoreService.readDocumentAsStream(metadataFile); logger.info("SAML file read newFile:{}", newFile); if (result != null) { @@ -114,16 +110,16 @@ public GluuErrorHandler validateMetadata(String metadataPath) return new GluuErrorHandler(false, true, validationLog); } - try (InputStream stream = documentStoreService.readDocumentAsStream(metadataPath)) { + try (InputStream stream = localDocumentStoreService.readDocumentAsStream(metadataPath)) { return XMLValidator.validateMetadata(stream, samlSchema); } } public boolean renameMetadata(String metadataPath, String destinationMetadataPath) { logger.debug("Rename metadata file documentStoreService:{},metadataPath:{}, destinationMetadataPath:{}", - documentStoreService, metadataPath, destinationMetadataPath); + localDocumentStoreService, metadataPath, destinationMetadataPath); try { - return documentStoreService.renameDocument(metadataPath, destinationMetadataPath) != null; + return localDocumentStoreService.renameDocument(metadataPath, destinationMetadataPath) != null; } catch (Exception ex) { logger.error("Failed to rename metadata '{}' to '{}'", metadataPath, destinationMetadataPath, ex); } @@ -133,24 +129,24 @@ public boolean renameMetadata(String metadataPath, String destinationMetadataPat public InputStream getFileFromDocumentStore(String path) { - logger.debug("Get file from DocumentStore. Path: {}",path); + logger.debug("Get file from DocumentStore. Path: {}", path); try { - return documentStoreService.readDocumentAsStream(path); - }catch(Exception e) { - logger.error("Failed to get file '{}' from DocumentStore",path); + return localDocumentStoreService.readDocumentAsStream(path); + } catch (Exception e) { + logger.error("Failed to get file '{}' from DocumentStore", path); return null; } } - private String getTempMetadataFilename(String metadataFolder, String fileName) { - logger.info("documentStoreService:{}, localDocumentStoreService:{}, metadataFolder:{}, fileName:{}", - documentStoreService, localDocumentStoreService, metadataFolder, fileName); + public String getTempMetadataFilename(String metadataFolder, String fileName) { + logger.info("localDocumentStoreService:{}, metadataFolder:{}, fileName:{}", localDocumentStoreService, + metadataFolder, fileName); synchronized (SamlIdpService.class) { String possibleTemp; do { possibleTemp = fileName + INumGenerator.generate(2); logger.debug("possibleTemp:{}", possibleTemp); - } while (documentStoreService.hasDocument(metadataFolder + possibleTemp)); + } while (localDocumentStoreService.hasDocument(metadataFolder + possibleTemp)); return possibleTemp; } } diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/AssetService.java b/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/AssetService.java index e3c552242f0..aa566f97737 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/AssetService.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/AssetService.java @@ -19,7 +19,6 @@ import io.jans.orm.search.filter.Filter; import io.jans.orm.PersistenceEntryManager; import io.jans.service.document.store.model.Document; -import io.jans.service.document.store.provider.DBDocumentStoreProvider; import io.jans.service.document.store.service.DBDocumentService; import io.jans.util.exception.InvalidAttributeException; @@ -33,11 +32,9 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.stream.*; import jakarta.enterprise.context.ApplicationScoped; @@ -66,9 +63,6 @@ public class AssetService { @Inject AuthUtil authUtil; - @Inject - DBDocumentStoreProvider dBDocumentStoreProvider; - @Inject DocumentStoreService documentStoreService; diff --git a/jans-linux-setup/jans_setup/templates/jans-config-api/dynamic-conf.json b/jans-linux-setup/jans_setup/templates/jans-config-api/dynamic-conf.json index 22919ca6e8a..16917a57127 100644 --- a/jans-linux-setup/jans_setup/templates/jans-config-api/dynamic-conf.json +++ b/jans-linux-setup/jans_setup/templates/jans-config-api/dynamic-conf.json @@ -112,7 +112,9 @@ "jans-auth", "jans-config-api", "jans-keycloak-link", - "jans-scim" + "jans-scim", + "jans-lock", + "jans-link" ], "description": "java archive library." }, @@ -261,17 +263,6 @@ ], "description": " FIDO Server Metadata." }, - { - "directory": "/opt/jans/jetty/%s/custom-libs", - "type": [ - "jar" - ], - "jansServiceModule": [ - "jans-lock", - "jans-link" - ], - "description": "java archive library." - }, { "directory": "/var/jans/keycloak-link-snapshots", "type": [ From 4369b7909a58d719be709a1d7e87d91eef95270f Mon Sep 17 00:00:00 2001 From: pujavs Date: Fri, 24 Jan 2025 21:53:46 +0530 Subject: [PATCH 20/20] fix(config-api): asset upload config and saml document store changes Signed-off-by: pujavs --- .../docs/jans-config-api-swagger.yaml | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index c38befde24a..639a6ad1c67 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -9337,19 +9337,19 @@ components: type: string selected: type: boolean - adminCanView: + whitePagesCanView: type: boolean adminCanEdit: type: boolean userCanEdit: type: boolean - userCanView: + adminCanView: type: boolean - userCanAccess: + userCanView: type: boolean adminCanAccess: type: boolean - whitePagesCanView: + userCanAccess: type: boolean baseDn: type: string @@ -10351,8 +10351,10 @@ components: type: string finishedFlowPage: type: string - bridgeScriptPage: - type: string + startEndUrlMapping: + type: object + additionalProperties: + type: string serializeRules: type: object additionalProperties: @@ -11331,14 +11333,14 @@ components: type: boolean internal: type: boolean - locationPath: - type: string locationType: type: string enum: - ldap - db - file + locationPath: + type: string baseDn: type: string ScriptError: @@ -11767,10 +11769,10 @@ components: ttl: type: integer format: int32 - persisted: - type: boolean opbrowserState: type: string + persisted: + type: boolean SessionIdAccessMap: type: object properties: