001/* 002 * Copyright (c) 2006-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 Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Anahide Tchertchian 011 * Florent Guillaume 012 */ 013 014package org.nuxeo.ecm.core.security; 015 016import java.security.Principal; 017 018import org.nuxeo.ecm.core.api.security.ACP; 019import org.nuxeo.ecm.core.api.security.Access; 020import org.nuxeo.ecm.core.model.Document; 021import org.nuxeo.ecm.core.query.sql.model.SQLQuery.Transformer; 022 023/** 024 * Interface for pluggable core security policy. 025 * 026 * @author Anahide Tchertchian 027 * @author Florent Guillaume 028 */ 029public interface SecurityPolicy { 030 031 /** 032 * Checks given permission for doc and principal. 033 * <p> 034 * Note that for the {@code Browse} permission, which is also implemented in SQL using {@link #getQueryTransformer}, 035 * a security policy must never bypass standard ACL access, it must only return DENY or UNKNOWN. Failing to do this 036 * would make direct access and queries behave differently. 037 * 038 * @param doc the document to check 039 * @param mergedAcp merged ACP resolved for this document 040 * @param principal principal to check 041 * @param permission permission to check 042 * @param resolvedPermissions permissions or groups of permissions containing permission 043 * @param additionalPrincipals 044 * @return access: GRANT, DENY, or UNKNOWN. When UNKNOWN is returned, following policies or default core security 045 * are applied. 046 */ 047 Access checkPermission(Document doc, ACP mergedAcp, Principal principal, String permission, 048 String[] resolvedPermissions, String[] additionalPrincipals); 049 050 /** 051 * Checks if this policy is restricting the given permission. 052 * <p> 053 * Queries check the BROWSE permission. 054 * 055 * @param permission the permission to check for 056 * @return {@code true} if the policy restricts the permission 057 */ 058 boolean isRestrictingPermission(String permission); 059 060 /** 061 * Checks if this policy can be expressed in a query for given repository. 062 * <p> 063 * If not, then any query made will have to be post-filtered. 064 * 065 * @param repositoryName the target repository name. 066 * @return {@code true} if the policy can be expressed in a query 067 */ 068 boolean isExpressibleInQuery(String repositoryName); 069 070 /** 071 * Checks if this policy can be expressed in a string-based query for given repository. 072 * <p> 073 * If not, then any query made will have to be post-filtered, if possible, otherwise denied. 074 * 075 * @param repositoryName the target repository name. 076 * @return {@code true} if the policy can be expressed in a string-based query 077 * @since 5.7.2 078 */ 079 boolean isExpressibleInQuery(String repositoryName, String queryLanguage); 080 081 /** 082 * Get the transformer to use to apply this policy to a query. 083 * <p> 084 * Called only when {@link #isExpressibleInQuery()} returned {@code true} 085 * 086 * @param repositoryName the target repository name. 087 * @return the transformer 088 */ 089 Transformer getQueryTransformer(String repositoryName); 090 091 /** 092 * Get the string-based transformer to use to apply this policy to a query. 093 * <p> 094 * Called only when {@link #isExpressibleInQuery(String, String)} returned {@code true} 095 * 096 * @param repositoryName the target repository name. 097 * @return the transformer 098 * @since 5.7.2 099 */ 100 QueryTransformer getQueryTransformer(String repositoryName, String queryLanguage); 101 102 /** 103 * Interface for a class that can transform a string-based query into another. Not used for NXQL. 104 * 105 * @since 5.7.2 106 */ 107 interface QueryTransformer { 108 109 /** 110 * Query transformer that does nothing. 111 */ 112 QueryTransformer IDENTITY = new IdentityQueryTransformer(); 113 114 /** 115 * Transforms a query into another query that has the security policy applied. 116 * 117 * @param principal the principal making the query 118 * @param query the query 119 * @return the query with security policy applied 120 * @since 5.7.2 121 */ 122 String transform(Principal principal, String query); 123 } 124 125 /** 126 * Query transformer that does nothing. Use {@link QueryTransformer#IDENTITY} instead of instantiating this class. 127 * 128 * @since 5.7.2 129 */ 130 class IdentityQueryTransformer implements QueryTransformer { 131 @Override 132 public String transform(Principal principal, String query) { 133 return query; 134 } 135 } 136 137}