001/*
002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Thomas Roger
016 */
017
018package org.nuxeo.ecm.core.api.impl;
019
020import java.util.Collections;
021import java.util.HashSet;
022import java.util.List;
023import java.util.Set;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.nuxeo.ecm.core.api.CoreSession;
028import org.nuxeo.ecm.core.api.DocumentModel;
029import org.nuxeo.ecm.core.api.Filter;
030
031/**
032 * A filter based on permissions.
033 * <p>
034 * If one of the permission check throws an Exception, the {@link #accept} method returns false.
035 *
036 * @since 5.7.2
037 */
038public class PermissionFilter implements Filter {
039
040    private static final long serialVersionUID = 1L;
041
042    private static final Log log = LogFactory.getLog(PermissionFilter.class);
043
044    protected final Set<String> required;
045
046    protected final Set<String> excluded;
047
048    public PermissionFilter(List<String> required, List<String> excluded) {
049        if (required == null) {
050            this.required = Collections.emptySet();
051        } else {
052            this.required = new HashSet<>(required);
053        }
054        if (excluded == null) {
055            this.excluded = Collections.emptySet();
056        } else {
057            this.excluded = new HashSet<>(excluded);
058        }
059    }
060
061    public PermissionFilter(String permission, boolean isRequired) {
062        if (isRequired) {
063            required = Collections.singleton(permission);
064            excluded = Collections.emptySet();
065        } else {
066            required = Collections.emptySet();
067            excluded = Collections.singleton(permission);
068        }
069    }
070
071    @Override
072    public boolean accept(DocumentModel docModel) {
073        CoreSession session = docModel.getCoreSession();
074        return session != null && hasPermission(session, docModel, excluded, false)
075                && hasPermission(session, docModel, required, true);
076
077    }
078
079    protected boolean hasPermission(CoreSession session, DocumentModel doc, Set<String> permissions, boolean required) {
080        for (String permission : permissions) {
081            if ((required && !session.hasPermission(doc.getRef(), permission))
082                    || (!required && session.hasPermission(doc.getRef(), permission))) {
083                return false;
084            }
085        }
086        return true;
087    }
088
089}