it.doqui.index.ecmengine.business.personalization.security.acl.ACLEntryAfterInvocationProvider.java Source code

Java tutorial

Introduction

Here is the source code for it.doqui.index.ecmengine.business.personalization.security.acl.ACLEntryAfterInvocationProvider.java

Source

/* Index ECM Engine - A system for managing the capture (when created
 * or received), classification (cataloguing), storage, retrieval,
 * revision, sharing, reuse and disposition of documents.
 *
 * Copyright (C) 2008 Regione Piemonte
 * Copyright (C) 2008 Provincia di Torino
 * Copyright (C) 2008 Comune di Torino
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2,
 * or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */

package it.doqui.index.ecmengine.business.personalization.security.acl;

import it.doqui.index.ecmengine.business.personalization.security.ReadersService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import net.sf.acegisecurity.AccessDeniedException;
import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.ConfigAttribute;
import net.sf.acegisecurity.ConfigAttributeDefinition;

import org.alfresco.repo.search.SimpleResultSetMetaData;
import org.alfresco.repo.search.impl.lucene.LuceneResultSet;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.ModelDAO;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterException;
import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.PermissionEvaluationMode;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetMetaData;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ACLEntryAfterInvocationProvider
        extends org.alfresco.repo.security.permissions.impl.acegi.ACLEntryAfterInvocationProvider {
    private static Log log = LogFactory.getLog(AclCheckDao.ECMENGINE_PERSONALIZATION_ACL_CHECK);

    private static final String AFTER_ACL_NODE = "AFTER_ACL_NODE";

    private ReadersService readersService;
    private AclCheckDao aclCheckDao;
    private ModelDAO modelDao;

    public ResultSet decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
            ResultSet returnedObject) throws AccessDeniedException {
        if (returnedObject == null) {
            return null;
        }

        boolean isCheckResultSetACL = false;

        Iterator<?> iter = config.getConfigAttributes();

        while (iter.hasNext()) {
            ConfigAttribute attr = (ConfigAttribute) iter.next();

            if (attr.getAttribute().startsWith(AFTER_ACL_NODE)) {
                isCheckResultSetACL = true;
            }
        }

        if (returnedObject instanceof LuceneResultSet && isCheckResultSetACL) {
            if (log.isDebugEnabled()) {
                log.debug("[ACLEntryAfterInvocationProvider::decide] Delegating...");
            }
            return decideLucene(authentication, object, config, (LuceneResultSet) returnedObject);
        } else {
            return super.decide(authentication, object, config, returnedObject);
        }
    }

    public ResultSet decideLucene(Authentication authentication, Object object, ConfigAttributeDefinition config,
            LuceneResultSet resultSet) throws AccessDeniedException {

        if (log.isDebugEnabled()) {
            log.debug("[ACLEntryAfterInvocationProvider::decideLucene] BEGIN");
            log.debug("[ACLEntryAfterInvocationProvider::decideLucene] resultset.length: " + resultSet.length());
            for (int i = 0; i < resultSet.length(); i++) {
                log.debug("[ACLEntryAfterInvocationProvider::decideLucene] resultset[" + i + "]: "
                        + resultSet.getDocument(i));
            }
        }

        try {
            final long prepareStart = System.currentTimeMillis();
            HashMap<Long, Integer> toCheck = new HashMap<Long, Integer>();
            Set<String> authorities = readersService.getAuthoritiesForCurrentUser();

            if (log.isDebugEnabled()) {
                log.debug("[ACLEntryAfterInvocationProvider::decideLucene] Authorities: " + authorities);
            }

            FilteringResultSet filteringResultSet = new FilteringResultSet(resultSet);
            ResultSetMetaData rsInfo = resultSet.getResultSetMetaData();

            Integer maxSize = null;
            if (rsInfo.getSearchParameters().getLimitBy() == LimitBy.FINAL_SIZE) {
                maxSize = new Integer(rsInfo.getSearchParameters().getLimit());
            }

            if (authorities == null) {
                // L'utente ha privilegi amministrativi
                if (maxSize != null && maxSize.intValue() > 0 && resultSet.length() > maxSize.intValue()) {

                    // Filtriamo in base alla dimensione massima impostata
                    for (int i = 0; i < resultSet.length(); i++) {
                        filteringResultSet.setIncluded(i, (i < maxSize.intValue()));
                    }

                    filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(LimitBy.FINAL_SIZE,
                            PermissionEvaluationMode.EAGER, rsInfo.getSearchParameters()));

                    return filteringResultSet;
                } else {

                    for (int i = 0; i < resultSet.length(); i++) {
                        filteringResultSet.setIncluded(i, true);
                    }

                    // La lunghezza del RS originale non supera la dimensione massima impostata
                    filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(LimitBy.UNLIMITED,
                            PermissionEvaluationMode.EAGER, rsInfo.getSearchParameters()));

                    return filteringResultSet; // L'utente ha i privilegi amministrativi o di sistema.
                }
            }
            if (log.isDebugEnabled()) {
                log.debug(
                        "[ACLEntryAfterInvocationProvider::decideLucene] Esecuzione codice per utente non admin.");
            }

            PermissionReference required = null;
            boolean configContainsSupportedDefinitions = false;

            Iterator<?> iter = config.getConfigAttributes();

            while (iter.hasNext()) {
                ConfigAttribute attr = (ConfigAttribute) iter.next();

                if (supports(attr)) {
                    configContainsSupportedDefinitions = true;
                }

                if (attr.getAttribute().startsWith(AFTER_ACL_NODE)) {
                    StringTokenizer st = new StringTokenizer(attr.getAttribute(), ".", false);
                    if (st.countTokens() != 3) {
                        throw new ACLEntryVoterException(
                                "There must be three . separated tokens in each config attribute");
                    }
                    @SuppressWarnings("unused")
                    String typeString = st.nextToken();
                    String qNameString = st.nextToken();
                    String permissionString = st.nextToken();

                    required = new SimplePermissionReference(
                            QName.createQName(qNameString, getNamespacePrefixResolver()), permissionString);
                }
            }

            // Insieme dei permission group che includono il permesso di Read
            if (log.isDebugEnabled()) {
                log.debug("[ACLEntryAfterInvocationProvider::decideLucene] required permission: " + required);
            }
            Set<PermissionReference> permissions = new HashSet<PermissionReference>(10);
            permissions.addAll(modelDao.getGrantingPermissions(required));

            permissions.add(modelDao.getPermissionReference(null, PermissionService.ALL_PERMISSIONS));

            for (int i = 0; i < resultSet.length(); i++) {
                if (log.isDebugEnabled()) {
                    log.debug("[ACLEntryAfterInvocationProvider::decideLucene] i: " + i);
                    log.debug("[ACLEntryAfterInvocationProvider::decideLucene] document[i]: "
                            + resultSet.getDocument(i));
                }

                String id = resultSet.getDocument(i).get("DBID");

                if (log.isDebugEnabled()) {
                    log.debug("[ACLEntryAfterInvocationProvider::decideLucene] id: " + id);
                }

                toCheck.put(new Long(id), new Integer(i));
            }

            final List<Long> toCheckList = new ArrayList<Long>(toCheck.keySet());

            if (log.isDebugEnabled()) {
                final long prepareStop = System.currentTimeMillis();
                log.debug("[ACLEntryAfterInvocationProvider::decideLucene] Prepare duration: "
                        + (prepareStop - prepareStart) + " ms [toCheck: " + toCheck.size() + "]");
            }

            final long start = System.currentTimeMillis();
            List<Long> readables = aclCheckDao.checkHasPermissionsOnNodes(toCheckList, authorities, permissions);

            if (log.isDebugEnabled()) {
                final long stop = System.currentTimeMillis();
                log.debug("[ACLEntryAfterInvocationProvider::decideLucene] Check duration: " + (stop - start)
                        + " ms [readables: " + readables.size() + "]");
            }

            final long filteringStart = System.currentTimeMillis();

            for (Long readable : readables) {
                filteringResultSet.setIncluded(toCheck.get(readable).intValue(), true);
            }

            if (!configContainsSupportedDefinitions) {
                if (maxSize == null) {
                    return resultSet;
                } else if (resultSet.length() > maxSize.intValue()) {
                    for (int i = 0; i < maxSize.intValue(); i++) {
                        filteringResultSet.setIncluded(i, true);
                    }
                    filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(LimitBy.FINAL_SIZE,
                            PermissionEvaluationMode.EAGER, rsInfo.getSearchParameters()));
                } else {
                    for (int i = 0; i < resultSet.length(); i++) {
                        filteringResultSet.setIncluded(i, true);
                    }
                    filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(LimitBy.UNLIMITED,
                            PermissionEvaluationMode.EAGER, rsInfo.getSearchParameters()));
                }
            } else {
                if (maxSize != null) {
                    if (log.isDebugEnabled()) {
                        log.debug("[ACLEntryAfterInvocationProvider::decideLucene] Max RS size: "
                                + maxSize.toString());
                    }

                    int counter = 0;
                    int included = 0;

                    maxSize = (maxSize <= resultSet.length()) ? maxSize : resultSet.length();

                    while (counter < maxSize) {
                        if (filteringResultSet.getIncluded(counter)) {
                            included++;
                        }
                        counter++;
                    }
                    while (counter < resultSet.length()) {
                        filteringResultSet.setIncluded(counter, false);
                        counter++;
                    }
                    filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(LimitBy.FINAL_SIZE,
                            PermissionEvaluationMode.EAGER, rsInfo.getSearchParameters()));
                }
            }
            // set the default, unlimited result set type
            filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(LimitBy.UNLIMITED,
                    PermissionEvaluationMode.EAGER, rsInfo.getSearchParameters()));

            if (log.isDebugEnabled()) {
                final long filteringStop = System.currentTimeMillis();
                log.debug("[ACLEntryAfterInvocationProvider::decideLucene] Filtering duration: "
                        + (filteringStop - filteringStart) + " ms");
            }

            return filteringResultSet;
        } finally {
            log.debug("[ACLEntryAfterInvocationProvider::decideLucene] END");
        }
    }

    public void setReadersService(ReadersService readersService) {
        this.readersService = readersService;
    }

    public void setAclCheckDao(AclCheckDao aclCheckDao) {
        this.aclCheckDao = aclCheckDao;
    }

    public void setModelDao(ModelDAO modelDao) {
        this.modelDao = modelDao;
    }
}