Project

General

Profile

« Previous | Next » 

Revision 95504cb1

Added by Andreas Müller 4 months ago

cleanup

View differences:

cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/GroupServiceImpl.java
6 6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7 7
* See LICENSE.TXT at the top of this package for the full license terms.
8 8
*/
9

  
10 9
package eu.etaxonomy.cdm.api.service;
11 10

  
12 11
import java.util.ArrayList;
......
44 43
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
45 44
public class GroupServiceImpl extends ServiceBase<Group,IGroupDao> implements IGroupService {
46 45

  
47
    protected IUserDao userDao;
46
    private IUserDao userDao;
48 47

  
49
    protected IGrantedAuthorityDao grantedAuthorityDao;
48
    private IGrantedAuthorityDao grantedAuthorityDao;
50 49

  
51 50
    @Override
52 51
    public List<String> findAllGroups() {
......
55 54

  
56 55
    @Override
57 56
    public List<String> findUsersInGroup(String groupName) {
58
        Assert.hasText(groupName);
57
        Assert.hasText(groupName, "Parameter 'groupName' must not be empty.");
59 58
        Group group = dao.findGroupByName(groupName);
60 59

  
61 60
        List<String> users = dao.listMembers(group, null, null);
......
80 79
    @Override
81 80
    @Transactional(readOnly=false)
82 81
    public void deleteGroup(String groupUUID) {
83
        Assert.notNull(groupUUID);
82
        Assert.notNull(groupUUID, "Parameter 'groupUUID' must not be empty.");
84 83

  
85 84
        Group group = dao.findByUuid(UUID.fromString(groupUUID));
86 85
        Iterator<User> it = group.getMembers().iterator();
......
95 94
    @Override
96 95
    @Transactional(readOnly=false)
97 96
    public void renameGroup(String oldName, String newName) {
98
        Assert.hasText(oldName);
99
        Assert.hasText(newName);
97
        Assert.hasText(oldName, "Parameter 'oldName' must not be empty.");
98
        Assert.hasText(newName, "Parameter 'newName' must not be empty.");
100 99

  
101 100
        Group group = dao.findGroupByName(oldName);
102 101

  
......
107 106
    @Override
108 107
    @Transactional(readOnly=false)
109 108
    public void addUserToGroup(String username, String groupName) {
110
        Assert.hasText(username);
111
        Assert.hasText(groupName);
109
        Assert.hasText(username, "Parameter 'username' must not be empty.");
110
        Assert.hasText(groupName, "Parameter 'groupName' must not be empty.");
112 111

  
113 112
        Group group = dao.findGroupByName(groupName);
114 113
        User user = userDao.findUserByUsername(username);
......
123 122
    @Override
124 123
    @Transactional(readOnly=false)
125 124
    public void removeUserFromGroup(String username, String groupName) {
126
        Assert.hasText(username);
127
        Assert.hasText(groupName);
125
        Assert.hasText(username, "Parameter 'username' must not be empty.");
126
        Assert.hasText(groupName, "Parameter 'groupName' must not be empty.");
128 127

  
129 128
        Group group = dao.findGroupByName(groupName);
130 129
        User user = userDao.findUserByUsername(username);
......
138 137

  
139 138
    @Override
140 139
    public List<GrantedAuthority> findGroupAuthorities(String groupName) {
141
        Assert.hasText(groupName);
140
        Assert.hasText(groupName, "Parameter 'groupName' must not be empty.");
142 141
        Group group = dao.findGroupByName(groupName);
143 142

  
144 143
        if (group != null){
......
151 150
    @Override
152 151
    @Transactional(readOnly=false)
153 152
    public void addGroupAuthority(String groupName, GrantedAuthority authority) {
154
        Assert.hasText(groupName);
155
        Assert.notNull(authority);
153
        Assert.hasText(groupName, "Parameter 'groupName' must not be empty.");
154
        Assert.notNull(authority, "Parameter 'authority' must not be empty.");
156 155

  
157 156
        Group group = dao.findGroupByName(groupName);
158 157

  
......
167 166
    @Transactional(readOnly=false)
168 167
    public void removeGroupAuthority(String groupName,
169 168
            GrantedAuthority authority) {
170
        Assert.hasText(groupName);
171
        Assert.notNull(authority);
169
        Assert.hasText(groupName, "Parameter 'groupName' must not be empty.");
170
        Assert.notNull(authority, "Parameter 'authority' must not be empty.");
172 171

  
173 172
        Group group = dao.findGroupByName(groupName);
174 173

  
......
211 210
    @Override
212 211
    @Transactional(readOnly=false)
213 212
    public void createGroup(String groupName, List<GrantedAuthority> authorities) {
214
        Assert.hasText(groupName);
215
        Assert.notNull(authorities);
213
        Assert.hasText(groupName, "Parameter 'groupName' must not be empty.");
214
        Assert.notNull(authorities, "Parameter 'authorities' must not be empty.");
216 215

  
217 216
        Group newGroup = Group.NewInstance(groupName);
218 217
        for (GrantedAuthority grantedAuthority: authorities){
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IGroupService.java
27 27
 */
28 28
public interface IGroupService extends IService<Group>, GroupManager{
29 29

  
30

  
31 30
    /**
32 31
     * Return a List of groups matching the given query string, optionally filtered by class, optionally with a particular MatchMode
33 32
     *
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/UserService.java
1
/**
2
 * Copyright (C) 2007 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.util.ArrayList;
12
import java.util.Collection;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.UUID;
17

  
18
import org.hibernate.NonUniqueResultException;
19
import org.hibernate.criterion.Criterion;
20
import org.springframework.beans.factory.annotation.Autowired;
21
import org.springframework.context.annotation.Lazy;
22
import org.springframework.dao.DataAccessException;
23
import org.springframework.dao.IncorrectResultSizeDataAccessException;
24
import org.springframework.security.access.AccessDeniedException;
25
import org.springframework.security.access.prepost.PreAuthorize;
26
import org.springframework.security.authentication.AuthenticationManager;
27
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
28
import org.springframework.security.authentication.dao.SaltSource;
29
import org.springframework.security.authentication.encoding.PasswordEncoder;
30
import org.springframework.security.core.Authentication;
31
import org.springframework.security.core.GrantedAuthority;
32
import org.springframework.security.core.context.SecurityContextHolder;
33
import org.springframework.security.core.userdetails.UserCache;
34
import org.springframework.security.core.userdetails.UserDetails;
35
import org.springframework.security.core.userdetails.UsernameNotFoundException;
36
import org.springframework.security.core.userdetails.cache.NullUserCache;
37
import org.springframework.stereotype.Service;
38
import org.springframework.transaction.annotation.Transactional;
39
import org.springframework.util.Assert;
40

  
41
import eu.etaxonomy.cdm.model.permission.GrantedAuthorityImpl;
42
import eu.etaxonomy.cdm.model.permission.User;
43
import eu.etaxonomy.cdm.persistence.dao.permission.IGrantedAuthorityDao;
44
import eu.etaxonomy.cdm.persistence.dao.permission.IGroupDao;
45
import eu.etaxonomy.cdm.persistence.dao.permission.IUserDao;
46
import eu.etaxonomy.cdm.persistence.query.MatchMode;
47
import eu.etaxonomy.cdm.persistence.query.OrderHint;
48

  
49
/**
50
 * Note: All group related functionality has been refactored into a GroupService.
51
 * The will be removed in a future version.
52
 */
53
@Service
54
@Transactional(readOnly = true)
55
// NOTE: no type level @PreAuthorize annotation for this class!
56
public class UserService extends ServiceBase<User,IUserDao> implements IUserService {
57

  
58
    protected IGroupDao groupDao;
59

  
60
    protected IGrantedAuthorityDao grantedAuthorityDao;
61

  
62
    private SaltSource saltSource; // = new ReflectionSaltSource();
63

  
64
    private PasswordEncoder passwordEncoder; // = new Md5PasswordEncoder();
65

  
66
    private AuthenticationManager authenticationManager;
67

  
68

  
69
    private UserCache userCache = new NullUserCache();
70

  
71
    @Autowired(required = false)
72
    public void setUserCache(UserCache userCache) {
73
        Assert.notNull(userCache, "userCache cannot be null");
74
        this.userCache = userCache;
75
    }
76

  
77
    @Autowired(required = false)
78
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
79

  
80
        this.passwordEncoder = passwordEncoder;
81
    }
82

  
83
    @Autowired(required = false)
84
    public void setSaltSource(SaltSource saltSource) {
85
        this.saltSource = saltSource;
86
    }
87

  
88
    @Autowired(required= false)
89
    @Lazy // avoid dependency cycle coming from OAuth2ServerConfiguration.AuthorizationServerConfiguration.authenticationManager
90
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
91
        this.authenticationManager = authenticationManager;
92
    }
93

  
94
    @Override
95
    @Autowired
96
    protected void setDao(IUserDao dao) {
97
        this.dao = dao;
98
    }
99

  
100
    @Autowired
101
    public void setGroupDao(IGroupDao groupDao) {
102
        this.groupDao = groupDao;
103
    }
104

  
105
    @Autowired
106
    public void setGrantedAuthorityDao(IGrantedAuthorityDao grantedAuthorityDao) {
107
        this.grantedAuthorityDao = grantedAuthorityDao;
108
    }
109

  
110

  
111
    /**
112
     * Changes the own password of in the database of the user which is
113
     * currently authenticated. Requires to supply the old password for security
114
     * reasons. Refreshes the authentication in the SecurityContext after the
115
     * password change by re-authenticating the user with the new password.
116
     *
117
     * @see org.springframework.security.provisioning.UserDetailsManager#changePassword(java.lang.String,
118
     *      java.lang.String)
119
     */
120
    @Override
121
    @Transactional(readOnly=false)
122
    @PreAuthorize("isAuthenticated()")
123
    public void changePassword(String oldPassword, String newPassword) {
124
        Assert.hasText(oldPassword);
125
        Assert.hasText(newPassword);
126
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
127
        if(authentication != null && authentication.getPrincipal() != null && authentication.getPrincipal() instanceof User) {
128

  
129
            // get current authentication and load it from the persistence layer,
130
            // to make sure we are modifying the instance which is
131
            // attached to the hibernate session
132
            User user = (User)authentication.getPrincipal();
133
            user = dao.load(user.getUuid());
134

  
135
            // check if old password is valid
136
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), oldPassword));
137
            encodeUserPassword(user, newPassword);
138
            dao.update(user);
139

  
140
            // authenticate the user again with the new password
141
            UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
142
            newAuthentication.setDetails(authentication.getDetails());
143
            SecurityContextHolder.getContext().setAuthentication(newAuthentication);
144
            userCache.removeUserFromCache(user.getUsername());
145

  
146
        } else {
147
            throw new AccessDeniedException("Can't change password as no Authentication object found in context for current user.");
148
        }
149
    }
150

  
151
    /**
152
     * make new password salt, encode and set it for the passed user
153
     *
154
     * @param user
155
     *  The user to set the new password for.
156
     * @param newPassword
157
     *  the new password to be encoded and set for the <code>user</code>
158
     */
159
    @Override
160
    public void encodeUserPassword(User user, String newPassword) {
161
        Object salt = this.saltSource.getSalt(user);
162
        String password = passwordEncoder.encodePassword(newPassword, salt);
163
        user.setPassword(password);
164
    }
165

  
166
    @Override
167
    @Transactional(readOnly=false)
168
    @PreAuthorize("#username == authentication.name or hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
169
    public void changePasswordForUser(String username, String newPassword) {
170
        Assert.hasText(username);
171
        Assert.hasText(newPassword);
172

  
173
        try {
174
            User user = dao.findUserByUsername(username);
175
            if(user == null) {
176
                throw new UsernameNotFoundException(username);
177
            }
178

  
179
            encodeUserPassword(user, newPassword);
180
            dao.update(user);
181
            userCache.removeUserFromCache(user.getUsername());
182
        } catch(NonUniqueResultException nure) {
183
            throw new IncorrectResultSizeDataAccessException("More than one user found with name '" + username + "'", 1);
184
        }
185
    }
186

  
187
    @Override
188
    @Transactional(readOnly=false)
189
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
190
    public void createUser(UserDetails user) {
191
    	Assert.isInstanceOf(User.class, user);
192
        encodeUserPassword((User)user, user.getPassword());
193
        dao.save((User)user);
194
    }
195

  
196
    @Override
197
    @Transactional(readOnly=false)
198
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
199
    public void deleteUser(String username) {
200
        Assert.hasLength(username);
201

  
202
        User user = dao.findUserByUsername(username);
203
        if(user != null) {
204
            dao.delete(user);
205
        }
206

  
207
        userCache.removeUserFromCache(username);
208
    }
209

  
210
    @Override
211
    @Transactional(readOnly=false)
212
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
213
    public void updateUser(UserDetails user) {
214
        Assert.isInstanceOf(User.class, user);
215

  
216
        dao.update((User)user);
217
        userCache.removeUserFromCache(user.getUsername());
218
    }
219

  
220
    @Override
221
    public boolean userExists(String username) {
222
        Assert.hasText(username);
223

  
224
        User user = dao.findUserByUsername(username);
225
        return user != null;
226
    }
227

  
228
    /**
229
     * <b>DO NOT CALL THIS METHOD IN LONG RUNNING SESSIONS OR CONVERSATIONS
230
     * A THROWN UsernameNotFoundException WILL RENDER THE CONVERSATION UNUSABLE</b>
231
     *
232
     * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
233
     */
234
    // NOTE: this method must not be secured since it is being used during the
235
    //       authentication process
236
    @Override
237
    public UserDetails loadUserByUsername(String username)
238
            throws UsernameNotFoundException, DataAccessException {
239
        Assert.hasText(username);
240
        try {
241
            User user = dao.findUserByUsername(username);
242
            if(user == null) {
243
                throw new UsernameNotFoundException(username);
244
            }
245
            return user;
246
        } catch(NonUniqueResultException nure) {
247
            throw new IncorrectResultSizeDataAccessException("More than one user found with name '" + username + "'", 1);
248
        }
249
    }
250

  
251

  
252
    @Override
253
    @Transactional(readOnly=false)
254
   // @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_RUN_AS_ADMIN') or hasRole('ROLE_USER_MANAGER')")
255
    public User save(User user) {
256
        if(user.getId() == 0 || dao.load(user.getUuid()) == null){
257
            createUser(user);
258
        }else{
259
            updateUser(user);
260
        }
261
        return user;
262
    }
263

  
264
    @Override
265
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
266
    public UUID update(User user) {
267
        updateUser(user);
268
        return user.getUuid();
269
    }
270

  
271
    @Override
272
    @Transactional(readOnly=false)
273
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
274
    public UUID saveGrantedAuthority(GrantedAuthority grantedAuthority) {
275
        return grantedAuthorityDao.save((GrantedAuthorityImpl)grantedAuthority).getUuid();
276
    }
277

  
278

  
279

  
280
    @Override
281
    @Transactional(readOnly = true)
282
    public List<User> listByUsername(String queryString,MatchMode matchmode, List<Criterion> criteria, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
283
         long numberOfResults = dao.countByUsername(queryString, matchmode, criteria);
284

  
285
         List<User> results = new ArrayList<>();
286
         if(numberOfResults > 0) {
287
                results = dao.findByUsername(queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths);
288
         }
289
         return results;
290
    }
291

  
292
    /* ================================================
293
     *  overriding methods to secure them
294
     *  via the type level annotation @PreAuthorize
295
     * ================================================ */
296

  
297
    @Override
298
    @Transactional(readOnly=false)
299
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
300
    public DeleteResult delete(User persistentObject)  {
301
        return super.delete(persistentObject);
302
    }
303

  
304
    @Override
305
    @Transactional(readOnly=false)
306
    public DeleteResult delete(UUID userUuid)  {
307
        return delete(dao.load(userUuid));
308
    }
309

  
310
    @Override
311
    @Transactional(readOnly=false)
312
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
313
    public Map<UUID, User> save(Collection<? extends User> newInstances) {
314
        Map<UUID, User> users = new HashMap<UUID, User>();
315
    	for (User user: newInstances){
316
        	createUser(user);
317
        	users.put(user.getUuid(), user);
318
        }
319
    	return users;
320
    }
321

  
322
    @Override
323
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
324
    public UUID saveOrUpdate(User transientObject) {
325
        return super.saveOrUpdate(transientObject);
326
    }
327

  
328
    @Override
329
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
330
    @Transactional(readOnly=false)
331
    public User merge(User detachedObject) {
332
        return super.merge(detachedObject);
333
    }
334

  
335
    @Override
336
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
337
    @Transactional(readOnly=false)
338
    public List<User> merge(List<User> detachedObjects) {
339
        return super.merge(detachedObjects);
340
    }
341

  
342
    @Override
343
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
344
    public Map<UUID, User> saveOrUpdate(Collection<User> transientInstances) {
345
        return super.saveOrUpdate(transientInstances);
346
    }
347

  
348
}
1
/**
2
 * Copyright (C) 2007 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.util.ArrayList;
12
import java.util.Collection;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.UUID;
17

  
18
import org.hibernate.NonUniqueResultException;
19
import org.hibernate.criterion.Criterion;
20
import org.springframework.beans.factory.annotation.Autowired;
21
import org.springframework.context.annotation.Lazy;
22
import org.springframework.dao.DataAccessException;
23
import org.springframework.dao.IncorrectResultSizeDataAccessException;
24
import org.springframework.security.access.AccessDeniedException;
25
import org.springframework.security.access.prepost.PreAuthorize;
26
import org.springframework.security.authentication.AuthenticationManager;
27
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
28
import org.springframework.security.authentication.dao.SaltSource;
29
import org.springframework.security.authentication.encoding.PasswordEncoder;
30
import org.springframework.security.core.Authentication;
31
import org.springframework.security.core.GrantedAuthority;
32
import org.springframework.security.core.context.SecurityContextHolder;
33
import org.springframework.security.core.userdetails.UserCache;
34
import org.springframework.security.core.userdetails.UserDetails;
35
import org.springframework.security.core.userdetails.UsernameNotFoundException;
36
import org.springframework.security.core.userdetails.cache.NullUserCache;
37
import org.springframework.stereotype.Service;
38
import org.springframework.transaction.annotation.Transactional;
39
import org.springframework.util.Assert;
40

  
41
import eu.etaxonomy.cdm.model.permission.GrantedAuthorityImpl;
42
import eu.etaxonomy.cdm.model.permission.User;
43
import eu.etaxonomy.cdm.persistence.dao.permission.IGrantedAuthorityDao;
44
import eu.etaxonomy.cdm.persistence.dao.permission.IGroupDao;
45
import eu.etaxonomy.cdm.persistence.dao.permission.IUserDao;
46
import eu.etaxonomy.cdm.persistence.query.MatchMode;
47
import eu.etaxonomy.cdm.persistence.query.OrderHint;
48

  
49
/**
50
 * Note: All group related functionality has been refactored into a GroupService.
51
 * The will be removed in a future version.
52
 */
53
@Service
54
@Transactional(readOnly = true)
55
// NOTE: no type level @PreAuthorize annotation for this class!
56
public class UserService extends ServiceBase<User,IUserDao> implements IUserService {
57

  
58
    protected IGroupDao groupDao;
59

  
60
    protected IGrantedAuthorityDao grantedAuthorityDao;
61

  
62
    private SaltSource saltSource; // = new ReflectionSaltSource();
63

  
64
    private PasswordEncoder passwordEncoder; // = new Md5PasswordEncoder();
65

  
66
    private AuthenticationManager authenticationManager;
67

  
68

  
69
    private UserCache userCache = new NullUserCache();
70

  
71
    @Autowired(required = false)
72
    public void setUserCache(UserCache userCache) {
73
        Assert.notNull(userCache, "userCache cannot be null");
74
        this.userCache = userCache;
75
    }
76

  
77
    @Autowired(required = false)
78
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
79

  
80
        this.passwordEncoder = passwordEncoder;
81
    }
82

  
83
    @Autowired(required = false)
84
    public void setSaltSource(SaltSource saltSource) {
85
        this.saltSource = saltSource;
86
    }
87

  
88
    @Autowired(required= false)
89
    @Lazy // avoid dependency cycle coming from OAuth2ServerConfiguration.AuthorizationServerConfiguration.authenticationManager
90
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
91
        this.authenticationManager = authenticationManager;
92
    }
93

  
94
    @Override
95
    @Autowired
96
    protected void setDao(IUserDao dao) {
97
        this.dao = dao;
98
    }
99

  
100
    @Autowired
101
    public void setGroupDao(IGroupDao groupDao) {
102
        this.groupDao = groupDao;
103
    }
104

  
105
    @Autowired
106
    public void setGrantedAuthorityDao(IGrantedAuthorityDao grantedAuthorityDao) {
107
        this.grantedAuthorityDao = grantedAuthorityDao;
108
    }
109

  
110

  
111
    /**
112
     * Changes the own password of in the database of the user which is
113
     * currently authenticated. Requires to supply the old password for security
114
     * reasons. Refreshes the authentication in the SecurityContext after the
115
     * password change by re-authenticating the user with the new password.
116
     *
117
     * @see org.springframework.security.provisioning.UserDetailsManager#changePassword(java.lang.String,
118
     *      java.lang.String)
119
     */
120
    @Override
121
    @Transactional(readOnly=false)
122
    @PreAuthorize("isAuthenticated()")
123
    public void changePassword(String oldPassword, String newPassword) {
124
        Assert.hasText(oldPassword);
125
        Assert.hasText(newPassword);
126
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
127
        if(authentication != null && authentication.getPrincipal() != null && authentication.getPrincipal() instanceof User) {
128

  
129
            // get current authentication and load it from the persistence layer,
130
            // to make sure we are modifying the instance which is
131
            // attached to the hibernate session
132
            User user = (User)authentication.getPrincipal();
133
            user = dao.load(user.getUuid());
134

  
135
            // check if old password is valid
136
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), oldPassword));
137
            encodeUserPassword(user, newPassword);
138
            dao.update(user);
139

  
140
            // authenticate the user again with the new password
141
            UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
142
            newAuthentication.setDetails(authentication.getDetails());
143
            SecurityContextHolder.getContext().setAuthentication(newAuthentication);
144
            userCache.removeUserFromCache(user.getUsername());
145

  
146
        } else {
147
            throw new AccessDeniedException("Can't change password as no Authentication object found in context for current user.");
148
        }
149
    }
150

  
151
    /**
152
     * make new password salt, encode and set it for the passed user
153
     *
154
     * @param user
155
     *  The user to set the new password for.
156
     * @param newPassword
157
     *  the new password to be encoded and set for the <code>user</code>
158
     */
159
    @Override
160
    public void encodeUserPassword(User user, String newPassword) {
161
        Object salt = this.saltSource.getSalt(user);
162
        String password = passwordEncoder.encodePassword(newPassword, salt);
163
        user.setPassword(password);
164
    }
165

  
166
    @Override
167
    @Transactional(readOnly=false)
168
    @PreAuthorize("#username == authentication.name or hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
169
    public void changePasswordForUser(String username, String newPassword) {
170
        Assert.hasText(username);
171
        Assert.hasText(newPassword);
172

  
173
        try {
174
            User user = dao.findUserByUsername(username);
175
            if(user == null) {
176
                throw new UsernameNotFoundException(username);
177
            }
178

  
179
            encodeUserPassword(user, newPassword);
180
            dao.update(user);
181
            userCache.removeUserFromCache(user.getUsername());
182
        } catch(NonUniqueResultException nure) {
183
            throw new IncorrectResultSizeDataAccessException("More than one user found with name '" + username + "'", 1);
184
        }
185
    }
186

  
187
    @Override
188
    @Transactional(readOnly=false)
189
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
190
    public void createUser(UserDetails user) {
191
    	Assert.isInstanceOf(User.class, user);
192
        encodeUserPassword((User)user, user.getPassword());
193
        dao.save((User)user);
194
    }
195

  
196
    @Override
197
    @Transactional(readOnly=false)
198
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
199
    public void deleteUser(String username) {
200
        Assert.hasLength(username);
201

  
202
        User user = dao.findUserByUsername(username);
203
        if(user != null) {
204
            dao.delete(user);
205
        }
206

  
207
        userCache.removeUserFromCache(username);
208
    }
209

  
210
    @Override
211
    @Transactional(readOnly=false)
212
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
213
    public void updateUser(UserDetails user) {
214
        Assert.isInstanceOf(User.class, user);
215

  
216
        dao.update((User)user);
217
        userCache.removeUserFromCache(user.getUsername());
218
    }
219

  
220
    @Override
221
    public boolean userExists(String username) {
222
        Assert.hasText(username, "Parameter 'username' must not be empty.");
223

  
224
        User user = dao.findUserByUsername(username);
225
        return user != null;
226
    }
227

  
228
    /**
229
     * <b>DO NOT CALL THIS METHOD IN LONG RUNNING SESSIONS OR CONVERSATIONS
230
     * A THROWN UsernameNotFoundException WILL RENDER THE CONVERSATION UNUSABLE</b>
231
     *
232
     * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
233
     */
234
    // NOTE: this method must not be secured since it is being used during the
235
    //       authentication process
236
    @Override
237
    public UserDetails loadUserByUsername(String username)
238
            throws UsernameNotFoundException, DataAccessException {
239
        Assert.hasText(username);
240
        try {
241
            User user = dao.findUserByUsername(username);
242
            if(user == null) {
243
                throw new UsernameNotFoundException(username);
244
            }
245
            return user;
246
        } catch(NonUniqueResultException nure) {
247
            throw new IncorrectResultSizeDataAccessException("More than one user found with name '" + username + "'", 1);
248
        }
249
    }
250

  
251

  
252
    @Override
253
    @Transactional(readOnly=false)
254
   // @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_RUN_AS_ADMIN') or hasRole('ROLE_USER_MANAGER')")
255
    public User save(User user) {
256
        if(user.getId() == 0 || dao.load(user.getUuid()) == null){
257
            createUser(user);
258
        }else{
259
            updateUser(user);
260
        }
261
        return user;
262
    }
263

  
264
    @Override
265
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
266
    public UUID update(User user) {
267
        updateUser(user);
268
        return user.getUuid();
269
    }
270

  
271
    @Override
272
    @Transactional(readOnly=false)
273
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
274
    public UUID saveGrantedAuthority(GrantedAuthority grantedAuthority) {
275
        return grantedAuthorityDao.save((GrantedAuthorityImpl)grantedAuthority).getUuid();
276
    }
277

  
278

  
279

  
280
    @Override
281
    @Transactional(readOnly = true)
282
    public List<User> listByUsername(String queryString,MatchMode matchmode, List<Criterion> criteria, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
283
         long numberOfResults = dao.countByUsername(queryString, matchmode, criteria);
284

  
285
         List<User> results = new ArrayList<>();
286
         if(numberOfResults > 0) {
287
                results = dao.findByUsername(queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths);
288
         }
289
         return results;
290
    }
291

  
292
    /* ================================================
293
     *  overriding methods to secure them
294
     *  via the type level annotation @PreAuthorize
295
     * ================================================ */
296

  
297
    @Override
298
    @Transactional(readOnly=false)
299
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
300
    public DeleteResult delete(User persistentObject)  {
301
        return super.delete(persistentObject);
302
    }
303

  
304
    @Override
305
    @Transactional(readOnly=false)
306
    public DeleteResult delete(UUID userUuid)  {
307
        return delete(dao.load(userUuid));
308
    }
309

  
310
    @Override
311
    @Transactional(readOnly=false)
312
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
313
    public Map<UUID, User> save(Collection<? extends User> newInstances) {
314
        Map<UUID, User> users = new HashMap<UUID, User>();
315
    	for (User user: newInstances){
316
        	createUser(user);
317
        	users.put(user.getUuid(), user);
318
        }
319
    	return users;
320
    }
321

  
322
    @Override
323
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
324
    public UUID saveOrUpdate(User transientObject) {
325
        return super.saveOrUpdate(transientObject);
326
    }
327

  
328
    @Override
329
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
330
    @Transactional(readOnly=false)
331
    public User merge(User detachedObject) {
332
        return super.merge(detachedObject);
333
    }
334

  
335
    @Override
336
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
337
    @Transactional(readOnly=false)
338
    public List<User> merge(List<User> detachedObjects) {
339
        return super.merge(detachedObjects);
340
    }
341

  
342
    @Override
343
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")
344
    public Map<UUID, User> saveOrUpdate(Collection<User> transientInstances) {
345
        return super.saveOrUpdate(transientInstances);
346
    }
347

  
348
}

Also available in: Unified diff