Project

General

Profile

Download (13 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 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 java.io.FileNotFoundException;
12
import java.util.ArrayList;
13
import java.util.List;
14
import java.util.Set;
15

    
16
import org.apache.log4j.Logger;
17
import org.junit.Assert;
18
import org.junit.Test;
19
import org.springframework.security.access.AccessDeniedException;
20
import org.springframework.security.authentication.AuthenticationManager;
21
import org.springframework.security.core.Authentication;
22
import org.springframework.security.core.GrantedAuthority;
23
import org.springframework.security.core.context.SecurityContext;
24
import org.springframework.security.core.context.SecurityContextHolder;
25
import org.unitils.dbunit.annotation.DataSet;
26
import org.unitils.spring.annotation.SpringBeanByType;
27

    
28
import eu.etaxonomy.cdm.database.PermissionDeniedException;
29
import eu.etaxonomy.cdm.model.permission.GrantedAuthorityImpl;
30
import eu.etaxonomy.cdm.model.permission.Group;
31
import eu.etaxonomy.cdm.model.permission.User;
32
import eu.etaxonomy.cdm.persistence.permission.Role;
33

    
34
/**
35
 * @author a.kohlbecker
36
 * @since Feb 4, 2014
37
 */
38
@DataSet(value="SecurityTest.xml")
39
public class UserAndGroupServiceImplTest extends AbstractSecurityTestBase {
40

    
41
    protected static final Logger logger = Logger.getLogger(UserAndGroupServiceImplTest.class);
42

    
43
    @SpringBeanByType
44
    private AuthenticationManager authenticationManager;
45

    
46
    @SpringBeanByType
47
    private IUserService userService;
48

    
49
    @SpringBeanByType
50
    private IGroupService groupService;
51

    
52
    @SpringBeanByType
53
    private IGrantedAuthorityService grantedAuthorityService;
54

    
55
    @SpringBeanByType
56
    private ITaxonService taxonService;
57

    
58
    private Authentication authentication;
59

    
60
    @Test
61
    public void testCreateUser() {
62

    
63
        authentication = authenticationManager.authenticate(tokenForAdmin);
64
        SecurityContext context = SecurityContextHolder.getContext();
65
        context.setAuthentication(authentication);
66

    
67
        try{
68
            userService.createUser(User.NewInstance("new_user_1", "00000"));
69
        }catch(Exception e){
70
            Assert.fail();
71
        }
72

    
73
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
74
        context = SecurityContextHolder.getContext();
75
        context.setAuthentication(authentication);
76

    
77
        try{
78
            userService.createUser(User.NewInstance("new_user_2", "00000"));
79
            Assert.fail();
80
        }catch(Exception e){
81
            Assert.assertEquals("Access is denied", e.getMessage());
82
        }
83
    }
84

    
85
    @Test
86
    public void testUpdateUser(){
87

    
88
        // TaxonEditor should be able to change its own email address
89
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
90
        SecurityContext context = SecurityContextHolder.getContext();
91
        context.setAuthentication(authentication);
92

    
93
        User user= userService.find(TAXON_EDITOR_UUID);
94
        user.setEmailAddress("test@bgbm.org");
95

    
96
        /* FIXME
97
        try{
98
            userService.updateUser(user);
99
        }catch (Exception e){
100
            Assert.fail("the user TaxonEditor should be able to change its own email address");
101
        }
102
        */
103

    
104
        authentication = authenticationManager.authenticate(tokenForUserManager);
105
        context = SecurityContextHolder.getContext();
106
        context.setAuthentication(authentication);
107

    
108
        user.setEmailAddress("user@bgbm.org");
109

    
110
        try{
111
            userService.updateUser(user);
112
        }catch (Exception e){
113
            Assert.fail("the user UserManager should be able to change others email addresses");
114
        }
115

    
116
        authentication = authenticationManager.authenticate(tokenForPartEditor);
117
        context = SecurityContextHolder.getContext();
118
        context.setAuthentication(authentication);
119

    
120
        try{
121
            userService.updateUser(user);
122
            Assert.fail("the user PartEditor should NOT be able to change others email addresses");
123
        }catch (Exception e){
124
            Assert.assertEquals("Access is denied", e.getMessage());
125
        }
126
    }
127

    
128
    @Test
129
    public void testChangePassword(){
130

    
131
        // the user TaxonEditor should be able to change its own password
132
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
133
        SecurityContext context = SecurityContextHolder.getContext();
134
        context.setAuthentication(authentication);
135

    
136
        userService.changePasswordForUser(tokenForTaxonEditor.getName(), "newPassword");
137

    
138
        Exception exception = null;
139
        // the user TaxonEditor should NOT be able to change others passwords
140
        try{
141
            userService.changePasswordForUser(tokenForAdmin.getName(), "newPassword");
142
            commitAndStartNewTransaction(null);
143
        } catch (AccessDeniedException e){
144
            logger.debug("Expected failure of evaluation.", e);
145
            exception  = e;
146
        } catch (RuntimeException e){
147
            exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
148
            logger.debug("Expected failure of evaluation.", exception);
149
        } finally {
150
            // needed in case saveOrUpdate was interrupted by the RuntimeException
151
            // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
152
            endTransaction();
153
            startNewTransaction();
154
        }
155
        Assert.assertNotNull("must fail here!", exception);
156

    
157
        // the user User manager should be able to change others passwords
158
        authentication = authenticationManager.authenticate(tokenForUserManager);
159
        context = SecurityContextHolder.getContext();
160
        context.setAuthentication(authentication);
161
        userService.changePasswordForUser(tokenForAdmin.getName(), "newPassword");
162
    }
163

    
164
    @Test
165
    public void testCreateGroup(){
166

    
167
        authentication = authenticationManager.authenticate(tokenForUserManager);
168
        SecurityContext context = SecurityContextHolder.getContext();
169
        context.setAuthentication(authentication);
170

    
171
        List<GrantedAuthority> authorityList = new ArrayList<>();
172
        GrantedAuthorityImpl roleRemotingAuthority = GrantedAuthorityImpl.NewInstance(null);
173
        roleRemotingAuthority.setAuthority(Role.ROLE_REMOTING.toString()); // testing if creating a Role from string is working
174
        authorityList.add(roleRemotingAuthority);
175

    
176
        String remotingGroupName = "publishers";
177

    
178
        groupService.createGroup(remotingGroupName, authorityList);
179

    
180
        commitAndStartNewTransaction(null);
181

    
182
        List<GrantedAuthority> groupAuthorities = groupService.findGroupAuthorities(remotingGroupName);
183

    
184
        Assert.assertEquals(Role.ROLE_REMOTING.toString(), groupAuthorities.get(0).getAuthority());
185
    }
186

    
187
    @Test
188
    public void testRefreshUser(){
189

    
190
        String newGroupName = "new_publishers";
191

    
192
        // -----------------------------------------------------------------
193
        // authenticate as TaxonEditor to load the user for the first time and to let cache it in the session
194
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
195
        SecurityContext context = SecurityContextHolder.getContext();
196
        context.setAuthentication(authentication);
197

    
198
        User user = (User) authentication.getPrincipal();
199

    
200
        // check that everything is clean
201
        for(GrantedAuthority authority : user.getAuthorities()){
202
            if(authority.equals(Role.ROLE_PUBLISH)){
203
                Assert.fail("an authority '" + Role.ROLE_PUBLISH + "' must not yet exists");
204
            }
205
        }
206
        for(Group group : user.getGroups()){
207
            if(group.getName().equals(newGroupName)){
208
                Assert.fail("the group '" + newGroupName + "' must not yet exists");
209
            }
210
        }
211

    
212
        // -----------------------------------------------------------------
213
        // authenticate as UserManager to be able to add the role ROLE_PUBLISH in various ways
214
        authentication = authenticationManager.authenticate(tokenForUserManager);
215
        context = SecurityContextHolder.getContext();
216
        context.setAuthentication(authentication);
217

    
218
        // create an entity of ROLE_PUBLISH and save it to the database
219
        commitAndStartNewTransaction(null);
220
        GrantedAuthorityImpl rolePublish = grantedAuthorityService.load(Role.ROLE_PUBLISH.getUuid());
221

    
222
        user = userService.load(TAXON_EDITOR_UUID);
223

    
224
        // 1. add to the users GrantedAuthorities
225
        // TODO is there any other way to do this?
226
        Set<GrantedAuthority> grantedAuthorities = user.getGrantedAuthorities();
227
        grantedAuthorities.add(rolePublish);
228
        user.setGrantedAuthorities(grantedAuthorities);
229
        userService.saveOrUpdate(user);
230

    
231
        commitAndStartNewTransaction(null);
232

    
233
        // 2. add to existing group
234
        Group group_special_editor = groupService.load(GROUP_SPECIAL_EDITOR_UUID);
235
        String groupSpecialEditor_Name = group_special_editor.getName();
236
        rolePublish = grantedAuthorityService.load(Role.ROLE_PUBLISH.getUuid());
237
        group_special_editor.addGrantedAuthority(rolePublish);
238
        groupService.saveOrUpdate(group_special_editor);
239

    
240
        commitAndStartNewTransaction(null);
241

    
242
        // 3. add in new group
243
        Group groupNewPublishers = Group.NewInstance(newGroupName);
244
        rolePublish = grantedAuthorityService.load(Role.ROLE_PUBLISH.getUuid());
245
        groupNewPublishers.addGrantedAuthority(rolePublish);
246
        groupService.saveOrUpdate(groupNewPublishers);
247
        groupService.addUserToGroup(user.getUsername(), newGroupName);
248

    
249
        commitAndStartNewTransaction(null);
250

    
251
        // -----------------------------------------------------------------
252
        // again authenticate as TaxonEditor
253
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
254
        context = SecurityContextHolder.getContext();
255
        context.setAuthentication(authentication);
256

    
257
        // and check if everything is updated
258
        user = (User) authentication.getPrincipal();
259

    
260
        // 1. check users authorities for the role
261
        boolean newAuthorityFound = false;
262
        for(GrantedAuthority authority : user.getAuthorities()){
263
            if(authority.equals(Role.ROLE_PUBLISH)){
264
                newAuthorityFound = true;
265
                break;
266
            }
267
        }
268
        Assert.assertTrue("the new authority '" + Role.ROLE_PUBLISH + "' is missing", newAuthorityFound);
269

    
270
        // 2. check for role in existing group
271
        boolean newAuthorityFoundInExistingGroup = false;
272
        for(Group group : user.getGroups()){
273
            if(group.getUuid().equals(GROUP_SPECIAL_EDITOR_UUID)){
274
                for(GrantedAuthority authority : group.getGrantedAuthorities()){
275
                    if(authority.equals(Role.ROLE_PUBLISH)){
276
                        newAuthorityFoundInExistingGroup = true;
277
                        break;
278
                    }
279
                }
280
                if(newAuthorityFoundInExistingGroup){
281
                    break;
282
                }
283
            }
284
        }
285
        Assert.assertTrue("the new authority '" + Role.ROLE_PUBLISH + "' is missing in existing group", newAuthorityFoundInExistingGroup);
286

    
287
        // 3. check new group
288
        boolean newGroupFound = false;
289
        for(Group group : user.getGroups()){
290
            if(group.getName().equals(newGroupName)){
291
                newGroupFound = true;
292
                break;
293
            }
294
        }
295
        Assert.assertTrue("the new group '" + newGroupName + "' is missing", newGroupFound);
296

    
297
        // ==================================================================
298
        // again authenticate as UserManager to be able to add the role ROLE_PUBLISH in various ways
299
        authentication = authenticationManager.authenticate(tokenForUserManager);
300
        context = SecurityContextHolder.getContext();
301
        context.setAuthentication(authentication);
302

    
303
        groupService.removeUserFromGroup(user.getUsername(), groupSpecialEditor_Name);
304

    
305
        commitAndStartNewTransaction(null);
306

    
307
        // -----------------------------------------------------------------
308
        // again authenticate as TaxonEditor
309
        authentication = authenticationManager.authenticate(tokenForTaxonEditor);
310
        context = SecurityContextHolder.getContext();
311
        context.setAuthentication(authentication);
312

    
313
        // and check if the group has been removed from the user
314
        user = (User) authentication.getPrincipal();
315

    
316
        for(Group group: user.getGroups()){
317
            if(group.getName().equals(groupSpecialEditor_Name)){
318
                Assert.fail("The user TaxonEditor should no longer be member of this group");
319
            }
320
        }
321
    }
322

    
323
    @Override
324
    public void createTestDataSet() throws FileNotFoundException {}
325

    
326
}
(37-37/38)