Project

General

Profile

Download (50.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2011 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
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.
8
 */
9
package eu.etaxonomy.cdm.api.service;
10

    
11
import static org.junit.Assert.assertEquals;
12
import static org.junit.Assert.assertFalse;
13
import static org.junit.Assert.assertTrue;
14

    
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;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import javax.sql.DataSource;
24

    
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.unitils.database.annotations.TestDataSource;
39
import org.unitils.dbunit.annotation.DataSet;
40
import org.unitils.spring.annotation.SpringBean;
41
import org.unitils.spring.annotation.SpringBeanByType;
42

    
43
import sun.security.provider.PolicyParser.ParsingException;
44
import eu.etaxonomy.cdm.database.PermissionDeniedException;
45
import eu.etaxonomy.cdm.model.common.GrantedAuthorityImpl;
46
import eu.etaxonomy.cdm.model.common.User;
47
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
48
import eu.etaxonomy.cdm.model.description.Feature;
49
import eu.etaxonomy.cdm.model.description.TaxonDescription;
50
import eu.etaxonomy.cdm.model.description.TextData;
51
import eu.etaxonomy.cdm.model.name.BotanicalName;
52
import eu.etaxonomy.cdm.model.name.Rank;
53
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
54
import eu.etaxonomy.cdm.model.name.ZoologicalName;
55
import eu.etaxonomy.cdm.model.reference.Reference;
56
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
57
import eu.etaxonomy.cdm.model.taxon.Synonym;
58
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
59
import eu.etaxonomy.cdm.model.taxon.Taxon;
60
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
61
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
62
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
63
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
64
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionClass;
65
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionEvaluator;
66
import eu.etaxonomy.cdm.persistence.hibernate.permission.Operation;
67
import eu.etaxonomy.cdm.persistence.query.MatchMode;
68

    
69

    
70
@DataSet
71
public class SecurityTest extends AbstractSecurityTestBase{
72

    
73

    
74
    private static final Logger logger = Logger.getLogger(SecurityTest.class);
75

    
76
    @SpringBeanByType
77
    private ITaxonService taxonService;
78

    
79
    @SpringBeanByType
80
    private INameService nameService;
81

    
82
    @SpringBeanByType
83
    private IReferenceService referenceService;
84

    
85
    @SpringBeanByType
86
    private ITaxonNodeService taxonNodeService;
87

    
88
    @SpringBeanByType
89
    private IDescriptionService descriptionService;
90

    
91
    @SpringBeanByType
92
    private IUserService userService;
93

    
94
    @SpringBeanByType
95
    private IClassificationService classificationService;
96

    
97
    @SpringBeanByType
98
    private AuthenticationManager authenticationManager;
99

    
100
    @SpringBeanByType
101
    private SaltSource saltSource;
102

    
103
    @SpringBeanByType
104
    private PasswordEncoder passwordEncoder;
105

    
106
    @SpringBean("cdmPermissionEvaluator")
107
    private CdmPermissionEvaluator permissionEvaluator;
108

    
109
    @TestDataSource
110
    protected DataSource dataSource;
111

    
112
    private Authentication authentication;
113

    
114

    
115
    /**
116
     * no assertions in this test, since it is only used to create password hashes for test data
117
     */
118
    @Test
119
    public void testEncryptPassword(){
120

    
121
        String password = PASSWORD_ADMIN;
122
        User user = User.NewInstance("userManager", "");
123

    
124
        Object salt = this.saltSource.getSalt(user);
125
        String passwordEncrypted = passwordEncoder.encodePassword(password, salt);
126
        logger.info("encrypted password: " + passwordEncrypted );
127
    }
128

    
129
    @Test
130
    @DataSet
131
    public void testHasPermission(){
132

    
133
        Taxon taxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()),null);
134

    
135
        authentication = authenticationManager.authenticate(tokenForTaxonomist);
136
        boolean hasPermission = permissionEvaluator.hasPermission(authentication, taxon, Operation.UPDATE);
137
        assertTrue(hasPermission);
138

    
139
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
140
        hasPermission = permissionEvaluator.hasPermission(authentication, taxon, Operation.UPDATE);
141
        assertFalse(hasPermission);
142
    }
143

    
144
    @Test
145
    @DataSet
146
    public void testListByUsernameAllow(){
147

    
148
        authentication = authenticationManager.authenticate(tokenForTaxonomist);
149
        SecurityContext context = SecurityContextHolder.getContext();
150
        context.setAuthentication(authentication);
151

    
152
        List<User> userList = userService.listByUsername("Editor", MatchMode.ANYWHERE, null, null, 0, null, null);
153
        Assert.assertTrue("The user list must have elements", userList.size() > 0 );
154
    }
155

    
156
    @Test
157
    @DataSet
158
    public void testUserService_CreateDeny(){
159

    
160
        authentication = authenticationManager.authenticate(tokenForTaxonomist);
161
        SecurityContext context = SecurityContextHolder.getContext();
162
        context.setAuthentication(authentication);
163

    
164
        RuntimeException exception = null;
165
        try {
166
            userService.createUser(User.NewInstance("new guy", "alkjdsfalkj"));
167
            commitAndStartNewTransaction(null);
168
        } catch (AccessDeniedException e){
169
            logger.debug("Expected failure of evaluation.", e);
170
            exception = e;
171
        } catch (RuntimeException e){
172
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
173
            logger.debug("Expected failure of evaluation.", e);
174
        } finally {
175
            // needed in case saveOrUpdate was interrupted by the RuntimeException
176
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
177
            endTransaction();
178
            startNewTransaction();
179
        }
180
        Assert.assertNotNull("Must fail here!", exception);
181

    
182
    }
183

    
184
    @Test
185
    @DataSet
186
    public void testUserService_CreateAllow(){
187

    
188
        authentication = authenticationManager.authenticate(tokenForUserManager);
189
        SecurityContext context = SecurityContextHolder.getContext();
190
        context.setAuthentication(authentication);
191

    
192
        RuntimeException exception = null;
193
        try {
194
            userService.createUser(User.NewInstance("new guy", "alkjdsfalkj"));
195
            commitAndStartNewTransaction(null);
196
        } catch (AccessDeniedException e){
197
            logger.error("Unexpected failure of evaluation.", e);
198
            exception = e;
199
        } catch (RuntimeException e){
200
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
201
            logger.error("unexpected failure of evaluation.", exception);
202
        } finally {
203
            // needed in case saveOrUpdate was interrupted by the RuntimeException
204
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
205
            endTransaction();
206
            startNewTransaction();
207
        }
208
        Assert.assertNull("Must not fail here!", exception);
209

    
210
    }
211

    
212

    
213
    @Test
214
    @DataSet
215
    @Ignore // FIXME http://dev.e-taxonomy.eu/trac/ticket/3098
216
    public void testHasPermissions(){
217

    
218
        Taxon taxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()),null);
219

    
220
        authentication = authenticationManager.authenticate(tokenForTaxonomist);
221
        boolean hasPermission = permissionEvaluator.hasPermission(authentication, taxon, Operation.ALL);
222
        assertTrue(hasPermission);
223
    }
224

    
225

    
226
    /**
227
     * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#saveTaxon(eu.etaxonomy.cdm.model.taxon.TaxonBase)}.
228
     */
229
    @Test
230
    public final void testSaveTaxon() {
231

    
232
        authentication = authenticationManager.authenticate(tokenForAdmin);
233
        SecurityContext context = SecurityContextHolder.getContext();
234
        context.setAuthentication(authentication);
235

    
236
        Taxon expectedTaxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null);
237
        expectedTaxon.getName().setTitleCache("Newby admin", true);
238
        UUID uuid = taxonService.save(expectedTaxon).getUuid();
239
        commitAndStartNewTransaction(null);
240
        TaxonBase<?> actualTaxon = taxonService.load(uuid);
241
        assertEquals(expectedTaxon, actualTaxon);
242

    
243
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
244
        context = SecurityContextHolder.getContext();
245
        context.setAuthentication(authentication);
246
        expectedTaxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()), null);
247
        expectedTaxon.getName().setTitleCache("Newby taxonEditor", true);
248
        uuid = taxonService.saveOrUpdate(expectedTaxon);
249
        commitAndStartNewTransaction(null);
250
        actualTaxon = taxonService.load(uuid);
251
        assertEquals(expectedTaxon, actualTaxon);
252

    
253
    }
254

    
255
    @Test
256
    public final void testSaveNameAllow() {
257

    
258
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
259
        SecurityContext context = SecurityContextHolder.getContext();
260
        context.setAuthentication(authentication);
261

    
262
        ZoologicalName newName = ZoologicalName.NewInstance(Rank.SPECIES());
263
        newName.setTitleCache("Newby taxonEditor", true);
264
        UUID uuid = nameService.saveOrUpdate(newName);
265
        commitAndStartNewTransaction(null);
266
        TaxonNameBase<?,?> savedName = nameService.load(uuid);
267
        assertEquals(newName, savedName);
268
    }
269

    
270

    
271
    @Test
272
    public final void testReuseNameAllow() {
273

    
274
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
275
        SecurityContext context = SecurityContextHolder.getContext();
276
        context.setAuthentication(authentication);
277

    
278
        TaxonBase<?> taxon = taxonService.find(UUID_ACHERONTIA_STYX);
279
        TaxonNameBase<?,?> n_acherontia_thetis = taxon.getName();
280

    
281
        Reference<?> sec = ReferenceFactory.newGeneric();
282
        sec.setUuid(UUID.fromString("bd7e4a15-6403-49a9-a6df-45b46fa99efd"));
283
        Taxon newTaxon = Taxon.NewInstance(n_acherontia_thetis, sec);
284
        Exception exception = null;
285
        try {
286
            taxonService.save(newTaxon);
287
            commitAndStartNewTransaction(null);
288
        } catch (AccessDeniedException e){
289
            logger.error("Unexpected failure of evaluation.", e);
290
            exception = e;
291
        } catch (RuntimeException e){
292
            logger.error("Unexpected failure of evaluation.", e);
293
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
294
        } finally {
295
            // needed in case saveOrUpdate was interrupted by the RuntimeException
296
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
297
            endTransaction();
298
            startNewTransaction();
299
        }
300
        Assert.assertNull("must not fail here!", exception);
301
    }
302

    
303
    @Test
304
    public final void testMakeTaxonNodeASynonymOfAnotherTaxonNodeAllow_1() {
305

    
306
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
307
        SecurityContext context = SecurityContextHolder.getContext();
308
        context.setAuthentication(authentication);
309

    
310
        Reference<?> book = referenceService.load(BOOK1_UUID);
311

    
312
        TaxonNode n_acherontia_styx = taxonNodeService.find(ACHERONTIA_STYX_NODE_UUID);
313
        TaxonNode n_acherontia_lachersis = taxonNodeService.find(ACHERONTIA_LACHESIS_NODE_UUID);
314

    
315
        Exception exception = null;
316
        try {
317
            taxonNodeService.makeTaxonNodeASynonymOfAnotherTaxonNode(n_acherontia_styx, n_acherontia_lachersis, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), book , "33");
318
            commitAndStartNewTransaction(null);
319
        } catch (AccessDeniedException e){
320
            logger.error("Unexpected failure of evaluation.", e);
321
            exception = e;
322
        } catch (RuntimeException e){
323
            logger.error("Unexpected failure of evaluation.", e);
324
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
325
        }finally {
326
            // needed in case saveOrUpdate was interrupted by the RuntimeException
327
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
328
            endTransaction();
329
            startNewTransaction();
330
        }
331
        Assert.assertNull("must not fail here!", exception);
332
    }
333

    
334
    @Test
335
    public final void testMakeTaxonNodeASynonymOfAnotherTaxonNodeAllow_2() {
336

    
337
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
338
        SecurityContext context = SecurityContextHolder.getContext();
339
        context.setAuthentication(authentication);
340

    
341
        Reference<?> book = referenceService.load(BOOK1_UUID);
342

    
343
        TaxonNode n_acherontia_styx = taxonNodeService.find(ACHERONTIA_STYX_NODE_UUID);
344
        TaxonNode n_acherontia_lachersis = taxonNodeService.find(ACHERONTIA_LACHESIS_NODE_UUID);
345

    
346
        Exception exception = null;
347
        try {
348
            taxonNodeService.makeTaxonNodeASynonymOfAnotherTaxonNode(n_acherontia_lachersis, n_acherontia_styx, SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF(), book , "33");
349
            commitAndStartNewTransaction(null);
350
        } catch (AccessDeniedException e){
351
            logger.error("Unexpected failure of evaluation.", e);
352
            exception = e;
353
        } catch (RuntimeException e){
354
            logger.error("Unexpected failure of evaluation.", e);
355
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
356
        }  finally {
357
            // needed in case saveOrUpdate was interrupted by the RuntimeException
358
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
359
            endTransaction();
360
            startNewTransaction();
361
        }
362
        Assert.assertNull("must not fail here!", exception);
363
    }
364

    
365
    @Test
366
    public final void testUpdateReferenceAllow() throws ParsingException {
367

    
368

    
369
        authentication = authenticationManager.authenticate(tokenForUserManager);
370
        SecurityContext context = SecurityContextHolder.getContext();
371
        context.setAuthentication(authentication);
372

    
373
        // add REFERENCE[UPDATE] to taxonEditor
374
        User taxonEditor = userService.load(TAXON_EDITOR_UUID);
375
        Set<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>();
376
        grantedAuthorities.addAll(taxonEditor.getGrantedAuthorities());
377
        GrantedAuthorityImpl referenceUpdate_ga = new CdmAuthority(CdmPermissionClass.REFERENCE, null, EnumSet.of(CRUD.UPDATE), null).asNewGrantedAuthority();
378
        grantedAuthorities.add(referenceUpdate_ga);
379
        taxonEditor.setGrantedAuthorities(grantedAuthorities);
380
        userService.saveOrUpdate(taxonEditor);
381
        commitAndStartNewTransaction(null);
382

    
383
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
384
        context = SecurityContextHolder.getContext();
385
        context.setAuthentication(authentication);
386

    
387
        Reference<?> book = referenceService.load(BOOK1_UUID);
388
        book.setTitleCache("Mobydick", true);
389
        Exception exception = null;
390
        try {
391
            referenceService.saveOrUpdate(book);
392
            commitAndStartNewTransaction(null);
393
        } catch (AccessDeniedException e){
394
            logger.error("Unexpected failure of evaluation.", e);
395
            exception = e;
396
        } catch (RuntimeException e){
397
            logger.error("Unexpected failure of evaluation.", e);
398
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
399
        } finally {
400
            // needed in case saveOrUpdate was interrupted by the RuntimeException
401
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
402
            endTransaction();
403
            startNewTransaction();
404
        }
405
        Assert.assertNull("must not fail here!", exception);
406
        book = referenceService.load(BOOK1_UUID);
407
        Assert.assertEquals("Mobydick", book.getTitleCache());
408
    }
409

    
410
    @Test
411
    public final void testUpateReferenceDeny() {
412

    
413
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
414
        SecurityContext context = SecurityContextHolder.getContext();
415
        context.setAuthentication(authentication);
416

    
417
        TaxonBase<?> taxon = taxonService.find(UUID_ACHERONTIA_STYX);
418
        taxon.getName().getNomenclaturalReference().setTitleCache("Mobydick", true);
419
        Exception exception = null;
420
        try {
421
            taxonService.saveOrUpdate(taxon);
422
            commitAndStartNewTransaction(null);
423
        } catch (AccessDeniedException e){
424
            logger.debug("Expected failure of evaluation.", e);
425
            exception  = e;
426
        } catch (RuntimeException e){
427
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
428
            logger.debug("Expected failure of evaluation.", e);
429
        } finally {
430
            // needed in case saveOrUpdate was interrupted by the RuntimeException
431
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
432
            endTransaction();
433
            startNewTransaction();
434
        }
435
        Assert.assertNotNull("must fail here!", exception);
436
    }
437

    
438
    @Test
439
    public void testChangeOwnPassword(){
440

    
441
        SecurityContext context = SecurityContextHolder.getContext();
442
        // authenticate as admin
443
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
444
        context.setAuthentication(authentication);
445

    
446
//        User currentUser =  (User) context.getAuthentication().getPrincipal();
447

    
448
        String newPass = "poiweorijo";
449
        userService.changePassword(PASSWORD_TAXON_EDITOR, newPass);
450
        commitAndStartNewTransaction(null);
451

    
452
        // try to re-authenticate user with changed password
453
        UsernamePasswordAuthenticationToken newTokenForTaxonEditor = new UsernamePasswordAuthenticationToken("taxonEditor", newPass);
454
        authentication = authenticationManager.authenticate(newTokenForTaxonEditor);
455
    }
456

    
457
    @Test
458
    public void testChangeOthersPasswordAllow(){
459

    
460
        SecurityContext context = SecurityContextHolder.getContext();
461
        RuntimeException exception = null;
462

    
463
        // (1) authenticate as admin
464
        authentication = authenticationManager.authenticate(tokenForAdmin);
465
        context.setAuthentication(authentication);
466

    
467

    
468
        try{
469
            userService.changePasswordForUser("taxonomist", "zuaisd");
470
            commitAndStartNewTransaction(null);
471
        } catch (AccessDeniedException e){
472
            logger.error("Unexpected failure of evaluation.", e);
473
            exception = e;
474
        } catch (RuntimeException e){
475
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
476
            logger.error("Unexpected failure of evaluation.", exception);
477
        } finally {
478
            // needed in case saveOrUpdate was interrupted by the RuntimeException
479
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
480
            endTransaction();
481
            startNewTransaction();
482
        }
483
        Assert.assertNull("must not fail here!", exception);
484

    
485
        // ok, now try authenticating taxonomist with new password
486
        UsernamePasswordAuthenticationToken newToken = new UsernamePasswordAuthenticationToken("taxonomist", "zuaisd");
487
        authentication = authenticationManager.authenticate(newToken);
488
    }
489

    
490
    @Test
491
    public void testChangeOthersPasswordDeny(){
492

    
493
        SecurityContext context = SecurityContextHolder.getContext();
494
        RuntimeException exception = null;
495

    
496
        // (2) authenticate as under privileged user - not an admin !!!
497
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
498
        context.setAuthentication(authentication);
499

    
500
        // check test preconditions user name and authorities
501
        Assert.assertEquals("descriptionEditor", context.getAuthentication().getName());
502
        Collection<? extends GrantedAuthority> authorities = context.getAuthentication().getAuthorities();
503
        for(GrantedAuthority authority: authorities){
504
            // role prefix 'ROLE_' is defined in org.springframework.security.access.vote.RoleVoter !!!
505
            Assert.assertNotSame("user must not have authority 'ROLE_ADMIN'", "ROLE_ADMIN", authority.getAuthority());
506
        }
507
        // finally perform the test :
508
        try{
509
            userService.changePasswordForUser("partEditor", "poiweorijo");
510
            commitAndStartNewTransaction(null);
511
        } catch (AccessDeniedException e){
512
            logger.debug("Expected failure of evaluation.", e);
513
            exception = e;
514
        } catch (RuntimeException e){
515
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
516
            logger.debug("Expected failure of evaluation.", e);
517
        } finally {
518
            // needed in case saveOrUpdate was interrupted by the RuntimeException
519
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
520
            endTransaction();
521
            startNewTransaction();
522
        }
523
        Assert.assertNotNull("must fail here!", exception);
524
    }
525

    
526
    @Test
527
    public void testUpdateUser(){
528

    
529
        authentication = authenticationManager.authenticate(tokenForAdmin);
530
        SecurityContext context = SecurityContextHolder.getContext();
531
        context.setAuthentication(authentication);
532
        String username = "standardUser";
533
        String password = "pw";
534
        User user = User.NewInstance(username, password);
535

    
536
        userService.createUser(user);
537
        user.setEmailAddress("test@bgbm.org");
538

    
539
        userService.updateUser(user);
540
        userService.update(user);
541
        userService.saveOrUpdate(user);
542
        commitAndStartNewTransaction(null);
543

    
544
    }
545

    
546
    /**
547
     * test with admin account - should succeed
548
     */
549
    @Test
550
    public final void testTaxonSaveOrUpdateAllow_1() {
551

    
552
        SecurityContext context = SecurityContextHolder.getContext();
553

    
554
        authentication = authenticationManager.authenticate(tokenForAdmin);
555
        context.setAuthentication(authentication);
556
        RuntimeException securityException= null;
557

    
558
        TaxonBase<?> taxon = taxonService.find(UUID_ACHERONTIA_STYX);
559
        Assert.assertFalse(taxon.isDoubtful());
560
        taxon.setDoubtful(true);
561
        try{
562
            taxonService.saveOrUpdate(taxon);
563
            commitAndStartNewTransaction(null);
564
        } catch (RuntimeException e){
565
            securityException  = findSecurityRuntimeException(e);
566
            logger.error("Unexpected failure of evaluation.", e);
567
        } finally {
568
            // needed in case saveOrUpdate was interrupted by the RuntimeException
569
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
570
            endTransaction();
571
            startNewTransaction();
572
        }
573
        Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
574
        // reload taxon
575
        taxon = taxonService.find(UUID_ACHERONTIA_STYX);
576
        Assert.assertTrue("The change must be persisted", taxon.isDoubtful());
577
    }
578

    
579
    /**
580
     * test with taxonEditor account - should succeed
581
     */
582
    @Test
583
    public final void testTaxonSaveOrUpdateAllow_2() {
584

    
585

    
586
        RuntimeException securityException= null;
587
        SecurityContext context = SecurityContextHolder.getContext();
588

    
589
         // taxonEditor account - should succeed
590
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
591

    
592
        context.setAuthentication(authentication);
593

    
594
        TaxonBase<?>  taxon = taxonService.find(UUID_ACHERONTIA_STYX);
595
        Assert.assertFalse(taxon.isDoubtful());
596
        taxon.setDoubtful(true);
597
        try{
598
            taxonService.saveOrUpdate(taxon);
599
            commitAndStartNewTransaction(null);
600
        } catch (RuntimeException e){
601
            securityException  = findSecurityRuntimeException(e);
602
            logger.error("Unexpected failure of evaluation.", e);
603
        } finally {
604
            // needed in case saveOrUpdate was interrupted by the RuntimeException
605
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
606
            endTransaction();
607
            startNewTransaction();
608
        }
609
        Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
610
        // reload taxon
611
        taxon = taxonService.find(UUID_ACHERONTIA_STYX);
612
        Assert.assertTrue("The change must be persited", taxon.isDoubtful());
613
    }
614

    
615
    /**
616
     * test with tokenForDescriptionEditor account - should fail
617
     */
618
    @Test
619
    public final void testTaxonSaveOrUpdateDeny_2() {
620

    
621
        SecurityContext context = SecurityContextHolder.getContext();
622
        RuntimeException securityException = null;
623

    
624
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
625
        context.setAuthentication(authentication);
626

    
627
        TaxonBase<?> taxon = taxonService.find(UUID_ACHERONTIA_STYX);
628

    
629
        Assert.assertFalse(taxon.isDoubtful());
630
        taxon.setDoubtful(true);
631
        try {
632
            taxonService.saveOrUpdate(taxon);
633
            commitAndStartNewTransaction(null);
634
        } catch (RuntimeException e){
635
            securityException = findSecurityRuntimeException(e);
636
            logger.debug("Expected failure of evaluation.", securityException);
637
        } finally {
638
            // needed in case saveOrUpdate was interrupted by the RuntimeException
639
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
640
            endTransaction();
641
            startNewTransaction();
642
        }
643

    
644
        Assert.assertNotNull("evaluation must fail since the user is not permitted", securityException);
645
        // reload taxon
646
        taxon = taxonService.find(UUID_ACHERONTIA_STYX);
647
        Assert.assertFalse("The change must not be persited", taxon.isDoubtful());
648
    }
649

    
650
    @Test
651
    public final void testTaxonPublishAllow_ROLE_ADMIN() {
652

    
653
        SecurityContext context = SecurityContextHolder.getContext();
654

    
655
        authentication = authenticationManager.authenticate(tokenForAdmin);
656
        context.setAuthentication(authentication);
657
        RuntimeException securityException= null;
658

    
659
        Taxon taxon = (Taxon) taxonService.find(UUID_ACHERONTIA_STYX);
660

    
661
        boolean lastIsPublish = taxon.isPublish();
662
        taxon.setPublish(!lastIsPublish);
663
        try{
664
            taxonService.saveOrUpdate(taxon);
665
            commitAndStartNewTransaction(null);
666
        } catch (RuntimeException e){
667
            securityException  = findSecurityRuntimeException(e);
668
            logger.error("Unexpected failure of evaluation.", e);
669
        } finally {
670
            // needed in case saveOrUpdate was interrupted by the RuntimeException
671
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
672
            endTransaction();
673
            startNewTransaction();
674
        }
675
        Assert.assertNull("evaluation must not fail since the user has ROLE_ADMIN, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
676
        // reload taxon
677
        taxon = (Taxon) taxonService.find(UUID_ACHERONTIA_STYX);
678
        Assert.assertTrue("The change must be persisted", taxon.isPublish() != lastIsPublish);
679
    }
680

    
681

    
682
    /**
683
     * test with Taxonomist account which has the ROLE_PUBLISH
684
     */
685
    @Test
686
    public final void testTaxonPublishAllow_ROLE_PUBLISH() {
687

    
688
        SecurityContext context = SecurityContextHolder.getContext();
689

    
690
        authentication = authenticationManager.authenticate(tokenForTaxonomist);
691
        context.setAuthentication(authentication);
692
        RuntimeException securityException= null;
693

    
694
        Taxon taxon = (Taxon) taxonService.find(UUID_ACHERONTIA_STYX);
695

    
696
        boolean lastIsPublish = taxon.isPublish();
697
        taxon.setPublish(!lastIsPublish);
698
        try{
699
            taxonService.saveOrUpdate(taxon);
700
            commitAndStartNewTransaction(null);
701
        } catch (RuntimeException e){
702
            securityException  = findSecurityRuntimeException(e);
703
            logger.error("Unexpected failure of evaluation.", e);
704
        } finally {
705
            // needed in case saveOrUpdate was interrupted by the RuntimeException
706
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
707
            endTransaction();
708
            startNewTransaction();
709
        }
710
        Assert.assertNull("evaluation must not fail since the user has ROLE_ADMIN, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
711
        // reload taxon
712
        taxon = (Taxon) taxonService.find(UUID_ACHERONTIA_STYX);
713
        Assert.assertTrue("The change must be persisted", taxon.isPublish() != lastIsPublish);
714
    }
715

    
716
    /**
717
     * test with TaxonEditor account which has not the ROLE_PUBLISH
718
     */
719
    @Test
720
    public final void testTaxonPublishDeny() {
721

    
722
        SecurityContext context = SecurityContextHolder.getContext();
723

    
724
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
725
        context.setAuthentication(authentication);
726
        RuntimeException securityException= null;
727

    
728
        Taxon taxon = (Taxon) taxonService.find(UUID_ACHERONTIA_STYX);
729

    
730
        boolean lastIsPublish = taxon.isPublish();
731
        taxon.setPublish(!lastIsPublish);
732
        try {
733
            taxonService.saveOrUpdate(taxon);
734
            commitAndStartNewTransaction(null);
735
        } catch (RuntimeException e){
736
            securityException = findSecurityRuntimeException(e);
737
            logger.debug("Expected failure of evaluation.", securityException);
738
        } finally {
739
            // needed in case saveOrUpdate was interrupted by the RuntimeException
740
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
741
            endTransaction();
742
            startNewTransaction();
743
        }
744

    
745
        Assert.assertNotNull("evaluation must fail since the user is not permitted", securityException);
746
        // reload taxon
747
        taxon = (Taxon) taxonService.find(UUID_ACHERONTIA_STYX);
748
        Assert.assertTrue("The taxon must be unchanged", taxon.isPublish() == lastIsPublish);
749
    }
750

    
751
    /**
752
     * test with admin account - should succeed
753
     */
754
    @Test
755
    public final void testTaxonDeleteAllow_1() {
756

    
757
        SecurityContext context = SecurityContextHolder.getContext();
758

    
759
        authentication = authenticationManager.authenticate(tokenForAdmin);
760
        context.setAuthentication(authentication);
761
        RuntimeException securityException= null;
762

    
763
        TaxonBase<?> taxon = taxonService.load(UUID_LACTUCA);
764
        taxonService.delete(taxon);
765
        commitAndStartNewTransaction(null);
766

    
767
        Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
768
        // reload taxon
769
        taxon = taxonService.load(UUID_LACTUCA);
770
        Assert.assertNull("The taxon must be deleted", taxon);
771
    }
772

    
773
    /**
774
     * test with admin account - should succeed
775
     */
776
    @Test
777
   public final void testTaxonDeleteAllow_2() {
778

    
779
        SecurityContext context = SecurityContextHolder.getContext();
780

    
781
        authentication = authenticationManager.authenticate(tokenForAdmin);
782
        context.setAuthentication(authentication);
783
        RuntimeException securityException= null;
784

    
785
        Taxon taxon = (Taxon)taxonService.load(UUID_ACHERONTINII);
786
        try{
787
           // try {
788
        	DeleteResult result = taxonService.deleteTaxon(taxon.getUuid(), null, null);
789
            /*} catch (DataChangeNoRollbackException e) {
790
                Assert.fail();
791
            }*/
792
            if (!result.isOk()){
793
            	Assert.fail();
794
            }
795
            commitAndStartNewTransaction(null);
796
        } catch (RuntimeException e){
797
            securityException  = findSecurityRuntimeException(e);
798
            logger.error("Unexpected failure of evaluation.", e);
799
        } finally {
800
            // needed in case saveOrUpdate was interrupted by the RuntimeException
801
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
802
            endTransaction();
803
            startNewTransaction();
804
        }
805
        Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
806
        // reload taxon
807

    
808
        taxon = (Taxon)taxonService.find(UUID_ACHERONTINII);
809
        Assert.assertNull("The taxon must be deleted", taxon);
810
    }
811

    
812

    
813
    /**
814
     * test with tokenForDescriptionEditor account - should fail
815
     */
816
    @Test
817
    public final void testTaxonDeleteDeny() {
818

    
819
        SecurityContext context = SecurityContextHolder.getContext();
820
//        RuntimeException securityException = null;
821

    
822
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
823
        context.setAuthentication(authentication);
824

    
825
        Taxon taxon = (Taxon)taxonService.load(UUID_LACTUCA);
826
        try{
827
        taxonService.deleteTaxon(taxon.getUuid(), null, null);
828
        Assert.fail();
829
        }catch(PermissionDeniedException e){
830

    
831
        }
832
       endTransaction();
833
       startNewTransaction();
834

    
835

    
836
        //Assert.assertNotNull("evaluation must fail since the user is not permitted", securityException);
837
        // reload taxon
838
        taxon = (Taxon)taxonService.load(UUID_LACTUCA);
839

    
840
        Assert.assertNotNull("The change must still exist", taxon);
841
        Assert.assertNotNull("The name must still exist",taxon.getName());
842
    }
843

    
844

    
845
    @Test
846
    @Ignore //FIXME: adding taxa to a description must be protected at the side of the Description itself!!
847
            //        => protecting method TaxonDescription.setTaxon() ?
848
    public void testAddDescriptionToTaxon(){
849

    
850
        SecurityContext context = SecurityContextHolder.getContext();
851
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
852
        context.setAuthentication(authentication);
853

    
854
        RuntimeException securityException = null;
855

    
856
        Taxon taxon = (Taxon)taxonService.load(ACHERONTIA_LACHESIS_UUID);
857

    
858
        TaxonDescription description = TaxonDescription.NewInstance(taxon);
859
        description.setTitleCache("test", true);
860
        try {
861
            descriptionService.saveOrUpdate(description);
862
            commitAndStartNewTransaction(null);
863
        } catch (RuntimeException e){
864
            securityException = findSecurityRuntimeException(e);
865
            logger.debug("Expected failure of evaluation.", securityException);
866
        } finally {
867
            // needed in case saveOrUpdate was interrupted by the RuntimeException
868
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
869
            endTransaction();
870
            startNewTransaction();
871
        }
872
        /*
873
         * Expectation:
874
         * The user should not be granted to add the Description to a taxon
875
         */
876
        Assert.assertNotNull("evaluation should fail since the user is not permitted to edit Taxa", securityException);
877
        taxon = (Taxon)taxonService.load(ACHERONTIA_LACHESIS_UUID);
878
        assertTrue(taxon.getDescriptions().contains(description));
879
    }
880

    
881
    @Test
882
    public void testMoveDescriptionElement(){
883

    
884
        SecurityContext context = SecurityContextHolder.getContext();
885
        authentication = authenticationManager.authenticate(tokenForTaxonomist);
886
        context.setAuthentication(authentication);
887

    
888
        RuntimeException securityException = null;
889

    
890
        Taxon t_acherontia_lachesis = (Taxon)taxonService.load(ACHERONTIA_LACHESIS_UUID);
891
        Taxon t_acherontia_styx = (Taxon)taxonService.load(UUID_ACHERONTIA_STYX);
892

    
893
        TaxonDescription description_acherontia_styx = t_acherontia_styx.getDescriptions().iterator().next();
894
        TaxonDescription description_acherontia_lachesis = t_acherontia_lachesis.getDescriptions().iterator().next();
895

    
896
        try {
897
            descriptionService.moveDescriptionElementsToDescription(description_acherontia_styx.getElements(), description_acherontia_lachesis, false);
898
            commitAndStartNewTransaction(null);
899
        } catch (RuntimeException e){
900
            securityException = findSecurityRuntimeException(e);
901
            logger.debug("Unexpected failure of evaluation.", securityException);
902
        } finally {
903
            // needed in case saveOrUpdate was interrupted by the RuntimeException
904
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
905
            endTransaction();
906
            startNewTransaction();
907
        }
908
        /*
909
         * Expectation:
910
         */
911
        Assert.assertNull("evaluation should not fail since the user has sufficient permissions", securityException);
912

    
913
    }
914

    
915
//    @Ignore // FIXME http://dev.e-taxonomy.eu/trac/ticket/4081 : #4081 (TaxonNodeServiceImpl.makeTaxonNodeASynonymOfAnotherTaxonNode() requires TAXONNAMEBASE.[UPDATE])
916
    @Test
917
    public void testAcceptedTaxonToSynomym(){
918

    
919
        SecurityContext context = SecurityContextHolder.getContext();
920
        authentication = authenticationManager.authenticate(tokenForPartEditor);
921
        context.setAuthentication(authentication);
922

    
923
        RuntimeException securityException = null;
924

    
925
        Taxon t_acherontia_lachesis = (Taxon)taxonService.load(ACHERONTIA_LACHESIS_UUID);
926
        UUID name_acherontia_lachesis_uuid = t_acherontia_lachesis.getName().getUuid();
927
        Taxon t_acherontia_styx = (Taxon)taxonService.load(UUID_ACHERONTIA_STYX);
928
        int countSynsBefore = t_acherontia_styx.getSynonyms().size();
929

    
930
        TaxonNode n_acherontia_lachesis = t_acherontia_lachesis.getTaxonNodes().iterator().next();
931
        TaxonNode n_acherontia_styx = t_acherontia_styx.getTaxonNodes().iterator().next();
932

    
933
        int numOfSynonymsBefore_styx = t_acherontia_styx.getSynonyms().size();
934
        int numOfSynonymsBefore_lachesis = t_acherontia_lachesis.getSynonyms().size();
935

    
936

    
937
        try {
938
            taxonNodeService.makeTaxonNodeASynonymOfAnotherTaxonNode(n_acherontia_lachesis, n_acherontia_styx, SynonymRelationshipType.SYNONYM_OF(), null, null);
939
//            synonymUuid = synonym.getUuid();
940
//            taxonService.saveOrUpdate(synonym);
941
            commitAndStartNewTransaction(null);
942
        } catch (RuntimeException e){
943
            securityException = findSecurityRuntimeException(e);
944
            logger.error("Unexpected Exception ", e);
945
            Assert.fail("Unexpected Exception: " + e.getMessage());
946
        } finally {
947
            // needed in case saveOrUpdate was interrupted by the RuntimeException
948
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
949
            endTransaction();
950
            startNewTransaction();
951
        }
952
        /*
953
         * Expectation:
954
         */
955
        Assert.assertNull("evaluation should not fail since the user has sufficient permissions", securityException);
956

    
957
        // reload from db and check assertions
958
        t_acherontia_styx = (Taxon)taxonService.load(UUID_ACHERONTIA_STYX);
959
        Assert.assertEquals(numOfSynonymsBefore_styx +1 + numOfSynonymsBefore_lachesis, t_acherontia_styx.getSynonyms().size());
960

    
961
        Assert.assertNotNull(nameService.load(name_acherontia_lachesis_uuid) );
962
        Assert.assertNull("The old TaxonNode should no longer exist", taxonNodeService.find(n_acherontia_lachesis.getUuid()));
963
    }
964

    
965
    @Test
966
    public void testCreateDescriptionWithElement(){
967

    
968
        SecurityContext context = SecurityContextHolder.getContext();
969
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
970
        context.setAuthentication(authentication);
971

    
972
        TaxonDescription description = null;
973
        RuntimeException securityException = null;
974
        Taxon taxon = (Taxon)taxonService.load(UUID_ACHERONTINII);
975
        Assert.assertTrue("taxon must not yet have descriptions", taxon.getDescriptions().size() == 0);
976

    
977

    
978
        // 1) test for failure - description element but no feature
979
        description = TaxonDescription.NewInstance(taxon);
980
        DescriptionElementBase textdataNoFeature = TextData.NewInstance();
981
        description.addElement(textdataNoFeature);
982

    
983
        assertTrue(permissionEvaluator.hasPermission(authentication, description, "UPDATE"));
984
        try{
985
            descriptionService.saveOrUpdate(description);
986
            commitAndStartNewTransaction(null);
987
        } catch (RuntimeException e){
988
            securityException = findSecurityRuntimeException(e);
989
            logger.error("RuntimeException caught");
990
            logger.debug("Expected failure of evaluation.", securityException);
991
        } finally {
992
            // needed in case saveOrUpdate was interrupted by the RuntimeException
993
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
994
            endTransaction();
995
            startNewTransaction();
996
        }
997

    
998
        Assert.assertNotNull("evaluation should fail", securityException);
999
        taxon = (Taxon)taxonService.load(UUID_ACHERONTINII);
1000
        Set<TaxonDescription> descriptions = taxon.getDescriptions();
1001
        assertTrue("taxon must not have any description", descriptions.size() == 0);
1002

    
1003
    }
1004

    
1005
    @Test
1006
    public void testCreateDescriptionWithElementDeny_1(){
1007

    
1008
        SecurityContext context = SecurityContextHolder.getContext();
1009
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
1010
        context.setAuthentication(authentication);
1011

    
1012
        TaxonDescription description = null;
1013
        RuntimeException securityException = null;
1014
        Taxon taxon = (Taxon)taxonService.load(UUID_ACHERONTINII);
1015
        Assert.assertTrue("taxon must not yet have descriptions", taxon.getDescriptions().size() == 0);
1016

    
1017
        // 2) test for failure  - description element but not granted feature
1018
        description = TaxonDescription.NewInstance(taxon);
1019
        DescriptionElementBase descriptionText = TextData.NewInstance(Feature.DESCRIPTION());
1020
        description.addElement(descriptionText);
1021

    
1022
        assertTrue(permissionEvaluator.hasPermission(authentication, description, "UPDATE"));
1023
        try{
1024
            descriptionService.saveOrUpdate(description);
1025
            commitAndStartNewTransaction(null);
1026
        } catch (RuntimeException e){
1027
            securityException = findSecurityRuntimeException(e);
1028
            logger.debug("Expected failure of evaluation.", securityException);
1029
        } finally {
1030
            // needed in case saveOrUpdate was interrupted by the RuntimeException
1031
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1032
            endTransaction();
1033
            startNewTransaction();
1034
        }
1035

    
1036
        Assert.assertNotNull("evaluation should fail", securityException);
1037
        taxon = (Taxon)taxonService.load(UUID_ACHERONTINII);
1038
        Set<TaxonDescription> descriptions = taxon.getDescriptions();
1039
        assertTrue("taxon must not have any description", descriptions.size() == 0);
1040

    
1041
    }
1042

    
1043
    @Test
1044
    public void testCreateDescriptionWithElementDeny_2(){
1045

    
1046
        SecurityContext context = SecurityContextHolder.getContext();
1047
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
1048
        context.setAuthentication(authentication);
1049

    
1050
        TaxonDescription description = null;
1051
        RuntimeException securityException = null;
1052
        Taxon taxon = (Taxon)taxonService.load(UUID_ACHERONTINII);
1053
        Assert.assertTrue("taxon must not yet have descriptions", taxon.getDescriptions().size() == 0);
1054

    
1055
        // 3) test for failure
1056
        description = TaxonDescription.NewInstance(taxon);
1057
        DescriptionElementBase ecologyText = TextData.NewInstance(Feature.ECOLOGY());
1058
        description.addElement(ecologyText);
1059

    
1060
        assertTrue(permissionEvaluator.hasPermission(authentication, description, "UPDATE"));
1061
        try{
1062
            descriptionService.saveOrUpdate(description);
1063
            commitAndStartNewTransaction(null);
1064
        } catch (RuntimeException e){
1065
            securityException = findSecurityRuntimeException(e);
1066
            logger.error("Unexpected failure of evaluation.", e);
1067
        } finally {
1068
            // needed in case saveOrUpdate was interrupted by the RuntimeException
1069
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1070
            endTransaction();
1071
            startNewTransaction();
1072
        }
1073

    
1074
        Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
1075
        taxon = (Taxon)taxonService.load(UUID_ACHERONTINII);
1076
        Set<TaxonDescription> descriptions = taxon.getDescriptions();
1077
        assertTrue("taxon must now have one description", descriptions.size() == 1);
1078
        assertTrue("description should have one description element", descriptions.iterator().next().getElements().size() == 1);
1079
    }
1080

    
1081
    @Test
1082
    public void testSaveSynonymAllow(){
1083

    
1084
        SecurityContext context = SecurityContextHolder.getContext();
1085
        RuntimeException securityException = null;
1086

    
1087
        // 1) test for success
1088
        authentication = authenticationManager.authenticate(tokenForTaxonomist);
1089
        context.setAuthentication(authentication);
1090

    
1091
        Synonym syn = Synonym.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null);
1092
        UUID synUuid = UUID.randomUUID();
1093
        syn.setUuid(synUuid);
1094
        try{
1095
            taxonService.saveOrUpdate(syn);
1096
            logger.debug("will commit ...");
1097
            commitAndStartNewTransaction(null);
1098
        } catch (RuntimeException e){
1099
            securityException = findSecurityRuntimeException(e);
1100
            logger.error("Unexpected failure of evaluation.", e);
1101
        } finally {
1102
            // needed in case saveOrUpdate was interrupted by the RuntimeException
1103
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1104
            endTransaction();
1105
            startNewTransaction();
1106
        }
1107
        Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
1108
        Assert.assertNotNull("The new Synonym must be persited", taxonService.find(synUuid));
1109
    }
1110

    
1111
    @Test
1112
    public void testSaveSynonymDenial(){
1113

    
1114
        SecurityContext context = SecurityContextHolder.getContext();
1115
        RuntimeException securityException = null;
1116
        // 2) test for denial
1117
        authentication = authenticationManager.authenticate(tokenForDescriptionEditor);
1118
        context.setAuthentication(authentication);
1119
        Synonym syn = Synonym.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null);
1120
        UUID synUuid = syn.getUuid();
1121
        try{
1122
            taxonService.saveOrUpdate(syn);
1123
            logger.debug("will commit ...");
1124
            commitAndStartNewTransaction(null);
1125
        } catch (RuntimeException e){
1126
            securityException = findSecurityRuntimeException(e);
1127
            logger.debug("Expected failure of evaluation: " + securityException.getClass());
1128
        } finally {
1129
            // needed in case saveOrUpdate was interrupted by the RuntimeException
1130
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1131
            endTransaction();
1132
            startNewTransaction();
1133
        }
1134

    
1135
        Assert.assertNotNull("evaluation must fail since the user is not permitted", securityException);
1136
        Assert.assertNull("The Synonym must not be persited", taxonService.find(synUuid));
1137
    }
1138

    
1139
    @Test
1140
    public void testEditPartOfClassificationAllow(){
1141

    
1142
        authentication = authenticationManager.authenticate(tokenForPartEditor);
1143
        SecurityContext context = SecurityContextHolder.getContext();
1144
        context.setAuthentication(authentication);
1145
        RuntimeException securityException = null;
1146
        classificationService.load(UUID.fromString("aeee7448-5298-4991-b724-8d5b75a0a7a9"));
1147
        // test for success
1148
        TaxonNode acherontia_node = taxonNodeService.load(ACHERONTIA_NODE_UUID);
1149
        long numOfChildNodes = acherontia_node.getChildNodes().size();
1150
        acherontia_node.addChildTaxon(Taxon.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null), null, null);
1151

    
1152
        try{
1153
            taxonNodeService.saveOrUpdate(acherontia_node);
1154
            commitAndStartNewTransaction(null);
1155
        } catch (RuntimeException e){
1156
            securityException = findSecurityRuntimeException(e);
1157
            logger.error("Unexpected failure of evaluation.", securityException);
1158
        } finally {
1159
            // needed in case saveOrUpdate was interrupted by the RuntimeException
1160
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1161
            endTransaction();
1162
            startNewTransaction();
1163
        }
1164

    
1165
        acherontia_node = taxonNodeService.load(ACHERONTIA_NODE_UUID);
1166
        Assert.assertNull("evaluation must not fail since the user is permitted, CAUSE :" + (securityException != null ? securityException.getMessage() : ""), securityException);
1167
        Assert.assertEquals("the acherontia_node must now have one more child node ", numOfChildNodes + 1 , acherontia_node.getChildNodes().size());
1168
    }
1169

    
1170
    @Test
1171
    public void testEditPartOfClassificationDeny(){
1172

    
1173
        authentication = authenticationManager.authenticate(tokenForPartEditor);
1174
        SecurityContext context = SecurityContextHolder.getContext();
1175
        context.setAuthentication(authentication);
1176
        RuntimeException securityException = null;
1177

    
1178
        // test for denial
1179
        TaxonNode acherontiini_node = taxonNodeService.load(ACHERONTIINI_NODE_UUID);
1180
        int numOfChildNodes = acherontiini_node.getCountChildren();
1181
        acherontiini_node.addChildTaxon(Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()), null), null, null);
1182

    
1183
        try{
1184
            logger.debug("==============================");
1185
            taxonNodeService.saveOrUpdate(acherontiini_node);
1186
            commitAndStartNewTransaction(null);
1187
        } catch (RuntimeException e){
1188
            securityException = findSecurityRuntimeException(e);
1189
            logger.debug("Expected failure of evaluation.", securityException);
1190
        } finally {
1191
            // needed in case saveOrUpdate was interrupted by the RuntimeException
1192
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
1193
            endTransaction();
1194
            startNewTransaction();
1195
        }
1196

    
1197
        acherontiini_node = taxonNodeService.load(ACHERONTIINI_NODE_UUID);
1198
        Assert.assertNotNull("evaluation must fail since the user is not permitted", securityException);
1199
        Assert.assertEquals("the number of child nodes must be unchanged ", numOfChildNodes , acherontiini_node.getChildNodes().size());
1200

    
1201
    }
1202

    
1203
    /* (non-Javadoc)
1204
     * @see eu.etaxonomy.cdm.test.integration.CdmIntegrationTest#createTestData()
1205
     */
1206
    @Override
1207
    public void createTestDataSet() throws FileNotFoundException {
1208
        // TODO Auto-generated method stub
1209

    
1210
    }
1211

    
1212
}
(19-19/31)