Project

General

Profile

Download (9.79 KB) Statistics
| Branch: | Tag: | Revision:
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.util.EnumSet;
12

    
13
import org.apache.log4j.Logger;
14
import org.springframework.beans.factory.annotation.Autowired;
15
import org.springframework.beans.factory.annotation.Qualifier;
16
import org.springframework.security.authentication.AnonymousAuthenticationToken;
17
import org.springframework.security.authentication.AuthenticationProvider;
18
import org.springframework.security.core.Authentication;
19
import org.springframework.security.core.context.SecurityContext;
20
import org.springframework.security.core.context.SecurityContextHolder;
21
import org.springframework.security.core.userdetails.UserDetails;
22
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
23
import org.springframework.transaction.TransactionStatus;
24

    
25
import com.vaadin.spring.annotation.SpringComponent;
26
import com.vaadin.spring.annotation.UIScope;
27

    
28
import eu.etaxonomy.cdm.api.application.CdmRepository;
29
import eu.etaxonomy.cdm.api.application.RunAsAuthenticator;
30
import eu.etaxonomy.cdm.database.PermissionDeniedException;
31
import eu.etaxonomy.cdm.model.common.CdmBase;
32
import eu.etaxonomy.cdm.model.common.User;
33
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
34
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
35
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthorityParsingException;
36
import eu.etaxonomy.cdm.persistence.hibernate.permission.ICdmPermissionEvaluator;
37
import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
38
import eu.etaxonomy.cdm.vaadin.security.RolesAndPermissions;
39
import eu.etaxonomy.cdm.vaadin.security.VaadinUserHelper;
40

    
41
/**
42
 * @author a.kohlbecker
43
 * @since May 19, 2017
44
 *
45
 */
46
@SpringComponent
47
@UIScope
48
public class CdmUserHelper extends VaadinUserHelper {
49

    
50
    public static final Logger logger = Logger.getLogger(CdmUserHelper.class);
51

    
52
    @Autowired
53
    private ICdmPermissionEvaluator permissionEvaluator;
54

    
55
    @Autowired
56
    @Qualifier("cdmRepository")
57
    private CdmRepository repo;
58

    
59
    @Autowired
60
    @Qualifier("runAsAuthenticationProvider")
61
    AuthenticationProvider runAsAuthenticationProvider;
62

    
63
    RunAsAuthenticator runAsAutheticator = new RunAsAuthenticator();
64

    
65
    public CdmUserHelper(){
66
        super();
67
        runAsAutheticator.setRunAsAuthenticationProvider(runAsAuthenticationProvider);
68

    
69
    }
70

    
71
    @Override
72
    public boolean userIsAutheticated() {
73
        Authentication authentication = getAuthentication();
74
        if(authentication != null){
75
            return authentication.isAuthenticated();
76
        }
77
        return false;
78
    }
79

    
80

    
81
    @Override
82
    public boolean userIsAnnonymous() {
83
        Authentication authentication = getAuthentication();
84
        return authentication != null
85
                && authentication.isAuthenticated()
86
                && authentication instanceof AnonymousAuthenticationToken;
87
    }
88

    
89
    @Override
90
    public String userName() {
91
        Authentication authentication = getAuthentication();
92
        if(authentication != null) {
93
            return authentication.getName();
94
        }
95
        return null;
96
    }
97

    
98
    @Override
99
    public boolean userIsAdmin() {
100
        Authentication authentication = getAuthentication();
101
        if(authentication != null) {
102
            return authentication.getAuthorities().stream().anyMatch(a -> {
103
                return a.getAuthority().equals(Role.ROLE_ADMIN.getAuthority());
104
            });
105
        }
106
        return false;
107
    }
108

    
109
    @Override
110
    public boolean userIsRegistrationCurator() {
111
        Authentication authentication = getAuthentication();
112
        if(authentication != null) {
113
            return authentication.getAuthorities().stream().anyMatch(a -> {
114
                return a.equals(RolesAndPermissions.ROLE_CURATION)
115
                        // doing faster regex check here instreas of using CdmAuthoritiy.fromString()
116
                        || a.getAuthority().matches("^Registration\\.\\[.*UPDATE");
117
            });
118
        }
119
        return false;
120
    }
121

    
122
    @Override
123
    public boolean userHasPermission(CdmBase entity, Object ... args){
124
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
125
        try {
126
            return permissionEvaluator.hasPermission(getAuthentication(), entity, crudSet);
127
        } catch (PermissionDeniedException e){
128
            //IGNORE
129
        }
130
        return false;
131
    }
132

    
133
    @Override
134
    public boolean userHasPermission(Class<? extends CdmBase> cdmType, Integer entitiyId, Object ... args){
135
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
136
        try {
137
            CdmBase entity = repo.getCommonService().find(cdmType, entitiyId);
138
            return permissionEvaluator.hasPermission(getAuthentication(), entity, crudSet);
139
        } catch (PermissionDeniedException e){
140
            //IGNORE
141
        }
142
        return false;
143
    }
144

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

    
156
    public void logout() {
157
        SecurityContext context = SecurityContextHolder.getContext();
158
        context.setAuthentication(null);
159
        SecurityContextHolder.clearContext();
160
    }
161

    
162

    
163
    private EnumSet<CRUD> crudSetFromArgs(Object[] args) {
164
        EnumSet<CRUD> crudSet = EnumSet.noneOf(CRUD.class);
165
        for(int i = 0; i < args.length; i++){
166
            try {
167
                crudSet.add(CRUD.valueOf(args[i].toString()));
168
            } catch (Exception e){
169
                throw new IllegalArgumentException("could not add " + args[i], e);
170
            }
171
        }
172
        return crudSet;
173
    }
174

    
175

    
176
    /**
177
     * @return
178
     *
179
     * FIXME is it ok to use the SecurityContextHolder or do we need to hold the context in the vaadin session?
180
     */
181
    private SecurityContext currentSecurityContext() {
182
        return SecurityContextHolder.getContext();
183
    }
184

    
185
    /**
186
     * @return
187
     */
188
    private Authentication getAuthentication() {
189
        return currentSecurityContext().getAuthentication();
190
    }
191

    
192
    /**
193
     * {@inheritDoc}
194
     *
195
     */
196
    @Override
197
    public CdmAuthority createAuthorityFor(String username, CdmBase cdmEntity, EnumSet<CRUD> crud, String property) {
198

    
199
        TransactionStatus txStatus = repo.startTransaction();
200
        UserDetails userDetails = repo.getUserService().loadUserByUsername(username);
201
        boolean newAuthorityAdded = false;
202
        CdmAuthority authority = null;
203
        if(userDetails != null){
204
            runAsAutheticator.runAsAuthentication(Role.ROLE_USER_MANAGER);
205
            User user = (User)userDetails;
206
            authority = new CdmAuthority(cdmEntity, property, crud);
207
            try {
208
                newAuthorityAdded = user.getGrantedAuthorities().add(authority.asNewGrantedAuthority());
209
            } catch (CdmAuthorityParsingException e) {
210
                throw new RuntimeException(e);
211
            }
212
            repo.getSession().flush();
213
            runAsAutheticator.restoreAuthentication();
214
            logger.debug("new authority for " + username + ": " + authority.toString());
215
            Authentication authentication = new PreAuthenticatedAuthenticationToken(user, user.getPassword(), user.getAuthorities());
216
            SecurityContextHolder.getContext().setAuthentication(authentication);
217
            logger.debug("security context refreshed with user " + username);
218
        }
219
        repo.commitTransaction(txStatus);
220
        return newAuthorityAdded ? authority : null;
221

    
222
    }
223

    
224
    /**
225
     * @param username
226
     * @param cdmType
227
     * @param entitiyId
228
     * @param crud
229
     * @return
230
     */
231
    @Override
232
    public CdmAuthority createAuthorityFor(String username, Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property) {
233

    
234
        CdmBase cdmEntity = repo.getCommonService().find(cdmType, entitiyId);
235
        return createAuthorityFor(username, cdmEntity, crud, property);
236
    }
237

    
238
    /**
239
     * {@inheritDoc}
240
     */
241
    @Override
242
    public CdmAuthority createAuthorityForCurrentUser(CdmBase cdmEntity, EnumSet<CRUD> crud, String property) {
243
        return createAuthorityFor(userName(), cdmEntity, crud, property);
244

    
245
    }
246

    
247
    /**
248
     * @param cdmType
249
     * @param entitiyId
250
     * @param crud
251
     * @return
252
     */
253
    @Override
254
    public CdmAuthority createAuthorityForCurrentUser(Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property) {
255
        return createAuthorityFor(userName(), cdmType, entitiyId, crud, property);
256
    }
257

    
258
    /**
259
     * {@inheritDoc}
260
     */
261
    @Override
262
    public void removeAuthorityForCurrentUser(CdmAuthority cdmAuthority) {
263
        removeAuthorityForCurrentUser(userName(), cdmAuthority);
264

    
265
    }
266

    
267
    /**
268
     * {@inheritDoc}
269
     */
270
    @Override
271
    public void removeAuthorityForCurrentUser(String username, CdmAuthority cdmAuthority) {
272

    
273
        UserDetails userDetails = repo.getUserService().loadUserByUsername(username);
274
        if(userDetails != null){
275
            runAsAutheticator.runAsAuthentication(Role.ROLE_USER_MANAGER);
276
            User user = (User)userDetails;
277
            user.getGrantedAuthorities().remove(cdmAuthority);
278
            repo.getSession().flush();
279
            runAsAutheticator.restoreAuthentication();
280
            Authentication authentication = new PreAuthenticatedAuthenticationToken(user, user.getPassword(), user.getAuthorities());
281
            SecurityContextHolder.getContext().setAuthentication(authentication);
282
            logger.debug("security context refreshed with user " + username);
283
        }
284

    
285
    }
286

    
287
}
(3-3/7)