Project

General

Profile

Download (8.69 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.core.Authentication;
18
import org.springframework.security.core.context.SecurityContext;
19
import org.springframework.security.core.context.SecurityContextHolder;
20
import org.springframework.security.core.userdetails.UserDetails;
21
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
22

    
23
import com.vaadin.spring.annotation.SpringComponent;
24
import com.vaadin.spring.annotation.UIScope;
25

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

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

    
47
    public static final Logger logger = Logger.getLogger(CdmUserHelper.class);
48

    
49
    @Autowired
50
    private ICdmPermissionEvaluator permissionEvaluator;
51

    
52
    @Autowired
53
    @Qualifier("cdmRepository")
54
    private CdmRepository repo;
55

    
56
    public CdmUserHelper(){
57
        super();
58
    }
59

    
60
    @Override
61
    public boolean userIsAutheticated() {
62
        Authentication authentication = getAuthentication();
63
        if(authentication != null){
64
            return authentication.isAuthenticated();
65
        }
66
        return false;
67
    }
68

    
69

    
70
    @Override
71
    public boolean userIsAnnonymous() {
72
        Authentication authentication = getAuthentication();
73
        return authentication != null
74
                && authentication.isAuthenticated()
75
                && authentication instanceof AnonymousAuthenticationToken;
76
    }
77

    
78
    @Override
79
    public String userName() {
80
        Authentication authentication = getAuthentication();
81
        if(authentication != null) {
82
            return authentication.getName();
83
        }
84
        return null;
85
    }
86

    
87
    @Override
88
    public boolean userIsAdmin() {
89
        Authentication authentication = getAuthentication();
90
        if(authentication != null) {
91
            return authentication.getAuthorities().stream().anyMatch(a -> {
92
                return a.getAuthority().equals(Role.ROLE_ADMIN.getAuthority());
93
            });
94
        }
95
        return false;
96
    }
97

    
98
    @Override
99
    public boolean userIsRegistrationCurator() {
100
        Authentication authentication = getAuthentication();
101
        if(authentication != null) {
102
            return authentication.getAuthorities().stream().anyMatch(a -> {
103
                return a.equals(RolesAndPermissions.ROLE_CURATION)
104
                        // doing faster regex check here instreas of using CdmAuthoritiy.fromString()
105
                        || a.getAuthority().matches("^Registration\\.\\[.*UPDATE");
106
            });
107
        }
108
        return false;
109
    }
110

    
111
    @Override
112
    public boolean userHasPermission(CdmBase entity, Object ... args){
113
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
114
        try {
115
            return permissionEvaluator.hasPermission(getAuthentication(), entity, crudSet);
116
        } catch (PermissionDeniedException e){
117
            //IGNORE
118
        }
119
        return false;
120
    }
121

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

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

    
145
    public void logout() {
146
        SecurityContext context = SecurityContextHolder.getContext();
147
        context.setAuthentication(null);
148
        SecurityContextHolder.clearContext();
149
    }
150

    
151

    
152
    private EnumSet<CRUD> crudSetFromArgs(Object[] args) {
153
        EnumSet<CRUD> crudSet = EnumSet.noneOf(CRUD.class);
154
        for(int i = 0; i < args.length; i++){
155
            try {
156
                crudSet.add(CRUD.valueOf(args[i].toString()));
157
            } catch (Exception e){
158
                throw new IllegalArgumentException("could not add " + args[i], e);
159
            }
160
        }
161
        return crudSet;
162
    }
163

    
164

    
165
    /**
166
     * @return
167
     *
168
     * FIXME is it ok to use the SecurityContextHolder or do we need to hold the context in the vaadin session?
169
     */
170
    private SecurityContext currentSecurityContext() {
171
        return SecurityContextHolder.getContext();
172
    }
173

    
174
    /**
175
     * @return
176
     */
177
    private Authentication getAuthentication() {
178
        return currentSecurityContext().getAuthentication();
179
    }
180

    
181
    /**
182
     * @param username
183
     * @param cdmType
184
     * @param entitiyId
185
     * @param crud
186
     * @return
187
     */
188
    @Override
189
    public void createAuthorityFor(String username, Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property) {
190
        UserDetails userDetails = repo.getUserService().loadUserByUsername(username);
191
        if(userDetails != null){
192
            User user = (User)userDetails;
193
            CdmBase entity = repo.getCommonService().find(cdmType, entitiyId);
194
            CdmAuthority authority = new CdmAuthority(entity, property, crud);
195
            try {
196
                user.getGrantedAuthorities().add(authority.asNewGrantedAuthority());
197
            } catch (CdmAuthorityParsingException e) {
198
                throw new RuntimeException(e);
199
            }
200
            repo.getSession().flush();
201
            logger.debug("new authority for " + username + ": " + authority.toString());
202
            Authentication authentication = new PreAuthenticatedAuthenticationToken(user, user.getPassword(), user.getAuthorities());
203
            SecurityContextHolder.getContext().setAuthentication(authentication);
204
            logger.debug("security context refreshed with user " + username);
205
        }
206
    }
207

    
208
    /**
209
     * @param cdmType
210
     * @param entitiyId
211
     * @param crud
212
     * @return
213
     */
214
    @Override
215
    public void createAuthorityForCurrentUser(Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property) {
216
        createAuthorityFor(userName(), cdmType, entitiyId, crud, property);
217
    }
218

    
219
    /**
220
     * {@inheritDoc}
221
     */
222
    @Override
223
    public void createAuthorityFor(String username, CdmBase cdmEntity, EnumSet<CRUD> crud, String property) {
224
        UserDetails userDetails = repo.getUserService().loadUserByUsername(username);
225
        if(userDetails != null){
226
            User user = (User)userDetails;
227
            CdmAuthority authority = new CdmAuthority(cdmEntity, property, crud);
228
            try {
229
                user.getGrantedAuthorities().add(authority.asNewGrantedAuthority());
230
            } catch (CdmAuthorityParsingException e) {
231
                throw new RuntimeException(e);
232
            }
233
            repo.getSession().flush();
234
            logger.debug("new authority for " + username + ": " + authority.toString());
235
            Authentication authentication = new PreAuthenticatedAuthenticationToken(user, user.getPassword(), user.getAuthorities());
236
            SecurityContextHolder.getContext().setAuthentication(authentication);
237
            logger.debug("security context refreshed with user " + username);
238
        }
239

    
240
    }
241

    
242
    /**
243
     * {@inheritDoc}
244
     */
245
    @Override
246
    public void createAuthorityForCurrentUser(CdmBase cdmEntity, EnumSet<CRUD> crud, String property) {
247
        createAuthorityFor(userName(), cdmEntity, crud, property);
248

    
249
    }
250

    
251
}
(3-3/5)