Commit d5c31527 authored by Brian Long's avatar Brian Long
Browse files

added share-models goal

parent 32d4e807
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -41,13 +41,13 @@
		<dependency>
			<groupId>com.inteligr8.alfresco</groupId>
			<artifactId>aps-public-rest-api</artifactId>
			<version>2.0.0</version>
			<version>2.0.1</version>
			<classifier>aps1</classifier>
		</dependency>
		<dependency>
			<groupId>com.inteligr8.alfresco</groupId>
			<artifactId>aps-public-rest-client</artifactId>
			<version>2.0.0</version>
			<version>2.0.1</version>
			<classifier>jersey</classifier>
		</dependency>
		<dependency>
@@ -159,6 +159,9 @@
						<aps-model.authType>${aps-model.authType}</aps-model.authType>
						<aps-model.basicAuth.mavenServerId>${aps-model.basicAuth.mavenServerId}</aps-model.basicAuth.mavenServerId>
						<aps-model.appName>${aps-model.appName}</aps-model.appName>
						<aps-model.share.editors>${aps-model.share.editors}</aps-model.share.editors>
						<aps-model.share.readers>${aps-model.share.readers}</aps-model.share.readers>
						<aps-model.share.app.editors>${aps-model.share.app.editors}</aps-model.share.app.editors>
					</properties>
				</configuration>
				<executions>
+34 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.inteligr8.alfresco</groupId>
	<artifactId>aps-model-maven-plugin-aps-info</artifactId>
	<version>@pom.version@</version>
	<packaging>pom</packaging>

	<name>APS Share Models Plugin Tests</name>
	
	<build>
		<plugins>
			<plugin>
				<groupId>${project.groupId}</groupId>
				<artifactId>aps-model-maven-plugin</artifactId>
				<version>@pom.version@</version>
				<executions>
					<execution>
						<id>share-models</id>
						<phase>validate</phase>
						<goals>
							<goal>share-models</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

</project>
+203 −0
Original line number Diff line number Diff line
package com.inteligr8.maven.aps.modeling.goal;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.component.annotations.Component;

import com.inteligr8.alfresco.activiti.api.ModelsApi;
import com.inteligr8.alfresco.activiti.model.Datum;
import com.inteligr8.alfresco.activiti.model.GroupLight;
import com.inteligr8.alfresco.activiti.model.PermissionLevel;
import com.inteligr8.alfresco.activiti.model.PermissionLight;
import com.inteligr8.alfresco.activiti.model.ResultList;
import com.inteligr8.alfresco.activiti.model.ResultListDataRepresentation;
import com.inteligr8.alfresco.activiti.model.ShareInfoRequest;
import com.inteligr8.alfresco.activiti.model.SharePermission;
import com.inteligr8.alfresco.activiti.model.Tenant;
import com.inteligr8.maven.aps.modeling.util.Index;

@Mojo( name = "share-models", threadSafe = true )
@Component( role = org.apache.maven.plugin.Mojo.class )
public class ApsShareGoal extends ApsAddressibleGoal {

	@Parameter( property = "aps-model.share.readers" )
	protected String readers;

	@Parameter( property = "aps-model.share.editors" )
	protected String editors;

	@Parameter( property = "aps-model.share.app.readers" )
	protected String appReaders;

	@Parameter( property = "aps-model.share.app.editors" )
	protected String appEditors;

	@Parameter( property = "aps-model.share.process.readers" )
	protected String processReaders;

	@Parameter( property = "aps-model.share.process.editors" )
	protected String processEditors;

	@Parameter( property = "aps-model.share.form.readers" )
	protected String formReaders;

	@Parameter( property = "aps-model.share.form.editors" )
	protected String formEditors;

	@Parameter( property = "aps-model.share.doRevoke", defaultValue = "false" )
	protected boolean doRevoke = false;

	protected Set<String> appReaderSet;
	protected Set<String> appEditorSet;
	protected Set<String> processReaderSet;
	protected Set<String> processEditorSet;
	protected Set<String> formReaderSet;
	protected Set<String> formEditorSet;
	
	private Index<String, Long> identityIndex = new Index<>(128, true);
	
	@Override
	public void executeEnabled() throws MojoExecutionException, MojoFailureException {
		this.getLog().info("editors: " + this.editors);
		this.normalizeParameters();
		this.buildIdentityIndex();
		
		if (!this.appReaderSet.isEmpty() || !this.appEditorSet.isEmpty())
			this.shareModels(ModelsApi.ModelType.App, this.appReaderSet, this.appEditorSet);

		if (!this.processReaderSet.isEmpty() || !this.processEditorSet.isEmpty())
			this.shareModels(ModelsApi.ModelType.Process, this.processReaderSet, this.processEditorSet);

		if (!this.formReaderSet.isEmpty() || !this.formEditorSet.isEmpty())
			this.shareModels(ModelsApi.ModelType.Form, this.formReaderSet, this.formEditorSet);
	}
	
	private void shareModels(ModelsApi.ModelType modelType, Set<String> readers, Set<String> editors) {
		ResultListDataRepresentation models = this.getApsApi().getModelsApi().get(null, null, modelType.getId(), null);
		for (Datum datum : models.getData()) {
			Number modelId = (Number)datum.getAdditionalProperties().get("id");
			String modelName = (String)datum.getAdditionalProperties().get("name");
			
			Set<String> groupsAddressed = new HashSet<>();
			Set<String> readersUnaddressed = new HashSet<>(readers);
			Set<String> editorsUnaddressed = new HashSet<>(editors);
			ShareInfoRequest changeRequest = new ShareInfoRequest();
			
			ResultList<SharePermission> shares = this.getApsApi().getShareApi().getShareInfo(modelId.toString());
			for (SharePermission share : shares.getData()) {
				if (share.getGroup() != null) {
					groupsAddressed.add(share.getGroup().getName());
					
					if (PermissionLevel.Write.equals(share.getPermission())) {
						if (editors.contains(share.getGroup().getName())) {
							this.getLog().debug("The named group '" + share.getGroup().getName() + "' is already an editor of model '" + modelName + "'");
							// no change
							continue;
						} else if (readers.contains(share.getGroup().getName())) {
							this.getLog().debug("The named group '" + share.getGroup().getName() + "' reverting from editor to reader of model '" + modelName + "'");
							changeRequest.getUpdated().add(new PermissionLight().withId(share.getId()).withPermission(PermissionLevel.Read));
							continue;
						}
					} else {
						if (editors.contains(share.getGroup().getName())) {
							this.getLog().debug("The named group '" + share.getGroup().getName() + "' elevating from reader to editor of model '" + modelName + "'");
							changeRequest.getUpdated().add(new PermissionLight().withId(share.getId()).withPermission(PermissionLevel.Write));
							continue;
						} else if (readers.contains(share.getGroup().getName())) {
							this.getLog().debug("The named group '" + share.getGroup().getName() + "' is already an reader of model '" + modelName + "'");
							// no change
							continue;
						}
					}
					
					if (this.doRevoke) {
						this.getLog().debug("The named group '" + share.getGroup().getName() + "' is an unregulated editor of model '" + modelName + "'; revoking ...");
						changeRequest.getRemoved().add(new PermissionLight().withId(share.getId()));
					} else {
						this.getLog().debug("The named group '" + share.getGroup().getName() + "' is an unregulated editor of model '" + modelName + "'");
						// not touching extra unnamed permissions
					}
				} else if (share.getPerson() != null) {
					this.getLog().debug("Person-based model sharing not supported at this time; ignoring");
				}
			}
			
			readersUnaddressed.removeAll(groupsAddressed);
			for (String reader : readersUnaddressed) {
				Long groupId = this.identityIndex.getValue(reader);
				if (groupId == null) {
					this.getLog().warn("The named group '" + reader + "' does not exist in APS; ignoring ...");
				} else {
					this.getLog().debug("The named group '" + reader + "' becoming a reader of model '" + modelName + "'");
					changeRequest.getAdded().add(new PermissionLight().withGroupId(groupId).withPermission(PermissionLevel.Read));
				}
			}

			editorsUnaddressed.removeAll(groupsAddressed);
			for (String editor : editorsUnaddressed) {
				Long groupId = this.identityIndex.getValue(editor);
				if (groupId == null) {
					this.getLog().warn("The named group '" + editor + "' does not exist in APS; ignoring ...");
				} else {
					this.getLog().debug("The named group '" + editor + "' becoming an editor of model '" + modelName + "'");
					changeRequest.getAdded().add(new PermissionLight().withGroupId(groupId).withPermission(PermissionLevel.Write));
				}
			}
			
			if (!changeRequest.getAdded().isEmpty() || !changeRequest.getUpdated().isEmpty() || !changeRequest.getRemoved().isEmpty()) {
				this.getLog().info("Sharing model: " + modelType + " => '" + modelName + "'");
				this.getApsApi().getShareApi().setShareInfo(modelId.toString(), changeRequest);
			}
		}
	}
	
	protected void normalizeParameters() {
		Set<String> readerSet = this.normalizeParameter(this.readers);
		Set<String> editorSet = this.normalizeParameter(this.editors);
		this.appReaderSet = this.normalizeParameter(this.appReaders, readerSet);
		this.appEditorSet = this.normalizeParameter(this.appEditors, editorSet);
		this.processReaderSet = this.normalizeParameter(this.processReaders, readerSet);
		this.processEditorSet = this.normalizeParameter(this.processEditors, editorSet);
		this.formReaderSet = this.normalizeParameter(this.formReaders, readerSet);
		this.formEditorSet = this.normalizeParameter(this.formEditors, editorSet);
	}
	
	private Set<String> normalizeParameter(String parameter, Collection<String> c) {
		Set<String> set = this.normalizeParameter(parameter);
		set.addAll(c);
		return set;
	}
	
	private Set<String> normalizeParameter(String parameter) {
		Set<String> params = new HashSet<>();
		if (parameter == null)
			return params;
		if (parameter.length() == 0)
			return params;
		
		String[] splitParams = parameter.split(",");
		params.addAll(Arrays.asList(splitParams));
		return params;
	}
	
	protected void buildIdentityIndex() {
		List<Tenant> tenants = this.getApsApi().getAdminApi().getTenants();
		for (Tenant tenant : tenants) {
			List<GroupLight> groups = this.getApsApi().getAdminApi().getGroups(tenant.getId(), true, true);
			this.getLog().debug("Indexing groups: " + groups.size());
			for (GroupLight group : groups)
				this.identityIndex.put(group.getName(), group.getId());
			if (this.getLog().isDebugEnabled())
				this.getLog().debug("Indexed groups: " + this.identityIndex.toString());
		}
	}

}