RM-2123 Move clearance checking to SecurityClearanceService.

Refactor ContentClassificationService#hasClearance so that it calls out to
SecurityClearanceService#isCurrentUserClearedForClassification. Restrict
isCurrentUserClearedForClassification so that it only applies to the current
authenticated user (we don't need to use it for anything else).  Also
extract classification level comparison to a new class.

+review RM-58

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@104568 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tom Page
2015-05-20 08:28:46 +00:00
parent 4d94c8b66b
commit 94c65b83e8
6 changed files with 169 additions and 150 deletions

View File

@@ -0,0 +1,45 @@
/*
* 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.Comparator;
/**
* A class to compare classification levels.
*
* @author tpage
* @since 3.0
*/
public class ClassificationLevelComparator implements Comparator<ClassificationLevel>
{
private ClassificationLevelManager classificationLevelManager;
public ClassificationLevelComparator(ClassificationLevelManager classificationLevelManager)
{
this.classificationLevelManager = classificationLevelManager;
}
@Override
public int compare(ClassificationLevel oneLevel, ClassificationLevel otherLevel)
{
int oneIndex = classificationLevelManager.getClassificationLevels().indexOf(oneLevel);
int otherIndex = classificationLevelManager.getClassificationLevels().indexOf(otherLevel);
return oneIndex - otherIndex;
}
}

View File

@@ -24,7 +24,6 @@ import static org.alfresco.util.ParameterCheck.mandatory;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -132,37 +131,8 @@ public class ContentClassificationServiceImpl extends ServiceBaseImpl implements
@Override
public boolean hasClearance(NodeRef nodeRef)
{
boolean result = false;
// Get the node's current classification
ClassificationLevel currentClassification = getCurrentClassification(nodeRef);
if (ClassificationLevelManager.UNCLASSIFIED.equals(currentClassification))
{
// since the node is not classified user has clearance
result = true;
}
else
{
// Get the user's security clearance
SecurityClearance securityClearance = securityClearanceService.getUserSecurityClearance();
if (!ClearanceLevelManager.NO_CLEARANCE.equals(securityClearance.getClearanceLevel()))
{
// get the users highest classification clearance
ClassificationLevel highestClassification = securityClearance.getClearanceLevel().getHighestClassificationLevel();
// if classification is less than or equal to highest classification then user has clearance
List<ClassificationLevel> allClassificationLevels = levelManager.getClassificationLevels();
int highestIndex = allClassificationLevels.indexOf(highestClassification);
int currentIndex = allClassificationLevels.indexOf(currentClassification);
if (highestIndex <= currentIndex)
{
// user has clearance
result = true;
}
}
}
return result;
return securityClearanceService.isCurrentUserClearedForClassification(currentClassification.getId());
}
}

View File

@@ -18,11 +18,11 @@
*/
package org.alfresco.module.org_alfresco_module_rm.classification;
import java.util.List;
import org.alfresco.query.PagingResults;
import org.alfresco.service.cmr.security.NoSuchPersonException;
import java.util.List;
/**
* This service offers access to users' security clearance levels.
*
@@ -48,6 +48,15 @@ public interface SecurityClearanceService
*/
PagingResults<SecurityClearance> getUsersSecurityClearance(UserQueryParams queryParams);
/**
* Check if a classification can be accessed by the current user.
*
* @param classificationId The classification level to look for.
* @return {@code true} if the user can access the classification level; {@code false} if the user doesn't have
* clearance, or the classification level doesn't exist.
*/
boolean isCurrentUserClearedForClassification(String classificationId);
/**
* Set the clearance level for a user.
*

View File

@@ -25,7 +25,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.ImmutableList;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.LevelIdNotFound;
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
import org.alfresco.query.PagingRequest;
@@ -49,22 +48,31 @@ public class SecurityClearanceServiceImpl extends ServiceBaseImpl implements Sec
private ClassificationLevelManager classificationLevelManager;
private PersonService personService;
private ClassificationServiceBootstrap classificationServiceBootstrap;
private ClassificationLevelComparator classificationLevelComparator;
public void setClearanceManager(ClearanceLevelManager clearanceManager) { this.clearanceManager = clearanceManager; }
public void setClassificationLevelManager(ClassificationLevelManager classificationLevelManager) { this.classificationLevelManager = classificationLevelManager; }
public void setPersonService(PersonService service) { this.personService = service; }
public void setClassificationServiceBootstrap(ClassificationServiceBootstrap classificationServiceBootstrap) { this.classificationServiceBootstrap = classificationServiceBootstrap; }
public void setClassificationLevelComparator(ClassificationLevelComparator classificationLevelComparator) { this.classificationLevelComparator = classificationLevelComparator; }
/** Store the references to the classification and clearance level managers in this class. */
public void init()
{
this.classificationLevelManager = classificationServiceBootstrap.getClassificationLevelManager();
this.clearanceManager = classificationServiceBootstrap.getClearanceLevelManager();
classificationLevelComparator = new ClassificationLevelComparator(classificationLevelManager);
}
@Override
public SecurityClearance getUserSecurityClearance()
{
if (authenticationUtil.isRunAsUserTheSystemUser())
{
return new SecurityClearance(null, clearanceManager.getMostSecureLevel());
}
final String currentUser = authenticationUtil.getFullyAuthenticatedUser();
ParameterCheck.mandatoryString("currentUser", currentUser);
@@ -79,11 +87,6 @@ public class SecurityClearanceServiceImpl extends ServiceBaseImpl implements Sec
*/
private SecurityClearance getUserSecurityClearance(final String userName)
{
if (authenticationUtil.isRunAsUserTheSystemUser())
{
return new SecurityClearance(null, clearanceManager.getMostSecureLevel());
}
final NodeRef personNode = personService.getPerson(userName, false);
final PersonInfo personInfo = personService.getPerson(personNode);
@@ -130,31 +133,26 @@ public class SecurityClearanceServiceImpl extends ServiceBaseImpl implements Sec
};
}
/**
* Check if a classification can be accessed by a user with a given clearance.
*
* @param clearance The clearance of the user.
* @param classificationId The classification level to look for.
* @return {@code true} if the user can access the classification level.
*/
protected boolean isClearedForClassification(SecurityClearance clearance, String classificationId)
@Override
public boolean isCurrentUserClearedForClassification(String classificationId)
{
ImmutableList<ClassificationLevel> classificationLevels = classificationLevelManager.getClassificationLevels();
// Get the current user's security clearance.
SecurityClearance securityClearance = getUserSecurityClearance();
String clearanceId = clearance.getClearanceLevel().getHighestClassificationLevel().getId();
for (ClassificationLevel classificationLevel : classificationLevels)
ClassificationLevel suppliedLevel;
try
{
if (classificationLevel.getId().equals(clearanceId))
{
return true;
}
else if (classificationLevel.getId().equals(classificationId))
{
return false;
}
suppliedLevel = classificationLevelManager.findLevelById(classificationId);
}
// Neither the clearance id nor the classification id were found - something's gone wrong.
throw new LevelIdNotFound(classificationId);
catch(LevelIdNotFound e)
{
// Return false to make "Level not found" indistinguishable from "Not cleared".
return false;
}
ClassificationLevel usersHighestLevel = securityClearance.getClearanceLevel().getHighestClassificationLevel();
int comparison = classificationLevelComparator.compare(usersHighestLevel, suppliedLevel);
return (comparison >= 0);
}
@Override
@@ -166,8 +164,7 @@ public class SecurityClearanceServiceImpl extends ServiceBaseImpl implements Sec
final NodeRef personNode = personService.getPerson(userName, false);
// Check the current user has clearance to see the specified level.
SecurityClearance userSecurityClearance = getUserSecurityClearance();
if (!isClearedForClassification(userSecurityClearance, clearanceId))
if (!isCurrentUserClearedForClassification(clearanceId))
{
throw new LevelIdNotFound(clearanceId);
}