Project

General

Profile

« Previous | Next » 

Revision a2728ed2

Added by Andreas Kohlbecker almost 6 years ago

ref #7550 moving the actual CdmUserHelper to cdmlib and making it available in cdm-vaadin by extending the UserHelper class and interface hierarchy

View differences:

src/main/java/eu/etaxonomy/cdm/service/CdmUserHelper.java
1
/**
2
* Copyright (C) 2017 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.service;
10

  
11
import java.io.Serializable;
12
import java.util.Collection;
13
import java.util.EnumSet;
14
import java.util.HashSet;
15
import java.util.Set;
16
import java.util.UUID;
17

  
18
import org.apache.log4j.Logger;
19
import org.springframework.beans.factory.annotation.Autowired;
20
import org.springframework.beans.factory.annotation.Qualifier;
21
import org.springframework.security.authentication.AnonymousAuthenticationToken;
22
import org.springframework.security.authentication.AuthenticationProvider;
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.springframework.security.core.userdetails.UserDetails;
28
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
29
import org.springframework.transaction.TransactionStatus;
30

  
31
import com.vaadin.spring.annotation.SpringComponent;
32
import com.vaadin.spring.annotation.UIScope;
33

  
34
import eu.etaxonomy.cdm.api.application.CdmRepository;
35
import eu.etaxonomy.cdm.api.application.RunAsAuthenticator;
36
import eu.etaxonomy.cdm.database.PermissionDeniedException;
37
import eu.etaxonomy.cdm.model.common.CdmBase;
38
import eu.etaxonomy.cdm.model.common.GrantedAuthorityImpl;
39
import eu.etaxonomy.cdm.model.common.User;
40
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
41
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
42
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthorityParsingException;
43
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionClass;
44
import eu.etaxonomy.cdm.persistence.hibernate.permission.ICdmPermissionEvaluator;
45
import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
46
import eu.etaxonomy.cdm.vaadin.permission.RolesAndPermissions;
47
import eu.etaxonomy.cdm.vaadin.permission.VaadinUserHelper;
48

  
49
/**
50
 * @author a.kohlbecker
51
 * @since May 19, 2017
52
 *
53
 */
54
@SpringComponent
55
@UIScope
56
public class CdmUserHelper extends VaadinUserHelper implements Serializable {
57

  
58
    private static final long serialVersionUID = -2521474709047255979L;
59

  
60
    public static final Logger logger = Logger.getLogger(CdmUserHelper.class);
61

  
62
    @Autowired
63
    private ICdmPermissionEvaluator permissionEvaluator;
64

  
65
    @Autowired
66
    @Qualifier("cdmRepository")
67
    private CdmRepository repo;
68

  
69
    AuthenticationProvider runAsAuthenticationProvider;
70

  
71
    @Autowired
72
    @Qualifier("runAsAuthenticationProvider")
73
    public void setRunAsAuthenticationProvider(AuthenticationProvider runAsAuthenticationProvider){
74
        this.runAsAuthenticationProvider = runAsAuthenticationProvider;
75
        runAsAutheticator.setRunAsAuthenticationProvider(runAsAuthenticationProvider);
76
    }
77

  
78
    RunAsAuthenticator runAsAutheticator = new RunAsAuthenticator();
79

  
80
    public CdmUserHelper(){
81
        super();
82
    }
83

  
84
    @Override
85
    public boolean userIsAutheticated() {
86
        Authentication authentication = getAuthentication();
87
        if(authentication != null){
88
            return authentication.isAuthenticated();
89
        }
90
        return false;
91
    }
92

  
93

  
94
    @Override
95
    public boolean userIsAnnonymous() {
96
        Authentication authentication = getAuthentication();
97
        return authentication != null
98
                && authentication.isAuthenticated()
99
                && authentication instanceof AnonymousAuthenticationToken;
100
    }
101

  
102
    @Override
103
    public User user() {
104
        Authentication authentication = getAuthentication();
105
        if(authentication != null && authentication.getPrincipal() != null) {
106
            return (User) authentication.getPrincipal();
107
        }
108
        return null;
109
    }
110

  
111
    @Override
112
    public String userName() {
113
        Authentication authentication = getAuthentication();
114
        if(authentication != null) {
115
            return authentication.getName();
116
        }
117
        return null;
118
    }
119

  
120
    @Override
121
    public boolean userIsAdmin() {
122
        Authentication authentication = getAuthentication();
123
        if(authentication != null) {
124
            return authentication.getAuthorities().stream().anyMatch(a -> {
125
                return a.getAuthority().equals(Role.ROLE_ADMIN.getAuthority());
126
            });
127
        }
128
        return false;
129
    }
130

  
131
    @Override
132
    public boolean userIsRegistrationCurator() {
133
        Authentication authentication = getAuthentication();
134
        if(authentication != null) {
135
            return authentication.getAuthorities().stream().anyMatch(a -> {
136
                return a.equals(RolesAndPermissions.ROLE_CURATION)
137
                        // doing faster regex check here instreas of using CdmAuthoritiy.fromString()
138
                        || a.getAuthority().matches("^Registration\\.\\[.*UPDATE");
139
            });
140
        }
141
        return false;
142
    }
143

  
144
    @Override
145
    public boolean userHasPermission(CdmBase entity, Object ... args){
146
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
147
        try {
148
            return permissionEvaluator.hasPermission(getAuthentication(), entity, crudSet);
149
        } catch (PermissionDeniedException e){
150
            //IGNORE
151
        }
152
        return false;
153
    }
154

  
155
    @Override
156
    public boolean userHasPermission(Class<? extends CdmBase> cdmType, Integer entitiyId, Object ... args){
157
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
158
        try {
159
            CdmBase entity = repo.getCommonService().find(cdmType, entitiyId);
160
            return permissionEvaluator.hasPermission(getAuthentication(), entity, crudSet);
161
        } catch (PermissionDeniedException e){
162
            //IGNORE
163
        }
164
        return false;
165
    }
166

  
167
    @Override
168
    public boolean userHasPermission(Class<? extends CdmBase> cdmType, UUID entitiyUuid, Object ... args){
169
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
170
        try {
171
            CdmBase entity = repo.getCommonService().find(cdmType, entitiyUuid);
172
            return permissionEvaluator.hasPermission(getAuthentication(), entity, crudSet);
173
        } catch (PermissionDeniedException e){
174
            //IGNORE
175
        }
176
        return false;
177
    }
178

  
179
    @Override
180
    public boolean userHasPermission(Class<? extends CdmBase> cdmType, Object ... args){
181
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
182
        try {
183
            return permissionEvaluator.hasPermission(getAuthentication(), cdmType, crudSet);
184
        } catch (PermissionDeniedException e){
185
            //IGNORE
186
        }
187
        return false;
188
    }
189

  
190
    public void logout() {
191
        SecurityContext context = SecurityContextHolder.getContext();
192
        context.setAuthentication(null);
193
        SecurityContextHolder.clearContext();
194
    }
195

  
196

  
197
    private EnumSet<CRUD> crudSetFromArgs(Object[] args) {
198
        EnumSet<CRUD> crudSet = EnumSet.noneOf(CRUD.class);
199
        for(int i = 0; i < args.length; i++){
200
            try {
201
                crudSet.add(CRUD.valueOf(args[i].toString()));
202
            } catch (Exception e){
203
                throw new IllegalArgumentException("could not add " + args[i], e);
204
            }
205
        }
206
        return crudSet;
207
    }
208

  
209

  
210
    /**
211
     * @return
212
     *
213
     * FIXME is it ok to use the SecurityContextHolder or do we need to hold the context in the vaadin session?
214
     */
215
    private SecurityContext currentSecurityContext() {
216
        return SecurityContextHolder.getContext();
217
    }
218

  
219
    /**
220
     * @return
221
     */
222
    private Authentication getAuthentication() {
223
        return currentSecurityContext().getAuthentication();
224
    }
225

  
226
    /**
227
     * {@inheritDoc}
228
     *
229
     */
230
    @Override
231
    public CdmAuthority createAuthorityFor(String username, CdmBase cdmEntity, EnumSet<CRUD> crud, String property) {
232

  
233
        TransactionStatus txStatus = repo.startTransaction();
234
        UserDetails userDetails = repo.getUserService().loadUserByUsername(username);
235
        boolean newAuthorityAdded = false;
236
        CdmAuthority authority = null;
237
        User user = (User)userDetails;
238
        if(userDetails != null){
239
            try{
240
                runAsAutheticator.runAsAuthentication(Role.ROLE_USER_MANAGER);
241
                authority = new CdmAuthority(cdmEntity, property, crud);
242
                try {
243
                    GrantedAuthorityImpl grantedAuthority = repo.getGrantedAuthorityService().findAuthorityString(authority.toString());
244
                    if(grantedAuthority == null){
245
                        grantedAuthority = authority.asNewGrantedAuthority();
246
                    }
247
                    newAuthorityAdded = user.getGrantedAuthorities().add(grantedAuthority);
248
                } catch (CdmAuthorityParsingException e) {
249
                    throw new RuntimeException(e);
250
                }
251
                repo.getSession().flush();
252
            } finally {
253
                // in any case restore the previous authentication
254
                runAsAutheticator.restoreAuthentication();
255
            }
256
            logger.debug("new authority for " + username + ": " + authority.toString());
257
            Authentication authentication = new PreAuthenticatedAuthenticationToken(user, user.getPassword(), user.getAuthorities());
258
            SecurityContextHolder.getContext().setAuthentication(authentication);
259
            logger.debug("security context refreshed with user " + username);
260
        }
261
        repo.commitTransaction(txStatus);
262
        return newAuthorityAdded ? authority : null;
263

  
264
    }
265

  
266
    /**
267
     * @param username
268
     * @param cdmType
269
     * @param entitiyId
270
     * @param crud
271
     * @return
272
     */
273
    @Override
274
    public CdmAuthority createAuthorityFor(String username, Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property) {
275

  
276
        CdmBase cdmEntity = repo.getCommonService().find(cdmType, entitiyId);
277
        return createAuthorityFor(username, cdmEntity, crud, property);
278
    }
279

  
280
    /**
281
     * @param username
282
     * @param cdmType
283
     * @param entitiyUuid
284
     * @param crud
285
     * @return
286
     */
287
    @Override
288
    public CdmAuthority createAuthorityFor(String username, Class<? extends CdmBase> cdmType, UUID entitiyUuid, EnumSet<CRUD> crud, String property) {
289

  
290
        CdmBase cdmEntity = repo.getCommonService().find(cdmType, entitiyUuid);
291
        return createAuthorityFor(username, cdmEntity, crud, property);
292
    }
293

  
294
    /**
295
     * {@inheritDoc}
296
     */
297
    @Override
298
    public CdmAuthority createAuthorityForCurrentUser(CdmBase cdmEntity, EnumSet<CRUD> crud, String property) {
299
        return createAuthorityFor(userName(), cdmEntity, crud, property);
300

  
301
    }
302

  
303
    /**
304
     * @param cdmType
305
     * @param entitiyId
306
     * @param crud
307
     * @return
308
     */
309
    @Override
310
    public CdmAuthority createAuthorityForCurrentUser(Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property) {
311
        return createAuthorityFor(userName(), cdmType, entitiyId, crud, property);
312
    }
313

  
314
    /**
315
     * @param cdmType
316
     * @param entitiyUuid
317
     * @param crud
318
     * @return
319
     */
320
    @Override
321
    public CdmAuthority createAuthorityForCurrentUser(Class<? extends CdmBase> cdmType, UUID entitiyUuid, EnumSet<CRUD> crud, String property) {
322
        return createAuthorityFor(userName(), cdmType, entitiyUuid, crud, property);
323
    }
324

  
325
    /**
326
     * {@inheritDoc}
327
     */
328
    @Override
329
    public void removeAuthorityForCurrentUser(CdmAuthority cdmAuthority) {
330
        removeAuthorityForCurrentUser(userName(), cdmAuthority);
331

  
332
    }
333

  
334
    /**
335
     * {@inheritDoc}
336
     */
337
    @Override
338
    public void removeAuthorityForCurrentUser(String username, CdmAuthority cdmAuthority) {
339

  
340
        UserDetails userDetails = repo.getUserService().loadUserByUsername(username);
341
        if(userDetails != null){
342
            runAsAutheticator.runAsAuthentication(Role.ROLE_USER_MANAGER);
343
            User user = (User)userDetails;
344
            user.getGrantedAuthorities().remove(cdmAuthority);
345
            repo.getSession().flush();
346
            runAsAutheticator.restoreAuthentication();
347
            Authentication authentication = new PreAuthenticatedAuthenticationToken(user, user.getPassword(), user.getAuthorities());
348
            SecurityContextHolder.getContext().setAuthentication(authentication);
349
            logger.debug("security context refreshed with user " + username);
350
        }
351

  
352
    }
353

  
354
    /**
355
     * {@inheritDoc}
356
     */
357
    @Override
358
    public Collection<CdmAuthority> findUserPermissions(CdmBase cdmEntity, EnumSet<CRUD> crud) {
359
        Set<CdmAuthority> matches = new HashSet<>();
360
        CdmPermissionClass permissionClass = CdmPermissionClass.getValueOf(cdmEntity);
361
        Collection<? extends GrantedAuthority> authorities = getAuthentication().getAuthorities();
362
        for(GrantedAuthority ga : authorities){
363
            try {
364
                CdmAuthority cdmAuthority = CdmAuthority.fromGrantedAuthority(ga);
365
                if(cdmAuthority.getPermissionClass().equals(permissionClass)){
366
                    if(cdmAuthority.getOperation().containsAll(crud)){
367
                        if(cdmAuthority.hasTargetUuid() && cdmAuthority.getTargetUUID().equals(cdmEntity.getUuid())){
368
                            matches.add(cdmAuthority);
369
                        } else {
370
                            matches.add(cdmAuthority);
371
                        }
372
                    }
373
                }
374
            } catch (CdmAuthorityParsingException e) {
375
                continue;
376
            }
377
        }
378
        return matches;
379
    }
380

  
381
}
src/main/java/eu/etaxonomy/cdm/vaadin/permission/UserHelper.java
1
/**
2
* Copyright (C) 2017 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.vaadin.permission;
10

  
11
import java.util.Collection;
12
import java.util.EnumSet;
13
import java.util.UUID;
14

  
15
import com.vaadin.server.VaadinSession;
16

  
17
import eu.etaxonomy.cdm.model.common.CdmBase;
18
import eu.etaxonomy.cdm.model.common.User;
19
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
20
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
21

  
22
/**
23
 * UserHelper interface. Implementations should use the {@link #VADDIN_SESSION_KEY} to auto registers
24
 * in the VaadinSession.
25
 *
26
 * @author a.kohlbecker
27
 * @since May 23, 2017
28
 *
29
 */
30
public interface UserHelper {
31

  
32
    public static final String VADDIN_SESSION_KEY = "USER_HELPER";
33

  
34
    /**
35
     * Static accessor method to obtain the auto-registered UserHelper-Bean from the
36
     * VaadinSession.
37
     *
38
     * @return
39
     */
40
    public static UserHelper fromSession() {
41
       return (UserHelper)VaadinSession.getCurrent().getAttribute(VADDIN_SESSION_KEY);
42
    }
43

  
44
    boolean userHasPermission(Class<? extends CdmBase> cdmType, Integer entitiyId, Object ... args);
45

  
46
    boolean userHasPermission(Class<? extends CdmBase> cdmType, UUID entitiyUUID, Object ... args);
47

  
48
    boolean userHasPermission(Class<? extends CdmBase> cdmType, Object ... args);
49

  
50
    boolean userHasPermission(CdmBase entity, Object ... args);
51

  
52
    boolean userIsRegistrationCurator();
53

  
54
    boolean userIsAdmin();
55

  
56
    User user();
57

  
58
    String userName();
59

  
60
    boolean userIsAnnonymous();
61

  
62
    boolean userIsAutheticated();
63

  
64
    /**
65
     *
66
     * @param username
67
     * @param cdmEntity
68
     * @param crud
69
     * @param property
70
     * @return the newly created CdmAuthority only if a new CdmAuthority has been added to the user otherwise
71
     * <code>null</code> in case the operation failed of if the user was already granted with this authority.
72
     */
73
    public CdmAuthority createAuthorityFor(String username, CdmBase cdmEntity, EnumSet<CRUD> crud, String property);
74

  
75
    /**
76
     *
77
     * @param username
78
     * @param cdmType
79
     * @param entitiyId
80
     * @param crud
81
     * @param property
82
     * @return the newly created CdmAuthority only if a new CdmAuthority has been added to the user otherwise
83
     * <code>null</code> in case the operation failed of if the user was already granted with this authority.
84
     */
85
    public CdmAuthority createAuthorityFor(String username, Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property);
86

  
87

  
88
    /**
89
    *
90
    * @param username
91
    * @param cdmType
92
    * @param entitiyUuid
93
    * @param crud
94
    * @param property
95
    * @return the newly created CdmAuthority only if a new CdmAuthority has been added to the user otherwise
96
    * <code>null</code> in case the operation failed of if the user was already granted with this authority.
97
    */
98
   public CdmAuthority createAuthorityFor(String username, Class<? extends CdmBase> cdmType, UUID entitiyUuid, EnumSet<CRUD> crud, String property);
99

  
100

  
101
    /**
102
     * @param cdmType
103
     * @param entitiyId
104
     * @param crud
105
     * @return the newly created CdmAuthority only if a new CdmAuthority has been added to the user otherwise
106
     * <code>null</code> in case the operation failed of if the user was already granted with this authority.
107
     */
108
    public CdmAuthority createAuthorityForCurrentUser(Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property);
109

  
110
    /**
111
     * @param cdmType
112
     * @param entitiyUuid
113
     * @param crud
114
     * @return the newly created CdmAuthority only if a new CdmAuthority has been added to the user otherwise
115
     * <code>null</code> in case the operation failed of if the user was already granted with this authority.
116
     */
117
    public CdmAuthority createAuthorityForCurrentUser(Class<? extends CdmBase> cdmType, UUID entitiyUuid, EnumSet<CRUD> crud, String property);
118

  
119
    /**
120
     * @param cdmType
121
     * @param entitiyId
122
     * @param crud
123
     * @return the newly created CdmAuthority only if a new CdmAuthority has been added to the user otherwise
124
     * <code>null</code> in case the operation failed of if the user was already granted with this authority.
125
     */
126
    public CdmAuthority createAuthorityForCurrentUser(CdmBase cdmEntity, EnumSet<CRUD> crud, String property);
127

  
128
    /**
129
     * Scans the currently authenticated user for CdmAuthorities which match the given parameters
130
     *
131
     * @param cdmEntity
132
     * @param crud
133
     * @return
134
     */
135
    public Collection<CdmAuthority> findUserPermissions(CdmBase cdmEntity, EnumSet<CRUD> crud);
136

  
137
    /**
138
     * @param newAuthority
139
     */
140
    public void removeAuthorityForCurrentUser(CdmAuthority newAuthority);
141

  
142
    /**
143
     * @param username
144
     * @param newAuthority
145
     */
146
    public void removeAuthorityForCurrentUser(String username, CdmAuthority newAuthority);
147

  
148

  
149
}

Also available in: Unified diff