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