2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.api
.service
;
13 import java
.util
.ArrayList
;
14 import java
.util
.List
;
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
;
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
;
37 * @author a.kohlbecker
41 @DataSet(value
="SecurityTest.xml")
42 public class UserAndGroupServiceImplTest
extends AbstractSecurityTestBase
{
44 protected static final Logger logger
= Logger
.getLogger(UserAndGroupServiceImplTest
.class);
47 private AuthenticationManager authenticationManager
;
50 private IUserService userService
;
53 private IGroupService groupService
;
56 private IGrantedAuthorityService grantedAuthorityService
;
59 private ITaxonService taxonService
;
62 private Authentication authentication
;
66 public void testCreateUser() {
69 authentication
= authenticationManager
.authenticate(tokenForAdmin
);
70 SecurityContext context
= SecurityContextHolder
.getContext();
71 context
.setAuthentication(authentication
);
75 userService
.createUser(User
.NewInstance("new user 1", "00000"));
80 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
81 context
= SecurityContextHolder
.getContext();
82 context
.setAuthentication(authentication
);
85 userService
.createUser(User
.NewInstance("new user 2", "00000"));
88 Assert
.assertEquals("Access is denied", e
.getMessage());
94 public void testUpdateUser(){
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
);
101 User user
= userService
.find(TAXON_EDITOR_UUID
);
102 user
.setEmailAddress("test@bgbm.org");
106 userService.updateUser(user);
107 }catch (Exception e){
108 Assert.fail("the user TaxonEditor should be able to change its own email address");
112 authentication
= authenticationManager
.authenticate(tokenForUserManager
);
113 context
= SecurityContextHolder
.getContext();
114 context
.setAuthentication(authentication
);
116 user
.setEmailAddress("user@bgbm.org");
119 userService
.updateUser(user
);
120 }catch (Exception e
){
121 Assert
.fail("the user UserManager should be able to change others email addresses");
124 authentication
= authenticationManager
.authenticate(tokenForPartEditor
);
125 context
= SecurityContextHolder
.getContext();
126 context
.setAuthentication(authentication
);
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());
138 public void testChangePassword(){
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
);
145 userService
.changePasswordForUser(tokenForTaxonEditor
.getName(), "newPassword");
147 Exception exception
= null;
148 // the user TaxonEditor should NOT be able to change others passwords
150 userService
.changePasswordForUser(tokenForAdmin
.getName(), "newPassword");
151 commitAndStartNewTransaction(null);
152 } catch (AccessDeniedException e
){
153 logger
.debug("Expected failure of evaluation.", e
);
155 } catch (RuntimeException e
){
156 exception
= findThrowableOfTypeIn(PermissionDeniedException
.class, e
);
157 logger
.debug("Expected failure of evaluation.", exception
);
159 // needed in case saveOrUpdate was interrupted by the RuntimeException
160 // commitAndStartNewTransaction() would raise an UnexpectedRollbackException
162 startNewTransaction();
164 Assert
.assertNotNull("must fail here!", exception
);
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");
175 public void testCreateGroup(){
177 authentication
= authenticationManager
.authenticate(tokenForUserManager
);
178 SecurityContext context
= SecurityContextHolder
.getContext();
179 context
.setAuthentication(authentication
);
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
);
187 String publishersGroupName
= "publishers";
189 groupService
.createGroup(publishersGroupName
, authorityList
);
191 commitAndStartNewTransaction(null);
193 List
<GrantedAuthority
> groupAuthorities
= groupService
.findGroupAuthorities(publishersGroupName
);
195 Assert
.assertEquals(Role
.ROLE_PUBLISH
.toString(), groupAuthorities
.get(0).getAuthority());
200 public void testRefreshUser(){
202 String newGroupName
= "new_publishers";
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
);
210 User user
= (User
) authentication
.getPrincipal();
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");
218 for(Group group
: user
.getGroups()){
219 if(group
.getName().equals(newGroupName
)){
220 Assert
.fail("the group '" + newGroupName
+ "' must not yet exists");
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
);
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());
235 user
= userService
.load(TAXON_EDITOR_UUID
);
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
);
244 commitAndStartNewTransaction(null);
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
);
253 commitAndStartNewTransaction(null);
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
);
262 commitAndStartNewTransaction(null);
264 // -----------------------------------------------------------------
265 // again authenticate as TaxonEditor
266 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
267 context
= SecurityContextHolder
.getContext();
268 context
.setAuthentication(authentication
);
270 // and check if everything is updated
271 user
= (User
) authentication
.getPrincipal();
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;
281 Assert
.assertTrue("the new authority '" + Role
.ROLE_PUBLISH
+ "' is missing", newAuthorityFound
);
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;
293 if(newAuthorityFoundInExistingGroup
){
298 Assert
.assertTrue("the new authority '" + Role
.ROLE_PUBLISH
+ "' is missing in existing group", newAuthorityFoundInExistingGroup
);
300 // 3. check new group
301 boolean newGroupFound
= false;
302 for(Group group
: user
.getGroups()){
303 if(group
.getName().equals(newGroupName
)){
304 newGroupFound
= true;
308 Assert
.assertTrue("the new group '" + newGroupName
+ "' is missing", newGroupFound
);
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
);
316 groupService
.removeUserFromGroup(user
.getUsername(), groupSpecialEditor_Name
);
318 commitAndStartNewTransaction(null);
320 // -----------------------------------------------------------------
321 // again authenticate as TaxonEditor
322 authentication
= authenticationManager
.authenticate(tokenForTaxonEditor
);
323 context
= SecurityContextHolder
.getContext();
324 context
.setAuthentication(authentication
);
326 // and check if the group has been removed from the user
327 user
= (User
) authentication
.getPrincipal();
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");