Project

General

Profile

Download (51.1 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.TaxonNameBase;
52
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
53
import eu.etaxonomy.cdm.model.name.ZoologicalName;
54
import eu.etaxonomy.cdm.model.reference.Reference;
55
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
56
import eu.etaxonomy.cdm.model.taxon.Synonym;
57
import eu.etaxonomy.cdm.model.taxon.SynonymType;
58
import eu.etaxonomy.cdm.model.taxon.Taxon;
59
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
60
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
61
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
62
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
63
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionClass;
64
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionEvaluator;
65
import eu.etaxonomy.cdm.persistence.hibernate.permission.Operation;
66
import eu.etaxonomy.cdm.persistence.query.MatchMode;
67
import sun.security.provider.PolicyParser.ParsingException;
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(TaxonNameFactory.NewBotanicalInstance(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(TaxonNameFactory.NewBotanicalInstance(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(TaxonNameFactory.NewBotanicalInstance(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(TaxonNameFactory.NewBotanicalInstance(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 = TaxonNameFactory.NewZoologicalInstance(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
    @Ignore  //#5829  should be fixed as soon as possible
273
    public final void testReuseNameAllow() {
274

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

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

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

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

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

    
311
        Reference book = referenceService.load(BOOK1_UUID);
312

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

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

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

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

    
342
        Reference book = referenceService.load(BOOK1_UUID);
343

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

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

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

    
369

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

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

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

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

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

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

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

    
439
    @Test
440
    public void testChangeOwnPassword(){
441

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

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

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

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

    
458
    @Test
459
    public void testChangeOthersPasswordAllow(){
460

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

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

    
468

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

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

    
491
    @Test
492
    public void testChangeOthersPasswordDeny(){
493

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

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

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

    
527
    @Test
528
    public void testUpdateUser(){
529

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

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

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

    
545
    }
546

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

    
553
        SecurityContext context = SecurityContextHolder.getContext();
554

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

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

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

    
586

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

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

    
593
        context.setAuthentication(authentication);
594

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

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

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

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

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

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

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

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

    
654
        SecurityContext context = SecurityContextHolder.getContext();
655

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

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

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

    
682

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

    
689
        SecurityContext context = SecurityContextHolder.getContext();
690

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

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

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

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

    
723
        SecurityContext context = SecurityContextHolder.getContext();
724

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

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

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

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

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

    
758
        SecurityContext context = SecurityContextHolder.getContext();
759

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

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

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

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

    
780
        SecurityContext context = SecurityContextHolder.getContext();
781

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

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

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

    
813

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

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

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

    
826
        Taxon taxon = (Taxon)taxonService.load(UUID_LACTUCA);
827
        try{
828
        DeleteResult result = taxonService.deleteTaxon(taxon.getUuid(), null, null);
829
        if(result.isOk()){
830
            Assert.fail();
831
        }
832
        }catch(PermissionDeniedException e){
833

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

    
838

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

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

    
847

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

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

    
857
        RuntimeException securityException = null;
858

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

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

    
884
    @Test
885
    public void testMoveDescriptionElement(){
886

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

    
891
        RuntimeException securityException = null;
892

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

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

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

    
916
    }
917

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

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

    
926
        RuntimeException securityException = null;
927

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

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

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

    
939

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

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

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

    
968
    @Test
969
    public void testCreateDescriptionWithElement(){
970

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

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

    
980

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

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

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

    
1006
    }
1007

    
1008
    @Test
1009
    public void testCreateDescriptionWithElementDeny_1(){
1010

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

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

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

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

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

    
1044
    }
1045

    
1046
    @Test
1047
    public void testCreateDescriptionWithElementDeny_2(){
1048

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

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

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

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

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

    
1084
    @Test
1085
    public void testSaveSynonymAllow(){
1086

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

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

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

    
1114
    @Test
1115
    public void testSaveSynonymDenial(){
1116

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

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

    
1142
    @Test
1143
    public void testEditPartOfClassificationAllow(){
1144

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

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

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

    
1173
    @Test
1174
    public void testEditPartOfClassificationDeny(){
1175

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

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

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

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

    
1204
    }
1205

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

    
1213
    }
1214

    
1215
}
(19-19/33)