Skip to content

Commit

Permalink
Optionally add product profiles as members to IMS groups
Browse files Browse the repository at this point in the history
This closes #727
  • Loading branch information
kwin committed Jun 11, 2024
1 parent 32105c0 commit de7eb64
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
ACTOOL_IMS_IT_ORGANIZATIONID: ${{ vars.ACTOOL_IMS_IT_ORGANIZATIONID }}
ACTOOL_IMS_IT_CLIENTID: ${{ vars.ACTOOL_IMS_IT_CLIENTID }}
ACTOOL_IMS_IT_CLIENTSECRET: ${{ secrets.ACTOOL_IMS_IT_CLIENTSECRET }}
ACTOOL_IMS_IT_PRODUCTPROFILE: ${{ vars.ACTOOL_IMS_IT_PRODUCTPROFILE }}
run: mvn -e -B -V -Pintegration-tests clean verify
- name: Build and Analyse with Maven
if: github.ref != 'refs/heads/develop' && matrix.isMainBuildEnv
Expand All @@ -54,6 +55,7 @@ jobs:
ACTOOL_IMS_IT_ORGANIZATIONID: ${{ vars.ACTOOL_IMS_IT_ORGANIZATIONID }}
ACTOOL_IMS_IT_CLIENTID: ${{ vars.ACTOOL_IMS_IT_CLIENTID }}
ACTOOL_IMS_IT_CLIENTSECRET: ${{ secrets.ACTOOL_IMS_IT_CLIENTSECRET }}
ACTOOL_IMS_IT_PRODUCTPROFILE: ${{ vars.ACTOOL_IMS_IT_PRODUCTPROFILE }}
run: mvn -e -B -V clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=Netcentric_accesscontroltool -Dsonar.organization=netcentric -Dsonar.host.url=https://sonarcloud.io -DnvdApiKeyEnvironmentVariable=NVD_API_KEY -Pdependency-check,coverage-report,integration-tests

- name: Build, Analyse and Deploy with Maven
Expand All @@ -71,4 +73,5 @@ jobs:
ACTOOL_IMS_IT_ORGANIZATIONID: ${{ vars.ACTOOL_IMS_IT_ORGANIZATIONID }}
ACTOOL_IMS_IT_CLIENTID: ${{ vars.ACTOOL_IMS_IT_CLIENTID }}
ACTOOL_IMS_IT_CLIENTSECRET: ${{ secrets.ACTOOL_IMS_IT_CLIENTSECRET }}
ACTOOL_IMS_IT_PRODUCTPROFILE: ${{ vars.ACTOOL_IMS_IT_PRODUCTPROFILE }}
run: mvn -e -B -V clean deploy org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=Netcentric_accesscontroltool -Dsonar.organization=netcentric -Dsonar.host.url=https://sonarcloud.io -DnvdApiKeyEnvironmentVariable=NVD_API_KEY -Pdependency-check,coverage-report,integration-tests
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
Expand Down Expand Up @@ -55,6 +57,7 @@
import biz.netcentric.cq.tools.actool.externalusermanagement.ExternalGroupManagement;
import biz.netcentric.cq.tools.actool.ims.IMSUserManagement.Configuration;
import biz.netcentric.cq.tools.actool.ims.request.ActionCommand;
import biz.netcentric.cq.tools.actool.ims.request.AddMembershipStep;
import biz.netcentric.cq.tools.actool.ims.request.CreateGroupStep;
import biz.netcentric.cq.tools.actool.ims.request.UserGroupActionCommand;
import biz.netcentric.cq.tools.actool.ims.response.AccessToken;
Expand Down Expand Up @@ -89,6 +92,8 @@ public class IMSUserManagement implements ExternalGroupManagement {
int connectTimeout() default 2000;
@AttributeDefinition(name = "Socket Timeout", description = "The time waiting for data – after establishing the connection; maximum time of inactivity between two data packets. Given in milliseconds.")
int socketTimeout() default 10000;
@AttributeDefinition(name = "AEM Product Profiles", description = "The given product profile names are automatically added to each synchronized IMS group. The given product profile names must exist for an AEM product!")
String[] productProfiles() default {};
}

public static final Logger LOG = LoggerFactory.getLogger(IMSUserManagement.class);
Expand Down Expand Up @@ -184,6 +189,12 @@ public void updateGroups(Collection<AuthorizableConfigBean> groupConfigs) throws
CreateGroupStep createGroupStep = new CreateGroupStep();
createGroupStep.description = groupConfig.getDescription();
actionCommand.addStep(createGroupStep);
// optionally maintain product profile memberships in the group as well
if (config.productProfiles() != null && config.productProfiles().length > 0) {
AddMembershipStep addMembershipStep = new AddMembershipStep();
addMembershipStep.productProfileIds = new HashSet<>(Arrays.asList(config.productProfiles()));
actionCommand.addStep(addMembershipStep);
}
actionCommands.add(actionCommand);
}
// update in batches of 10 commands
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package biz.netcentric.cq.tools.actool.ims.request;

import java.util.Set;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;

@JsonTypeName("add")
@JsonInclude(Include.NON_EMPTY) // neither empty strings nor null values are allowed for the fields
public class AddMembershipStep implements Step {

@JsonProperty("user")
public Set<String> userIds;

@JsonProperty("productConfiguration")
public Set<String> productProfileIds;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package biz.netcentric.cq.tools.actool.ims;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.util.Collections;
Expand All @@ -9,6 +11,7 @@

import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.osgi.services.HttpClientBuilderFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.osgi.util.converter.Converters;

Expand All @@ -26,15 +29,21 @@
*/
class IMSUserManagementIT {

@Test
void test() throws IOException {
Map<String, Object> properties = new HashMap<>();
private static final String ACTOOL_IMS_IT_PRODUCTPROFILE = null;
Map<String, Object> properties;

@BeforeEach
void setUp() {
properties = new HashMap<>();
properties.put("organizationId", getMandatoryEnvironmentVariable("ACTOOL_IMS_IT_ORGANIZATIONID"));
properties.put("clientId", getMandatoryEnvironmentVariable("ACTOOL_IMS_IT_CLIENTID"));
properties.put("clientSecret", getMandatoryEnvironmentVariable("ACTOOL_IMS_IT_CLIENTSECRET"));
properties.put("isTestOnly", Boolean.TRUE);
}

@Test
void testSimpleGroup() throws IOException {
Configuration config = Converters.standardConverter().convert(properties).to(Configuration.class);

IMSUserManagement imsUserManagement = new IMSUserManagement(config, new HttpClientBuilderFactory() {
@Override
public HttpClientBuilder newBuilder() {
Expand All @@ -59,6 +68,39 @@ public HttpClientBuilder newBuilder() {
imsUserManagement.updateGroups(Collections.singleton(group3));
}

@Test
void testGroupWithProductProfileMembership() throws IOException {
properties.put("productProfiles", getMandatoryEnvironmentVariable("ACTOOL_IMS_IT_PRODUCTPROFILE"));
Configuration config = Converters.standardConverter().convert(properties).to(Configuration.class);
IMSUserManagement imsUserManagement = new IMSUserManagement(config, new HttpClientBuilderFactory() {
@Override
public HttpClientBuilder newBuilder() {
return HttpClientBuilder.create();
}
});
AuthorizableConfigBean group = new AuthorizableConfigBean();
group.setAuthorizableId("testGroup");
group.setDescription("my description");
imsUserManagement.updateGroups(Collections.singleton(group));
}

@Test
void testGroupWithInvalidProductProfileMembership() throws IOException {
properties.put("productProfiles", "Invalid name");
Configuration config = Converters.standardConverter().convert(properties).to(Configuration.class);
IMSUserManagement imsUserManagement = new IMSUserManagement(config, new HttpClientBuilderFactory() {
@Override
public HttpClientBuilder newBuilder() {
return HttpClientBuilder.create();
}
});
AuthorizableConfigBean group = new AuthorizableConfigBean();
group.setAuthorizableId("testGroup");
group.setDescription("my description");
IOException t = assertThrows(IOException.class, () -> { imsUserManagement.updateGroups(Collections.singleton(group)); });
assertTrue(t.getMessage().contains("error.plc.not_found"), "Exceptions message is supposed to contain 'error.plc.not_found' but was " + t.getMessage());
}

private static String getMandatoryEnvironmentVariable(String name) {
String value = System.getenv(name);
if (value == null) {
Expand Down

0 comments on commit de7eb64

Please sign in to comment.