From 8d6e021207576902fb5b7a4f28751bac0d8133de Mon Sep 17 00:00:00 2001 From: Gerard Olenski <31597546+gerardolenski@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:25:51 +0100 Subject: [PATCH] ACS 9185 implement rest api for reauthorizing a single user (#3190) * ACS-9185 Reauthorize endpoint * ACS-9185 Add the reauthorization code endpoint * ACS-9185 Refactored model * ACS-9185 Fixed rest wrapper implementation --------- Co-authored-by: Damian Ujma --- .../rest/model/RestAuthCodeModel.java | 49 ++++++++++++++ .../alfresco/rest/model/RestAuthKeyModel.java | 49 ++++++++++++++ .../org/alfresco/rest/requests/People.java | 27 ++++++++ .../community/ReauthorizeSanityTests.java | 65 +++++++++++++++++++ .../org/alfresco/rest/api/model/AuthCode.java | 32 +++++++++ .../org/alfresco/rest/api/model/AuthKey.java | 43 ++++++++++++ .../rest/api/people/PeopleEntityResource.java | 27 ++++++++ 7 files changed, 292 insertions(+) create mode 100644 packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestAuthCodeModel.java create mode 100644 packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestAuthKeyModel.java create mode 100644 packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/people/deauthorization/community/ReauthorizeSanityTests.java create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/model/AuthCode.java create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/model/AuthKey.java diff --git a/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestAuthCodeModel.java b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestAuthCodeModel.java new file mode 100644 index 0000000000..6953dcf54e --- /dev/null +++ b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestAuthCodeModel.java @@ -0,0 +1,49 @@ +/*- + * #%L + * alfresco-tas-restapi + * %% + * Copyright (C) 2005 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import org.alfresco.utility.model.TestModel; + +/** + * Authorization code implementation + */ +public class RestAuthCodeModel extends TestModel +{ + @JsonProperty + private String authorizationCode; + + public String getAuthorizationCode() + { + return authorizationCode; + } + + public void setAuthorizationCode(String authorizationCode) + { + this.authorizationCode = authorizationCode; + } +} diff --git a/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestAuthKeyModel.java b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestAuthKeyModel.java new file mode 100644 index 0000000000..ab083f5845 --- /dev/null +++ b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/model/RestAuthKeyModel.java @@ -0,0 +1,49 @@ +/*- + * #%L + * alfresco-tas-restapi + * %% + * Copyright (C) 2005 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import org.alfresco.utility.model.TestModel; + +/** + * Authorization key implementation + */ +public class RestAuthKeyModel extends TestModel +{ + @JsonProperty(required = true) + private String authorizationKey; + + public String getAuthorizationKey() + { + return authorizationKey; + } + + public void setAuthorizationKey(String authorizationKey) + { + this.authorizationKey = authorizationKey; + } +} diff --git a/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/requests/People.java b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/requests/People.java index f043d9514f..45ab8b9aca 100644 --- a/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/requests/People.java +++ b/packaging/tests/tas-restapi/src/main/java/org/alfresco/rest/requests/People.java @@ -42,6 +42,8 @@ import org.alfresco.rest.core.RestWrapper; import org.alfresco.rest.exception.EmptyJsonResponseException; import org.alfresco.rest.exception.JsonToModelConversionException; import org.alfresco.rest.model.RestActivityModelsCollection; +import org.alfresco.rest.model.RestAuthCodeModel; +import org.alfresco.rest.model.RestAuthKeyModel; import org.alfresco.rest.model.RestFavoriteSiteModel; import org.alfresco.rest.model.RestGroupsModelsCollection; import org.alfresco.rest.model.RestNetworkModel; @@ -446,6 +448,31 @@ public class People extends ModelRequest restWrapper.processEmptyModel(request); } + /** + * Reauthorizes a user. + */ + public void reauthorizeUser(RestAuthKeyModel authKey) + { + var request = RestRequest.requestWithBody(HttpMethod.POST, authKey.toJson(), "people/{personId}/reauthorize", this.person.getUsername()); + restWrapper.processEmptyModel(request); + } + + /** + * Get the reauthorization code. + */ + public RestAuthCodeModel getReauthorizationCode() + { + var request = RestRequest.simpleRequest(HttpMethod.POST, "people/{personId}/reauthorization-code", this.person.getUsername()); + try + { + return restWrapper.processModel(RestAuthCodeModel.class, request); + } + catch (JsonToModelConversionException | EmptyJsonResponseException e) + { + return null; + } + } + /** * Update avatar image PUT call on 'people/{nodeId}/children */ diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/people/deauthorization/community/ReauthorizeSanityTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/people/deauthorization/community/ReauthorizeSanityTests.java new file mode 100644 index 0000000000..b2cda9fc96 --- /dev/null +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/people/deauthorization/community/ReauthorizeSanityTests.java @@ -0,0 +1,65 @@ +package org.alfresco.rest.people.deauthorization.community; + +import org.springframework.http.HttpStatus; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import org.alfresco.rest.RestTest; +import org.alfresco.rest.model.RestAuthKeyModel; +import org.alfresco.utility.model.TestGroup; +import org.alfresco.utility.model.UserModel; +import org.alfresco.utility.testrail.ExecutionType; +import org.alfresco.utility.testrail.annotation.TestRail; + +/** + * Verifies API behavior in community edition. Should be excluded in enterprise edition. + */ +@Test +public class ReauthorizeSanityTests extends RestTest +{ + private UserModel userModel; + private UserModel adminUser; + + @BeforeClass(alwaysRun = true) + public void dataPreparation() + { + adminUser = dataUser.getAdminUser(); + userModel = dataUser.createRandomTestUser(); + } + + @Test(groups = {TestGroup.REST_API, TestGroup.PEOPLE, TestGroup.SANITY}) + @TestRail(section = {TestGroup.REST_API, TestGroup.PEOPLE}, executionType = ExecutionType.SANITY, + description = "Check if reauthorization is not implemented in Community Edition") + public void reauthorizationIsNotImplementedInCommunityEdition() + { + // given + var key = new RestAuthKeyModel(); + key.setAuthorizationKey("am9obnRlc3RAMTIzNDU="); + + // when admin invokes API + restClient.authenticateUser(adminUser).withCoreAPI().usingUser(userModel).reauthorizeUser(key); + // then + restClient.assertStatusCodeIs(HttpStatus.NOT_IMPLEMENTED); + + // when user invokes API + restClient.authenticateUser(userModel).withCoreAPI().usingUser(userModel).reauthorizeUser(key); + // then + restClient.assertStatusCodeIs(HttpStatus.NOT_IMPLEMENTED); + } + + @Test(groups = {TestGroup.REST_API, TestGroup.PEOPLE, TestGroup.SANITY}) + @TestRail(section = {TestGroup.REST_API, TestGroup.PEOPLE}, executionType = ExecutionType.SANITY, + description = "Check if the reauthorization code is not implemented in Community Edition") + public void reauthorizationCodeIsNotImplementedInCommunityEdition() + { + // when admin invokes API + restClient.authenticateUser(adminUser).withCoreAPI().usingUser(userModel).getReauthorizationCode(); + // then + restClient.assertStatusCodeIs(HttpStatus.NOT_IMPLEMENTED); + + // when user invokes API + restClient.authenticateUser(userModel).withCoreAPI().usingUser(userModel).getReauthorizationCode(); + // then + restClient.assertStatusCodeIs(HttpStatus.NOT_IMPLEMENTED); + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/AuthCode.java b/remote-api/src/main/java/org/alfresco/rest/api/model/AuthCode.java new file mode 100644 index 0000000000..6d0f46d3ed --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/AuthCode.java @@ -0,0 +1,32 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.api.model; + +/** + * An object representing user authorization code. + */ +public record AuthCode(String authorizationCode) +{} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/AuthKey.java b/remote-api/src/main/java/org/alfresco/rest/api/model/AuthKey.java new file mode 100644 index 0000000000..b9b2f73290 --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/AuthKey.java @@ -0,0 +1,43 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2025 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.rest.api.model; + +import static org.apache.commons.lang3.StringUtils.length; + +/** + * An object representing user authorization key request body. + */ +public record AuthKey(String authorizationKey) +{ + @Override + public String toString() + { + // for security reasons the key content should be never logged + return "AuthKey[" + + "authorizationKeyLength=" + length(authorizationKey) + + ']'; + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/people/PeopleEntityResource.java b/remote-api/src/main/java/org/alfresco/rest/api/people/PeopleEntityResource.java index cb2fb825f0..e6c340477c 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/people/PeopleEntityResource.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/people/PeopleEntityResource.java @@ -34,6 +34,8 @@ import org.springframework.beans.factory.InitializingBean; import org.alfresco.model.ContentModel; import org.alfresco.rest.api.People; +import org.alfresco.rest.api.model.AuthCode; +import org.alfresco.rest.api.model.AuthKey; import org.alfresco.rest.api.model.Client; import org.alfresco.rest.api.model.PasswordReset; import org.alfresco.rest.api.model.Person; @@ -245,4 +247,29 @@ public class PeopleEntityResource implements EntityResourceAction.ReadById