diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelComparator.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelComparator.java new file mode 100644 index 0000000000..7527ba3bf3 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelComparator.java @@ -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 . + */ +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 +{ + 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; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ContentClassificationServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ContentClassificationServiceImpl.java index 3ffd6d31f8..f1ae0659cb 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ContentClassificationServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ContentClassificationServiceImpl.java @@ -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 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()); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceService.java index 82a2251d2e..48766faed1 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceService.java @@ -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 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. * diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceServiceImpl.java index 14d3ca280d..4374e24986 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceServiceImpl.java @@ -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 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); } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ContentClassificationServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ContentClassificationServiceImplUnitTest.java index 1554fe9da5..5c0cc10859 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ContentClassificationServiceImplUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ContentClassificationServiceImplUnitTest.java @@ -184,20 +184,6 @@ public class ContentClassificationServiceImplUnitTest implements ClassifiedConte verifyNoMoreInteractions(mockNodeService, mockLevelManager); } - - /** - * Given that the node is unclassified - * When I ask if the current user has clearance - * Then true - */ - @Test public void clearedForUnclassifiedNode() - { - // Content is unclassified by default. - NodeRef nodeRef = generateNodeRef(mockNodeService); - - assertTrue(contentClassificationServiceImpl.hasClearance(nodeRef)); - } - /** * Given that the node is classified * And the user has no security clearance @@ -223,11 +209,11 @@ public class ContentClassificationServiceImplUnitTest implements ClassifiedConte /** * Given that the node is classified - * And the user has clearance grater than the classification + * And the user has clearance greater or equal to the the classification * When I ask if the user has clearance * Then true */ - @Test public void classifiedNodeUserClearanceGreater() + @Test public void classifiedNodeUserClearanceAtLeast() { // init classification levels ClassificationLevel topSecret = new ClassificationLevel("TopSecret", generateText()); @@ -244,39 +230,7 @@ public class ContentClassificationServiceImplUnitTest implements ClassifiedConte when(mockLevelManager.findLevelById(secretId)).thenReturn(secret); // set users security clearance - ClearanceLevel topSecretClearance = new ClearanceLevel(topSecret, "Top Secret"); - SecurityClearance clearance = new SecurityClearance(mock(PersonInfo.class), topSecretClearance); - when(mockSecurityClearanceService.getUserSecurityClearance()).thenReturn(clearance); - - assertTrue(contentClassificationServiceImpl.hasClearance(nodeRef)); - } - - /** - * Given that the node is classified - * And the user has clearance equal to the the classification - * When I ask if the user has clearance - * Then true - */ - @Test public void classifiedNodeUserClearanceEqual() - { - // init classification levels - ClassificationLevel topSecret = new ClassificationLevel("TopSecret", generateText()); - String secretId = "Secret"; - ClassificationLevel secret = new ClassificationLevel(secretId, generateText()); - ClassificationLevel confidential = new ClassificationLevel("Confidential", generateText()); - List classificationLevels = Arrays.asList(topSecret, secret, confidential, ClassificationLevelManager.UNCLASSIFIED); - when(mockLevelManager.getClassificationLevels()).thenReturn(ImmutableList.copyOf(classificationLevels)); - - // set nodes classification - NodeRef nodeRef = generateNodeRef(mockNodeService); - when(mockNodeService.hasAspect(nodeRef, ASPECT_CLASSIFIED)).thenReturn(true); - when(mockNodeService.getProperty(nodeRef, PROP_CURRENT_CLASSIFICATION)).thenReturn(secretId); - when(mockLevelManager.findLevelById(secretId)).thenReturn(secret); - - // set users security clearance - ClearanceLevel secretClearance = new ClearanceLevel(secret, "Secret"); - SecurityClearance clearance = new SecurityClearance(mock(PersonInfo.class), secretClearance); - when(mockSecurityClearanceService.getUserSecurityClearance()).thenReturn(clearance); + when(mockSecurityClearanceService.isCurrentUserClearedForClassification("Secret")).thenReturn(true); assertTrue(contentClassificationServiceImpl.hasClearance(nodeRef)); } @@ -285,7 +239,7 @@ public class ContentClassificationServiceImplUnitTest implements ClassifiedConte * Given that the node is classified * And the user has clearance less than the classification * When I ask if the user has clearance - * Then true + * Then false */ @Test public void classifiedNodeUserClearanceLess() { @@ -304,9 +258,7 @@ public class ContentClassificationServiceImplUnitTest implements ClassifiedConte when(mockLevelManager.findLevelById(secretId)).thenReturn(secret); // set users security clearance - ClearanceLevel confidentialClearance = new ClearanceLevel(confidential, "Confidential"); - SecurityClearance clearance = new SecurityClearance(mock(PersonInfo.class), confidentialClearance); - when(mockSecurityClearanceService.getUserSecurityClearance()).thenReturn(clearance); + when(mockSecurityClearanceService.isCurrentUserClearedForClassification("Secret")).thenReturn(false); assertFalse(contentClassificationServiceImpl.hasClearance(nodeRef)); } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceServiceImplUnitTest.java index f9c0804a26..05e6086780 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceServiceImplUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/SecurityClearanceServiceImplUnitTest.java @@ -22,14 +22,15 @@ import static org.alfresco.module.org_alfresco_module_rm.classification.model.Cl import static org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel.PROP_CLEARANCE_LEVEL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; 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.test.util.MockAuthenticationUtilHelper; import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; @@ -45,8 +46,6 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import com.google.common.collect.ImmutableList; - /** * Unit tests for {@link SecurityClearanceServiceImpl}. * @@ -58,13 +57,14 @@ public class SecurityClearanceServiceImplUnitTest { @InjectMocks private SecurityClearanceServiceImpl securityClearanceServiceImpl; - @Mock private AuthenticationUtil mockAuthenticationUtil; - @Mock private ClassificationLevelManager mockClassificationLevelManager; - @Mock private DictionaryService mockDictionaryService; - @Mock private NodeService mockNodeService; - @Mock private PersonService mockPersonService; - @Mock private ClassificationService mockClassificationService; - @Mock private ClearanceLevelManager mockClearanceLevelManager; + @Mock private AuthenticationUtil mockAuthenticationUtil; + @Mock private ClassificationLevelManager mockClassificationLevelManager; + @Mock private DictionaryService mockDictionaryService; + @Mock private NodeService mockNodeService; + @Mock private PersonService mockPersonService; + @Mock private ClassificationService mockClassificationService; + @Mock private ClearanceLevelManager mockClearanceLevelManager; + @Mock private ClassificationLevelComparator mockClassificationLevelComparator; @Before public void setUp() { @@ -94,11 +94,11 @@ public class SecurityClearanceServiceImplUnitTest @Test public void userWithNoClearanceGetsDefaultClearance() { final PersonInfo user1 = createMockPerson("user1", "User", "One", null); - MockAuthenticationUtilHelper.setup(mockAuthenticationUtil, user1.getUserName()); + MockAuthenticationUtilHelper.setup(mockAuthenticationUtil, user1.getUserName()); when(mockClassificationService.getUnclassifiedClassificationLevel()) .thenReturn(ClassificationLevelManager.UNCLASSIFIED); when(mockClearanceLevelManager.findLevelByClassificationLevelId(ClassificationLevelManager.UNCLASSIFIED_ID)) - .thenReturn(ClearanceLevelManager.NO_CLEARANCE); + .thenReturn(ClearanceLevelManager.NO_CLEARANCE); final SecurityClearance clearance = securityClearanceServiceImpl.getUserSecurityClearance(); @@ -109,12 +109,12 @@ public class SecurityClearanceServiceImplUnitTest /** Check that a user can have their clearance set by an authorised user. */ @Test public void setUserSecurityClearance_setClearance() { - // Create the clearance. - String topSecretId = "ClearanceId"; - ClassificationLevel level = new ClassificationLevel(topSecretId, "TopSecretKey"); - ClearanceLevel clearanceLevel = new ClearanceLevel(level, "TopSecretKey"); - when(mockClearanceLevelManager.findLevelByClassificationLevelId(topSecretId)).thenReturn(clearanceLevel); - when(mockClassificationLevelManager.getClassificationLevels()).thenReturn(ImmutableList.of(level)); + // Create the user who will have their clearance set. + String userName = "User 1"; + NodeRef personNode = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, userName); + PersonInfo personInfo = new PersonInfo(personNode, userName, "first", "last"); + when(mockPersonService.getPerson(userName, false)).thenReturn(personNode); + when(mockPersonService.getPerson(personNode)).thenReturn(personInfo); // Create the authorised user. String authorisedUserName = "authorisedUser"; @@ -123,17 +123,20 @@ public class SecurityClearanceServiceImplUnitTest PersonInfo authorisedPersonInfo = new PersonInfo(authorisedPersonNode, authorisedUserName, "first", "last"); when(mockPersonService.getPerson(authorisedUserName, false)).thenReturn(authorisedPersonNode); when(mockPersonService.getPerson(authorisedPersonNode)).thenReturn(authorisedPersonInfo); + // The current user is not system. + when(mockAuthenticationUtil.isRunAsUserTheSystemUser()).thenReturn(false); + + // Create the clearance level. + String topSecretId = "ClearanceId"; + ClassificationLevel level = new ClassificationLevel(topSecretId, "TopSecretKey"); + ClearanceLevel clearanceLevel = new ClearanceLevel(level, "TopSecretKey"); + when(mockClearanceLevelManager.findLevelByClassificationLevelId(topSecretId)).thenReturn(clearanceLevel); // The authorised user is cleared to use this clearance. when(mockNodeService.hasAspect(authorisedPersonNode, ASPECT_SECURITY_CLEARANCE)).thenReturn(true); when(mockNodeService.getProperty(authorisedPersonNode, PROP_CLEARANCE_LEVEL)).thenReturn(topSecretId); - - // Create the user who will have their clearance set. - String userName = "User 1"; - NodeRef personNode = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, userName); - PersonInfo personInfo = new PersonInfo(personNode, userName, "first", "last"); - when(mockPersonService.getPerson(userName, false)).thenReturn(personNode); - when(mockPersonService.getPerson(personNode)).thenReturn(personInfo); + // The authenticated user's clearance level is at least as secure as the level being used. + when(mockClassificationLevelComparator.compare(level, level)).thenReturn(0); // Once the user's clearance has been set then the node service is queried about it. when(mockNodeService.hasAspect(personNode, ASPECT_SECURITY_CLEARANCE)).thenReturn(true); @@ -156,13 +159,11 @@ public class SecurityClearanceServiceImplUnitTest // Create the "Top Secret" and "Confidential" clearances. String topSecretId = "TopSecretClearanceId"; ClassificationLevel topSecret = new ClassificationLevel(topSecretId, "TopSecretKey"); - ClearanceLevel topSecretClearance = new ClearanceLevel(topSecret, "TopSecretKey"); - when(mockClearanceLevelManager.findLevelByClassificationLevelId(topSecretId)).thenReturn(topSecretClearance); + when(mockClassificationLevelManager.findLevelById(topSecretId)).thenReturn(topSecret); String confidentialId = "ConfidentialClearanceId"; ClassificationLevel confidential = new ClassificationLevel(confidentialId, "ConfidentialKey"); ClearanceLevel confidentialClearance = new ClearanceLevel(confidential, "ConfidentialKey"); when(mockClearanceLevelManager.findLevelByClassificationLevelId(confidentialId)).thenReturn(confidentialClearance); - when(mockClassificationLevelManager.getClassificationLevels()).thenReturn(ImmutableList.of(topSecret, confidential)); // Create the user attempting to use the API with "Confidential" clearance. String userName = "unauthorisedUser"; @@ -175,6 +176,8 @@ public class SecurityClearanceServiceImplUnitTest // The authorised user is cleared to use this clearance. when(mockNodeService.hasAspect(personNode, ASPECT_SECURITY_CLEARANCE)).thenReturn(true); when(mockNodeService.getProperty(personNode, PROP_CLEARANCE_LEVEL)).thenReturn(confidentialId); + // The authenticated user's clearance level not high enough. + when(mockClassificationLevelComparator.compare(confidential, topSecret)).thenReturn(-1); // Create the user who will have their clearance set. String targetUserName = "Target User"; @@ -188,23 +191,66 @@ public class SecurityClearanceServiceImplUnitTest } /** - * Check that a user with no clearance is not cleared to use the "Secret" classification. + * Check that a user with "Secret" clearance is cleared to use the "Secret" classification. */ - @Test public void isClearedForClassification() + @Test public void isCurrentUserClearedForClassification_hasClearance() { - ClassificationLevel topSecret = new ClassificationLevel("1", "TopSecret"); ClassificationLevel secret = new ClassificationLevel("2", "Secret"); - ImmutableList classificationLevels = ImmutableList.of(topSecret, secret); - when(mockClassificationLevelManager.getClassificationLevels()).thenReturn(classificationLevels); + when(mockClassificationLevelManager.findLevelById("2")).thenReturn(secret); - SecurityClearance clearance = new SecurityClearance(mock(PersonInfo.class), ClearanceLevelManager.NO_CLEARANCE); + createMockPerson("Cleared", "Cleared", "Cleared", "2"); + when(mockAuthenticationUtil.getFullyAuthenticatedUser()).thenReturn("Uncleared"); + when(mockClearanceLevelManager.findLevelByClassificationLevelId("2")).thenReturn(new ClearanceLevel(secret, "Secret")); + + // The authenticated user's clearance level is high enough to view the classification. + when(mockClassificationLevelComparator.compare(secret, secret)).thenReturn(0); // Call the method under test. - boolean result = securityClearanceServiceImpl.isClearedForClassification(clearance, "2"); + boolean result = securityClearanceServiceImpl.isCurrentUserClearedForClassification("2"); + + assertTrue("A user with 'Secret' clearance should be able to access the 'Secret' classification.", result); + } + + /** + * Check that a user with no clearance is not cleared to use the "Secret" classification. + */ + @Test public void isCurrentUserClearedForClassification_noClearance() + { + ClassificationLevel secret = new ClassificationLevel("2", "Secret"); + when(mockClassificationLevelManager.findLevelById("2")).thenReturn(secret); + + createMockPerson("Uncleared", "Uncleared", "Uncleared", ClassificationLevelManager.UNCLASSIFIED_ID); + when(mockAuthenticationUtil.getFullyAuthenticatedUser()).thenReturn("Uncleared"); + when(mockClearanceLevelManager.findLevelByClassificationLevelId(ClassificationLevelManager.UNCLASSIFIED_ID)).thenReturn(ClearanceLevelManager.NO_CLEARANCE); + + // The authenticated user's clearance level not high enough. + when(mockClassificationLevelComparator.compare(ClassificationLevelManager.UNCLASSIFIED, secret)).thenReturn(-1); + + // Call the method under test. + boolean result = securityClearanceServiceImpl.isCurrentUserClearedForClassification("2"); assertFalse("A user with no clearance should not be able to access the 'Secret' classification.", result); } + /** + * Check that a user with "Top Secret" clearance is not cleared to use a non-existent classification. + */ + @Test public void isCurrentUserClearedForClassification_classificationNotFound() + { + ClassificationLevel topSecret = new ClassificationLevel("1", "TopSecret"); + createMockPerson("Uncleared", "Uncleared", "Uncleared", "1"); + when(mockAuthenticationUtil.getFullyAuthenticatedUser()).thenReturn("Uncleared"); + when(mockClearanceLevelManager.findLevelByClassificationLevelId("1")).thenReturn(new ClearanceLevel(topSecret, "TopSecret")); + // Set up the made up classification. + String madeUpId = "Made Up Id"; + when(mockClassificationLevelManager.findLevelById(madeUpId)).thenThrow(new LevelIdNotFound(madeUpId)); + + // Call the method under test. + boolean result = securityClearanceServiceImpl.isCurrentUserClearedForClassification(madeUpId); + + assertFalse("No one should be cleared to use a fictional classification.", result); + } + /** * Check that all levels are returned */