blob: dd7ce7ae5351805bfdd264c39cffca5cd484ebd2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.resourceaccesssecurity;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.security.AccessSecurityException;
import aQute.bnd.annotation.ConsumerType;
/**
* The <code>ResourceAccessGate</code> defines a service API which might be used
* to make some restrictions to accessing resources.
*
* Implementations of this service interface must be registered like
* ResourceProvider with a path (like provider.roots). If different
* ResourceAccessGateService services match a path, not only the
* ResourceAccessGateService with the longest path will be called, but all of
* them, that's in contrast to the ResourceProvider, but in this case more
* logical (and secure!). The gates will be called in the order of the
* service ranking.
* If one of the gates grants access for a given operation access will be granted.
*
* service properties:
* <ul>
* <li><b>path</b>: regexp to define on which paths the service should be called
* (default .*)</li>
* <li><b>operations</b>: set of operations on which the service should be
* called ("read,create,update,delete,execute", default all of them)</li>
* <li><b>finaloperations</b>: set of operations on which the service answer is
* final and no further service should be called (default none of them), except
* the GateResult is {@link GateResult.DONTCARE}</li>
* </ul>
*
* The resource access gate can either have the context {@link #PROVIDER_CONTEXT},
* in this case the gate is only applied to resource providers requesting the
* security checks. Or the context can be {@link #APPLICATION_CONTEXT}. In this
* case the access gate is invoked for the whole resource tree.
* This is indicated by the required service property {@link #CONTEXT}. If the
* property is missing or invalid, the service is ignored.
*/
@ConsumerType
public interface ResourceAccessGate {
/**
* The service name to use when registering implementations of this
* interface as services (value is
* "org.apache.sling.api.resource.ResourceAccessGate").
*/
String SERVICE_NAME = ResourceAccessGate.class.getName();
/**
* The name of the service registration property containing the context
* of this service. Allowed values are {@link #APPLICATION_CONTEXT} and
* {@link #PROVIDER_CONTEXT}.
* This property is required and has no default value.
* (value is "access.context")
*/
String CONTEXT = "access.context";
/**
* Allowed value for the {@link #CONTEXT} service registration property.
* Services marked with this context are applied to all resources.
*/
String APPLICATION_CONTEXT = "application";
/**
* Allowed value for the {@link #CONTEXT} service registration property.
* Services marked with this context are only applied to resource
* providers which indicate the additional checks with the
* {@link org.apache.sling.api.resource.ResourceProvider#USE_RESOURCE_ACCESS_SECURITY}
* property.
*/
String PROVIDER_CONTEXT = "provider";
/**
* The name of the service registration property containing the path as a
* regular expression for which the service should be called (value is
* "path").
*/
String PATH = "path";
/**
* The name of the service registration property containing the operations
* for which the service should be called, defaults to all the operations
* (value is "operations").
*/
String OPERATIONS = "operations";
/**
* The name of the service registration property containing the operations
* for which the service should be called and no further service should be
* called after this, except the services returns DONTCARE as result,
* default is empty (non of them are final) (value is "finaloperations").
*/
String FINALOPERATIONS = "finaloperations";
/**
* <code>GateResult</code> defines 3 possible states which can be returned
* by the different canXXX methods of this interface.
* <ul>
* <li>GRANTED: means no restrictions</li>
* <li>DENIED: means no permission for the requested action</li>
* <li>DONTCARE: means that the implementation of the service has no
* information or can't decide and therefore neither can't grant or deny
* access</li>
* </ul>
*/
public enum GateResult {
GRANTED, DENIED, CANT_DECIDE
};
public enum Operation {
READ("read"), CREATE("create"), UPDATE("update"), DELETE("delete"), EXECUTE(
"execute");
private String text;
Operation(String text) {
this.text = text;
}
public static Operation fromString(String opAsString) {
Operation returnValue = null;
for (Operation op : Operation.values()) {
if (opAsString.equals(op.getText())) {
returnValue = op;
break;
}
}
return returnValue;
}
public String getText() {
return this.text;
}
}
public GateResult canRead(Resource resource);
public GateResult canCreate(String absPathName,
ResourceResolver resourceResolver);
public GateResult canUpdate(Resource resource);
public GateResult canDelete(Resource resource);
public GateResult canExecute(Resource resource);
public GateResult canReadValue(Resource resource, String valueName);
public GateResult canCreateValue(Resource resource, String valueName);
public GateResult canUpdateValue(Resource resource, String valueName);
public GateResult canDeleteValue(Resource resource, String valueName);
/**
* Allows to transform the query based on the current user's credentials.
* Can be used to narrow down queries to omit results that the current user
* is not allowed to see anyway, speeding up downstream access control.
*
* Query transformations are not critical with respect to access control as
* results are checked using the canRead.. methods anyway.
*
* @param query
* the query
* @param language
* the language in which the query is expressed
* @param resourceResolver
* the resource resolver which resolves the query
* @return the transformed query or the original query if no tranformation
* took place. This method should never return <code>null</code>
* @throws AccessSecurityException
*/
public String transformQuery(String query, String language,
ResourceResolver resourceResolver) throws AccessSecurityException;
/* for convenience (and performance) */
public boolean hasReadRestrictions(ResourceResolver resourceResolver);
public boolean hasCreateRestrictions(ResourceResolver resourceResolver);
public boolean hasUpdateRestrictions(ResourceResolver resourceResolver);
public boolean hasDeleteRestrictions(ResourceResolver resourceResolver);
public boolean hasExecuteRestrictions(ResourceResolver resourceResolver);
public boolean canReadAllValues(Resource resource);
public boolean canCreateAllValues(Resource resource);
public boolean canUpdateAllValues(Resource resource);
public boolean canDeleteAllValues(Resource resource);
}