Project

General

Profile

« Previous | Next » 

Revision 42af5bd2

Added by Andreas Kohlbecker almost 7 years ago

ref #6169 UserHelper checking permissions:

  • UserHelper as SpringComponent which selfregisters in the VaadinSession
  • disabling fields in PersonField of User has not sufficient permissions

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.util.EnumSet;
12

  
13
import org.springframework.beans.factory.annotation.Autowired;
14
import org.springframework.security.authentication.AnonymousAuthenticationToken;
15
import org.springframework.security.core.Authentication;
16
import org.springframework.security.core.context.SecurityContext;
17
import org.springframework.security.core.context.SecurityContextHolder;
18

  
19
import com.vaadin.spring.annotation.SpringComponent;
20
import com.vaadin.spring.annotation.UIScope;
21

  
22
import eu.etaxonomy.cdm.database.PermissionDeniedException;
23
import eu.etaxonomy.cdm.model.common.CdmBase;
24
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
25
import eu.etaxonomy.cdm.persistence.hibernate.permission.ICdmPermissionEvaluator;
26
import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
27
import eu.etaxonomy.cdm.vaadin.security.RolesAndPermissions;
28
import eu.etaxonomy.cdm.vaadin.security.VaadinUserHelper;
29

  
30
/**
31
 * @author a.kohlbecker
32
 * @since May 19, 2017
33
 *
34
 */
35
@SpringComponent
36
@UIScope
37
public class CdmUserHelper extends VaadinUserHelper {
38

  
39
    @Autowired
40
    private ICdmPermissionEvaluator permissionEvaluator;
41

  
42
    public CdmUserHelper(){
43
        super();
44
    }
45

  
46
    @Override
47
    public boolean userIsAutheticated() {
48
        Authentication authentication = getAuthentication();
49
        if(authentication != null){
50
            return authentication.isAuthenticated();
51
        }
52
        return false;
53
    }
54

  
55

  
56
    @Override
57
    public boolean userIsAnnonymous() {
58
        Authentication authentication = getAuthentication();
59
        return authentication != null
60
                && authentication.isAuthenticated()
61
                && authentication instanceof AnonymousAuthenticationToken;
62
    }
63

  
64
    @Override
65
    public String userName() {
66
        Authentication authentication = getAuthentication();
67
        if(authentication != null) {
68
            return authentication.getName();
69
        }
70
        return null;
71
    }
72

  
73
    @Override
74
    public boolean userIsAdmin() {
75
        Authentication authentication = getAuthentication();
76
        if(authentication != null) {
77
            return authentication.getAuthorities().stream().anyMatch(a -> {
78
                return a.getAuthority().equals(Role.ROLE_ADMIN.getAuthority());
79
            });
80
        }
81
        return false;
82
    }
83

  
84
    @Override
85
    public boolean userIsRegistrationCurator() {
86
        Authentication authentication = getAuthentication();
87
        if(authentication != null) {
88
            return authentication.getAuthorities().stream().anyMatch(a -> {
89
                return a.equals(RolesAndPermissions.ROLE_CURATION)
90
                        // doing faster regex check here instreas of using CdmAuthoritiy.fromString()
91
                        || a.getAuthority().matches("^Registration\\.\\[.*UPDATE");
92
            });
93
        }
94
        return false;
95
    }
96

  
97
    @Override
98
    public boolean userHasPermission(CdmBase entity, Object ... args){
99
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
100
        try {
101
        return permissionEvaluator.hasPermission(getAuthentication(), entity, crudSet);
102
        } catch (PermissionDeniedException e){
103
            //IGNORE
104
        }
105
        return false;
106
    }
107

  
108
    @Override
109
    public boolean userHasPermission(Class<? extends CdmBase> cdmType, Integer entitiyId, Object ... args){
110
        EnumSet<CRUD> crudSet = crudSetFromArgs(args);
111
        try {
112
        return permissionEvaluator.hasPermission(getAuthentication(), cdmType, entitiyId.toString(), crudSet);
113
        } catch (PermissionDeniedException e){
114
            //IGNORE
115
        }
116
        return false;
117
    }
118

  
119

  
120
    private EnumSet<CRUD> crudSetFromArgs(Object[] args) {
121
        EnumSet<CRUD> crudSet = EnumSet.noneOf(CRUD.class);
122
        for(int i = 0; i < args.length; i++){
123
            try {
124
                crudSet.add(CRUD.valueOf(args[i].toString()));
125
            } catch (Exception e){
126
                throw new IllegalArgumentException("could not add " + args[i], e);
127
            }
128
        }
129
        return crudSet;
130
    }
131

  
132

  
133
    /**
134
     * @return
135
     *
136
     * FIXME is it ok to use the SecurityContextHolder or do we need to hold the context in the vaadin session?
137
     */
138
    private SecurityContext currentSecurityContext() {
139
        return SecurityContextHolder.getContext();
140
    }
141

  
142
    /**
143
     * @return
144
     */
145
    private Authentication getAuthentication() {
146
        return currentSecurityContext().getAuthentication();
147
    }
148

  
149
}
src/main/java/eu/etaxonomy/cdm/vaadin/component/common/PersonField.java
16 16
import com.vaadin.ui.themes.ValoTheme;
17 17

  
18 18
import eu.etaxonomy.cdm.model.agent.Person;
19
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
19 20
import eu.etaxonomy.vaadin.component.CompositeCustomField;
20 21
import eu.etaxonomy.vaadin.component.SwitchButton;
21 22

  
......
53 54
    private TextField suffixField = new TextField();
54 55
    private SwitchButton unlockSwitch = new SwitchButton();
55 56

  
56

  
57

  
58 57
    /**
59 58
     * @param caption
60 59
     */
......
79 78
        addStyledComponent(unlockSwitch);
80 79

  
81 80
        addSizedComponent(root);
81

  
82
    }
83

  
84
    /**
85
     *
86
     */
87
    private void checkUserPermissions(Person newValue) {
88
        boolean userCanEdit = UserHelper.fromSession().userHasPermission(newValue, "DELETE", "UPDATE");
89
        cacheField.setEnabled(userCanEdit);
90
        firstNameField.setEnabled(userCanEdit);
91
        lastNameField.setEnabled(userCanEdit);
92
        prefixField.setEnabled(userCanEdit);
93
        suffixField.setEnabled(userCanEdit);
82 94
    }
83 95

  
84 96
    private void setMode(Mode mode){
......
188 200
    protected void setInternalValue(Person newValue) {
189 201
        super.setInternalValue(newValue);
190 202
        fieldGroup.setItemDataSource(newValue);
191
        // refreshMode();
203
        checkUserPermissions(newValue);
192 204
    }
193 205

  
194 206
    @Override
src/main/java/eu/etaxonomy/cdm/vaadin/security/UserHelper.java
8 8
*/
9 9
package eu.etaxonomy.cdm.vaadin.security;
10 10

  
11
import org.springframework.security.authentication.AnonymousAuthenticationToken;
12
import org.springframework.security.core.Authentication;
13
import org.springframework.security.core.context.SecurityContext;
14
import org.springframework.security.core.context.SecurityContextHolder;
11
import com.vaadin.server.VaadinSession;
15 12

  
16
import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
13
import eu.etaxonomy.cdm.model.common.CdmBase;
17 14

  
18 15
/**
16
 * UserHelper interface. Imeplemtations should use the {@link #VADDIN_SESSION_KEY} to auto registers
17
 * in the VaadinSession.
18
 *
19 19
 * @author a.kohlbecker
20
 * @since May 19, 2017
20
 * @since May 23, 2017
21 21
 *
22 22
 */
23
public class UserHelper {
23
public interface UserHelper {
24 24

  
25
    public static final String VADDIN_SESSION_KEY = "USER_HELPER";
25 26

  
26
    public static boolean userIsAutheticated() {
27
        Authentication authentication = getAuthentication();
28
        if(authentication != null){
29
            return authentication.isAuthenticated();
30
        }
31
        return false;
27
    /**
28
     * Static accessor method to obtain the auto-registered UserHelper-Bean from the
29
     * VaadinSession.
30
     *
31
     * @return
32
     */
33
    public static UserHelper fromSession() {
34
       return (UserHelper)VaadinSession.getCurrent().getAttribute(VADDIN_SESSION_KEY);
32 35
    }
33 36

  
37
    boolean userHasPermission(Class<? extends CdmBase> cdmType, Integer entitiyId, Object ... args);
34 38

  
35
    public static boolean userIsAnnonymous() {
36
        Authentication authentication = getAuthentication();
37
        return authentication != null
38
                && authentication.isAuthenticated()
39
                && authentication instanceof AnonymousAuthenticationToken;
40
    }
39
    boolean userHasPermission(CdmBase entity, Object ... args);
41 40

  
42
    public static String userName() {
43
        Authentication authentication = getAuthentication();
44
        if(authentication != null) {
45
            return authentication.getName();
46
        }
47
        return null;
48
    }
41
    boolean userIsRegistrationCurator();
49 42

  
50
    public static boolean userIsAdmin() {
51
        Authentication authentication = getAuthentication();
52
        if(authentication != null) {
53
            return authentication.getAuthorities().stream().anyMatch(a -> {
54
                return a.getAuthority().equals(Role.ROLE_ADMIN.getAuthority());
55
            });
56
        }
57
        return false;
58
    }
43
    boolean userIsAdmin();
59 44

  
60
    public static boolean userIsRegistrationCurator() {
61
        Authentication authentication = getAuthentication();
62
        if(authentication != null) {
63
            return authentication.getAuthorities().stream().anyMatch(a -> {
64
                return a.equals(RolesAndPermissions.ROLE_CURATION)
65
                        // doing faster regex check here instreas of using CdmAuthoritiy.fromString()
66
                        || a.getAuthority().matches("^Registration\\.\\[.*UPDATE");
67
            });
68
        }
69
        return false;
70
    }
45
    String userName();
71 46

  
72
    /**
73
     * @return
74
     *
75
     * FIXME is it ok to use the SecurityContextHolder or do we need to hold the context in the vaadin session?
76
     */
77
    private static SecurityContext currentSecurityContext() {
78
        return SecurityContextHolder.getContext();
79
    }
47
    boolean userIsAnnonymous();
80 48

  
81
    /**
82
     * @return
83
     */
84
    private static Authentication getAuthentication() {
85
        return currentSecurityContext().getAuthentication();
86
    }
49
    boolean userIsAutheticated();
87 50

  
88 51
}
src/main/java/eu/etaxonomy/cdm/vaadin/security/VaadinUserHelper.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.security;
10

  
11
import com.vaadin.server.VaadinSession;
12

  
13
/**
14
 * Abstract UserHelper which auto registers in the VaadinSession.
15
 *
16
 * @author a.kohlbecker
17
 * @since May 23, 2017
18
 *
19
 */
20
public abstract class VaadinUserHelper implements UserHelper {
21

  
22
    public VaadinUserHelper() {
23
        VaadinSession.getCurrent().setAttribute(VADDIN_SESSION_KEY, this);
24
    }
25

  
26
}
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListPresenter.java
63 63
        // list all if the authenticated user is having the role CURATION of if it is an admin
64 64
        Authentication authentication = currentSecurityContext().getAuthentication();
65 65
        User submitter = null;
66
        if(!(UserHelper.userIsRegistrationCurator() || UserHelper.userIsAdmin())) {
66
        if(!(UserHelper.fromSession().userIsRegistrationCurator() || UserHelper.fromSession().userIsAdmin())) {
67 67
            submitter = (User) authentication.getPrincipal();
68 68
        }
69 69

  
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListViewBean.java
210 210

  
211 211
    public void populateList(Collection<RegistrationDTO> registrations) {
212 212

  
213
        boolean isCurator = UserHelper.userIsRegistrationCurator() || UserHelper.userIsAdmin();
213
        boolean isCurator = UserHelper.fromSession().userIsRegistrationCurator() || UserHelper.fromSession().userIsAdmin();
214 214
        for(RegistrationDTO regDto : registrations) {
215 215
            RegistrationItem item = new RegistrationItem(regDto, this);
216 216
            item.getSubmitterLabel().setVisible(isCurator);
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkflowViewBean.java
134 134

  
135 135
        registration.addComponent(createWorkflowTabSheet(workingset, null));
136 136
        RegistrationItem registrationItem = new RegistrationItem(workingset, this);
137
        if(UserHelper.userIsRegistrationCurator() || UserHelper.userIsAdmin()){
137
        if(UserHelper.fromSession().userIsRegistrationCurator() || UserHelper.fromSession().userIsAdmin()){
138 138
            registrationItem.getSubmitterLabel().setVisible(true);
139 139
        };
140 140
        registration.addComponent(registrationItem);
......
234 234
        messageButton.setCaptionAsHtml(true);
235 235
        buttonGroup.addComponent(messageButton);
236 236

  
237
        if(UserHelper.userIsRegistrationCurator() || UserHelper.userIsAdmin()) {
237
        if(UserHelper.fromSession().userIsRegistrationCurator() || UserHelper.fromSession().userIsAdmin()) {
238 238
        Button editButton = new Button(FontAwesome.EDIT);
239 239
        editButton.setStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_PRIMARY);
240 240
        editButton.addClickListener(e -> getEventBus().publishEvent(new RegistrationEditorAction(
src/main/java/eu/etaxonomy/cdm/vaadin/view/taxon/TaxonNamePopupEditor.java
47 47

  
48 48
    private final static int GRID_ROWS = 7;
49 49

  
50
    private TextField titleField;
51

  
52 50
    private TextField genusOrUninomialField;
53 51

  
54 52
    private TextField infraGenericEpithetField;
......
62 60
    private SwitchableTextField protectedNameCacheField;
63 61

  
64 62

  
65

  
66 63
    /**
67 64
     * @param layout
68 65
     * @param dtoType
......
160 157
        ListSelect rankSelect = selectFieldFactory.createListSelect("Rank", Rank.class, OrderHint.BY_ORDER_INDEX.asList(), "label");
161 158
        rankSelect.setNullSelectionAllowed(false);
162 159
        rankSelect.setRows(1);
163
        rankSelect.addValidator(e -> updateFieldVisibility());
160
        rankSelect.addValueChangeListener(e -> updateFieldVisibility((Rank)e.getProperty().getValue()));
164 161
        addField(rankSelect, "rank", 3, row);
165 162
        grid.setComponentAlignment(rankSelect, Alignment.TOP_RIGHT);
166 163
        row++;
......
197 194
    }
198 195

  
199 196
    /**
197
     * @param rank
200 198
     * @return
201 199
     */
202
    private Object updateFieldVisibility() {
203
        // TODO Auto-generated method stub
204
        // TODO change label of
205
        // - genusOrUninomialField
206
        return null;
200
    private void updateFieldVisibility(Rank rank) {
201
        boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES());
202
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
203
        specificEpithetField.setVisible(isSpeciesOrBelow);
204
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
205
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
207 206
    }
208 207

  
209 208
    /**
src/main/java/eu/etaxonomy/vaadin/ui/navigation/NavigationManagerBean.java
24 24
import com.vaadin.ui.UI;
25 25
import com.vaadin.ui.Window;
26 26

  
27
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
27 28
import eu.etaxonomy.vaadin.ui.UIInitializedEvent;
28 29
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent;
29 30
import eu.etaxonomy.vaadin.ui.view.PopupView;
......
44 45
	@Autowired
45 46
	private ViewChangeListener viewChangeListener;
46 47

  
48
	@Autowired
49
    private UserHelper userHelper;
50

  
47 51
	private Map<PopupView, Window> popupMap;
48 52

  
49 53
	public NavigationManagerBean() {

Also available in: Unified diff