2 * Copyright (C) 2011 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.api
.service
;
11 import static org
.junit
.Assert
.assertEquals
;
12 import static org
.junit
.Assert
.assertFalse
;
13 import static org
.junit
.Assert
.assertTrue
;
15 import java
.io
.FileNotFoundException
;
16 import java
.util
.Collection
;
17 import java
.util
.EnumSet
;
18 import java
.util
.HashSet
;
19 import java
.util
.List
;
21 import java
.util
.UUID
;
23 import javax
.sql
.DataSource
;
25 import org
.apache
.log4j
.Logger
;
26 import org
.junit
.Assert
;
27 import org
.junit
.Ignore
;
28 import org
.junit
.Test
;
29 import org
.springframework
.security
.access
.AccessDeniedException
;
30 import org
.springframework
.security
.authentication
.AuthenticationManager
;
31 import org
.springframework
.security
.authentication
.UsernamePasswordAuthenticationToken
;
32 import org
.springframework
.security
.authentication
.dao
.SaltSource
;
33 import org
.springframework
.security
.authentication
.encoding
.PasswordEncoder
;
34 import org
.springframework
.security
.core
.Authentication
;
35 import org
.springframework
.security
.core
.GrantedAuthority
;
36 import org
.springframework
.security
.core
.context
.SecurityContext
;
37 import org
.springframework
.security
.core
.context
.SecurityContextHolder
;
38 import org
.springframework
.transaction
.PlatformTransactionManager
;
39 import org
.unitils
.database
.annotations
.TestDataSource
;
40 import org
.unitils
.dbunit
.annotation
.DataSet
;
41 import org
.unitils
.spring
.annotation
.SpringBean
;
42 import org
.unitils
.spring
.annotation
.SpringBeanByType
;
44 import sun
.security
.provider
.PolicyParser
.ParsingException
;
45 import eu
.etaxonomy
.cdm
.api
.service
.DeleteResult
.DeleteStatus
;
46 import eu
.etaxonomy
.cdm
.api
.service
.exception
.DataChangeNoRollbackException
;
47 import eu
.etaxonomy
.cdm
.api
.service
.exception
.ReferencedObjectUndeletableException
;
48 import eu
.etaxonomy
.cdm
.database
.PermissionDeniedException
;
49 import eu
.etaxonomy
.cdm
.model
.common
.GrantedAuthorityImpl
;
50 import eu
.etaxonomy
.cdm
.model
.common
.User
;
51 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
52 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
53 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
54 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
55 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
56 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
57 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
58 import eu
.etaxonomy
.cdm
.model
.name
.ZoologicalName
;
59 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
60 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
61 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
62 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
63 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
64 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
65 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
66 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
67 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
68 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CdmAuthority
;
69 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CdmPermissionClass
;
70 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CdmPermissionEvaluator
;
71 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.Operation
;
72 import eu
.etaxonomy
.cdm
.persistence
.query
.MatchMode
;
76 public class SecurityTest
extends AbstractSecurityTestBase
{
79 private static final Logger logger
= Logger
.getLogger(SecurityTest
.class);
82 private ITaxonService taxonService
;
85 private INameService nameService
;
88 private IReferenceService referenceService
;
91 private ITaxonNodeService taxonNodeService
;
94 private IDescriptionService descriptionService
;
97 private IUserService userService
;
100 private IClassificationService classificationService
;
103 private AuthenticationManager authenticationManager
;
106 private SaltSource saltSource
;
109 private PasswordEncoder passwordEncoder
;
111 @SpringBean("cdmPermissionEvaluator")
112 private CdmPermissionEvaluator permissionEvaluator
;
115 protected DataSource dataSource
;
117 private Authentication authentication
;
121 * no assertions in this test, since it is only used to create password hashes for test data
124 public void testEncryptPassword(){
126 String password
= PASSWORD_ADMIN
;
127 User user
= User
.NewInstance("userManager", "");
129 Object salt
= this.saltSource
.getSalt(user
);
130 String passwordEncrypted
= passwordEncoder
.encodePassword(password
, salt
);
131 logger
.info("encrypted password: " + passwordEncrypted
);
136 public void testHasPermission(){
138 Taxon taxon
= Taxon
.NewInstance(BotanicalName
.NewInstance(Rank
.GENUS()),null);
140 authentication
= authenticationManager
.authenticate(tokenForTaxonomist
);
141 boolean hasPermission
= permissionEvaluator
.hasPermission(authentication
, taxon
, Operation
.UPDATE
);
142 assertTrue(hasPermission
);
144 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
145 hasPermission
= permissionEvaluator
.hasPermission(authentication
, taxon
, Operation
.UPDATE
);
146 assertFalse(hasPermission
);
151 public void testListByUsernameAllow(){
153 authentication
= authenticationManager
.authenticate(tokenForTaxonomist
);
154 SecurityContext context
= SecurityContextHolder
.getContext();
155 context
.setAuthentication(authentication
);
157 List
<User
> userList
= userService
.listByUsername("Editor", MatchMode
.ANYWHERE
, null, null, 0, null, null);
158 Assert
.assertTrue("The user list must have elements", userList
.size() > 0 );
163 public void testUserService_CreateDeny(){
165 authentication
= authenticationManager
.authenticate(tokenForTaxonomist
);
166 SecurityContext context
= SecurityContextHolder
.getContext();
167 context
.setAuthentication(authentication
);
169 RuntimeException exception
= null;
171 userService
.createUser(User
.NewInstance("new guy", "alkjdsfalkj"));
172 commitAndStartNewTransaction(null);
173 } catch (AccessDeniedException e
){
174 logger
.debug("Expected failure of evaluation.", e
);
176 } catch (RuntimeException e
){
177 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
178 logger
.debug("Expected failure of evaluation.", e
);
180 // needed in case saveOrUpdate was interrupted by the RuntimeException
181 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
183 startNewTransaction();
185 Assert
.assertNotNull("Must fail here!", exception
);
191 public void testUserService_CreateAllow(){
193 authentication
= authenticationManager
.authenticate(tokenForUserManager
);
194 SecurityContext context
= SecurityContextHolder
.getContext();
195 context
.setAuthentication(authentication
);
197 RuntimeException exception
= null;
199 userService
.createUser(User
.NewInstance("new guy", "alkjdsfalkj"));
200 commitAndStartNewTransaction(null);
201 } catch (AccessDeniedException e
){
202 logger
.error("Unexpected failure of evaluation.", e
);
204 } catch (RuntimeException e
){
205 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
206 logger
.error("unexpected failure of evaluation.", exception
);
208 // needed in case saveOrUpdate was interrupted by the RuntimeException
209 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
211 startNewTransaction();
213 Assert
.assertNull("Must not fail here!", exception
);
220 @Ignore // FIXME http://dev.e-taxonomy.eu/trac/ticket/3098
221 public void testHasPermissions(){
223 Taxon taxon
= Taxon
.NewInstance(BotanicalName
.NewInstance(Rank
.GENUS()),null);
225 authentication
= authenticationManager
.authenticate(tokenForTaxonomist
);
226 boolean hasPermission
= permissionEvaluator
.hasPermission(authentication
, taxon
, Operation
.ALL
);
227 assertTrue(hasPermission
);
232 * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#saveTaxon(eu.etaxonomy.cdm.model.taxon.TaxonBase)}.
235 public final void testSaveTaxon() {
237 authentication
= authenticationManager
.authenticate(tokenForAdmin
);
238 SecurityContext context
= SecurityContextHolder
.getContext();
239 context
.setAuthentication(authentication
);
241 Taxon expectedTaxon
= Taxon
.NewInstance(BotanicalName
.NewInstance(Rank
.SPECIES()), null);
242 expectedTaxon
.getName().setTitleCache("Newby admin", true);
243 UUID uuid
= taxonService
.save(expectedTaxon
);
244 commitAndStartNewTransaction(null);
245 TaxonBase
<?
> actualTaxon
= taxonService
.load(uuid
);
246 assertEquals(expectedTaxon
, actualTaxon
);
248 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
249 context
= SecurityContextHolder
.getContext();
250 context
.setAuthentication(authentication
);
251 expectedTaxon
= Taxon
.NewInstance(BotanicalName
.NewInstance(Rank
.GENUS()), null);
252 expectedTaxon
.getName().setTitleCache("Newby taxonEditor", true);
253 uuid
= taxonService
.saveOrUpdate(expectedTaxon
);
254 commitAndStartNewTransaction(null);
255 actualTaxon
= taxonService
.load(uuid
);
256 assertEquals(expectedTaxon
, actualTaxon
);
261 public final void testSaveNameAllow() {
263 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
264 SecurityContext context
= SecurityContextHolder
.getContext();
265 context
.setAuthentication(authentication
);
267 ZoologicalName newName
= ZoologicalName
.NewInstance(Rank
.SPECIES());
268 newName
.setTitleCache("Newby taxonEditor", true);
269 UUID uuid
= nameService
.saveOrUpdate(newName
);
270 commitAndStartNewTransaction(null);
271 TaxonNameBase savedName
= nameService
.load(uuid
);
272 assertEquals(newName
, savedName
);
277 public final void testReuseNameAllow() {
279 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
280 SecurityContext context
= SecurityContextHolder
.getContext();
281 context
.setAuthentication(authentication
);
283 TaxonBase taxon
= taxonService
.find(UUID_ACHERONTIA_STYX
);
284 TaxonNameBase n_acherontia_thetis
= taxon
.getName();
286 Taxon newTaxon
= Taxon
.NewInstance(n_acherontia_thetis
, ReferenceFactory
.newGeneric());
287 Exception exception
= null;
289 UUID uuid
= taxonService
.save(newTaxon
);
290 commitAndStartNewTransaction(null);
291 } catch (AccessDeniedException e
){
292 logger
.error("Unexpected failure of evaluation.", e
);
294 } catch (RuntimeException e
){
295 logger
.error("Unexpected failure of evaluation.", e
);
296 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
298 // needed in case saveOrUpdate was interrupted by the RuntimeException
299 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
301 startNewTransaction();
303 Assert
.assertNull("must not fail here!", exception
);
307 public final void testMakeTaxonNodeASynonymOfAnotherTaxonNodeAllow_1() {
309 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
310 SecurityContext context
= SecurityContextHolder
.getContext();
311 context
.setAuthentication(authentication
);
313 Reference book
= referenceService
.load(BOOK1_UUID
);
315 TaxonNode n_acherontia_styx
= taxonNodeService
.find(ACHERONTIA_STYX_NODE_UUID
);
316 TaxonNode n_acherontia_lachersis
= taxonNodeService
.find(ACHERONTIA_LACHESIS_NODE_UUID
);
318 Exception exception
= null;
320 taxonNodeService
.makeTaxonNodeASynonymOfAnotherTaxonNode(n_acherontia_styx
, n_acherontia_lachersis
, SynonymRelationshipType
.HETEROTYPIC_SYNONYM_OF(), book
, "33");
321 commitAndStartNewTransaction(null);
322 } catch (AccessDeniedException e
){
323 logger
.error("Unexpected failure of evaluation.", e
);
325 } catch (RuntimeException e
){
326 logger
.error("Unexpected failure of evaluation.", e
);
327 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
329 // needed in case saveOrUpdate was interrupted by the RuntimeException
330 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
332 startNewTransaction();
334 Assert
.assertNull("must not fail here!", exception
);
338 public final void testMakeTaxonNodeASynonymOfAnotherTaxonNodeAllow_2() {
340 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
341 SecurityContext context
= SecurityContextHolder
.getContext();
342 context
.setAuthentication(authentication
);
344 Reference book
= referenceService
.load(BOOK1_UUID
);
346 TaxonNode n_acherontia_styx
= taxonNodeService
.find(ACHERONTIA_STYX_NODE_UUID
);
347 TaxonNode n_acherontia_lachersis
= taxonNodeService
.find(ACHERONTIA_LACHESIS_NODE_UUID
);
349 Exception exception
= null;
351 taxonNodeService
.makeTaxonNodeASynonymOfAnotherTaxonNode(n_acherontia_lachersis
, n_acherontia_styx
, SynonymRelationshipType
.HOMOTYPIC_SYNONYM_OF(), book
, "33");
352 commitAndStartNewTransaction(null);
353 } catch (AccessDeniedException e
){
354 logger
.error("Unexpected failure of evaluation.", e
);
356 } catch (RuntimeException e
){
357 logger
.error("Unexpected failure of evaluation.", e
);
358 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
360 // needed in case saveOrUpdate was interrupted by the RuntimeException
361 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
363 startNewTransaction();
365 Assert
.assertNull("must not fail here!", exception
);
369 public final void testUpdateReferenceAllow() throws ParsingException
{
372 authentication
= authenticationManager
.authenticate(tokenForUserManager
);
373 SecurityContext context
= SecurityContextHolder
.getContext();
374 context
.setAuthentication(authentication
);
376 // add REFERENCE[UPDATE] to taxonEditor
377 User taxonEditor
= userService
.load(TAXON_EDITOR_UUID
);
378 Set
<GrantedAuthority
> grantedAuthorities
= new HashSet
<GrantedAuthority
>();
379 grantedAuthorities
.addAll(taxonEditor
.getGrantedAuthorities());
380 GrantedAuthorityImpl referenceUpdate_ga
= new CdmAuthority(CdmPermissionClass
.REFERENCE
, null, EnumSet
.of(CRUD
.UPDATE
), null).asNewGrantedAuthority();
381 grantedAuthorities
.add(referenceUpdate_ga
);
382 taxonEditor
.setGrantedAuthorities(grantedAuthorities
);
383 userService
.saveOrUpdate(taxonEditor
);
384 commitAndStartNewTransaction(null);
386 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
387 context
= SecurityContextHolder
.getContext();
388 context
.setAuthentication(authentication
);
390 Reference book
= referenceService
.load(BOOK1_UUID
);
391 book
.setTitleCache("Mobydick", true);
392 Exception exception
= null;
394 referenceService
.saveOrUpdate(book
);
395 commitAndStartNewTransaction(null);
396 } catch (AccessDeniedException e
){
397 logger
.error("Unexpected failure of evaluation.", e
);
399 } catch (RuntimeException e
){
400 logger
.error("Unexpected failure of evaluation.", e
);
401 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
403 // needed in case saveOrUpdate was interrupted by the RuntimeException
404 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
406 startNewTransaction();
408 Assert
.assertNull("must not fail here!", exception
);
409 book
= referenceService
.load(BOOK1_UUID
);
410 Assert
.assertEquals("Mobydick", book
.getTitleCache());
414 public final void testUpateReferenceDeny() {
416 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
417 SecurityContext context
= SecurityContextHolder
.getContext();
418 context
.setAuthentication(authentication
);
420 TaxonBase taxon
= taxonService
.find(UUID_ACHERONTIA_STYX
);
421 taxon
.getName().getNomenclaturalReference().setTitleCache("Mobydick", true);
422 Exception exception
= null;
424 UUID uuid
= taxonService
.saveOrUpdate(taxon
);
425 commitAndStartNewTransaction(null);
426 } catch (AccessDeniedException e
){
427 logger
.debug("Expected failure of evaluation.", e
);
429 } catch (RuntimeException e
){
430 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
431 logger
.debug("Expected failure of evaluation.", e
);
433 // needed in case saveOrUpdate was interrupted by the RuntimeException
434 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
436 startNewTransaction();
438 Assert
.assertNotNull("must fail here!", exception
);
442 public void testChangeOwnPassword(){
444 SecurityContext context
= SecurityContextHolder
.getContext();
445 // authenticate as admin
446 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
447 context
.setAuthentication(authentication
);
449 // User currentUser = (User) context.getAuthentication().getPrincipal();
451 String newPass
= "poiweorijo";
452 userService
.changePassword(PASSWORD_TAXON_EDITOR
, newPass
);
453 commitAndStartNewTransaction(null);
455 // try to re-authenticate user with changed password
456 UsernamePasswordAuthenticationToken newTokenForTaxonEditor
= new UsernamePasswordAuthenticationToken("taxonEditor", newPass
);
457 authentication
= authenticationManager
.authenticate(newTokenForTaxonEditor
);
461 public void testChangeOthersPasswordAllow(){
463 SecurityContext context
= SecurityContextHolder
.getContext();
464 RuntimeException exception
= null;
466 // (1) authenticate as admin
467 authentication
= authenticationManager
.authenticate(tokenForAdmin
);
468 context
.setAuthentication(authentication
);
472 userService
.changePasswordForUser("taxonomist", "zuaisd");
473 commitAndStartNewTransaction(null);
474 } catch (AccessDeniedException e
){
475 logger
.error("Unexpected failure of evaluation.", e
);
477 } catch (RuntimeException e
){
478 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
479 logger
.error("Unexpected failure of evaluation.", exception
);
481 // needed in case saveOrUpdate was interrupted by the RuntimeException
482 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
484 startNewTransaction();
486 Assert
.assertNull("must not fail here!", exception
);
488 // ok, now try authenticating taxonomist with new password
489 UsernamePasswordAuthenticationToken newToken
= new UsernamePasswordAuthenticationToken("taxonomist", "zuaisd");
490 authentication
= authenticationManager
.authenticate(newToken
);
494 public void testChangeOthersPasswordDeny(){
496 SecurityContext context
= SecurityContextHolder
.getContext();
497 RuntimeException exception
= null;
499 // (2) authenticate as under privileged user - not an admin !!!
500 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
501 context
.setAuthentication(authentication
);
503 // check test preconditions user name and authorities
504 Assert
.assertEquals("descriptionEditor", context
.getAuthentication().getName());
505 Collection
<?
extends GrantedAuthority
> authorities
= context
.getAuthentication().getAuthorities();
506 for(GrantedAuthority authority
: authorities
){
507 // role prefix 'ROLE_' is defined in org.springframework.security.access.vote.RoleVoter !!!
508 Assert
.assertNotSame("user must not have authority 'ROLE_ADMIN'", "ROLE_ADMIN", authority
.getAuthority());
510 // finally perform the test :
512 userService
.changePasswordForUser("partEditor", "poiweorijo");
513 commitAndStartNewTransaction(null);
514 } catch (AccessDeniedException e
){
515 logger
.debug("Expected failure of evaluation.", e
);
517 } catch (RuntimeException e
){
518 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
519 logger
.debug("Expected failure of evaluation.", e
);
521 // needed in case saveOrUpdate was interrupted by the RuntimeException
522 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
524 startNewTransaction();
526 Assert
.assertNotNull("must fail here!", exception
);
530 public void testUpdateUser(){
532 authentication
= authenticationManager
.authenticate(tokenForAdmin
);
533 SecurityContext context
= SecurityContextHolder
.getContext();
534 context
.setAuthentication(authentication
);
535 String username
= "standardUser";
536 String password
= "pw";
537 User user
= User
.NewInstance(username
, password
);
539 userService
.createUser(user
);
540 user
.setEmailAddress("test@bgbm.org");
542 userService
.updateUser(user
);
543 userService
.update(user
);
544 userService
.saveOrUpdate(user
);
545 commitAndStartNewTransaction(null);
550 * test with admin account - should succeed
553 public final void testTaxonSaveOrUpdateAllow_1() {
555 SecurityContext context
= SecurityContextHolder
.getContext();
557 authentication
= authenticationManager
.authenticate(tokenForAdmin
);
558 context
.setAuthentication(authentication
);
559 RuntimeException securityException
= null;
561 TaxonBase
<?
> taxon
= taxonService
.find(UUID_ACHERONTIA_STYX
);
562 Assert
.assertFalse(taxon
.isDoubtful());
563 taxon
.setDoubtful(true);
565 taxonService
.saveOrUpdate(taxon
);
566 commitAndStartNewTransaction(null);
567 } catch (RuntimeException e
){
568 securityException
= findSecurityRuntimeException(e
);
569 logger
.error("Unexpected failure of evaluation.", e
);
571 // needed in case saveOrUpdate was interrupted by the RuntimeException
572 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
574 startNewTransaction();
576 Assert
.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
578 taxon
= taxonService
.find(UUID_ACHERONTIA_STYX
);
579 Assert
.assertTrue("The change must be persisted", taxon
.isDoubtful());
583 * test with taxonEditor account - should succeed
586 public final void testTaxonSaveOrUpdateAllow_2() {
589 RuntimeException securityException
= null;
590 SecurityContext context
= SecurityContextHolder
.getContext();
592 // taxonEditor account - should succeed
593 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
595 context
.setAuthentication(authentication
);
597 TaxonBase
<?
> taxon
= taxonService
.find(UUID_ACHERONTIA_STYX
);
598 Assert
.assertFalse(taxon
.isDoubtful());
599 taxon
.setDoubtful(true);
601 taxonService
.saveOrUpdate(taxon
);
602 commitAndStartNewTransaction(null);
603 } catch (RuntimeException e
){
604 securityException
= findSecurityRuntimeException(e
);
605 logger
.error("Unexpected failure of evaluation.", e
);
607 // needed in case saveOrUpdate was interrupted by the RuntimeException
608 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
610 startNewTransaction();
612 Assert
.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
614 taxon
= taxonService
.find(UUID_ACHERONTIA_STYX
);
615 Assert
.assertTrue("The change must be persited", taxon
.isDoubtful());
619 * test with tokenForDescriptionEditor account - should fail
622 public final void testTaxonSaveOrUpdateDeny_2() {
624 SecurityContext context
= SecurityContextHolder
.getContext();
625 RuntimeException securityException
= null;
627 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
628 context
.setAuthentication(authentication
);
630 TaxonBase
<?
> taxon
= taxonService
.find(UUID_ACHERONTIA_STYX
);
632 Assert
.assertFalse(taxon
.isDoubtful());
633 taxon
.setDoubtful(true);
635 taxonService
.saveOrUpdate(taxon
);
636 commitAndStartNewTransaction(null);
637 } catch (RuntimeException e
){
638 securityException
= findSecurityRuntimeException(e
);
639 logger
.debug("Expected failure of evaluation.", securityException
);
641 // needed in case saveOrUpdate was interrupted by the RuntimeException
642 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
644 startNewTransaction();
647 Assert
.assertNotNull("evaluation must fail since the user is not permitted", securityException
);
649 taxon
= taxonService
.find(UUID_ACHERONTIA_STYX
);
650 Assert
.assertFalse("The change must not be persited", taxon
.isDoubtful());
654 public final void testTaxonPublishAllow_ROLE_ADMIN() {
656 SecurityContext context
= SecurityContextHolder
.getContext();
658 authentication
= authenticationManager
.authenticate(tokenForAdmin
);
659 context
.setAuthentication(authentication
);
660 RuntimeException securityException
= null;
662 Taxon taxon
= (Taxon
) taxonService
.find(UUID_ACHERONTIA_STYX
);
664 boolean lastIsPublish
= taxon
.isPublish();
665 taxon
.setPublish(!lastIsPublish
);
667 taxonService
.saveOrUpdate(taxon
);
668 commitAndStartNewTransaction(null);
669 } catch (RuntimeException e
){
670 securityException
= findSecurityRuntimeException(e
);
671 logger
.error("Unexpected failure of evaluation.", e
);
673 // needed in case saveOrUpdate was interrupted by the RuntimeException
674 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
676 startNewTransaction();
678 Assert
.assertNull("evaluation must not fail since the user has ROLE_ADMIN, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
680 taxon
= (Taxon
) taxonService
.find(UUID_ACHERONTIA_STYX
);
681 Assert
.assertTrue("The change must be persisted", taxon
.isPublish() != lastIsPublish
);
686 * test with Taxonomist account which has the ROLE_PUBLISH
689 public final void testTaxonPublishAllow_ROLE_PUBLISH() {
691 SecurityContext context
= SecurityContextHolder
.getContext();
693 authentication
= authenticationManager
.authenticate(tokenForTaxonomist
);
694 context
.setAuthentication(authentication
);
695 RuntimeException securityException
= null;
697 Taxon taxon
= (Taxon
) taxonService
.find(UUID_ACHERONTIA_STYX
);
699 boolean lastIsPublish
= taxon
.isPublish();
700 taxon
.setPublish(!lastIsPublish
);
702 taxonService
.saveOrUpdate(taxon
);
703 commitAndStartNewTransaction(null);
704 } catch (RuntimeException e
){
705 securityException
= findSecurityRuntimeException(e
);
706 logger
.error("Unexpected failure of evaluation.", e
);
708 // needed in case saveOrUpdate was interrupted by the RuntimeException
709 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
711 startNewTransaction();
713 Assert
.assertNull("evaluation must not fail since the user has ROLE_ADMIN, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
715 taxon
= (Taxon
) taxonService
.find(UUID_ACHERONTIA_STYX
);
716 Assert
.assertTrue("The change must be persisted", taxon
.isPublish() != lastIsPublish
);
720 * test with TaxonEditor account which has not the ROLE_PUBLISH
723 public final void testTaxonPublishDeny() {
725 SecurityContext context
= SecurityContextHolder
.getContext();
727 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
728 context
.setAuthentication(authentication
);
729 RuntimeException securityException
= null;
731 Taxon taxon
= (Taxon
) taxonService
.find(UUID_ACHERONTIA_STYX
);
733 boolean lastIsPublish
= taxon
.isPublish();
734 taxon
.setPublish(!lastIsPublish
);
736 taxonService
.saveOrUpdate(taxon
);
737 commitAndStartNewTransaction(null);
738 } catch (RuntimeException e
){
739 securityException
= findSecurityRuntimeException(e
);
740 logger
.debug("Expected failure of evaluation.", securityException
);
742 // needed in case saveOrUpdate was interrupted by the RuntimeException
743 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
745 startNewTransaction();
748 Assert
.assertNotNull("evaluation must fail since the user is not permitted", securityException
);
750 taxon
= (Taxon
) taxonService
.find(UUID_ACHERONTIA_STYX
);
751 Assert
.assertTrue("The taxon must be unchanged", taxon
.isPublish() == lastIsPublish
);
755 * test with admin account - should succeed
758 public final void testTaxonDeleteAllow_1() {
760 SecurityContext context
= SecurityContextHolder
.getContext();
762 authentication
= authenticationManager
.authenticate(tokenForAdmin
);
763 context
.setAuthentication(authentication
);
764 RuntimeException securityException
= null;
766 TaxonBase
<?
> taxon
= taxonService
.load(UUID_LACTUCA
);
767 taxonService
.delete(taxon
);
768 commitAndStartNewTransaction(null);
773 Assert
.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
775 taxon
= taxonService
.load(UUID_LACTUCA
);
776 Assert
.assertNull("The taxon must be deleted", taxon
);
780 * test with admin account - should succeed
783 public final void testTaxonDeleteAllow_2() {
785 SecurityContext context
= SecurityContextHolder
.getContext();
787 authentication
= authenticationManager
.authenticate(tokenForAdmin
);
788 context
.setAuthentication(authentication
);
789 RuntimeException securityException
= null;
791 Taxon taxon
= (Taxon
)taxonService
.load(UUID_ACHERONTINII
);
794 DeleteResult result
= taxonService
.deleteTaxon(taxon
, null, null);
795 /*} catch (DataChangeNoRollbackException e) {
801 commitAndStartNewTransaction(null);
802 } catch (RuntimeException e
){
803 securityException
= findSecurityRuntimeException(e
);
804 logger
.error("Unexpected failure of evaluation.", e
);
806 // needed in case saveOrUpdate was interrupted by the RuntimeException
807 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
809 startNewTransaction();
811 Assert
.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
814 taxon
= (Taxon
)taxonService
.find(UUID_ACHERONTINII
);
815 Assert
.assertNull("The taxon must be deleted", taxon
);
820 * test with tokenForDescriptionEditor account - should fail
823 public final void testTaxonDeleteDeny() {
825 SecurityContext context
= SecurityContextHolder
.getContext();
826 RuntimeException securityException
= null;
828 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
829 context
.setAuthentication(authentication
);
831 Taxon taxon
= (Taxon
)taxonService
.load(UUID_LACTUCA
);
832 DeleteResult result
= taxonService
.deleteTaxon(taxon
, null, null);
833 if (!result
.isError()) {
837 startNewTransaction();
840 //Assert.assertNotNull("evaluation must fail since the user is not permitted", securityException);
842 taxon
= (Taxon
)taxonService
.load(UUID_LACTUCA
);
844 Assert
.assertNotNull("The change must still exist", taxon
);
845 Assert
.assertNotNull("The name must still exist",taxon
.getName());
850 @Ignore //FIXME: adding taxa to a description must be protected at the side of the Description itself!!
851 // => protecting method TaxonDescription.setTaxon() ?
852 public void testAddDescriptionToTaxon(){
854 SecurityContext context
= SecurityContextHolder
.getContext();
855 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
856 context
.setAuthentication(authentication
);
858 RuntimeException securityException
= null;
860 Taxon taxon
= (Taxon
)taxonService
.load(ACHERONTIA_LACHESIS_UUID
);
862 TaxonDescription description
= TaxonDescription
.NewInstance(taxon
);
863 description
.setTitleCache("test");
865 descriptionService
.saveOrUpdate(description
);
866 commitAndStartNewTransaction(null);
867 } catch (RuntimeException e
){
868 securityException
= findSecurityRuntimeException(e
);
869 logger
.debug("Expected failure of evaluation.", securityException
);
871 // needed in case saveOrUpdate was interrupted by the RuntimeException
872 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
874 startNewTransaction();
878 * The user should not be granted to add the Description to a taxon
880 Assert
.assertNotNull("evaluation should fail since the user is not permitted to edit Taxa", securityException
);
881 taxon
= (Taxon
)taxonService
.load(ACHERONTIA_LACHESIS_UUID
);
882 assertTrue(taxon
.getDescriptions().contains(description
));
886 public void testMoveDescriptionElement(){
888 SecurityContext context
= SecurityContextHolder
.getContext();
889 authentication
= authenticationManager
.authenticate(tokenForTaxonomist
);
890 context
.setAuthentication(authentication
);
892 RuntimeException securityException
= null;
894 Taxon t_acherontia_lachesis
= (Taxon
)taxonService
.load(ACHERONTIA_LACHESIS_UUID
);
895 Taxon t_acherontia_styx
= (Taxon
)taxonService
.load(UUID_ACHERONTIA_STYX
);
897 TaxonDescription description_acherontia_styx
= t_acherontia_styx
.getDescriptions().iterator().next();
898 TaxonDescription description_acherontia_lachesis
= t_acherontia_lachesis
.getDescriptions().iterator().next();
901 descriptionService
.moveDescriptionElementsToDescription(description_acherontia_styx
.getElements(), description_acherontia_lachesis
, false);
902 commitAndStartNewTransaction(null);
903 } catch (RuntimeException e
){
904 securityException
= findSecurityRuntimeException(e
);
905 logger
.debug("Unexpected failure of evaluation.", securityException
);
907 // needed in case saveOrUpdate was interrupted by the RuntimeException
908 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
910 startNewTransaction();
915 Assert
.assertNull("evaluation should not fail since the user has sufficient permissions", securityException
);
919 // @Ignore // FIXME http://dev.e-taxonomy.eu/trac/ticket/4081 : #4081 (TaxonNodeServiceImpl.makeTaxonNodeASynonymOfAnotherTaxonNode() requires TAXONNAMEBASE.[UPDATE])
921 public void testAcceptedTaxonToSynomym(){
923 SecurityContext context
= SecurityContextHolder
.getContext();
924 authentication
= authenticationManager
.authenticate(tokenForPartEditor
);
925 context
.setAuthentication(authentication
);
927 RuntimeException securityException
= null;
929 Taxon t_acherontia_lachesis
= (Taxon
)taxonService
.load(ACHERONTIA_LACHESIS_UUID
);
930 Taxon t_acherontia_styx
= (Taxon
)taxonService
.load(UUID_ACHERONTIA_STYX
);
933 TaxonNode n_acherontia_lachesis
= t_acherontia_lachesis
.getTaxonNodes().iterator().next();
934 TaxonNode n_acherontia_styx
= t_acherontia_styx
.getTaxonNodes().iterator().next();
936 int numOfSynonymsBefore_styx
= t_acherontia_styx
.getSynonyms().size();
937 int numOfSynonymsBefore_lachesis
= t_acherontia_lachesis
.getSynonyms().size();
939 UUID synonymUuid
= null; // UUID.randomUUID();
942 Synonym synonym
= taxonNodeService
.makeTaxonNodeASynonymOfAnotherTaxonNode(n_acherontia_lachesis
, n_acherontia_styx
, SynonymRelationshipType
.SYNONYM_OF(), null, null);
943 synonymUuid
= synonym
.getUuid();
944 taxonService
.saveOrUpdate(synonym
);
945 commitAndStartNewTransaction(null);
946 } catch (RuntimeException e
){
947 securityException
= findSecurityRuntimeException(e
);
948 logger
.error("Unexpected Exception ", e
);
949 Assert
.fail("Unexpected Exception: " + e
.getMessage());
951 // needed in case saveOrUpdate was interrupted by the RuntimeException
952 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
954 startNewTransaction();
959 Assert
.assertNull("evaluation should not fail since the user has sufficient permissions", securityException
);
961 // reload from db and check assertions
962 t_acherontia_styx
= (Taxon
)taxonService
.load(UUID_ACHERONTIA_STYX
);
963 Assert
.assertEquals("Acherontia styx now must have a synonym", numOfSynonymsBefore_styx
+ numOfSynonymsBefore_lachesis
+ 1, t_acherontia_styx
.getSynonyms().size());
964 Assert
.assertTrue("Acherontia lachesis now must be a synonym", taxonService
.load(synonymUuid
) instanceof Synonym
);
965 Assert
.assertNull("The old TaxonNode should no longer exist", taxonNodeService
.find(n_acherontia_lachesis
.getUuid()));
969 public void testCreateDescriptionWithElement(){
971 SecurityContext context
= SecurityContextHolder
.getContext();
972 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
973 context
.setAuthentication(authentication
);
975 TaxonDescription description
= null;
976 RuntimeException securityException
= null;
977 Taxon taxon
= (Taxon
)taxonService
.load(UUID_ACHERONTINII
);
978 Assert
.assertTrue("taxon must not yet have descriptions", taxon
.getDescriptions().size() == 0);
981 // 1) test for failure - description element but no feature
982 description
= TaxonDescription
.NewInstance(taxon
);
983 DescriptionElementBase textdataNoFeature
= TextData
.NewInstance();
984 description
.addElement(textdataNoFeature
);
986 assertTrue(permissionEvaluator
.hasPermission(authentication
, description
, "UPDATE"));
988 descriptionService
.saveOrUpdate(description
);
989 commitAndStartNewTransaction(null);
990 } catch (RuntimeException e
){
991 securityException
= findSecurityRuntimeException(e
);
992 logger
.error("RuntimeException caught");
993 logger
.debug("Expected failure of evaluation.", securityException
);
995 // needed in case saveOrUpdate was interrupted by the RuntimeException
996 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
998 startNewTransaction();
1001 Assert
.assertNotNull("evaluation should fail", securityException
);
1002 taxon
= (Taxon
)taxonService
.load(UUID_ACHERONTINII
);
1003 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
1004 assertTrue("taxon must not have any description", descriptions
.size() == 0);
1009 public void testCreateDescriptionWithElementDeny_1(){
1011 SecurityContext context
= SecurityContextHolder
.getContext();
1012 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
1013 context
.setAuthentication(authentication
);
1015 TaxonDescription description
= null;
1016 RuntimeException securityException
= null;
1017 Taxon taxon
= (Taxon
)taxonService
.load(UUID_ACHERONTINII
);
1018 Assert
.assertTrue("taxon must not yet have descriptions", taxon
.getDescriptions().size() == 0);
1020 // 2) test for failure - description element but not granted feature
1021 description
= TaxonDescription
.NewInstance(taxon
);
1022 DescriptionElementBase descriptionText
= TextData
.NewInstance(Feature
.DESCRIPTION());
1023 description
.addElement(descriptionText
);
1025 securityException
= null;
1026 assertTrue(permissionEvaluator
.hasPermission(authentication
, description
, "UPDATE"));
1028 descriptionService
.saveOrUpdate(description
);
1029 commitAndStartNewTransaction(null);
1030 } catch (RuntimeException e
){
1031 securityException
= findSecurityRuntimeException(e
);
1032 logger
.debug("Expected failure of evaluation.", securityException
);
1034 // needed in case saveOrUpdate was interrupted by the RuntimeException
1035 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1037 startNewTransaction();
1040 Assert
.assertNotNull("evaluation should fail", securityException
);
1041 taxon
= (Taxon
)taxonService
.load(UUID_ACHERONTINII
);
1042 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
1043 assertTrue("taxon must not have any description", descriptions
.size() == 0);
1048 public void testCreateDescriptionWithElementDeny_2(){
1050 SecurityContext context
= SecurityContextHolder
.getContext();
1051 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
1052 context
.setAuthentication(authentication
);
1054 TaxonDescription description
= null;
1055 RuntimeException securityException
= null;
1056 Taxon taxon
= (Taxon
)taxonService
.load(UUID_ACHERONTINII
);
1057 Assert
.assertTrue("taxon must not yet have descriptions", taxon
.getDescriptions().size() == 0);
1059 // 3) test for failure
1060 description
= TaxonDescription
.NewInstance(taxon
);
1061 DescriptionElementBase ecologyText
= TextData
.NewInstance(Feature
.ECOLOGY());
1062 description
.addElement(ecologyText
);
1064 securityException
= null;
1065 assertTrue(permissionEvaluator
.hasPermission(authentication
, description
, "UPDATE"));
1067 descriptionService
.saveOrUpdate(description
);
1068 commitAndStartNewTransaction(null);
1069 } catch (RuntimeException e
){
1070 securityException
= findSecurityRuntimeException(e
);
1071 logger
.error("Unexpected failure of evaluation.", e
);
1073 // needed in case saveOrUpdate was interrupted by the RuntimeException
1074 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1076 startNewTransaction();
1079 Assert
.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
1080 taxon
= (Taxon
)taxonService
.load(UUID_ACHERONTINII
);
1081 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
1082 assertTrue("taxon must now have one description", descriptions
.size() == 1);
1083 assertTrue("description should have one description element", descriptions
.iterator().next().getElements().size() == 1);
1087 public void testSaveSynonymAllow(){
1089 SecurityContext context
= SecurityContextHolder
.getContext();
1090 RuntimeException securityException
= null;
1092 // 1) test for success
1093 authentication
= authenticationManager
.authenticate(tokenForTaxonomist
);
1094 context
.setAuthentication(authentication
);
1096 Synonym syn
= Synonym
.NewInstance(BotanicalName
.NewInstance(Rank
.SPECIES()), null);
1097 UUID synUuid
= UUID
.randomUUID();
1098 syn
.setUuid(synUuid
);
1100 taxonService
.saveOrUpdate(syn
);
1101 logger
.debug("will commit ...");
1102 commitAndStartNewTransaction(null);
1103 } catch (RuntimeException e
){
1104 securityException
= findSecurityRuntimeException(e
);
1105 logger
.error("Unexpected failure of evaluation.", e
);
1107 // needed in case saveOrUpdate was interrupted by the RuntimeException
1108 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1110 startNewTransaction();
1112 Assert
.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
1113 Assert
.assertNotNull("The new Synonym must be persited", taxonService
.find(synUuid
));
1117 public void testSaveSynonymDenial(){
1119 SecurityContext context
= SecurityContextHolder
.getContext();
1120 RuntimeException securityException
= null;
1121 // 2) test for denial
1122 authentication
= authenticationManager
.authenticate(tokenForDescriptionEditor
);
1123 context
.setAuthentication(authentication
);
1124 securityException
= null;
1125 Synonym syn
= Synonym
.NewInstance(BotanicalName
.NewInstance(Rank
.SPECIES()), null);
1126 UUID synUuid
= syn
.getUuid();
1128 taxonService
.saveOrUpdate(syn
);
1129 logger
.debug("will commit ...");
1130 commitAndStartNewTransaction(null);
1131 } catch (RuntimeException e
){
1132 securityException
= findSecurityRuntimeException(e
);
1133 logger
.debug("Expected failure of evaluation: " + securityException
.getClass());
1135 // needed in case saveOrUpdate was interrupted by the RuntimeException
1136 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1138 startNewTransaction();
1141 Assert
.assertNotNull("evaluation must fail since the user is not permitted", securityException
);
1142 Assert
.assertNull("The Synonym must not be persited", taxonService
.find(synUuid
));
1146 public void testEditPartOfClassificationAllow(){
1148 authentication
= authenticationManager
.authenticate(tokenForPartEditor
);
1149 SecurityContext context
= SecurityContextHolder
.getContext();
1150 context
.setAuthentication(authentication
);
1151 RuntimeException securityException
= null;
1152 Classification classification
= classificationService
.load(UUID
.fromString("aeee7448-5298-4991-b724-8d5b75a0a7a9"));
1154 TaxonNode acherontia_node
= taxonNodeService
.load(ACHERONTIA_NODE_UUID
);
1155 long numOfChildNodes
= acherontia_node
.getChildNodes().size();
1156 TaxonNode childNode
= acherontia_node
.addChildTaxon(Taxon
.NewInstance(BotanicalName
.NewInstance(Rank
.SPECIES()), null), null, null);
1159 taxonNodeService
.saveOrUpdate(acherontia_node
);
1160 commitAndStartNewTransaction(null);
1161 } catch (RuntimeException e
){
1162 securityException
= findSecurityRuntimeException(e
);
1163 logger
.error("Unexpected failure of evaluation.", securityException
);
1165 // needed in case saveOrUpdate was interrupted by the RuntimeException
1166 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1168 startNewTransaction();
1171 acherontia_node
= taxonNodeService
.load(ACHERONTIA_NODE_UUID
);
1172 Assert
.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException
!= null ? securityException
.getMessage() : ""), securityException
);
1173 Assert
.assertEquals("the acherontia_node must now have one more child node ", numOfChildNodes
+ 1 , acherontia_node
.getChildNodes().size());
1177 public void testEditPartOfClassificationDeny(){
1179 authentication
= authenticationManager
.authenticate(tokenForPartEditor
);
1180 SecurityContext context
= SecurityContextHolder
.getContext();
1181 context
.setAuthentication(authentication
);
1182 RuntimeException securityException
= null;
1185 securityException
= null;
1186 TaxonNode acherontiini_node
= taxonNodeService
.load(ACHERONTIINI_NODE_UUID
);
1187 int numOfChildNodes
= acherontiini_node
.getCountChildren();
1188 acherontiini_node
.addChildTaxon(Taxon
.NewInstance(BotanicalName
.NewInstance(Rank
.GENUS()), null), null, null);
1191 logger
.debug("==============================");
1192 taxonNodeService
.saveOrUpdate(acherontiini_node
);
1193 commitAndStartNewTransaction(null);
1194 } catch (RuntimeException e
){
1195 securityException
= findSecurityRuntimeException(e
);
1196 logger
.debug("Expected failure of evaluation.", securityException
);
1198 // needed in case saveOrUpdate was interrupted by the RuntimeException
1199 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1201 startNewTransaction();
1204 acherontiini_node
= taxonNodeService
.load(ACHERONTIINI_NODE_UUID
);
1205 Assert
.assertNotNull("evaluation must fail since the user is not permitted", securityException
);
1206 Assert
.assertEquals("the number of child nodes must be unchanged ", numOfChildNodes
, acherontiini_node
.getChildNodes().size());
1211 * @see eu.etaxonomy.cdm.test.integration.CdmIntegrationTest#createTestData()
1214 protected void createTestDataSet() throws FileNotFoundException
{
1215 // TODO Auto-generated method stub