001/*
002 * (C) Copyright 2006-2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Anahide Tchertchian
018 *     Florent Guillaume
019 */
020
021package org.nuxeo.ecm.core.security;
022
023import org.nuxeo.ecm.core.api.NuxeoPrincipal;
024import org.nuxeo.ecm.core.api.security.ACP;
025import org.nuxeo.ecm.core.api.security.Access;
026import org.nuxeo.ecm.core.model.Document;
027import org.nuxeo.ecm.core.query.sql.model.SQLQuery.Transformer;
028
029/**
030 * Interface for pluggable core security policy.
031 *
032 * @author Anahide Tchertchian
033 * @author Florent Guillaume
034 */
035public interface SecurityPolicy {
036
037    /**
038     * Checks given permission for doc and principal.
039     * <p>
040     * Note that for the {@code Browse} permission, which is also implemented in SQL using {@link #getQueryTransformer},
041     * a security policy must never bypass standard ACL access, it must only return DENY or UNKNOWN. Failing to do this
042     * would make direct access and queries behave differently.
043     *
044     * @param doc the document to check
045     * @param mergedAcp merged ACP resolved for this document
046     * @param principal principal to check
047     * @param permission permission to check
048     * @param resolvedPermissions permissions or groups of permissions containing permission
049     * @param additionalPrincipals
050     * @return access: GRANT, DENY, or UNKNOWN. When UNKNOWN is returned, following policies or default core security
051     *         are applied.
052     */
053    Access checkPermission(Document doc, ACP mergedAcp, NuxeoPrincipal principal, String permission,
054            String[] resolvedPermissions, String[] additionalPrincipals);
055
056    /**
057     * Checks if this policy is restricting the given permission.
058     * <p>
059     * Queries check the BROWSE permission.
060     *
061     * @param permission the permission to check for
062     * @return {@code true} if the policy restricts the permission
063     */
064    boolean isRestrictingPermission(String permission);
065
066    /**
067     * Checks if this policy can be expressed in a query for given repository.
068     * <p>
069     * If not, then any query made will have to be post-filtered.
070     *
071     * @param repositoryName the target repository name.
072     * @return {@code true} if the policy can be expressed in a query
073     */
074    boolean isExpressibleInQuery(String repositoryName);
075
076    /**
077     * Checks if this policy can be expressed in a string-based query for given repository.
078     * <p>
079     * If not, then any query made will have to be post-filtered, if possible, otherwise denied.
080     *
081     * @param repositoryName the target repository name.
082     * @return {@code true} if the policy can be expressed in a string-based query
083     * @since 5.7.2
084     */
085    boolean isExpressibleInQuery(String repositoryName, String queryLanguage);
086
087    /**
088     * Get the transformer to use to apply this policy to a query.
089     * <p>
090     * Called only when {@link #isExpressibleInQuery()} returned {@code true}
091     *
092     * @param repositoryName the target repository name.
093     * @return the transformer
094     */
095    Transformer getQueryTransformer(String repositoryName);
096
097    /**
098     * Get the string-based transformer to use to apply this policy to a query.
099     * <p>
100     * Called only when {@link #isExpressibleInQuery(String, String)} returned {@code true}
101     *
102     * @param repositoryName the target repository name.
103     * @return the transformer
104     * @since 5.7.2
105     */
106    QueryTransformer getQueryTransformer(String repositoryName, String queryLanguage);
107
108    /**
109     * Interface for a class that can transform a string-based query into another. Not used for NXQL.
110     *
111     * @since 5.7.2
112     */
113    interface QueryTransformer {
114
115        /**
116         * Query transformer that does nothing.
117         */
118        QueryTransformer IDENTITY = new IdentityQueryTransformer();
119
120        /**
121         * Transforms a query into another query that has the security policy applied.
122         *
123         * @param principal the principal making the query
124         * @param query the query
125         * @return the query with security policy applied
126         * @since 5.7.2
127         */
128        String transform(NuxeoPrincipal principal, String query);
129    }
130
131    /**
132     * Query transformer that does nothing. Use {@link QueryTransformer#IDENTITY} instead of instantiating this class.
133     *
134     * @since 5.7.2
135     */
136    class IdentityQueryTransformer implements QueryTransformer {
137        @Override
138        public String transform(NuxeoPrincipal principal, String query) {
139            return query;
140        }
141    }
142
143}