X-Git-Url: https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blobdiff_plain/cefb81d6f68c99e6b6605731d8c8b3cfe49b91b5..4794837a93289f3b8e8256f6a94577c5278ba666:/cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/service/SecurityTest.java diff --git a/cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/service/SecurityTest.java b/cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/service/SecurityTest.java index 4c7e5ea70c..9cf3322040 100644 --- a/cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/service/SecurityTest.java +++ b/cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/service/SecurityTest.java @@ -9,9 +9,11 @@ package eu.etaxonomy.cdm.api.service; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.Collection; +import java.util.List; import java.util.Set; import java.util.UUID; @@ -25,9 +27,7 @@ import org.junit.Test; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.authentication.dao.ReflectionSaltSource; import org.springframework.security.authentication.dao.SaltSource; -import org.springframework.security.authentication.encoding.Md5PasswordEncoder; import org.springframework.security.authentication.encoding.PasswordEncoder; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; @@ -42,7 +42,6 @@ import org.unitils.spring.annotation.SpringBeanByType; import eu.etaxonomy.cdm.database.EvaluationFailedException; import eu.etaxonomy.cdm.model.common.User; import eu.etaxonomy.cdm.model.description.DescriptionElementBase; -import eu.etaxonomy.cdm.model.description.Distribution; import eu.etaxonomy.cdm.model.description.Feature; import eu.etaxonomy.cdm.model.description.TaxonDescription; import eu.etaxonomy.cdm.model.description.TextData; @@ -53,6 +52,8 @@ import eu.etaxonomy.cdm.model.taxon.Taxon; import eu.etaxonomy.cdm.model.taxon.TaxonBase; import eu.etaxonomy.cdm.model.taxon.TaxonNode; import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionEvaluator; +import eu.etaxonomy.cdm.persistence.hibernate.permission.Operation; +import eu.etaxonomy.cdm.persistence.query.MatchMode; import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTestWithSecurity; @@ -63,6 +64,8 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ private static final UUID UUID_ACHERONTIA_STYX = UUID.fromString("7b8b5cb3-37ba-4dba-91ac-4c6ffd6ac331"); + private static final UUID UUID_LACTUCA = UUID.fromString("b2b007a4-9c8c-43a1-8da4-20ed85464cf2"); + private static final UUID PART_EDITOR_UUID = UUID.fromString("38a251bd-0ba4-426f-8fcb-5c09560749a7"); private static final String PASSWORD_TAXON_EDITOR = "test2"; @@ -123,12 +126,13 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ private UsernamePasswordAuthenticationToken tokenForTaxonomist; + private UsernamePasswordAuthenticationToken tokenForUserManager; + @Before public void setUp(){ /* User 'admin': - ROLE_ADMIN - - ALL.ADMIN - TAXONBASE.READ - TAXONBASE.CREATE - TAXONBASE.DELETE @@ -136,6 +140,15 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ */ tokenForAdmin = new UsernamePasswordAuthenticationToken("admin", PASSWORD_ADMIN); + /* User 'userManager': + - ROLE_ADMIN + - TAXONBASE.READ + - TAXONBASE.CREATE + - TAXONBASE.DELETE + - TAXONBASE.UPDATE + */ + tokenForUserManager = new UsernamePasswordAuthenticationToken("userManager", PASSWORD_ADMIN); + /* User 'taxonEditor': - TAXONBASE.CREATE - TAXONBASE.UPDATE @@ -166,6 +179,7 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ tokenForTaxonomist = new UsernamePasswordAuthenticationToken("taxonomist", "test4"); } + /** * no assertions in this test, since it is only used to create password hashes for test data */ @@ -173,26 +187,116 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ public void testEncryptPassword(){ String password = PASSWORD_ADMIN; - User user = User.NewInstance("admin", ""); + User user = User.NewInstance("userManager", ""); Object salt = this.saltSource.getSalt(user); String passwordEncrypted = passwordEncoder.encodePassword(password, salt); logger.info("encrypted password: " + passwordEncrypted ); } + @Test + @DataSet + public void testHasPermission(){ + + Taxon taxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()),null); + + authentication = authenticationManager.authenticate(tokenForTaxonomist); + boolean hasPermission = permissionEvaluator.hasPermission(authentication, taxon, Operation.UPDATE); + assertTrue(hasPermission); + + authentication = authenticationManager.authenticate(tokenForDescriptionEditor); + hasPermission = permissionEvaluator.hasPermission(authentication, taxon, Operation.UPDATE); + assertFalse(hasPermission); + } + + @Test + @DataSet + public void testListByUsernameAllow(){ + + authentication = authenticationManager.authenticate(tokenForTaxonomist); + SecurityContext context = SecurityContextHolder.getContext(); + context.setAuthentication(authentication); + + List userList = userService.listByUsername("Editor", MatchMode.ANYWHERE, null, null, 0, null, null); + Assert.assertTrue("The user list must have elements", userList.size() > 0 ); + } + + @Test + @DataSet + public void testUserService_CreateDeny(){ + + authentication = authenticationManager.authenticate(tokenForTaxonomist); + SecurityContext context = SecurityContextHolder.getContext(); + context.setAuthentication(authentication); + + RuntimeException exception = null; + try { + userService.createUser(User.NewInstance("new guy", "alkjdsfalkj")); + commitAndStartNewTransaction(null); + } catch (AccessDeniedException e){ + logger.debug("Expected failure of evaluation.", e); + exception = e; + } catch (RuntimeException e){ + exception = findThrowableOfTypeIn(EvaluationFailedException.class, e); + logger.debug("Expected failure of evaluation.", exception); + } finally { + // needed in case saveOrUpdate was interrupted by the RuntimeException + // commitAndStartNewTransaction() would raise an UnexpectedRollbackException + endTransaction(); + startNewTransaction(); + } + Assert.assertNotNull("Must fail here!", exception); + + } + + @Test + @DataSet + public void testUserService_CreateAllow(){ + + authentication = authenticationManager.authenticate(tokenForUserManager); + SecurityContext context = SecurityContextHolder.getContext(); + context.setAuthentication(authentication); + + RuntimeException exception = null; + try { + userService.createUser(User.NewInstance("new guy", "alkjdsfalkj")); + commitAndStartNewTransaction(null); + } catch (AccessDeniedException e){ + logger.error("Unexpected failure of evaluation.", e); + exception = e; + } catch (RuntimeException e){ + exception = findThrowableOfTypeIn(EvaluationFailedException.class, e); + logger.error("unexpected failure of evaluation.", exception); + } finally { + // needed in case saveOrUpdate was interrupted by the RuntimeException + // commitAndStartNewTransaction() would raise an UnexpectedRollbackException + endTransaction(); + startNewTransaction(); + } + Assert.assertNull("Must not fail here!", exception); + + } + + + @Test + @DataSet + @Ignore // FIXME http://dev.e-taxonomy.eu/trac/ticket/3098 + public void testHasPermissions(){ + + Taxon taxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()),null); + + authentication = authenticationManager.authenticate(tokenForTaxonomist); + boolean hasPermission = permissionEvaluator.hasPermission(authentication, taxon, Operation.ALL); + assertTrue(hasPermission); + } + + /** * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#saveTaxon(eu.etaxonomy.cdm.model.taxon.TaxonBase)}. */ @Test public final void testSaveTaxon() { - /* - Md5PasswordEncoder encoder =new Md5PasswordEncoder(); - ReflectionSaltSource saltSource = new ReflectionSaltSource(); - saltSource.setUserPropertyToUse("getUsername"); - User user = User.NewInstance("partEditor", "test4"); - System.err.println(encoder.encodePassword("test4", saltSource.getSalt(user))); - */ authentication = authenticationManager.authenticate(tokenForAdmin); SecurityContext context = SecurityContextHolder.getContext(); context.setAuthentication(authentication); @@ -214,7 +318,6 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ } @Test - @Ignore //FIXME no need to test this, no access controll needed for userService.changePassword public void testChangeOwnPassword(){ SecurityContext context = SecurityContextHolder.getContext(); @@ -234,24 +337,25 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ } @Test - public void testChangeOthersPassword(){ + public void testChangeOthersPasswordAllow(){ SecurityContext context = SecurityContextHolder.getContext(); + RuntimeException exception = null; + // (1) authenticate as admin authentication = authenticationManager.authenticate(tokenForAdmin); context.setAuthentication(authentication); - RuntimeException exception = null; try{ userService.changePasswordForUser("taxonomist", "zuaisd"); commitAndStartNewTransaction(null); } catch (AccessDeniedException e){ - logger.debug("Unexpected failure of evaluation.", e); + logger.error("Unexpected failure of evaluation.", e); exception = e; } catch (RuntimeException e){ exception = findThrowableOfTypeIn(EvaluationFailedException.class, e); - logger.debug("Unexpected failure of evaluation.", exception); + logger.error("Unexpected failure of evaluation.", exception); } finally { // needed in case saveOrUpdate was interrupted by the RuntimeException // commitAndStartNewTransaction() would raise an UnexpectedRollbackException @@ -263,6 +367,13 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ // ok, now try authenticating taxonomist with new password UsernamePasswordAuthenticationToken newToken = new UsernamePasswordAuthenticationToken("taxonomist", "zuaisd"); authentication = authenticationManager.authenticate(newToken); + } + + @Test + public void testChangeOthersPasswordDeny(){ + + SecurityContext context = SecurityContextHolder.getContext(); + RuntimeException exception = null; // (2) authenticate as under privileged user - not an admin !!! authentication = authenticationManager.authenticate(tokenForDescriptionEditor); @@ -270,7 +381,7 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ // check test preconditions user name and authorities Assert.assertEquals("descriptionEditor", context.getAuthentication().getName()); - Collection authorities = context.getAuthentication().getAuthorities(); + Collection authorities = context.getAuthentication().getAuthorities(); for(GrantedAuthority authority: authorities){ // role prefix 'ROLE_' is defined in org.springframework.security.access.vote.RoleVoter !!! Assert.assertNotSame("user must not have authority 'ROLE_ADMIN'", "ROLE_ADMIN", authority.getAuthority()); @@ -314,23 +425,27 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ } + /** + * test with admin account - should succeed + */ @Test - public final void testSaveOrUpdateTaxon() { + public final void testTaxonSaveOrUpdateAllow_1() { + SecurityContext context = SecurityContextHolder.getContext(); - // 1) test with admin account - should succeed authentication = authenticationManager.authenticate(tokenForAdmin); context.setAuthentication(authentication); + RuntimeException securityException= null; TaxonBase taxon = taxonService.load(UUID_ACHERONTIA_STYX); + Assert.assertFalse(taxon.isDoubtful()); taxon.setDoubtful(true); - RuntimeException securityException= null; try{ taxonService.saveOrUpdate(taxon); commitAndStartNewTransaction(null); } catch (RuntimeException e){ securityException = findSecurityRuntimeException(e); - logger.debug("Unexpected failure of evaluation.", securityException); + logger.error("Unexpected failure of evaluation.", e); } finally { // needed in case saveOrUpdate was interrupted by the RuntimeException // commitAndStartNewTransaction() would raise an UnexpectedRollbackException @@ -341,20 +456,32 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ // reload taxon taxon = taxonService.load(UUID_ACHERONTIA_STYX); Assert.assertTrue("The change must be persited", taxon.isDoubtful()); + } - // 2) test with taxonEditor account - should succeed + /** + * test with taxonEditor account - should succeed + */ + @Test + public final void testTaxonSaveOrUpdateAllow_2() { + + + RuntimeException securityException= null; + SecurityContext context = SecurityContextHolder.getContext(); + + // taxonEditor account - should succeed authentication = authenticationManager.authenticate(tokenForTaxonEditor); + context.setAuthentication(authentication); - taxon = taxonService.load(UUID_ACHERONTIA_STYX); - taxon.setDoubtful(false); - securityException= null; + TaxonBase taxon = taxonService.load(UUID_ACHERONTIA_STYX); + Assert.assertFalse(taxon.isDoubtful()); + taxon.setDoubtful(true); try{ taxonService.saveOrUpdate(taxon); commitAndStartNewTransaction(null); } catch (RuntimeException e){ securityException = findSecurityRuntimeException(e); - logger.debug("Unexpected failure of evaluation.", securityException); + logger.error("Unexpected failure of evaluation.", e); } finally { // needed in case saveOrUpdate was interrupted by the RuntimeException // commitAndStartNewTransaction() would raise an UnexpectedRollbackException @@ -364,19 +491,145 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException); // reload taxon taxon = taxonService.load(UUID_ACHERONTIA_STYX); - Assert.assertFalse("The change must be persited", taxon.isDoubtful()); + Assert.assertTrue("The change must be persited", taxon.isDoubtful()); + } - // 3) test with tokenForDescriptionEditor account - should fail -// authentication = authenticationManager.authenticate(tokenForTaxonEditor); -// context.setAuthentication(authentication); -// taxon = taxonService.load(uuid); -// -// taxon.setDoubtful(true); -// taxonService.saveOrUpdate(taxon); -// commitAndStartNewTransaction(null); + /** + * test with tokenForDescriptionEditor account - should fail + */ + @Test + public final void testTaxonSaveOrUpdateDeny_2() { + + SecurityContext context = SecurityContextHolder.getContext(); + RuntimeException securityException = null; + + authentication = authenticationManager.authenticate(tokenForDescriptionEditor); + context.setAuthentication(authentication); + + TaxonBase taxon = taxonService.load(UUID_ACHERONTIA_STYX); + + Assert.assertFalse(taxon.isDoubtful()); + taxon.setDoubtful(true); + try { + taxonService.saveOrUpdate(taxon); + commitAndStartNewTransaction(null); + } catch (RuntimeException e){ + securityException = findSecurityRuntimeException(e); + logger.debug("Expected failure of evaluation.", securityException); + } finally { + // needed in case saveOrUpdate was interrupted by the RuntimeException + // commitAndStartNewTransaction() would raise an UnexpectedRollbackException + endTransaction(); + startNewTransaction(); + } + Assert.assertNotNull("evaluation must fail since the user is not permitted", securityException); + // reload taxon + taxon = taxonService.load(UUID_ACHERONTIA_STYX); + Assert.assertFalse("The change must not be persited", taxon.isDoubtful()); } + /** + * test with admin account - should succeed + */ + @Test + public final void testTaxonDeleteAllow_1() { + + SecurityContext context = SecurityContextHolder.getContext(); + + authentication = authenticationManager.authenticate(tokenForAdmin); + context.setAuthentication(authentication); + RuntimeException securityException= null; + + TaxonBase taxon = taxonService.load(UUID_LACTUCA); + try{ + taxonService.delete(taxon); + commitAndStartNewTransaction(null); + } catch (RuntimeException e){ + securityException = findSecurityRuntimeException(e); + logger.error("Unexpected failure of evaluation.", e); + } finally { + // needed in case saveOrUpdate was interrupted by the RuntimeException + // commitAndStartNewTransaction() would raise an UnexpectedRollbackException + endTransaction(); + startNewTransaction(); + } + Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException); + // reload taxon + taxon = taxonService.load(UUID_LACTUCA); + Assert.assertNull("The taxon must be deleted", taxon); + } + + /** + * test with admin account - should succeed + */ + @Test + @Ignore + /*FIXME fails due to org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations) + * see ticket #3086 + */ + public final void testTaxonDeleteAllow_2() { + + SecurityContext context = SecurityContextHolder.getContext(); + + authentication = authenticationManager.authenticate(tokenForAdmin); + context.setAuthentication(authentication); + RuntimeException securityException= null; + + TaxonBase taxon = taxonService.load(UUID_ACHERONTINII); + try{ + taxonService.delete(taxon); + commitAndStartNewTransaction(null); + } catch (RuntimeException e){ + securityException = findSecurityRuntimeException(e); + logger.error("Unexpected failure of evaluation.", e); + } finally { + // needed in case saveOrUpdate was interrupted by the RuntimeException + // commitAndStartNewTransaction() would raise an UnexpectedRollbackException + endTransaction(); + startNewTransaction(); + } + Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException); + // reload taxon + taxon = taxonService.load(UUID_ACHERONTINII); + Assert.assertNull("The taxon must be deleted", taxon); + } + + + /** + * test with tokenForDescriptionEditor account - should fail + */ + @Test + public final void testTaxonDeleteDeny() { + + SecurityContext context = SecurityContextHolder.getContext(); + RuntimeException securityException = null; + + authentication = authenticationManager.authenticate(tokenForDescriptionEditor); + context.setAuthentication(authentication); + + TaxonBase taxon = taxonService.load(UUID_LACTUCA); + + try { + taxonService.delete(taxon); + commitAndStartNewTransaction(null); + } catch (RuntimeException e){ + securityException = findSecurityRuntimeException(e); + logger.debug("Expected failure of evaluation.", securityException); + } finally { + // needed in case saveOrUpdate was interrupted by the RuntimeException + // commitAndStartNewTransaction() would raise an UnexpectedRollbackException + endTransaction(); + startNewTransaction(); + } + + Assert.assertNotNull("evaluation must fail since the user is not permitted", securityException); + // reload taxon + taxon = taxonService.load(UUID_LACTUCA); + Assert.assertNotNull("The change must still exist", taxon); + } + + @Test @Ignore //FIXME: adding taxa to a description must be protected at the side of the Description itself!! // => protecting method TaxonDescription.setTaxon() ? @@ -415,27 +668,29 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ @Test public void testCreateDescriptionWithElement(){ - authentication = authenticationManager.authenticate(tokenForDescriptionEditor); + SecurityContext context = SecurityContextHolder.getContext(); + authentication = authenticationManager.authenticate(tokenForDescriptionEditor); context.setAuthentication(authentication); + TaxonDescription description = null; + RuntimeException securityException = null; Taxon taxon = (Taxon)taxonService.load(UUID_ACHERONTINII); Assert.assertTrue("taxon must not yet have descriptions", taxon.getDescriptions().size() == 0); - TaxonDescription description = null; // 1) test for failure - description element but no feature description = TaxonDescription.NewInstance(taxon); DescriptionElementBase textdataNoFeature = TextData.NewInstance(); description.addElement(textdataNoFeature); - RuntimeException securityException = null; assertTrue(permissionEvaluator.hasPermission(authentication, description, "UPDATE")); try{ descriptionService.saveOrUpdate(description); commitAndStartNewTransaction(null); } catch (RuntimeException e){ securityException = findSecurityRuntimeException(e); + logger.error("RuntimeException caught"); logger.debug("Expected failure of evaluation.", securityException); } finally { // needed in case saveOrUpdate was interrupted by the RuntimeException @@ -449,6 +704,20 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ Set descriptions = taxon.getDescriptions(); assertTrue("taxon must not have any description", descriptions.size() == 0); + } + + @Test + public void testCreateDescriptionWithElementDeny_1(){ + + SecurityContext context = SecurityContextHolder.getContext(); + authentication = authenticationManager.authenticate(tokenForDescriptionEditor); + context.setAuthentication(authentication); + + TaxonDescription description = null; + RuntimeException securityException = null; + Taxon taxon = (Taxon)taxonService.load(UUID_ACHERONTINII); + Assert.assertTrue("taxon must not yet have descriptions", taxon.getDescriptions().size() == 0); + // 2) test for failure - description element but not granted feature description = TaxonDescription.NewInstance(taxon); DescriptionElementBase descriptionText = TextData.NewInstance(Feature.DESCRIPTION()); @@ -471,9 +740,23 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ Assert.assertNotNull("evaluation should fail", securityException); taxon = (Taxon)taxonService.load(UUID_ACHERONTINII); - descriptions = taxon.getDescriptions(); + Set descriptions = taxon.getDescriptions(); assertTrue("taxon must not have any description", descriptions.size() == 0); + } + + @Test + public void testCreateDescriptionWithElementDeny_2(){ + + SecurityContext context = SecurityContextHolder.getContext(); + authentication = authenticationManager.authenticate(tokenForDescriptionEditor); + context.setAuthentication(authentication); + + TaxonDescription description = null; + RuntimeException securityException = null; + Taxon taxon = (Taxon)taxonService.load(UUID_ACHERONTINII); + Assert.assertTrue("taxon must not yet have descriptions", taxon.getDescriptions().size() == 0); + // 3) test for failure description = TaxonDescription.NewInstance(taxon); DescriptionElementBase ecologyText = TextData.NewInstance(Feature.ECOLOGY()); @@ -486,7 +769,7 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ commitAndStartNewTransaction(null); } catch (RuntimeException e){ securityException = findSecurityRuntimeException(e); - logger.debug("Unexpected failure of evaluation.", e); + logger.error("Unexpected failure of evaluation.", e); } finally { // needed in case saveOrUpdate was interrupted by the RuntimeException // commitAndStartNewTransaction() would raise an UnexpectedRollbackException @@ -496,22 +779,21 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException); taxon = (Taxon)taxonService.load(UUID_ACHERONTINII); - descriptions = taxon.getDescriptions(); + Set descriptions = taxon.getDescriptions(); assertTrue("taxon must now have one description", descriptions.size() == 1); assertTrue("description should have one description element", descriptions.iterator().next().getElements().size() == 1); - } @Test - public void testSaveSynonym(){ + public void testSaveSynonymAllow(){ SecurityContext context = SecurityContextHolder.getContext(); + RuntimeException securityException = null; // 1) test for success authentication = authenticationManager.authenticate(tokenForTaxonomist); context.setAuthentication(authentication); - RuntimeException securityException = null; Synonym syn = Synonym.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null); UUID synUuid = UUID.randomUUID(); syn.setUuid(synUuid); @@ -521,7 +803,7 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ commitAndStartNewTransaction(null); } catch (RuntimeException e){ securityException = findSecurityRuntimeException(e); - logger.debug("Unexpected failure of evaluation.", e); + logger.error("Unexpected failure of evaluation.", e); } finally { // needed in case saveOrUpdate was interrupted by the RuntimeException // commitAndStartNewTransaction() would raise an UnexpectedRollbackException @@ -530,13 +812,19 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ } Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException); Assert.assertNotNull("The new Synonym must be persited", taxonService.find(synUuid)); + } + + @Test + public void testSaveSynonymDenial(){ + SecurityContext context = SecurityContextHolder.getContext(); + RuntimeException securityException = null; // 2) test for denial authentication = authenticationManager.authenticate(tokenForDescriptionEditor); context.setAuthentication(authentication); securityException = null; - syn = Synonym.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null); - synUuid = syn.getUuid(); + Synonym syn = Synonym.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null); + UUID synUuid = syn.getUuid(); try{ taxonService.saveOrUpdate(syn); logger.debug("will commit ..."); @@ -556,23 +844,14 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ } @Test - public void testEditPartOfClassification(){ - /* - * the user 'partEditor' has the following authorities: - * - * - TAXONNODE.CREATE{20c8f083-5870-4cbd-bf56-c5b2b98ab6a7} - * - TAXONNODE.UPDATE{20c8f083-5870-4cbd-bf56-c5b2b98ab6a7} - * - * that is 'partEditor' is granted to edit the subtree of - * which ACHERONTIA_NODE_UUID [20c8f083-5870-4cbd-bf56-c5b2b98ab6a7] is the root node. - */ + public void testEditPartOfClassificationAllow(){ authentication = authenticationManager.authenticate(tokenForPartEditor); SecurityContext context = SecurityContextHolder.getContext(); context.setAuthentication(authentication); + RuntimeException securityException = null; // test for success - RuntimeException securityException = null; TaxonNode acherontia_node = taxonNodeService.load(ACHERONTIA_NODE_UUID); long numOfChildNodes = acherontia_node.getChildNodes().size(); TaxonNode childNode = acherontia_node.addChildTaxon(Taxon.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null), null, null, null); @@ -582,7 +861,7 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ commitAndStartNewTransaction(null); } catch (RuntimeException e){ securityException = findSecurityRuntimeException(e); - logger.debug("Unexpected failure of evaluation.", securityException); + logger.error("Unexpected failure of evaluation.", securityException); } finally { // needed in case saveOrUpdate was interrupted by the RuntimeException // commitAndStartNewTransaction() would raise an UnexpectedRollbackException @@ -593,11 +872,20 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ acherontia_node = taxonNodeService.load(ACHERONTIA_NODE_UUID); Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException); Assert.assertEquals("the acherontia_node must now have one more child node ", numOfChildNodes + 1 , acherontia_node.getChildNodes().size()); + } + + @Test + public void testEditPartOfClassificationDeny(){ + + authentication = authenticationManager.authenticate(tokenForPartEditor); + SecurityContext context = SecurityContextHolder.getContext(); + context.setAuthentication(authentication); + RuntimeException securityException = null; // test for denial securityException = null; TaxonNode acherontiini_node = taxonNodeService.load(ACHERONTIINI_NODE_UUID); - numOfChildNodes = acherontiini_node.getCountChildren(); + int numOfChildNodes = acherontiini_node.getCountChildren(); acherontiini_node.addChildTaxon(Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()), null), null, null, null); try{ @@ -620,16 +908,4 @@ public class SecurityTest extends CdmTransactionalIntegrationTestWithSecurity{ } - public static void main(String[] args){ - Md5PasswordEncoder encoder =new Md5PasswordEncoder(); - - ReflectionSaltSource saltSource = new ReflectionSaltSource(); - saltSource.setUserPropertyToUse("getUsername"); - User user = User.NewInstance("taxonomist", "test4"); - System.err.println(encoder.encodePassword("test4", saltSource.getSalt(user))); - } - - - - }