diff --git a/src/main/java/framework/api/enums/ApiEndpoint.java b/src/main/java/framework/api/enums/ApiEndpoint.java index 0243ea6c498ea8ff5b0a63f115fb3221efa26c27..623659b65c1d86d7ebcc9680a371095bb0eca912 100644 --- a/src/main/java/framework/api/enums/ApiEndpoint.java +++ b/src/main/java/framework/api/enums/ApiEndpoint.java @@ -1,50 +1,73 @@ package framework.api.enums; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public enum ApiEndpoint { - IDENTITY_ATTRIBUTE("/sap-api/identity-attribute", "Identity Attribute"), - USER_ROLE("/user-api/role", "User Role"), - PARTICIPANT_TYPE("/identity-api/participant", "Participant"), - IDENTITY_ATTRIBUTE_LOCAL_AGENT_SEARCH("/user-api/identity-attribute/search", - "Identity Attribute Local Agent Search"); - private final String path; - private final String displayName; + // 🔹 Identity API + IDENTITY_ATTRIBUTE("/sap-api/identity-attribute", true), + IDENTITY_CERTIFICATE("/identity-api/certificate", true), + PARTICIPANT_TYPE("/identity-api/participant", true), + PARTICIPANT_SEARCH("/identity-api/participant/search", true), + + // 🔹 Onboarding API + ONBOARDING_PARTICIPANT("/onboarding-api/participant-type", false), + ONBOARDING_TEMPLATE("/onboarding-api/onboarding-template", true), + ONBOARDING_REQUEST("/onboarding-api/onboarding-request", false), + + // 🔹 User API + USER_ROLE("/user-api/role", true), + USER_SEARCH("/user-api/user/search", true), + USER_CREDENTIAL_MY_ID("/user-api/credential/my-id", true), + USER_SESSION_CREDENTIAL("/user-api/session/credential", true), + USER_CREDENTIAL_CREDENTIAL_ID("/user-api/credential/credential-id", true), + USER_EPHFEMERAL_PROOF("/user-api/mtls/ephemeral-proof", true), - private static final Map<String, ApiEndpoint> DISPLAY_NAME_MAP = new HashMap<>(); + // 🔹 Local Agent API + IDENTITY_ATTRIBUTE_LOCAL_AGENT_SEARCH("/user-api/identity-attribute/search", true); + + private final String path; + private final boolean isCrudTestable; + private static final Map<String, ApiEndpoint> PATH_MAP = new HashMap<>(); static { for (ApiEndpoint endpoint : values()) { - DISPLAY_NAME_MAP.put(endpoint.displayName.toLowerCase(), endpoint); + PATH_MAP.put(endpoint.path.toLowerCase(), endpoint); } } - ApiEndpoint(String path, String displayName) { + ApiEndpoint(String path, boolean isCrudTestable) { this.path = path; - this.displayName = displayName; + this.isCrudTestable = isCrudTestable; } public String getPath() { return path; } - public String getDisplayName() { - return displayName; + public boolean isCrudTestable() { + return isCrudTestable; } - @Override - public String toString() { - return displayName; + public static List<ApiEndpoint> getCrudTestableEndpoints() { + return List.of(values()).stream() + .filter(ApiEndpoint::isCrudTestable) + .collect(Collectors.toList()); } - public static ApiEndpoint fromString(String displayName) { - ApiEndpoint endpoint = DISPLAY_NAME_MAP.get(displayName.toLowerCase()); + public static ApiEndpoint fromPath(String path) { + ApiEndpoint endpoint = PATH_MAP.get(path.toLowerCase()); if (endpoint == null) { - throw new IllegalArgumentException("No endpoint found for display name: " + displayName); + throw new IllegalArgumentException("No endpoint found for path: " + path); } return endpoint; } + @Override + public String toString() { + return path; + } } diff --git a/src/main/java/framework/api/enums/HttpStatus.java b/src/main/java/framework/api/enums/HttpStatus.java index 8c0d92dbc146badab245aea0aa51c6508ad0c0dc..65132604adb453a6e6ba3200e8d27addde7db3a1 100644 --- a/src/main/java/framework/api/enums/HttpStatus.java +++ b/src/main/java/framework/api/enums/HttpStatus.java @@ -7,7 +7,8 @@ public enum HttpStatus { DELETED(204, "Deleted"), BAD_REQUEST(400, "Bad Request"), FORBIDDEN(403, "Forbidden"), - NOT_FOUND(404, "Not Found"); + NOT_FOUND(404, "Not Found"), + UNAUTHORIZED(401, "Unauthorized"); private final int code; private final String description; diff --git a/src/test/java/features/api/simplOpen/Authority.feature b/src/test/java/features/api/simplOpen/Authority.feature index 20571531dc2d605d6c8fd95bf4c386b7cd7be3d9..626521e28bcafa339a5ecf5e95246134d147a0bb 100644 --- a/src/test/java/features/api/simplOpen/Authority.feature +++ b/src/test/java/features/api/simplOpen/Authority.feature @@ -4,7 +4,7 @@ Feature: Authority API scenarios @TCA01_API @SIMPL-3336 @SIMPL-3337 @SIMPL-3338 @SIMPL-3344 Scenario: User with IATTR_M Role Creates a New Identity Attribute Given a user with role "IATTR_M" is logged in to governance authority - When the user creates and assigns "Identity attribute" with the following data: + When the user creates and assigns Identity Attribute with the following data: | Code | RANDOM_CODE | | Enabled | true | | Assignable to roles | true | @@ -20,7 +20,7 @@ Feature: Authority API scenarios @TCA02_API @SIMPL-3334 Scenario: Successful retrieval of an Identity Attribute by ID Given a user with role "IATTR_M" is logged in to governance authority - And the user creates and assigns "Identity attribute" with the following data: + And the user creates and assigns Identity Attribute with the following data: | Code | RANDOM_CODE | | Enabled | true | | Assignable to roles | true | @@ -34,7 +34,7 @@ Feature: Authority API scenarios @TCA03_API @SIMPL-3335 @SIMPL-3343 Scenario: User with IATTR_M role updates an Identity Attribute Given a user with role "IATTR_M" is logged in to governance authority - And an "Identity Attribute" is already created and assigned + And an Identity Attribute is already created and assigned When the user updates the Identity Attribute with the new data: | Code | UPDATED_CODE | | Enabled | false | @@ -67,7 +67,7 @@ Feature: Authority API scenarios @TCA06_API @SIMPL-4532 Scenario: Disable an Identity Attribute Given a user with role "IATTR_M" is logged in to governance authority - And an "Identity Attribute" is already created and assigned + And an Identity Attribute is already created and assigned When the user sets the Identity Attribute as assignable to "false" And the operation is completed successfully And the user searches for the identity attribute by ID @@ -77,7 +77,7 @@ Feature: Authority API scenarios @TCA07_API @SIMPL-4502 @SIMPL-4533 @bug:SIMPL-10207 @bug:SIMPL-10297 Scenario: Unsuccessful Identity Attribute enablement and disablement Given a user with role "IATTR_M" is logged in to governance authority - And an "Identity Attribute" is already created and assigned + And an Identity Attribute is already created and assigned When the user attempts to set the Identity Attribute as assignable to "true" with a modified ID And the system indicates bad request And the user attempts to set the Identity Attribute as assignable to "false" with a modified ID @@ -87,8 +87,13 @@ Feature: Authority API scenarios @TCA08_API @SIMPL-5233 Scenario: Creation of New Tier1 Role with T1UAR_M Role - Role Successfully Created Given a user with role "AUTHORITY_T1UAR_M" is logged in to governance authority - When the user creates "User Role" with the following data: + When the user creates User Role with the following data: | name | RANDOM_NAME | | description | RANDOM_DESCRIPTION | Then the system indicates successful creation And the response body contains the expected User Role's details + + @TCA09_API @SIMPL-5265 @SIMPL-5235 + Scenario: Unauthorized Access Attempt for CRUD Operations + When the user tries to perform any CRUD operation + Then the system declines all unauthorized requests diff --git a/src/test/java/stepDefinitions/api/simplOpen/AuthoritySteps.java b/src/test/java/stepDefinitions/api/simplOpen/AuthoritySteps.java index b956fd06ed61e90a8d4fffc6f6c438b31732661b..4a189980a1a96c275a2aa9989573d7ce015c7bae 100644 --- a/src/test/java/stepDefinitions/api/simplOpen/AuthoritySteps.java +++ b/src/test/java/stepDefinitions/api/simplOpen/AuthoritySteps.java @@ -30,13 +30,12 @@ import static org.junit.Assert.*; public class AuthoritySteps { private RequestHandler requestHandler; - private ApiEndpoint identityAttributeEndpoint; - private ApiEndpoint userRoleEndpoint; private IdentityAttribute identityAttribute = new IdentityAttribute(); private UserRole userRole = new UserRole(); private String savedIdentityAttributeId; private final List<String> createdIdentityAttributesIDs = new ArrayList<>(); private final List<String> createdUserRoleIDs = new ArrayList<>(); + private final List<Integer> unauthorizedStatusCodes = new ArrayList<>(); private String randomIdentityAttributeId; @Before("@AuthorityAPI") @@ -58,32 +57,28 @@ public class AuthoritySteps { requestHandler.addHeader("Authorization", "Bearer " + token); } - @Given("an {string} is already created and assigned") - public void anIdentityAttributeIsAlreadyCreated(String endpointName) { - identityAttributeEndpoint = ApiEndpoint.fromString(endpointName); - + @Given("an Identity Attribute is already created and assigned") + public void anIdentityAttributeIsAlreadyCreated() { JsonObject requestBody = new IdentityAttributeRequestBuilder() .withRandomData() .build(); - requestHandler.sendRequest(HttpMethod.POST, identityAttributeEndpoint.getPath(), requestBody); + requestHandler.sendRequest(HttpMethod.POST, ApiEndpoint.IDENTITY_ATTRIBUTE.getPath(), requestBody); JsonObject createdIdentityAttribute = requestHandler.getLastResponseBody(); Gson gson = new Gson(); identityAttribute = gson.fromJson(createdIdentityAttribute, IdentityAttribute.class); createdIdentityAttributesIDs.add(requestHandler.getLastResponseBody().get("id").getAsString()); } - @When("the user creates and assigns {string} with the following data:") - public void theUserSendsAPostRequestWithAListOfParticipantTypes(String endpointName, DataTable dataTable) { + @When("the user creates and assigns Identity Attribute with the following data:") + public void theUserSendsAPostRequestWithAListOfParticipantTypes(DataTable dataTable) { Gson gson = new Gson(); - identityAttributeEndpoint = ApiEndpoint.fromString(endpointName); - Map<String, String> data = dataTable.asMap(String.class, String.class); JsonObject requestBody = new IdentityAttributeRequestBuilder() .fromMap(data) .build(); - requestHandler.sendRequest(HttpMethod.POST, identityAttributeEndpoint.getPath(), requestBody); + requestHandler.sendRequest(HttpMethod.POST, ApiEndpoint.IDENTITY_ATTRIBUTE.getPath(), requestBody); JsonObject createdIdentityAttribute = requestHandler.getLastResponseBody(); @@ -93,17 +88,15 @@ public class AuthoritySteps { createdIdentityAttributesIDs.add(identityAttribute.getId()); } - @When("the user creates {string} with the following data:") - public void theUserCreatesRoleWithTheFollowingData(String endpointName, DataTable dataTable) { + @When("the user creates User Role with the following data:") + public void theUserCreatesRoleWithTheFollowingData(DataTable dataTable) { Gson gson = new Gson(); - userRoleEndpoint = ApiEndpoint.fromString(endpointName); - Map<String, String> data = dataTable.asMap(String.class, String.class); JsonObject requestBody = new UserRolesRequestBuilder() .fromMap(data) .build(); - requestHandler.sendRequest(HttpMethod.POST, userRoleEndpoint.getPath(), requestBody); + requestHandler.sendRequest(HttpMethod.POST, ApiEndpoint.USER_ROLE.getPath(), requestBody); JsonObject createdUserRole = requestHandler.getLastResponseBody(); @@ -123,7 +116,7 @@ public class AuthoritySteps { .fromMap(data) .build(); - requestHandler.sendRequest(HttpMethod.PUT, identityAttributeEndpoint.getPath() + "/" + identityAttributeId, requestBody); + requestHandler.sendRequest(HttpMethod.PUT, ApiEndpoint.IDENTITY_ATTRIBUTE.getPath() + "/" + identityAttributeId, requestBody); JsonObject updatedIdentityAttribute = requestHandler.getLastRequestBody(); identityAttribute = gson.fromJson(updatedIdentityAttribute, IdentityAttribute.class); } @@ -210,6 +203,19 @@ public class AuthoritySteps { assertEquals("Mismatch in status code", expectedStatusCode, actualStatusCode); } + @When("the user tries to perform any CRUD operation") + public void theUserTriesToPerformAnyCRUDOperation() { + List<ApiEndpoint> endpoints = ApiEndpoint.getCrudTestableEndpoints(); + List<HttpMethod> methods = List.of(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE); + + for (ApiEndpoint endpoint : endpoints) { + for (HttpMethod method : methods) { + requestHandler.sendRequest(method, endpoint.getPath()); + unauthorizedStatusCodes.add(requestHandler.getStatusCode()); + } + } + } + @Then("the system indicates absence of such resource") public void theSystemIndicatesAbsenceOfSuchResource() { int actualStatusCode = requestHandler.getLastStatusCode(); @@ -226,6 +232,16 @@ public class AuthoritySteps { assertEquals("Mismatch in status code", expectedStatusCode, actualStatusCode); } + @Then("the system declines all unauthorized requests") + public void theSystemDeclinesUnauthorizedRequest() { + int expectedStatusCode = HttpStatus.UNAUTHORIZED.getCode(); + + assertFalse("No unauthorized requests were made", unauthorizedStatusCodes.isEmpty()); + for (int statusCode : unauthorizedStatusCodes) { + assertEquals("Mismatch in status code", expectedStatusCode, statusCode); + } + } + @Then("the response body contains updated Identity Attribute data:") public void theResponseBodyContainsUpdatedIdentityAttributeData(DataTable dataTable) { Gson gson = new Gson(); @@ -364,7 +380,7 @@ public class AuthoritySteps { @After(value = "@AuthorityAPI", order = 2) public void deleteIdentityAttribute() { for (String id : createdIdentityAttributesIDs) { - String deleteEndpoint = identityAttributeEndpoint.getPath() + '/' + id; + String deleteEndpoint = ApiEndpoint.IDENTITY_ATTRIBUTE.getPath() + '/' + id; requestHandler.sendRequest(HttpMethod.DELETE, deleteEndpoint); int actualStatusCode = requestHandler.getStatusCode(); int expectedStatusCode = HttpStatus.DELETED.getCode();