implementing #4082 (implement default permission groups)
[cdmlib.git] / cdmlib-services / src / test / java / eu / etaxonomy / cdm / api / service / UserAndGroupServiceImplTest.java
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
10 package eu.etaxonomy.cdm.api.service;
11
12
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Set;
16
17 import org.apache.log4j.Logger;
18 import org.junit.Assert;
19 import org.junit.Test;
20 import org.springframework.security.access.AccessDeniedException;
21 import org.springframework.security.authentication.AuthenticationManager;
22 import org.springframework.security.core.Authentication;
23 import org.springframework.security.core.GrantedAuthority;
24 import org.springframework.security.core.context.SecurityContext;
25 import org.springframework.security.core.context.SecurityContextHolder;
26 import org.unitils.dbunit.annotation.DataSet;
27 import org.unitils.spring.annotation.SpringBeanByType;
28
29 import eu.etaxonomy.cdm.database.PermissionDeniedException;
30 import eu.etaxonomy.cdm.model.common.GrantedAuthorityImpl;
31 import eu.etaxonomy.cdm.model.common.Group;
32 import eu.etaxonomy.cdm.model.common.User;
33 import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
34
35
36 /**
37 * @author a.kohlbecker
38 * @date Feb 4, 2014
39 *
40 */
41 @DataSet(value="SecurityTest.xml")
42 public class UserAndGroupServiceImplTest extends AbstractSecurityTestBase {
43
44 protected static final Logger logger = Logger.getLogger(UserAndGroupServiceImplTest.class);
45
46 @SpringBeanByType
47 private AuthenticationManager authenticationManager;
48
49 @SpringBeanByType
50 private IUserService userService;
51
52 @SpringBeanByType
53 private IGroupService groupService;
54
55 @SpringBeanByType
56 private IGrantedAuthorityService grantedAuthorityService;
57
58 @SpringBeanByType
59 private ITaxonService taxonService;
60
61
62 private Authentication authentication;
63
64
65 @Test
66 public void testCreateUser() {
67
68
69 authentication = authenticationManager.authenticate(tokenForAdmin);
70 SecurityContext context = SecurityContextHolder.getContext();
71 context.setAuthentication(authentication);
72
73
74 try{
75 userService.createUser(User.NewInstance("new user 1", "00000"));
76 }catch(Exception e){
77 Assert.fail();
78 }
79
80 authentication = authenticationManager.authenticate(tokenForTaxonEditor);
81 context = SecurityContextHolder.getContext();
82 context.setAuthentication(authentication);
83
84 try{
85 userService.createUser(User.NewInstance("new user 2", "00000"));
86 Assert.fail();
87 }catch(Exception e){
88 Assert.assertEquals("Access is denied", e.getMessage());
89 }
90 }
91
92
93 @Test
94 public void testUpdateUser(){
95
96 // TaxonEditor should be able to change its own email address
97 authentication = authenticationManager.authenticate(tokenForTaxonEditor);
98 SecurityContext context = SecurityContextHolder.getContext();
99 context.setAuthentication(authentication);
100
101 User user= userService.find(TAXON_EDITOR_UUID);
102 user.setEmailAddress("test@bgbm.org");
103
104 /* FIXME
105 try{
106 userService.updateUser(user);
107 }catch (Exception e){
108 Assert.fail("the user TaxonEditor should be able to change its own email address");
109 }
110 */
111
112 authentication = authenticationManager.authenticate(tokenForUserManager);
113 context = SecurityContextHolder.getContext();
114 context.setAuthentication(authentication);
115
116 user.setEmailAddress("user@bgbm.org");
117
118 try{
119 userService.updateUser(user);
120 }catch (Exception e){
121 Assert.fail("the user UserManager should be able to change others email addresses");
122 }
123
124 authentication = authenticationManager.authenticate(tokenForPartEditor);
125 context = SecurityContextHolder.getContext();
126 context.setAuthentication(authentication);
127
128 try{
129 userService.updateUser(user);
130 Assert.fail("the user PartEditor should NOT be able to change others email addresses");
131 }catch (Exception e){
132 Assert.assertEquals("Access is denied", e.getMessage());
133 }
134
135 }
136
137 @Test
138 public void testChangePassword(){
139
140 // the user TaxonEditor should be able to change its own password
141 authentication = authenticationManager.authenticate(tokenForTaxonEditor);
142 SecurityContext context = SecurityContextHolder.getContext();
143 context.setAuthentication(authentication);
144
145 userService.changePasswordForUser(tokenForTaxonEditor.getName(), "newPassword");
146
147 Exception exception = null;
148 // the user TaxonEditor should NOT be able to change others passwords
149 try{
150 userService.changePasswordForUser(tokenForAdmin.getName(), "newPassword");
151 commitAndStartNewTransaction(null);
152 } catch (AccessDeniedException e){
153 logger.debug("Expected failure of evaluation.", e);
154 exception = e;
155 } catch (RuntimeException e){
156 exception = findThrowableOfTypeIn(PermissionDeniedException.class, e);
157 logger.debug("Expected failure of evaluation.", exception);
158 } finally {
159 // needed in case saveOrUpdate was interrupted by the RuntimeException
160 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
161 endTransaction();
162 startNewTransaction();
163 }
164 Assert.assertNotNull("must fail here!", exception);
165
166 // the user User manager should be able to change others passwords
167 authentication = authenticationManager.authenticate(tokenForUserManager);
168 context = SecurityContextHolder.getContext();
169 context.setAuthentication(authentication);
170 userService.changePasswordForUser(tokenForAdmin.getName(), "newPassword");
171 }
172
173
174 @Test
175 public void testCreateGroup(){
176
177 authentication = authenticationManager.authenticate(tokenForUserManager);
178 SecurityContext context = SecurityContextHolder.getContext();
179 context.setAuthentication(authentication);
180
181
182 List<GrantedAuthority> authorityList = new ArrayList<GrantedAuthority>();
183 GrantedAuthorityImpl rolePublishAthotrity = GrantedAuthorityImpl.NewInstance();
184 rolePublishAthotrity.setAuthority(Role.ROLE_PUBLISH.toString()); // testing if creating a Role from string is working
185 authorityList.add(rolePublishAthotrity);
186
187 String publishersGroupName = "publishers";
188
189 groupService.createGroup(publishersGroupName, authorityList);
190
191 commitAndStartNewTransaction(null);
192
193 List<GrantedAuthority> groupAuthorities = groupService.findGroupAuthorities(publishersGroupName);
194
195 Assert.assertEquals(Role.ROLE_PUBLISH.toString(), groupAuthorities.get(0).getAuthority());
196
197 }
198
199 @Test
200 public void testRefreshUser(){
201
202 String newGroupName = "new_publishers";
203
204 // -----------------------------------------------------------------
205 // authenticate as TaxonEditor to load the user for the first time and to let cache it in the session
206 authentication = authenticationManager.authenticate(tokenForTaxonEditor);
207 SecurityContext context = SecurityContextHolder.getContext();
208 context.setAuthentication(authentication);
209
210 User user = (User) authentication.getPrincipal();
211
212 // check that everything is clean
213 for(GrantedAuthority authority : user.getAuthorities()){
214 if(authority.equals(Role.ROLE_PUBLISH)){
215 Assert.fail("an authority '" + Role.ROLE_PUBLISH + "' must not yet exists");
216 }
217 }
218 for(Group group : user.getGroups()){
219 if(group.getName().equals(newGroupName)){
220 Assert.fail("the group '" + newGroupName + "' must not yet exists");
221 }
222 }
223
224 // -----------------------------------------------------------------
225 // authenticate as UserManager to be able to add the role ROLE_PUBLISH in various ways
226 authentication = authenticationManager.authenticate(tokenForUserManager);
227 context = SecurityContextHolder.getContext();
228 context.setAuthentication(authentication);
229
230 // create an entity of ROLE_PUBLISH and save it to the database
231 grantedAuthorityService.save(Role.ROLE_PUBLISH.asNewGrantedAuthority());
232 commitAndStartNewTransaction(null);
233 GrantedAuthorityImpl rolePublish = grantedAuthorityService.load(Role.ROLE_PUBLISH.getUuid());
234
235 user = userService.load(TAXON_EDITOR_UUID);
236
237 // 1. add to the users GrantedAuthorities
238 // TODO is there any other way to do this?
239 Set<GrantedAuthority> grantedAuthorities = user.getGrantedAuthorities();
240 grantedAuthorities.add(rolePublish);
241 user.setGrantedAuthorities(grantedAuthorities);
242 userService.saveOrUpdate(user);
243
244 commitAndStartNewTransaction(null);
245
246 // 2. add to existing group
247 Group group_special_editor = groupService.load(GROUP_SPECIAL_EDITOR_UUID);
248 String groupSpecialEditor_Name = group_special_editor.getName();
249 rolePublish = grantedAuthorityService.load(Role.ROLE_PUBLISH.getUuid());
250 group_special_editor.addGrantedAuthority(rolePublish);
251 groupService.saveOrUpdate(group_special_editor);
252
253 commitAndStartNewTransaction(null);
254
255 // 3. add in new group
256 Group groupNewPublishers = Group.NewInstance(newGroupName);
257 rolePublish = grantedAuthorityService.load(Role.ROLE_PUBLISH.getUuid());
258 groupNewPublishers.addGrantedAuthority(rolePublish);
259 groupService.saveOrUpdate(groupNewPublishers);
260 groupService.addUserToGroup(user.getUsername(), newGroupName);
261
262 commitAndStartNewTransaction(null);
263
264 // -----------------------------------------------------------------
265 // again authenticate as TaxonEditor
266 authentication = authenticationManager.authenticate(tokenForTaxonEditor);
267 context = SecurityContextHolder.getContext();
268 context.setAuthentication(authentication);
269
270 // and check if everything is updated
271 user = (User) authentication.getPrincipal();
272
273 // 1. check users authorities for the role
274 boolean newAuthorityFound = false;
275 for(GrantedAuthority authority : user.getAuthorities()){
276 if(authority.equals(Role.ROLE_PUBLISH)){
277 newAuthorityFound = true;
278 break;
279 }
280 }
281 Assert.assertTrue("the new authority '" + Role.ROLE_PUBLISH + "' is missing", newAuthorityFound);
282
283 // 2. check for role in existing group
284 boolean newAuthorityFoundInExistingGroup = false;
285 for(Group group : user.getGroups()){
286 if(group.getUuid().equals(GROUP_SPECIAL_EDITOR_UUID)){
287 for(GrantedAuthority authority : group.getGrantedAuthorities()){
288 if(authority.equals(Role.ROLE_PUBLISH)){
289 newAuthorityFoundInExistingGroup = true;
290 break;
291 }
292 }
293 if(newAuthorityFoundInExistingGroup){
294 break;
295 }
296 }
297 }
298 Assert.assertTrue("the new authority '" + Role.ROLE_PUBLISH + "' is missing in existing group", newAuthorityFoundInExistingGroup);
299
300 // 3. check new group
301 boolean newGroupFound = false;
302 for(Group group : user.getGroups()){
303 if(group.getName().equals(newGroupName)){
304 newGroupFound = true;
305 break;
306 }
307 }
308 Assert.assertTrue("the new group '" + newGroupName + "' is missing", newGroupFound);
309
310 // ==================================================================
311 // again authenticate as UserManager to be able to add the role ROLE_PUBLISH in various ways
312 authentication = authenticationManager.authenticate(tokenForUserManager);
313 context = SecurityContextHolder.getContext();
314 context.setAuthentication(authentication);
315
316 groupService.removeUserFromGroup(user.getUsername(), groupSpecialEditor_Name);
317
318 commitAndStartNewTransaction(null);
319
320 // -----------------------------------------------------------------
321 // again authenticate as TaxonEditor
322 authentication = authenticationManager.authenticate(tokenForTaxonEditor);
323 context = SecurityContextHolder.getContext();
324 context.setAuthentication(authentication);
325
326 // and check if the group has been removed from the user
327 user = (User) authentication.getPrincipal();
328
329 for(Group group: user.getGroups()){
330 if(group.getName().equals(groupSpecialEditor_Name)){
331 Assert.fail("The user TaxonEditor should no longer be member of this group");
332 }
333
334 }
335
336 }
337
338 }