Project

General

Profile

Download (8.14 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 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.persistence.permission;
10

    
11
import java.io.Serializable;
12
import java.lang.reflect.Constructor;
13
import java.lang.reflect.InvocationTargetException;
14
import java.util.Collection;
15
import java.util.EnumSet;
16
import java.util.HashSet;
17

    
18
import org.apache.log4j.Logger;
19
import org.springframework.security.access.AccessDecisionManager;
20
import org.springframework.security.access.AccessDeniedException;
21
import org.springframework.security.access.ConfigAttribute;
22
import org.springframework.security.authentication.InsufficientAuthenticationException;
23
import org.springframework.security.core.Authentication;
24
import org.springframework.security.core.GrantedAuthority;
25
import org.springframework.stereotype.Component;
26

    
27
import eu.etaxonomy.cdm.model.common.CdmBase;
28
import eu.etaxonomy.cdm.model.permission.CRUD;
29
import eu.etaxonomy.cdm.model.permission.Operation;
30
import eu.etaxonomy.cdm.model.permission.PermissionClass;
31

    
32
/**
33
 * @author k.luther
34
 * @author a.kohlbecker
35
 * @since 06.07.2011
36
 */
37
@Component
38
public class CdmPermissionEvaluator implements ICdmPermissionEvaluator {
39

    
40
    protected static final Logger logger = Logger.getLogger(CdmPermissionEvaluator.class);
41

    
42
    private AccessDecisionManager accessDecisionManager;
43

    
44
    public AccessDecisionManager getAccessDecisionManager() {
45
        return accessDecisionManager;
46
    }
47

    
48
    public CdmPermissionEvaluator() {
49

    
50
    }
51

    
52
    public void setAccessDecisionManager(AccessDecisionManager accessDecisionManager) {
53
        this.accessDecisionManager = accessDecisionManager;
54
    }
55

    
56
    @Override
57
    public boolean hasPermission(Authentication authentication,
58
            Serializable targetId, String targetType, Object permission) {
59
        logger.warn("UNINMPLEMENTED: hasPermission always returns false");
60
        // TODO Auto-generated method stub
61
        return false;
62
    }
63

    
64
    @Override
65
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
66

    
67
        EnumSet<CRUD> requiredOperation = null;
68

    
69
        TargetEntityStates cdmEntitiyStates;
70
        if(targetDomainObject instanceof CdmBase){
71
            cdmEntitiyStates = new TargetEntityStates((CdmBase)targetDomainObject);
72
        } else {
73
            cdmEntitiyStates = (TargetEntityStates)targetDomainObject;
74
        }
75

    
76
        if(logger.isDebugEnabled()){
77
            String targteDomainObjText = "  Object: " + (targetDomainObject == null? "null":cdmEntitiyStates.getEntity().instanceToString());
78
            logUserAndRequirement(authentication, permission.toString(), targteDomainObjText);
79
        }
80
        try {
81
            requiredOperation = operationFrom(permission);
82

    
83
        } catch (IllegalArgumentException e) {
84
            logger.debug("permission string '"+ permission.toString() + "' not parsable => true");
85
            return false;
86
        }
87

    
88
        return hasPermission(authentication, cdmEntitiyStates, requiredOperation);
89

    
90
    }
91

    
92
    @Override
93
    public boolean hasPermission(Authentication authentication, CdmBase targetEntity, EnumSet<CRUD> requiredOperation) {
94
        return hasPermission(authentication, new TargetEntityStates(targetEntity), requiredOperation);
95
    }
96

    
97
    @Override
98
    public boolean hasPermission(Authentication authentication, TargetEntityStates targetEntityStates, EnumSet<CRUD> requiredOperation) {
99

    
100
        if(authentication == null) {
101
            return false;
102
        }
103

    
104
        CdmAuthority evalPermission = authorityRequiredFor(targetEntityStates.getEntity(), requiredOperation);
105

    
106
        if (evalPermission.getPermissionClass() != null) {
107
            logger.debug("starting evaluation => ...");
108
            return evalPermission(authentication, evalPermission, targetEntityStates);
109
        }else{
110
            logger.debug("skipping evaluation => true");
111
            return true;
112
        }
113
    }
114

    
115
    @Override
116
    public <T extends CdmBase> boolean hasPermission(Authentication authentication, Class<T> targetDomainObjectClass,
117
            EnumSet<CRUD> requiredOperations) {
118

    
119
        if(authentication == null) {
120
            return false;
121
        }
122

    
123
        if(logger.isDebugEnabled()){
124
            String targteDomainObjClassText = "  Cdm-Type: " + targetDomainObjectClass.getSimpleName();
125
            logUserAndRequirement(authentication, requiredOperations.toString(), targteDomainObjClassText);
126
        }
127

    
128
        CdmAuthority evalPermission = new CdmAuthority(PermissionClass.getValueOf(targetDomainObjectClass), null, requiredOperations, null);
129

    
130
        T instance;
131
        try {
132
            Constructor<T> c = targetDomainObjectClass.getDeclaredConstructor();
133
            c.setAccessible(true);
134
            instance = c.newInstance();
135
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
136
            logger.error("Error while creating permission test instance ==> will deny", e);
137
            return false;
138
        }
139

    
140
        return evalPermission(authentication, evalPermission, new TargetEntityStates(instance));
141
    }
142

    
143
    protected void logUserAndRequirement(Authentication authentication, String permissions, String targteDomainObjText) {
144
        StringBuilder grantedAuthoritiesTxt = new StringBuilder();
145
        for(GrantedAuthority ga : authentication.getAuthorities()){
146
            grantedAuthoritiesTxt.append("    - ").append(ga.getAuthority()).append("\n");
147
        }
148
        if(grantedAuthoritiesTxt.length() == 0){
149
            grantedAuthoritiesTxt.append("    - ").append("<No GrantedAuthority given>").append("\n");
150
        }
151
        logger.debug("hasPermission()\n"
152
                + "  User '" + authentication.getName() + "':\n"
153
                + grantedAuthoritiesTxt
154
                + targteDomainObjText + "\n"
155
                + "  Permission: " + permissions);
156
    }
157

    
158
    protected EnumSet<CRUD> operationFrom(Object permission) {
159
        EnumSet<CRUD> requiredOperation;
160
        // FIXME refactor into Operation ======
161
        if (Operation.isOperation(permission)){
162
            requiredOperation = (EnumSet<CRUD>)permission;
163
        } else {
164
            // try to treat as string
165
            requiredOperation = Operation.fromString(permission.toString());
166
        }
167
        // =======================================
168
        return requiredOperation;
169
    }
170

    
171
    private CdmAuthority authorityRequiredFor(CdmBase targetEntity, EnumSet<CRUD> requiredOperation) {
172
        CdmAuthority evalPermission = new CdmAuthority(targetEntity, requiredOperation);
173
        return evalPermission;
174
    }
175

    
176
    private boolean evalPermission(Authentication authentication, CdmAuthority evalPermission, TargetEntityStates targetEntityStates){
177

    
178
        //if user has administrator rights return true;
179
        if( hasOneOfRoles(authentication, Role.ROLE_ADMIN)){
180
            return true;
181
        }
182

    
183
        // === run voters
184
        Collection<ConfigAttribute> attributes = new HashSet<ConfigAttribute>();
185
        attributes.add(evalPermission);
186

    
187
        logger.debug("AccessDecisionManager will decide ...");
188
        try {
189
            accessDecisionManager.decide(authentication, targetEntityStates, attributes);
190
        } catch (InsufficientAuthenticationException e) {
191
            logger.debug("AccessDecisionManager denied by " + e, e);
192
            return false;
193
        } catch (AccessDeniedException e) {
194
            logger.debug("AccessDecisionManager denied by " + e, e);
195
            return false;
196
        }
197

    
198
        return true;
199
    }
200

    
201
    @Override
202
    public boolean hasOneOfRoles(Authentication authentication, Role ... roles) {
203
        for (GrantedAuthority authority: authentication.getAuthorities()){
204
            for(Role role : roles){
205
                 if (role != null && authority.getAuthority().equals(role.getAuthority())){
206
                     if(logger.isDebugEnabled()){
207
                         logger.debug(role.getAuthority() + " found => true");
208
                     }
209
                     return true;
210
                 }
211
            }
212
         }
213
        return false;
214
    }
215

    
216
}
(3-3/10)