Project

General

Profile

« Previous | Next » 

Revision 7631d065

Added by Andreas Kohlbecker over 6 years ago

fix #7021 excluding not protected cache fields from modification check in CdmSecurityHibernateInterceptor

View differences:

cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/CdmSecurityHibernateInterceptor.java
8 8
 */
9 9
package eu.etaxonomy.cdm.persistence.hibernate;
10 10

  
11

  
12

  
11
import java.beans.Introspector;
13 12
import java.io.Serializable;
13
import java.util.ArrayList;
14
import java.util.Collection;
14 15
import java.util.EnumSet;
15 16
import java.util.HashMap;
16 17
import java.util.HashSet;
18
import java.util.List;
17 19
import java.util.Map;
18 20
import java.util.Set;
19 21

  
......
32 34
import eu.etaxonomy.cdm.persistence.hibernate.permission.ICdmPermissionEvaluator;
33 35
import eu.etaxonomy.cdm.persistence.hibernate.permission.Operation;
34 36
import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
37

  
35 38
/**
36 39
 * @author k.luther
37 40
 * @author a.kohlbecker
......
111 114
        if (previousState == null){
112 115
            return onSave(cdmEntity, id, currentState, propertyNames, null);
113 116
        }
114
        if (isModified(currentState, previousState, propertyNames, exculdeMap.get(baseType(cdmEntity)))) {
117
        Set<String> excludes = exculdeMap.get(baseType(cdmEntity));
118
        excludes.addAll(unprotectedCacheFields(currentState, previousState, propertyNames));
119
        if (isModified(currentState, previousState, propertyNames, excludes)) {
115 120
            // evaluate throws EvaluationFailedException
121
            //if(cdmEntity.getCreated())
116 122
            checkPermissions(cdmEntity, Operation.UPDATE);
117 123
            logger.debug("Operation.UPDATE permission check suceeded - object update granted");
118 124

  
......
126 132
        return true;
127 133
    }
128 134

  
135
    /**
136
     * Detects all cache fields and the according protection flags. For cache fields which are not
137
     * protected the name of the cache field and of the protection flag are returned.
138
     * <p>
139
     * This method relies on  the convention that the protection flag for cache fields are named like
140
     * {@code protected{CacheFieldName} } whereas the cache fields a always ending with "Cache"
141
     *
142
     * @param currentState
143
     * @param previousState
144
     * @param propertyNames
145
     * @return
146
     */
147
    protected Collection<? extends String> unprotectedCacheFields(Object[] currentState, Object[] previousState,
148
            String[] propertyNames) {
149

  
150
        List<String> excludes = new ArrayList<>();
151
        for(int i = 0; i < propertyNames.length; i ++){
152
            if(propertyNames[i].matches("^protected.*Cache$")){
153
                if(currentState[i] instanceof Boolean && ((Boolean)currentState[i]) == false && currentState[i].equals(previousState[i])){
154
                    excludes.add(propertyNames[i]);
155
                    String cacheFieldName = propertyNames[i].replace("protected", "");
156
                    cacheFieldName = Introspector.decapitalize(cacheFieldName);
157
                    excludes.add(cacheFieldName);
158
                }
159
            }
160
        }
161

  
162
        return excludes;
163
    }
164

  
129 165
    private Class<? extends CdmBase> baseType(CdmBase cdmEntity) {
130 166
        Class<? extends CdmBase> basetype = CdmBaseType.baseTypeFor(cdmEntity.getClass());
131 167
        return basetype == null ? CdmBase.class : basetype;

Also available in: Unified diff