mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Initial creation of ClassificationService, as part of RM-1945 and RM-1946.
This check-in adds the basic ClassificationService API, its initial implementation, ClassificationServiceImpl, along with some basic support types such as ClassificationServiceException (for service-specific exceptions) and Configuration. It also adds unit tests ClassificationServiceImplUnitTest and ConfigurationUnitTest. The ClassificationService begins our support for ‘Classified Records’, whereby Alfresco content can be given a ClassificationLevel and thereafter will only be accessible to users with the appropriate security clearance. The vanilla service includes a default set, rm-classification-levels.json (Top Secret etc) which links through to the i18n’d display data via rm-classification.properties in the usual way. The service is defined in its own spring context file, rm-classified-records-context.xml, as it is distinct from the file plan and should be applicable to content outside that file plan. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@99932 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name" : "TopSecret",
|
||||||
|
"displayLabel" : "rm.classification.topSecret"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "Secret",
|
||||||
|
"displayLabel" : "rm.classification.secret"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "Confidential",
|
||||||
|
"displayLabel" : "rm.classification.confidential"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "NoClearance",
|
||||||
|
"displayLabel" : "rm.classification.noClearance"
|
||||||
|
}
|
||||||
|
]
|
@@ -0,0 +1,5 @@
|
|||||||
|
## Default roles
|
||||||
|
rm.classification.topSecret=Top Secret
|
||||||
|
rm.classification.secret=Secret
|
||||||
|
rm.classification.confidential=Confidential
|
||||||
|
rm.classification.noClearance=No Clearance
|
@@ -60,6 +60,7 @@
|
|||||||
<value>alfresco.module.org_alfresco_module_rm.messages.dataset-service</value>
|
<value>alfresco.module.org_alfresco_module_rm.messages.dataset-service</value>
|
||||||
<value>alfresco.module.org_alfresco_module_rm.messages.rm-system</value>
|
<value>alfresco.module.org_alfresco_module_rm.messages.rm-system</value>
|
||||||
<value>alfresco.module.org_alfresco_module_rm.messages.template</value>
|
<value>alfresco.module.org_alfresco_module_rm.messages.template</value>
|
||||||
|
<value>alfresco.module.org_alfresco_module_rm.messages.rm-classification</value>
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -87,7 +88,10 @@
|
|||||||
<!-- Import the RM service's -->
|
<!-- Import the RM service's -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-service-context.xml"/>
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-service-context.xml"/>
|
||||||
|
|
||||||
<!-- Import DOD 5015 -->
|
<!-- Import the Classified Records Services -->
|
||||||
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-classified-records-context.xml"/>
|
||||||
|
|
||||||
|
<!-- Import DOD 5015 -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/dod5015/dod5015-context.xml"/>
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/dod5015/dod5015-context.xml"/>
|
||||||
|
|
||||||
<!-- Import the RM identifier service's -->
|
<!-- Import the RM identifier service's -->
|
||||||
|
@@ -0,0 +1,52 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||||
|
|
||||||
|
<beans>
|
||||||
|
|
||||||
|
<!-- Classification Service -->
|
||||||
|
|
||||||
|
<bean id="classificationService"
|
||||||
|
class="org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceImpl"
|
||||||
|
init-method="initConfiguredClassificationLevels"
|
||||||
|
parent="baseService">
|
||||||
|
<property name="attributeService" ref="AttributeService"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ClassificationService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
|
<property name="proxyInterfaces">
|
||||||
|
<value>org.alfresco.module.org_alfresco_module_rm.classification.ClassificationService</value>
|
||||||
|
</property>
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="classificationService"/>
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref local="ClassificationService_transaction"/>
|
||||||
|
<idref bean="exceptionTranslator"/>
|
||||||
|
<idref local="ClassificationService_security"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ClassificationService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||||
|
<property name="transactionManager">
|
||||||
|
<ref bean="transactionManager"/>
|
||||||
|
</property>
|
||||||
|
<property name="transactionAttributes">
|
||||||
|
<props>
|
||||||
|
<prop key="*">${server.transaction.mode.default}</prop>
|
||||||
|
</props>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ClassificationService_security" parent="baseSecurity">
|
||||||
|
<property name="objectDefinitionSource">
|
||||||
|
<value>
|
||||||
|
<![CDATA[
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.classification.ClassificationService.getApplicableLevels=RM_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.classification.ClassificationService.*=RM_DENY
|
||||||
|
]]>
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</beans>
|
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.classification;
|
||||||
|
|
||||||
|
import org.springframework.extensions.surf.util.I18NUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a POJO data type for a Classification Level.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public final class ClassificationLevel implements Serializable
|
||||||
|
{
|
||||||
|
private final String id;
|
||||||
|
private final String displayLabelKey;
|
||||||
|
|
||||||
|
public ClassificationLevel(final String id, final String displayLabelKey)
|
||||||
|
{
|
||||||
|
if (id == null || id.trim().equals(""))
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Illegal id: '" + id + "'");
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
this.displayLabelKey = displayLabelKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the unique identifier for this classification level. */
|
||||||
|
public String getId() { return this.id; }
|
||||||
|
|
||||||
|
/** Returns the localised (current locale) display label for this classification level. */
|
||||||
|
public String getDisplayLabel() { return I18NUtil.getMessage(displayLabelKey); }
|
||||||
|
|
||||||
|
@Override public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
msg.append(ClassificationLevel.class.getSimpleName())
|
||||||
|
.append(":").append(id);
|
||||||
|
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ClassificationLevel that = (ClassificationLevel) o;
|
||||||
|
|
||||||
|
return this.id.equals(that.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int hashCode() { return id.hashCode(); }
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.classification;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Classification Service supports the 'Classified Records' feature, whereby Alfresco
|
||||||
|
* content can be given a {@link ClassificationLevel}. This restricts access to that
|
||||||
|
* content to users having the appropriate security clearance.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public interface ClassificationService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns an immutable list of the defined classification levels.
|
||||||
|
* @return classification levels in descending order from highest to lowest.
|
||||||
|
*/
|
||||||
|
public List<ClassificationLevel> getApplicableLevels();
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.classification;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic class for any runtime exception thrown within the {@link ClassificationService}.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public class ClassificationServiceException extends AlfrescoRuntimeException
|
||||||
|
{
|
||||||
|
public ClassificationServiceException(String msgId) { super(msgId); }
|
||||||
|
public ClassificationServiceException(String msgId, Throwable cause) { super(msgId, cause); }
|
||||||
|
|
||||||
|
/** Represents a fatal error due to missing required configuration. */
|
||||||
|
public static class MissingConfiguration extends ClassificationServiceException
|
||||||
|
{
|
||||||
|
public MissingConfiguration(String msgId) { super(msgId); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Represents a fatal error due to illegal configuration.
|
||||||
|
* The configuration was understood by the server, but was rejected as illegal. */
|
||||||
|
public static class IllegalConfiguration extends ClassificationServiceException
|
||||||
|
{
|
||||||
|
public IllegalConfiguration(String msgId) { super(msgId); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Represents a fatal error due to malformed configuration.
|
||||||
|
* The configuration could not be understood by the server. */
|
||||||
|
public static class MalformedConfiguration extends ClassificationServiceException
|
||||||
|
{
|
||||||
|
public MalformedConfiguration(String msgId) { super(msgId); }
|
||||||
|
public MalformedConfiguration(String msgId, Throwable cause) { super(msgId, cause); }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.classification;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.MissingConfiguration;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.service.cmr.attributes.AttributeService;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public class ClassificationServiceImpl extends ServiceBaseImpl
|
||||||
|
implements ClassificationService
|
||||||
|
{
|
||||||
|
private static Log logger = LogFactory.getLog(ClassificationServiceImpl.class);
|
||||||
|
|
||||||
|
private static final String[] ATTRIBUTE_KEYS = new String[] { "org.alfresco",
|
||||||
|
"module.org_alfresco_module_rm",
|
||||||
|
"classification.levels" };
|
||||||
|
|
||||||
|
public static final String DEFAULT_CONFIG_LOCATION =
|
||||||
|
"/alfresco/module/org_alfresco_module_rm/classification/rm-classification-levels.json";
|
||||||
|
|
||||||
|
private AttributeService attributeService; // TODO What about other code (e.g. REST API) accessing the AttrService?
|
||||||
|
|
||||||
|
/** The classification levels currently configured in this server. */
|
||||||
|
private List<ClassificationLevel> configuredLevels;
|
||||||
|
|
||||||
|
private Configuration config = new Configuration(DEFAULT_CONFIG_LOCATION);
|
||||||
|
|
||||||
|
public void setAttributeService(AttributeService service) { this.attributeService = service; }
|
||||||
|
|
||||||
|
public void initConfiguredClassificationLevels()
|
||||||
|
{
|
||||||
|
final List<ClassificationLevel> allPersistedLevels = getPersistedLevels();
|
||||||
|
final List<ClassificationLevel> configuredLevels = getConfiguredLevels();
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
// Note! We cannot log the level names or even the size of these lists for security reasons.
|
||||||
|
logger.debug("Persisted classification levels: " + loggableStatusOf(allPersistedLevels));
|
||||||
|
logger.debug("Configured classification levels: " + loggableStatusOf(configuredLevels));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configuredLevels == null || configuredLevels.isEmpty())
|
||||||
|
{
|
||||||
|
throw new MissingConfiguration("Classification level configuration is missing.");
|
||||||
|
}
|
||||||
|
else if ( !configuredLevels.equals(allPersistedLevels))
|
||||||
|
{
|
||||||
|
attributeService.setAttribute((Serializable) configuredLevels, ATTRIBUTE_KEYS);
|
||||||
|
this.configuredLevels = configuredLevels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.configuredLevels = allPersistedLevels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper method for debug-logging of sensitive lists. */
|
||||||
|
private String loggableStatusOf(List<?> l)
|
||||||
|
{
|
||||||
|
if (l == null) { return "null"; }
|
||||||
|
else if (l.isEmpty()) { return "empty"; }
|
||||||
|
else { return "non-empty"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list (in descending order) of classification levels - as persisted in the system.
|
||||||
|
* @return the list of classification levels if they have been persisted, else {@code null}.
|
||||||
|
*/
|
||||||
|
List<ClassificationLevel> getPersistedLevels() {
|
||||||
|
return authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<List<ClassificationLevel>>()
|
||||||
|
{
|
||||||
|
@Override public List<ClassificationLevel> doWork() throws Exception
|
||||||
|
{
|
||||||
|
return (List<ClassificationLevel>) attributeService.getAttribute(ATTRIBUTE_KEYS);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the list (in descending order) of classification levels - as defined in the system configuration. */
|
||||||
|
List<ClassificationLevel> getConfiguredLevels()
|
||||||
|
{
|
||||||
|
return config.getConfiguredLevels();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ClassificationLevel> getApplicableLevels()
|
||||||
|
{
|
||||||
|
return configuredLevels == null ? Collections.<ClassificationLevel>emptyList() :
|
||||||
|
Collections.unmodifiableList(configuredLevels);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.classification;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.MalformedConfiguration;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.json.JSONTokener;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is responsible for providing the configured classification levels, dealing with
|
||||||
|
* JSON schema as part of that.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
class Configuration
|
||||||
|
{
|
||||||
|
public final String configLocation;
|
||||||
|
|
||||||
|
public Configuration(String classpathLocation)
|
||||||
|
{
|
||||||
|
this.configLocation = classpathLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list (in descending order) of classification levels - as defined in the system configuration.
|
||||||
|
*
|
||||||
|
* @return the configured classification levels in descending order, or an empty list if there are none.
|
||||||
|
*/
|
||||||
|
public List<ClassificationLevel> getConfiguredLevels()
|
||||||
|
{
|
||||||
|
List<ClassificationLevel> result;
|
||||||
|
try (final InputStream in = this.getClass().getResourceAsStream(configLocation))
|
||||||
|
{
|
||||||
|
if ( in == null) { result = Collections.emptyList(); }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
final String jsonString = IOUtils.toString(in);
|
||||||
|
final JSONArray jsonArray = new JSONArray(new JSONTokener(jsonString));
|
||||||
|
|
||||||
|
result = new ArrayList<>(jsonArray.length());
|
||||||
|
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
final JSONObject nextObj = jsonArray.getJSONObject(i);
|
||||||
|
final String name = nextObj.getString("name");
|
||||||
|
final String displayLabelKey = nextObj.getString("displayLabel");
|
||||||
|
result.add(new ClassificationLevel(name, displayLabelKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException | JSONException e)
|
||||||
|
{
|
||||||
|
throw new MalformedConfiguration("Could not read classification level configuration", e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This package contains the various types required for the 'Classified Records' feature.
|
||||||
|
*
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.classification;
|
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.classification;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.MissingConfiguration;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||||
|
import org.alfresco.service.cmr.attributes.AttributeService;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link ClassificationServiceImpl}.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public class ClassificationServiceImplUnitTest extends BaseUnitTest
|
||||||
|
{
|
||||||
|
private static final List<ClassificationLevel> DEFAULT_CLASSIFICATION_LEVELS = asLevelList("Top Secret", "rm.classification.topSecret",
|
||||||
|
"Secret", "rm.classification.secret",
|
||||||
|
"Confidential", "rm.classification.confidential",
|
||||||
|
"No Clearance", "rm.classification.noClearance");
|
||||||
|
private static final List<ClassificationLevel> ALT_CLASSIFICATION_LEVELS = asLevelList("Board", "B",
|
||||||
|
"Executive Management", "EM",
|
||||||
|
"Employee", "E",
|
||||||
|
"Public", "P");
|
||||||
|
/**
|
||||||
|
* A convenience method for turning lists of level id Strings into lists
|
||||||
|
* of {@code ClassificationLevel} objects.
|
||||||
|
*
|
||||||
|
* @param idsAndLabels A varargs/array of Strings like so: [ id0, label0, id1, label1... ]
|
||||||
|
* @throws IllegalArgumentException if {@code idsAndLabels} has a non-even length.
|
||||||
|
*/
|
||||||
|
public static List<ClassificationLevel> asLevelList(String ... idsAndLabels)
|
||||||
|
{
|
||||||
|
if (idsAndLabels.length % 2 != 0)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException(String.format("Cannot create %s objects with %d args.",
|
||||||
|
ClassificationLevel.class.getSimpleName(), idsAndLabels.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
final int resultLength = idsAndLabels.length / 2;
|
||||||
|
final String[] ids = new String[resultLength];
|
||||||
|
final String[] labels = new String[resultLength];
|
||||||
|
|
||||||
|
for (int i = 0; i < idsAndLabels.length; i++)
|
||||||
|
{
|
||||||
|
if (i % 2 == 0) { ids[i / 2] = idsAndLabels[i]; }
|
||||||
|
else { labels[(i - 1) / 2] = idsAndLabels[i]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<ClassificationLevel> levels = new ArrayList<>(resultLength);
|
||||||
|
|
||||||
|
for (int i = 0; i < resultLength; i++)
|
||||||
|
{
|
||||||
|
levels.add(new ClassificationLevel(ids[i], labels[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mock(name="attributeService") protected AttributeService mockedAttributeService;
|
||||||
|
|
||||||
|
private ClassificationServiceImpl classificationService;
|
||||||
|
|
||||||
|
@Test public void defaultConfigurationVanillaSystem()
|
||||||
|
{
|
||||||
|
classificationService = new TestClassificationService(null, DEFAULT_CLASSIFICATION_LEVELS);
|
||||||
|
classificationService.setAttributeService(mockedAttributeService);
|
||||||
|
|
||||||
|
classificationService.initConfiguredClassificationLevels();
|
||||||
|
|
||||||
|
assertEquals(DEFAULT_CLASSIFICATION_LEVELS, classificationService.getApplicableLevels());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void alternativeConfigurationVanillaSystem()
|
||||||
|
{
|
||||||
|
classificationService = new TestClassificationService(null, ALT_CLASSIFICATION_LEVELS);
|
||||||
|
classificationService.setAttributeService(mockedAttributeService);
|
||||||
|
|
||||||
|
classificationService.initConfiguredClassificationLevels();
|
||||||
|
|
||||||
|
assertEquals(ALT_CLASSIFICATION_LEVELS, classificationService.getApplicableLevels());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void alternativeConfigurationPreviouslyStartedSystem()
|
||||||
|
{
|
||||||
|
classificationService = new TestClassificationService(DEFAULT_CLASSIFICATION_LEVELS, ALT_CLASSIFICATION_LEVELS);
|
||||||
|
classificationService.setAttributeService(mockedAttributeService);
|
||||||
|
|
||||||
|
classificationService.initConfiguredClassificationLevels();
|
||||||
|
|
||||||
|
assertEquals(ALT_CLASSIFICATION_LEVELS, classificationService.getApplicableLevels());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test (expected=MissingConfiguration.class)
|
||||||
|
public void missingConfigurationVanillaSystemShouldFail() throws Exception
|
||||||
|
{
|
||||||
|
classificationService = new TestClassificationService(null, null);
|
||||||
|
classificationService.setAttributeService(mockedAttributeService);
|
||||||
|
|
||||||
|
classificationService.initConfiguredClassificationLevels();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for test purposes that allows us to replace the persisted
|
||||||
|
* and configured lists of {@link ClassificationLevel}s.
|
||||||
|
*/
|
||||||
|
private static class TestClassificationService extends ClassificationServiceImpl
|
||||||
|
{
|
||||||
|
private final List<ClassificationLevel> persisted;
|
||||||
|
private final List<ClassificationLevel> configured;
|
||||||
|
public TestClassificationService(List<ClassificationLevel> persisted, List<ClassificationLevel> configured)
|
||||||
|
{
|
||||||
|
this.persisted = persisted;
|
||||||
|
this.configured = configured;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override List<ClassificationLevel> getPersistedLevels() { return persisted; }
|
||||||
|
@Override List<ClassificationLevel> getConfiguredLevels() { return configured; }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.classification;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.MalformedConfiguration;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceImplUnitTest.asLevelList;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link Configuration}.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public class ConfigurationUnitTest
|
||||||
|
{
|
||||||
|
private static final List<ClassificationLevel> DEFAULT_CLASSIFICATION_LEVELS = asLevelList("TopSecret", "TS",
|
||||||
|
"Secret", "S",
|
||||||
|
"Confidential", "C",
|
||||||
|
"NoClearance", "NC");
|
||||||
|
|
||||||
|
@Test public void readingDefaultConfigurationShouldWork()
|
||||||
|
{
|
||||||
|
Configuration c = new Configuration(ClassificationServiceImpl.DEFAULT_CONFIG_LOCATION);
|
||||||
|
List<ClassificationLevel> config = c.getConfiguredLevels();
|
||||||
|
assertEquals(DEFAULT_CLASSIFICATION_LEVELS, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void readingMissingConfigurationShouldProduceEmptyConfig() throws Exception
|
||||||
|
{
|
||||||
|
Configuration c = new Configuration("/no/such/resource");
|
||||||
|
assertTrue(c.getConfiguredLevels().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test (expected = MalformedConfiguration.class)
|
||||||
|
public void readingMalformedConfigurationShouldFail() throws Exception
|
||||||
|
{
|
||||||
|
Configuration c = new Configuration("/alfresco/classification/rm-classification-levels-malformed.json");
|
||||||
|
c.getConfiguredLevels();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name" : "TopSecret",
|
||||||
|
"displayLabel" : "Top Secret"
|
||||||
|
}, { {
|
||||||
|
]
|
Reference in New Issue
Block a user