Initial implementations for RM-2112 and RM-2113.

Added a securityClearance aspect to the classifiedContentModel.
   This can be applied to a user’s person node to give them clearance.
   TODO. Not clear how/if we can use this for groups of users.
Added a SecurityClearanceService which gets users’ security clearances.
Added a getDefaultClassificationLevel method to the ClassificationService.
  TODO This needs to be reviewed.



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@103042 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Neil McErlean
2015-04-29 09:37:16 +00:00
parent 3e2fd99f96
commit e42957d58e
8 changed files with 255 additions and 3 deletions

View File

@@ -67,6 +67,11 @@ public interface ClassificationService
Set<String> classificationReasonIds, NodeRef content) throws LevelIdNotFound, ReasonIdNotFound,
InvalidNodeRefException, InvalidNode;
/**
* Gets the default {@link ClassificationLevel}, which will usually be the level with the lowest security clearance.
*/
ClassificationLevel getDefaultClassificationLevel();
/**
* Gets the classification level for the given classification level id
*

View File

@@ -267,6 +267,12 @@ public class ClassificationServiceImpl extends ServiceBaseImpl
nodeService.addAspect(content, ASPECT_CLASSIFIED, properties);
}
@Override public ClassificationLevel getDefaultClassificationLevel()
{
List<ClassificationLevel> classificationLevels = getClassificationLevels();
return classificationLevels.isEmpty() ? null : classificationLevels.get(classificationLevels.size() - 1);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.classification.ClassificationService#getClassificationLevelById(java.lang.String)
*/

View File

@@ -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.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.service.cmr.security.NoSuchPersonException;
import org.alfresco.service.cmr.security.PersonService.PersonInfo;
import org.alfresco.util.Pair;
/**
* This service offers access to users' security clearance levels.
*
* @author Neil Mc Erlean
* @since 3.0
*/
public interface SecurityClearanceService
{
/**
* Get the currently authenticated user's security clearance.
*
* @return a {@link PersonInfo}, {@link ClassificationLevel} pair for the currently authenticated user.
* @throws NoSuchPersonException if the current user's person node cannot be found.
*/
Pair<PersonInfo, ClassificationLevel> getUserSecurityClearance();
/**
* Get users' security clearances.
*
* @param userNameFragment A username fragment which will be used to apply a 'starts with' query.
* @param sortAscending if @code true} returns data sorted in ascending order by username.
* @param req paging request definition.
* @return {@link PersonInfo}, {@link ClassificationLevel} pairs for the specified page of users.
*/
PagingResults<Pair<PersonInfo, ClassificationLevel>> getUsersSecurityClearance(String userNameFragment,
boolean sortAscending,
PagingRequest req);
}

View File

@@ -0,0 +1,108 @@
/*
* 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 static java.util.Arrays.asList;
import static org.alfresco.model.ContentModel.PROP_FIRSTNAME;
import static org.alfresco.model.ContentModel.PROP_LASTNAME;
import static org.alfresco.model.ContentModel.PROP_USERNAME;
import static org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel.ASPECT_SECURITY_CLEARANCE;
import static org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel.PROP_CLEARANCE_LEVEL;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.security.PersonService.PersonInfo;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author Neil Mc Erlean
* @since 3.0
*/
public class SecurityClearanceServiceImpl extends ServiceBaseImpl implements SecurityClearanceService
{
private ClassificationService classificationService;
private PersonService personService;
public void setClassificationService(ClassificationService service) { this.classificationService = service; }
public void setPersonService (PersonService service) { this.personService = service; }
public Pair<PersonInfo, ClassificationLevel> getUserSecurityClearance()
{
final String currentUser = authenticationUtil.getFullyAuthenticatedUser();
Objects.requireNonNull(currentUser, "Fully authenticated user is null, which is not allowed.");
return getUserSecurityClearance(currentUser);
}
private Pair<PersonInfo, ClassificationLevel> getUserSecurityClearance(final String userName)
{
final NodeRef personNode = personService.getPerson(userName, false);
final PersonInfo personInfo = personService.getPerson(personNode);
final ClassificationLevel classificationLevel;
if (nodeService.hasAspect(personNode, ASPECT_SECURITY_CLEARANCE))
{
final String clearanceLevel = (String)nodeService.getProperty(personNode, PROP_CLEARANCE_LEVEL);
// TODO Should we fall back to a default here or give an error?
classificationLevel = clearanceLevel == null ? classificationService.getDefaultClassificationLevel() :
classificationService.getClassificationLevelById(clearanceLevel);
}
else { classificationLevel = classificationService.getDefaultClassificationLevel(); }
return new Pair<>(personInfo, classificationLevel);
}
public PagingResults<Pair<PersonInfo, ClassificationLevel>> getUsersSecurityClearance(String userNameFragment,
boolean sortAscending,
PagingRequest req)
{
final List<QName> filterProps = asList(PROP_USERNAME, PROP_FIRSTNAME, PROP_LASTNAME);
final List<Pair<QName, Boolean>> sortProps = asList(new Pair<>(PROP_USERNAME, sortAscending));
final PagingResults<PersonInfo> p = personService.getPeople(userNameFragment, filterProps, sortProps, req);
return new PagingResults<Pair<PersonInfo, ClassificationLevel>>()
{
@Override public List<Pair<PersonInfo, ClassificationLevel>> getPage()
{
List<Pair<PersonInfo, ClassificationLevel>> pcPage= new ArrayList<>(p.getPage().size());
for (PersonInfo pi : p.getPage())
{
pcPage.add(getUserSecurityClearance(pi.getUserName()));
}
return pcPage;
}
@Override public boolean hasMoreItems() { return p.hasMoreItems(); }
@Override public Pair<Integer, Integer> getTotalResultCount() { return p.getTotalResultCount(); }
@Override public String getQueryExecutionId() { return p.getQueryExecutionId(); }
};
}
}

View File

@@ -40,4 +40,8 @@ public interface ClassifiedContentModel
QName PROP_CURRENT_CLASSIFICATION = QName.createQName(CLF_URI, "currentClassification");
QName PROP_CLASSIFICATION_AUTHORITY = QName.createQName(CLF_URI, "classificationAuthority");
QName PROP_CLASSIFICATION_REASONS = QName.createQName(CLF_URI, "classificationReasons");
/** Security Clearance aspect. */
QName ASPECT_SECURITY_CLEARANCE = QName.createQName(CLF_URI, "securityClearance");
QName PROP_CLEARANCE_LEVEL = QName.createQName(CLF_URI, "clearanceLevel");
}

View File

@@ -19,7 +19,14 @@
/**
* This package contains the various types required for the 'Classified Records' feature.
* Nodes within Alfresco can be given a {@link org.alfresco.module.org_alfresco_module_rm.classification.ClassificationLevel}
* which then restricts access to them to users having the appropriate clearance.
* <p/>
* The {@link org.alfresco.module.org_alfresco_module_rm.classification.ClassificationService} is responsible
* for the management of those levels and it is the
* {@link org.alfresco.module.org_alfresco_module_rm.classification.SecurityClearanceService} which deals
* wth users and their clearances.
*
* @since 3.0
*/
package org.alfresco.module.org_alfresco_module_rm.classification;
package org.alfresco.module.org_alfresco_module_rm.classification;