Project

General

Profile

Download (51 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 eu.etaxonomy.cdm.database.PermissionDeniedException;
44
import eu.etaxonomy.cdm.model.common.GrantedAuthorityImpl;
45
import eu.etaxonomy.cdm.model.common.User;
46
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
47
import eu.etaxonomy.cdm.model.description.Feature;
48
import eu.etaxonomy.cdm.model.description.TaxonDescription;
49
import eu.etaxonomy.cdm.model.description.TextData;
50
import eu.etaxonomy.cdm.model.name.Rank;
51
import eu.etaxonomy.cdm.model.name.TaxonName;
52
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
53
import eu.etaxonomy.cdm.model.reference.Reference;
54
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
55
import eu.etaxonomy.cdm.model.taxon.Synonym;
56
import eu.etaxonomy.cdm.model.taxon.SynonymType;
57
import eu.etaxonomy.cdm.model.taxon.Taxon;
58
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
59
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
60
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
61
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
62
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionClass;
63
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionEvaluator;
64
import eu.etaxonomy.cdm.persistence.hibernate.permission.Operation;
65
import eu.etaxonomy.cdm.persistence.query.MatchMode;
66
import sun.security.provider.PolicyParser.ParsingException;
67

    
68

    
69
@DataSet
70
public class SecurityTest extends AbstractSecurityTestBase{
71

    
72

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

    
75
    @SpringBeanByType
76
    private ITaxonService taxonService;
77

    
78
    @SpringBeanByType
79
    private INameService nameService;
80

    
81
    @SpringBeanByType
82
    private IReferenceService referenceService;
83

    
84
    @SpringBeanByType
85
    private ITaxonNodeService taxonNodeService;
86

    
87
    @SpringBeanByType
88
    private IDescriptionService descriptionService;
89

    
90
    @SpringBeanByType
91
    private IUserService userService;
92

    
93
    @SpringBeanByType
94
    private IClassificationService classificationService;
95

    
96
    @SpringBeanByType
97
    private AuthenticationManager authenticationManager;
98

    
99
    @SpringBeanByType
100
    private SaltSource saltSource;
101

    
102
    @SpringBeanByType
103
    private PasswordEncoder passwordEncoder;
104

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

    
108
    @TestDataSource
109
    protected DataSource dataSource;
110

    
111
    private Authentication authentication;
112

    
113

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

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

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

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

    
132
        Taxon taxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()),null);
133

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

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

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

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

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

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

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

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

    
181
    }
182

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

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

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

    
209
    }
210

    
211

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

    
217
        Taxon taxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()),null);
218

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

    
224

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

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

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

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

    
252
    }
253

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

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

    
261
        TaxonName newName = TaxonNameFactory.NewZoologicalInstance(Rank.SPECIES());
262
        newName.setTitleCache("Newby taxonEditor", true);
263
        UUID uuid = nameService.saveOrUpdate(newName);
264
        commitAndStartNewTransaction(null);
265
        TaxonName savedName = nameService.load(uuid);
266
        assertEquals(newName, savedName);
267
    }
268

    
269

    
270
    @Test
271
    @Ignore  //#5829  should be fixed as soon as possible
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
        TaxonName 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, SynonymType.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, SynonymType.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, taxon.getTaxonNodes().iterator().next().getClassification().getUuid());
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
        DeleteResult result = taxonService.deleteTaxon(taxon.getUuid(), null, null);
828
        if(result.isOk()){
829
            Assert.fail();
830
        }
831
        }catch(PermissionDeniedException e){
832

    
833
        }
834
       endTransaction();
835
       startNewTransaction();
836

    
837

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

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

    
846

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

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

    
856
        RuntimeException securityException = null;
857

    
858
        Taxon taxon = (Taxon)taxonService.load(ACHERONTIA_LACHESIS_UUID);
859

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

    
883
    @Test
884
    public void testMoveDescriptionElement(){
885

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

    
890
        RuntimeException securityException = null;
891

    
892
        Taxon t_acherontia_lachesis = (Taxon)taxonService.load(ACHERONTIA_LACHESIS_UUID);
893
        Taxon t_acherontia_styx = (Taxon)taxonService.load(UUID_ACHERONTIA_STYX);
894

    
895
        TaxonDescription description_acherontia_styx = t_acherontia_styx.getDescriptions().iterator().next();
896
        TaxonDescription description_acherontia_lachesis = t_acherontia_lachesis.getDescriptions().iterator().next();
897

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

    
915
    }
916

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

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

    
925
        RuntimeException securityException = null;
926

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

    
932
        TaxonNode n_acherontia_lachesis = t_acherontia_lachesis.getTaxonNodes().iterator().next();
933
        TaxonNode n_acherontia_styx = t_acherontia_styx.getTaxonNodes().iterator().next();
934

    
935
        int numOfSynonymsBefore_styx = t_acherontia_styx.getSynonyms().size();
936
        int numOfSynonymsBefore_lachesis = t_acherontia_lachesis.getSynonyms().size();
937

    
938

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

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

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

    
967
    @Test
968
    public void testCreateDescriptionWithElement(){
969

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

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

    
979

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

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

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

    
1005
    }
1006

    
1007
    @Test
1008
    public void testCreateDescriptionWithElementDeny_1(){
1009

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

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

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

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

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

    
1043
    }
1044

    
1045
    @Test
1046
    public void testCreateDescriptionWithElementDeny_2(){
1047

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

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

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

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

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

    
1083
    @Test
1084
    public void testSaveSynonymAllow(){
1085

    
1086
        SecurityContext context = SecurityContextHolder.getContext();
1087
        RuntimeException securityException = null;
1088

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

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

    
1113
    @Test
1114
    public void testSaveSynonymDenial(){
1115

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

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

    
1141
    @Test
1142
    public void testEditPartOfClassificationAllow(){
1143

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

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

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

    
1172
    @Test
1173
    public void testEditPartOfClassificationDeny(){
1174

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

    
1180
        // test for denial
1181
        TaxonNode acherontiini_node = taxonNodeService.load(ACHERONTIINI_NODE_UUID);
1182
        int numOfChildNodes = acherontiini_node.getCountChildren();
1183
        acherontiini_node.addChildTaxon(Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()), null), null, null);
1184

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

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

    
1203
    }
1204

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

    
1212
    }
1213

    
1214
}
(20-20/34)