diff --git a/docs/admin/auth-server/endpoints/ssa.md b/docs/admin/auth-server/endpoints/ssa.md index d820b666423..445fa4c7f61 100644 --- a/docs/admin/auth-server/endpoints/ssa.md +++ b/docs/admin/auth-server/endpoints/ssa.md @@ -1,9 +1,401 @@ ---- -tags: - - administration - - auth-server - - endpoint ---- +# Software Statement Assertion (SSA) -This is a placeholder +The SSA is a JSON Web Token (JWT) containing client metadata and some custom attributes. +You can check the following +[Swagger](https://gluu.org/swagger-ui/?url=https://raw.githubusercontent.com/JanssenProject/jans/main/jans-auth-server/docs/swagger.yaml) +for more details of the endpoints. + +## SSA Security + +To call SSA services, a token of type `client_credentials` must be generated with the following scopes enabled: + +- `https://jans.io/auth/ssa.admin` — Allows calling all SSA services. +- `https://jans.io/auth/ssa.portal` — Allows only call `Get SSA` service. +- `https://jans.io/auth/ssa.developer` — Allows only call `Get SSA`, but you can only filter ssa that have +- been created by the same client. + +## Create a new SSA + +Create `SSA` for the organization with `expiration` (optional). + +### Request body description + +| Field | Detail | Optional | +|----------------|--------------------------------------------------------------------------------------------------------------------------|----------| +| org_id | The "org_id" is used for organization identification. | false | +| description | Describe ssa | false | +| software_id | The "software_id" is used for software identification. | false | +| software_roles | List of string values, fixed value `["password", "notify"]`. | false | +| grant_types | Fixed value Fixed value `["client_credentials"]`. | false | +| expiration | Expiration date. `(Default value: calculated based on global SSA settings)` | true | +| one_time_use | Defined whether the SSA will be used only once or can be used multiple times. `(Default value: true)` | true | +| rotate_ssa | TODO - Will be used to rotate expiration of the SSA, currently is only saved as part of the SSA. `(Default value: true)` | true | + +### Response description + +Returned SSA is a JWT, containing the following structure: + +``` +{ + "ssa": "eyJraWQiOiI1NTk3MGFkZS00M2MwLTQ4YWMtODEyZi0yZTY1MzhjMTEyN2Zfc2lnX3JzNTEyIiwidHlwIjoiand0IiwiYWxnIjoiUlM1MTIifQ.eyJzb2Z0d2FyZV9pZCI6ImdsdXUtc2Nhbi1hcGkiLCJncmFudF90eXBlcyI6WyJjbGllbnRfY3JlZGVudGlhbHMiXSwib3JnX2lkIjoxLCJpc3MiOiJodHRwczovL2phbnMubG9jYWxob3N0Iiwic29mdHdhcmVfcm9sZXMiOlsicGFzc3d1cmQiXSwiZXhwIjoxNjY4NjA5MDA1LCJpYXQiOjE2Njg2NDE5NjcsImp0aSI6ImU4OWVjYTQxLTM0ODUtNDUxNi1hMTYyLWZiODYyNjJhYmFjMyJ9.jRgh8_aiwMTJxeT9cwfup9QP9LBc6gQstvabCzUOJvELnzosxiNJHeU2mrvavaNK6BGvs_lbNjODVDeetGCD48_F2ay9r8qmo-f3GPzdzcJozKgfzonSkAE5Ran9LKcQQJpVc1rDYcV2xYiJLJ6FSuvnoClkDEE1tXysxshLPs-GXOZE7rD8XUXzezuxZWUE1jXwA-EFajoat8CP6QulHGxlcn_sKIhawhGODxJPz4Pf3jgeZVLG_7HfRJgxNiKcdzQIxnkbdpuS-0Q4-oc5yntsXhFhn31Pa3vGsiPPH9f3ndL2ZZKk3xCgyImLDJuGaxXg-qEVoIG4zNWNHMUNUQ" +} +``` + +**Header** + +- `alg` — The signature algorithm which used `RS256`. +- `typ` — The type which used. +- `kid` — The key identification `gluu-scan-api-rs256-ssa-signature-key`. + +**Payload** + +- `iat` — The time the JWT was created. +- `iss` — The "iss" (issuer) claim identifies the principal that issued the JWT. +- `jti` — The "jti" (JWT ID) claim provides a unique identifier for the JWT. +- `software_id` — The "software_id" is used for software identification. +- `org_id` — The "org_id" is used for organization identification. +- `software_roles` — List of string values, fixed value `["password", "notify"]`. +- `grant_types` — Fixed value `["client_credentials"]`. +- `exp` — Expiration Time. + +### Example: + +**Request:** + +``` +POST {{your-url}}/ssa +Content-Type: application/json +Authorization: Bearer {{your-token}} + +{ + "org_id": 1, + "description": "test", + "software_id": "gluu-scan-api", + "software_roles": [ + "password" + ], + "grant_types": [ + "client_credentials" + ], + "expiration": 1668609005, + "one_time_use": true, + "rotate_ssa": true +} +``` + +**Response:** + +``` +HTTP/1.1 201 Created +Date: Wed, 16 Nov 2022 23:39:27 GMT +Server: Apache/2.4.52 (Ubuntu) +X-Xss-Protection: 1; mode=block +X-Content-Type-Options: nosniff +Strict-Transport-Security: max-age=31536000; includeSubDomains +Cache-Control: no-store +Content-Type: application/json +Pragma: no-cache +Content-Length: 757 +Keep-Alive: timeout=5, max=100 +Connection: Keep-Alive + +{ + "ssa": "eyJraWQiOiI1NTk3MGFkZS00M2MwLTQ4YWMtODEyZi0yZTY1MzhjMTEyN2Zfc2lnX3JzNTEyIiwidHlwIjoiand0IiwiYWxnIjoiUlM1MTIifQ.eyJzb2Z0d2FyZV9pZCI6ImdsdXUtc2Nhbi1hcGkiLCJncmFudF90eXBlcyI6WyJjbGllbnRfY3JlZGVudGlhbHMiXSwib3JnX2lkIjoxLCJpc3MiOiJodHRwczovL2phbnMubG9jYWxob3N0Iiwic29mdHdhcmVfcm9sZXMiOlsicGFzc3d1cmQiXSwiZXhwIjoxNjY4NjA5MDA1LCJpYXQiOjE2Njg2NDE5NjcsImp0aSI6ImU4OWVjYTQxLTM0ODUtNDUxNi1hMTYyLWZiODYyNjJhYmFjMyJ9.jRgh8_aiwMTJxeT9cwfup9QP9LBc6gQstvabCzUOJvELnzosxiNJHeU2mrvavaNK6BGvs_lbNjODVDeetGCD48_F2ay9r8qmo-f3GPzdzcJozKgfzonSkAE5Ran9LKcQQJpVc1rDYcV2xYiJLJ6FSuvnoClkDEE1tXysxshLPs-GXOZE7rD8XUXzezuxZWUE1jXwA-EFajoat8CP6QulHGxlcn_sKIhawhGODxJPz4Pf3jgeZVLG_7HfRJgxNiKcdzQIxnkbdpuS-0Q4-oc5yntsXhFhn31Pa3vGsiPPH9f3ndL2ZZKk3xCgyImLDJuGaxXg-qEVoIG4zNWNHMUNUQ" +} +``` + +## Get SSA + +Get existing active SSA based on `jti` or `org_id`. + +### Query Parameters + +- `jti` — Unique identifier +- `org_id` — Organization ID + +### Response description + +``` +[ + { + "ssa": { + "jti": "c3eb1c16-be9b-4e96-974e-aea5e3cf95b0" + "org_id": 1, + "software_id": "gluu-scan-api", + "software_roles": [ + "password" + ], + "grant_types": [ + "client_credentials" + ], + "iss": "https://jans.localhost", + "exp": 1668608852, + "iat": 1668608851, + }, + "iss": "ed4d5f74-ce41-4180-aed4-54cffa974630", + "created_at": 1668608851, + "expiration": 1668608852 + } +] +``` + +- SSA + - `jti` — The "jti" (JWT ID) claim provides a unique identifier for the JWT. + - `org_id` — The "org_id" is used for organization identification. + - `software_id` — The "software_id" is used for software identification. + - `software_roles` — List of string values, fixed value `["password", "notify"]`. + - `grant_types` — Fixed value `["client_credentials"]`. + - `iss` — The "iss" (issuer) claim identifies the principal that issued the JWT. + - `exp` — Expiration time. + - `iat` — Creation time. +- `iss` — The "iss" is related to the client that created this SSA. +- `created_at` — Creation time. +- `expiration` — Expiration time. + +### Example: + +**Request:** + +Get SSA using `jti`. + +``` +GET {{your-url}}/ssa?jti={{your-jti}} +Content-Type: application/json +Authorization: Bearer {{your-token}} +``` + +Get SSA using `org_id`. + +``` +GET {{your-url}}/ssa?org_id={{your-org_id}} +Content-Type: application/json +Authorization: Bearer {{your-token}} +``` + +**Response:** + +``` +HTTP/1.1 200 OK +Date: Wed, 16 Nov 2022 15:27:35 GMT +Server: Apache/2.4.52 (Ubuntu) +X-Xss-Protection: 1; mode=block +X-Content-Type-Options: nosniff +Strict-Transport-Security: max-age=31536000; includeSubDomains +Cache-Control: no-store +Content-Type: application/json +Pragma: no-cache +Content-Length: 432 +Keep-Alive: timeout=5, max=100 +Connection: Keep-Alive + +[ + { + "ssa": { + "software_id": "gluu-scan-api", + "grant_types": [ + "client_credentials" + ], + "org_id": 1, + "iss": "https://jans.localhost", + "software_roles": [ + "passwurd" + ], + "exp": 1668608852, + "iat": 1668608851, + "jti": "c3eb1c16-be9b-4e96-974e-aea5e3cf95b0" + }, + "iss": "ed4d5f74-ce41-4180-aed4-54cffa974630", + "created_at": 1668608851, + "expiration": 1668608852 + } +] +``` + +## Validate SSA + +Validate existing active SSA based on `jti` + +### Header Parameters + +- jti — Unique identifier + +### Response description + +Method returns status 200 with an empty body if the corresponding SSA exists and is active. + +### Example: + +``` +HEAD {{your-url}}/ssa +jti: {{your-jti}} +``` + +``` +HTTP/1.1 200 OK +Date: Wed, 16 Nov 2022 21:49:11 GMT +Server: Apache/2.4.52 (Ubuntu) +X-Xss-Protection: 1; mode=block +X-Content-Type-Options: nosniff +Strict-Transport-Security: max-age=31536000; includeSubDomains +Cache-Control: no-store +Content-Type: application/json +Pragma: no-cache +Keep-Alive: timeout=5, max=100 +Connection: Keep-Alive + + +``` + +## Revoke SSA + +Revoke existing active SSA based on `jti` or `org_id`. + +### Query Parameters + +- `jti` — for revoke only one SSA, the specified by jti +- `org_id` — for revoke all SSA of the specified organization. + +### Response description + +Method returns status 200 with an empty body if all required SSAs were revoked correctly. + +### Example: + +**Request:** + +Revoke using `jti`. + +``` +DELETE {{your-url}}/ssa?jti={{your-jti}} +Authorization: Bearer {{your-token}} +``` + +Revoke using `org_id`. + +``` +DELETE {{your-url}}/ssa?org_id={{your-org_id}} +Authorization: Bearer {{your-token}} +``` + +**Response:** + +``` +HTTP/1.1 200 OK +Date: Wed, 16 Nov 2022 23:15:56 GMT +Server: Apache/2.4.52 (Ubuntu) +X-Xss-Protection: 1; mode=block +X-Content-Type-Options: nosniff +Strict-Transport-Security: max-age=31536000; includeSubDomains +Cache-Control: no-store +Content-Type: application/json +Pragma: no-cache +Content-Length: 0 +Keep-Alive: timeout=5, max=100 +Connection: Keep-Alive + + +``` + +## SSA Custom Script + +The custom script will allow us to modify the SSA process. +[SSA Custom Script](https://github.com/JanssenProject/jans/blob/main/jans-linux-setup/jans_setup/static/extension/ssa_modify_response/ssa_modify_response.py) + +- Modify the JWT returned by the creation SSA web service. +- Modify the list returned by the get SSA web service. +- Run a process after revoking an SSA. + +### Create method + +This method is executed after having generated the jwt that the service will return. + +In the following example, new fields is added to the header and payload of the JWT. + +``` +def create(self, jsonWebResponse, context): + print "Modify ssa response script. Modify idToken: %s" % jsonWebResponse + + jsonWebResponse.getHeader().setClaim("custom_header_name", "custom_header_value") + jsonWebResponse.getClaims().setClaim("custom_claim_name", "custom_claim_value") + + print "Modify ssa response script. After modify idToken: %s" % jsonWebResponse + return True +``` + +#### Parameters + +- `jsonWebResponse` — JWT with SSA structure using `io.jans.as.model.jwt.Jwt` class +- `context` — Contains, SSA global configuration class, client, execution context, etc. + +### Get method + +This method is executed after having generated the SSA list that will be returned by the service. + +``` +def get(self, jsonArray, context): + print "Modify ssa response script. Modify get ssa list: %s" % jsonArray + return True +``` + +#### Parameters + +- `jsonArray` — Contains SSA list using `org.json.JSONArray` class +- `context` — Contains, SSA global configuration class, client, execution context, etc. + +### Revoke method + +This method is executed after the SSA list has been revoked. + +``` +def revoke(self, ssaList, context): + print "Modify ssa response script. Modify revoke ssaList: %s" % ssaList + return True +``` + +#### Parameters + +- `ssaList` — SSA revoked list. +- `context` — Contains, SSA global configuration class, client, execution context, etc. + +## SSA Global settings + +The following fields are used to configure parameters globally. + +``` +"ssaConfiguration": { + "ssaEndpoint": "{{your-url}}/ssa", + "ssaCustomAttributes": [ + "myCustomAttr1", + "myCustomAttr2" + ], + "ssaSigningAlg": "RS512", + "ssaExpirationInDays": 30 +} +``` + +- `ssaEndpoint` — Base endpoint for SSA. +- `ssaCustomAttributes` — List of custom attributes, which are received in the request when creating an SSA. +- `ssaSigningAlg` — Algorithm to sign the JWT that is returned after creating an SSA. +- `ssaExpirationInDays` — Expiration expressed in days, when an SSA is created and the expiration is not sent. + +## SSA Class structure + +The SSA entity contains the following fields: + +- `id` type `String` — Unique class identifier, and is used as the `jti` identifier for the `JWT`. +- `orgId` type `String` — Organization ID. +- `description` type `String` — SSA Description. +- `state` type enum `SsaState` — Contains the following SSA status values (`ACTIVE`, `EXPIRED`, `REVOKED`, `USED`). +- `creationDate` type `Date` — SSA Creation date. +- `creatorId` type `String` — Client that created SSA. +- `creatorType` type enum `CreatorType` — Contains the following CreatorType values (`NONE`, `CLIENT`, `USER`, `AUTO`). +- `ttl` type `Integer` — SSA lifetime in milliseconds. +- `atributes` type class `SsaAtributes` + - `oneTimeUse` type `Boolean` — Whether the SSA will be single use. + - `rotateSsa` type `Boolean` — TODO - Will be used to rotate expiration of the SSA, currently is only saved as part of the SSA. + - `clientDn` type `String` — Client's DN. + - `customAttributes` type `Map` — Contain additional fields, previously configured in the SSA global configuration. + - `softwareId` type `String` — Is used for software identification. + - `softwareRoles` type `List` — List of string values, fixed value `["password", "notify"]`. + - `grantTypes` type `List` — Fixed value `["client_credentials"]`. diff --git a/jans-auth-server/client/src/main/java/io/jans/as/client/ssa/get/SsaGetClient.java b/jans-auth-server/client/src/main/java/io/jans/as/client/ssa/get/SsaGetClient.java index 3e4e319ed4a..ce5e26236a5 100644 --- a/jans-auth-server/client/src/main/java/io/jans/as/client/ssa/get/SsaGetClient.java +++ b/jans-auth-server/client/src/main/java/io/jans/as/client/ssa/get/SsaGetClient.java @@ -11,7 +11,6 @@ import jakarta.ws.rs.HttpMethod; import jakarta.ws.rs.client.Invocation.Builder; import org.apache.commons.lang.StringUtils; -import org.apache.http.client.utils.URIBuilder; import org.apache.log4j.Logger; public class SsaGetClient extends BaseClient { @@ -27,12 +26,11 @@ public String getHttpMethod() { return HttpMethod.GET; } - public SsaGetResponse execSsaGet(String accessToken, String jti, Long orgId, Boolean softwareRoles) { + public SsaGetResponse execSsaGet(String accessToken, String jti, Long orgId) { SsaGetRequest ssaGetRequest = new SsaGetRequest(); ssaGetRequest.setAccessToken(accessToken); ssaGetRequest.setJti(jti); ssaGetRequest.setOrgId(orgId); - ssaGetRequest.setSoftwareRoles(softwareRoles); setRequest(ssaGetRequest); return exec(); } diff --git a/jans-auth-server/client/src/main/java/io/jans/as/client/ssa/get/SsaGetRequest.java b/jans-auth-server/client/src/main/java/io/jans/as/client/ssa/get/SsaGetRequest.java index 2d92972e52f..0be3fa39cc4 100644 --- a/jans-auth-server/client/src/main/java/io/jans/as/client/ssa/get/SsaGetRequest.java +++ b/jans-auth-server/client/src/main/java/io/jans/as/client/ssa/get/SsaGetRequest.java @@ -20,8 +20,6 @@ public class SsaGetRequest extends BaseRequest { private Long orgId; - private Boolean softwareRoles; - public SsaGetRequest() { setContentType(MediaType.APPLICATION_JSON); setMediaType(MediaType.APPLICATION_JSON); @@ -52,20 +50,11 @@ public void setOrgId(Long orgId) { this.orgId = orgId; } - public Boolean getSoftwareRoles() { - return softwareRoles; - } - - public void setSoftwareRoles(Boolean softwareRoles) { - this.softwareRoles = softwareRoles; - } - @Override public String getQueryString() { QueryBuilder builder = QueryBuilder.instance(); builder.append(SsaRequestParam.JTI.getName(), jti); builder.append(SsaRequestParam.ORG_ID.getName(), orgId != null ? orgId.toString() : ""); - builder.append(SsaRequestParam.SOFTWARE_ROLES.getName(), softwareRoles != null ? softwareRoles.toString() : ""); return builder.toString(); } } diff --git a/jans-auth-server/client/src/test/java/io/jans/as/client/ssa/SsaGetTest.java b/jans-auth-server/client/src/test/java/io/jans/as/client/ssa/SsaGetTest.java index 6e3436ad5b2..23e0181a127 100644 --- a/jans-auth-server/client/src/test/java/io/jans/as/client/ssa/SsaGetTest.java +++ b/jans-auth-server/client/src/test/java/io/jans/as/client/ssa/SsaGetTest.java @@ -51,7 +51,7 @@ public void getSsaSearchByOrgId(final String redirectUris, final String sectorId // Ssa get SsaGetClient ssaGetClient = new SsaGetClient(ssaEndpoint); - SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, null, orgId1, false); + SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, null, orgId1); AssertBuilder.ssaGet(ssaGetResponse) .ssaListSize(2) .jtiList(jtiList) @@ -82,7 +82,7 @@ public void getSsaSearchByJti(final String redirectUris, final String sectorIden // Ssa get SsaGetClient ssaGetClient = new SsaGetClient(ssaEndpoint); - SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, jti, null, false); + SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, jti, null); AssertBuilder.ssaGet(ssaGetResponse) .ssaListSize(1) .jtiList(jtiList) @@ -114,7 +114,7 @@ public void getSsaSearchByOrgIdAndJti(final String redirectUris, final String se // Ssa get SsaGetClient ssaGetClient = new SsaGetClient(ssaEndpoint); - SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, jti, orgId1, false); + SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, jti, orgId1); AssertBuilder.ssaGet(ssaGetResponse) .ssaListSize(1) .jtiList(jtiList) @@ -145,7 +145,7 @@ public void getSsaSearchByJtiNotExits(final String redirectUris, final String se // Ssa get SsaGetClient ssaGetClient = new SsaGetClient(ssaEndpoint); - SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, jti, null, false); + SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, jti, null); AssertBuilder.ssaGet(ssaGetResponse) .ssaListSize(0) .jtiList(jtiList) diff --git a/jans-auth-server/client/src/test/java/io/jans/as/client/ssa/SsaRevokeTest.java b/jans-auth-server/client/src/test/java/io/jans/as/client/ssa/SsaRevokeTest.java index 626d3ea0153..63af4c88366 100644 --- a/jans-auth-server/client/src/test/java/io/jans/as/client/ssa/SsaRevokeTest.java +++ b/jans-auth-server/client/src/test/java/io/jans/as/client/ssa/SsaRevokeTest.java @@ -64,7 +64,7 @@ public void revokeWithJtiResponseOK(final String redirectUris, final String sect // Ssa get SsaGetClient ssaGetClient = new SsaGetClient(ssaEndpoint); - SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, jti, orgId, false); + SsaGetResponse ssaGetResponse = ssaGetClient.execSsaGet(accessToken, jti, orgId); showClient(ssaGetClient); assertNotNull(ssaGetResponse, "Ssa get response is null"); assertTrue(ssaGetResponse.getSsaList().isEmpty()); diff --git a/jans-auth-server/model/src/main/java/io/jans/as/model/ssa/SsaScopeType.java b/jans-auth-server/model/src/main/java/io/jans/as/model/ssa/SsaScopeType.java index aeca4bb2ffb..94073f6a884 100644 --- a/jans-auth-server/model/src/main/java/io/jans/as/model/ssa/SsaScopeType.java +++ b/jans-auth-server/model/src/main/java/io/jans/as/model/ssa/SsaScopeType.java @@ -16,7 +16,6 @@ public enum SsaScopeType { SSA_DEVELOPER("https://jans.io/auth/ssa.developer"), ; - private static final Map lookup = new HashMap<>(); static { diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaRestWebService.java b/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaRestWebService.java index 30d3646083e..cc564b01664 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaRestWebService.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaRestWebService.java @@ -37,9 +37,9 @@ Response create( /** * Get list of SSA based on "jti" or "org_id" filter. * - * @param jti Unique identifier - * @param orgId Organization ID - * @param httpRequest Http request + * @param jti Unique identifier + * @param orgId Organization ID + * @param httpRequest Http request * @return the {@link Response} with status {@code 200 (Ok)} and with body the ssa list, * or with status {@code 401 (Unauthorized)} if unauthorized access request, * or with status {@code 500 (Internal Server Error)} if internal error occurred. @@ -48,7 +48,6 @@ Response create( @Path("/ssa") @Produces({MediaType.APPLICATION_JSON}) Response get( - @QueryParam("software_roles") Boolean softwareRoles, @QueryParam("jti") String jti, @QueryParam("org_id") Long orgId, @Context HttpServletRequest httpRequest diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaRestWebServiceImpl.java b/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaRestWebServiceImpl.java index b349da1eeb1..34a84c47520 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaRestWebServiceImpl.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaRestWebServiceImpl.java @@ -60,8 +60,8 @@ public Response create(String requestParams, HttpServletRequest httpRequest) { * @return {@link Response} with status {@code 200 (Ok)} and with body List of SSA. */ @Override - public Response get(Boolean softwareRoles, String jti, Long orgId, HttpServletRequest httpRequest) { - return ssaGetAction.get(softwareRoles, jti, orgId, httpRequest); + public Response get(String jti, Long orgId, HttpServletRequest httpRequest) { + return ssaGetAction.get(jti, orgId, httpRequest); } /** diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaService.java b/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaService.java index 1d55d14f9ce..de422f591cf 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaService.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/SsaService.java @@ -104,7 +104,7 @@ public Ssa findSsaByJti(String jti) { */ public List getSsaList(String jti, Long orgId, SsaState status, String clientId, String[] scopes) { List filters = new ArrayList<>(); - if (hasPortalScope(Arrays.asList(scopes))) { + if (hasDeveloperScope(Arrays.asList(scopes))) { filters.add(Filter.createEqualityFilter("creatorId", clientId)); } if (jti != null) { @@ -183,19 +183,19 @@ public Response.ResponseBuilder createNotAcceptableResponse() { } /** - * Check if there is only one "ssa.portal" scope + * Check if there is only one "ssa.developer" scope * * @param scopes List of scope - * @return true if is only one "ssa.portal", or false otherwise + * @return true if is only one "ssa.developer", or false otherwise */ - private boolean hasPortalScope(List scopes) { + private boolean hasDeveloperScope(List scopes) { Iterator scopesIterator = scopes.iterator(); boolean result = false; while (scopesIterator.hasNext()) { String scope = scopesIterator.next(); - if (scope.equals(SsaScopeType.SSA_ADMIN.getValue())) { + if (scope.equals(SsaScopeType.SSA_ADMIN.getValue()) || scope.equals(SsaScopeType.SSA_PORTAL.getValue())) { return false; - } else if (scope.equals(SsaScopeType.SSA_PORTAL.getValue())) { + } else if (scope.equals(SsaScopeType.SSA_DEVELOPER.getValue())) { result = true; } } diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/action/SsaGetAction.java b/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/action/SsaGetAction.java index 6667477149d..5d32f4fbfde 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/action/SsaGetAction.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/ssa/ws/rs/action/SsaGetAction.java @@ -93,14 +93,14 @@ public class SsaGetAction { * @param httpRequest Http request * @return {@link Response} with status {@code 200 (Ok)} and the body containing the list of SSAs. */ - public Response get(Boolean softwareRoles, String jti, Long orgId, HttpServletRequest httpRequest) { - log.debug("Attempting to read ssa: softwareRoles = {}, jti = '{}', orgId = {}", softwareRoles, jti, orgId); + public Response get(String jti, Long orgId, HttpServletRequest httpRequest) { + log.debug("Attempting to read ssa: softwareRoles = {}, orgId = {}", jti, orgId); errorResponseFactory.validateFeatureEnabled(FeatureFlagType.SSA); Response.ResponseBuilder builder = Response.ok(); try { final Client client = ssaRestWebServiceValidator.getClientFromSession(); - ssaRestWebServiceValidator.checkScopesPolicy(client, Arrays.asList(SsaScopeType.SSA_ADMIN.getValue(), SsaScopeType.SSA_PORTAL.getValue())); + ssaRestWebServiceValidator.checkScopesPolicy(client, Arrays.asList(SsaScopeType.SSA_ADMIN.getValue(), SsaScopeType.SSA_PORTAL.getValue(), SsaScopeType.SSA_DEVELOPER.getValue())); final List ssaList = ssaService.getSsaList(jti, orgId, SsaState.ACTIVE, client.getClientId(), client.getScopes()); diff --git a/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/SsaRestWebServiceImplTest.java b/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/SsaRestWebServiceImplTest.java index 33bd1aaa6c4..a4d437b5c6a 100644 --- a/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/SsaRestWebServiceImplTest.java +++ b/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/SsaRestWebServiceImplTest.java @@ -47,11 +47,11 @@ public void create_validParams_validResponse() { @Test public void get_validParams_validResponse() { - when(ssaGetAction.get(anyBoolean(), anyString(), any(), any())).thenReturn(mock(Response.class)); + when(ssaGetAction.get(anyString(), any(), any())).thenReturn(mock(Response.class)); - Response response = ssaRestWebServiceImpl.get(false, "testJti", 1000L, mock(HttpServletRequest.class)); + Response response = ssaRestWebServiceImpl.get("testJti", 1000L, mock(HttpServletRequest.class)); assertNotNull(response, "response is null"); - verify(ssaGetAction).get(anyBoolean(), anyString(), any(), any()); + verify(ssaGetAction).get(anyString(), any(), any()); verifyNoMoreInteractions(ssaGetAction); } diff --git a/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/SsaServiceTest.java b/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/SsaServiceTest.java index 71e5b10fb6b..061959b2804 100644 --- a/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/SsaServiceTest.java +++ b/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/SsaServiceTest.java @@ -198,7 +198,7 @@ public void findSsaByJti_jtiNotFound_ssaNull() { } @Test - public void getSsaList_withPortalScope_valid() { + public void getSsaList_withDeveloperScope_valid() { BaseDnConfiguration baseDnConfiguration = new BaseDnConfiguration(); baseDnConfiguration.setSsa("ou=ssa,o=jans"); when(staticConfiguration.getBaseDn()).thenReturn(baseDnConfiguration); @@ -207,7 +207,7 @@ public void getSsaList_withPortalScope_valid() { Long orgId = null; SsaState status = null; String clientId = "test-client"; - String[] scopes = new String[]{SsaScopeType.SSA_PORTAL.getValue()}; + String[] scopes = new String[]{SsaScopeType.SSA_DEVELOPER.getValue()}; List ssaList = ssaService.getSsaList(jti, orgId, status, clientId, scopes); assertNotNull(ssaList); verify(log).trace(eq("Filter with AND created: " + String.format("[(creatorId=%s)]", clientId))); diff --git a/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/action/SsaGetActionTest.java b/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/action/SsaGetActionTest.java index c6ab02f411b..ec49b30b04d 100644 --- a/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/action/SsaGetActionTest.java +++ b/jans-auth-server/server/src/test/java/io/jans/as/server/ssa/ws/rs/action/SsaGetActionTest.java @@ -55,14 +55,13 @@ public void get_withAllParam_valid() { client.setDn("inum=0000,ou=clients,o=jans"); when(ssaRestWebServiceValidator.getClientFromSession()).thenReturn(client); - boolean softwareRoles = false; String jti = "my-jti"; Long orgId = 1000L; - Response response = ssaGetAction.get(softwareRoles, jti, orgId, mock(HttpServletRequest.class)); + Response response = ssaGetAction.get(jti, orgId, mock(HttpServletRequest.class)); assertNotNull(response, "response is null"); assertNotNull(response.getEntity(), "response entity is null"); assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); - verify(log).debug(anyString(), any(), any(), any()); + verify(log).debug(anyString(), any(), any()); verify(errorResponseFactory).validateFeatureEnabled(any()); verify(ssaContextBuilder).buildModifySsaResponseContext(any(), any(), any(), any(), any()); verify(ssaJsonService).jsonArrayToString(any()); @@ -79,11 +78,10 @@ public void get_invalidClientAndIsErrorEnabledFalse_badRequestResponse() { doThrow(error).when(ssaRestWebServiceValidator).getClientFromSession(); when(log.isErrorEnabled()).thenReturn(Boolean.FALSE); - boolean softwareRoles = false; String jti = "my-jti"; Long orgId = 1000L; - assertThrows(WebApplicationException.class, () -> ssaGetAction.get(softwareRoles, jti, orgId, mock(HttpServletRequest.class))); - verify(log).debug(anyString(), any(), any(), any()); + assertThrows(WebApplicationException.class, () -> ssaGetAction.get(jti, orgId, mock(HttpServletRequest.class))); + verify(log).debug(anyString(), any(), any()); verify(ssaRestWebServiceValidator).getClientFromSession(); verify(log).isErrorEnabled(); verify(log, never()).error(anyString(), any(WebApplicationException.class)); @@ -100,11 +98,10 @@ public void get_invalidClientAndIsErrorEnabledTrue_badRequestResponse() { doThrow(error).when(ssaRestWebServiceValidator).getClientFromSession(); when(log.isErrorEnabled()).thenReturn(Boolean.TRUE); - boolean softwareRoles = false; String jti = "my-jti"; Long orgId = 1000L; - assertThrows(WebApplicationException.class, () -> ssaGetAction.get(softwareRoles, jti, orgId, mock(HttpServletRequest.class))); - verify(log).debug(anyString(), any(), any(), any()); + assertThrows(WebApplicationException.class, () -> ssaGetAction.get(jti, orgId, mock(HttpServletRequest.class))); + verify(log).debug(anyString(), any(), any()); verify(ssaRestWebServiceValidator).getClientFromSession(); verify(log).isErrorEnabled(); verify(log).error(anyString(), any(WebApplicationException.class)); @@ -120,11 +117,10 @@ public void get_invalidClientInternalServer_badRequestResponse() { .build()); when(errorResponseFactory.createWebApplicationException(any(Response.Status.class), any(SsaErrorResponseType.class), anyString())).thenThrow(error); - boolean softwareRoles = false; String jti = "my-jti"; Long orgId = 1000L; - assertThrows(WebApplicationException.class, () -> ssaGetAction.get(softwareRoles, jti, orgId, mock(HttpServletRequest.class))); - verify(log).debug(anyString(), any(), any(), any()); + assertThrows(WebApplicationException.class, () -> ssaGetAction.get(jti, orgId, mock(HttpServletRequest.class))); + verify(log).debug(anyString(), any(), any()); verify(ssaRestWebServiceValidator).getClientFromSession(); verify(log, never()).isErrorEnabled(); verify(log).error(any(), any(Exception.class));