blob: bb8e605fc0be6d9575cd6023fad81dc23db3ced9 [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.directory.fortress.core.impl;
import org.apache.directory.fortress.core.SecurityException;
import org.apache.directory.fortress.core.ValidationException;
import org.apache.directory.fortress.core.model.FortEntity;
import org.apache.directory.fortress.core.model.Permission;
import org.apache.directory.fortress.core.model.Session;
import org.apache.directory.fortress.core.util.VUtil;
/**
* Abstract class allows outside clients to manage security and multi-tenant concerns within the Fortress runtime.
* The {@link #setAdmin(org.apache.directory.fortress.core.model.Session)} method allows A/RBAC sessions to be loaded and
* allows authorization
* to be performed on behalf of the user who is contained within the Session object itself.
* The ARBAC permissions will be checked each time outside client makes calls into Fortress API.
* This allows Fortress clients to operate in a multi-tenant context: {@link #setContextId(String)}.
* <p>
* Implementers of this abstract class will NOT be thread safe iff the instance variables are set.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public abstract class Manageable implements org.apache.directory.fortress.core.Manageable
{
// These instance variables are the reason why children of this abstract class will not be thread safe:
protected Session adminSess;
protected String contextId;
/**
* Use this method to load an administrative user's ARBAC Session object into Manager object will enable authorization to
* be performed on behalf of admin user. Setting Session into this object will enforce ARBAC controls and render this
* class's implementer thread unsafe.
*
* @param session contains a valid Fortress A/RBAC Session object.
*/
public final void setAdmin(Session session)
{
this.adminSess = session;
}
/**
* Use this method to set the tenant id onto function call into Fortress which allows segregation of data by customer.
* The contextId is used for multi-tenancy to isolate data sets within a particular sub-tree within DIT.
* Setting contextId into this object will render this class' implementer thread unsafe.
*
* @param contextId maps to sub-tree in DIT, e.g. ou=contextId, dc=example, dc=com.
*/
public final void setContextId(String contextId)
{
this.contextId = contextId;
}
/**
* Set A/RBAC session on entity and perform authorization on behalf of the caller if the {@link #adminSess} is set.
*
* @param className contains the class name.
* @param opName contains operation name.
* @param entity contains {@link org.apache.directory.fortress.core.model.FortEntity} instance.
* @throws org.apache.directory.fortress.core.SecurityException
* in the event of data validation or system error.
*/
protected final void setEntitySession(String className, String opName, FortEntity entity) throws SecurityException
{
entity.setContextId(this.contextId);
if (this.adminSess != null)
{
Permission perm = new Permission(className, opName);
perm.setContextId(this.contextId);
AdminUtil.setEntitySession( this.adminSess, perm, entity, this.contextId );
}
}
/**
* Every Fortress Manager API (e.g. addUser, updateUser, addRole, ...) will perform authorization on behalf of the
* caller IFF the {@link AuditMgrImpl#adminSess} has been set before invocation.
*
* @param className contains the class name.
* @param opName contains operation name.
* @throws org.apache.directory.fortress.core.SecurityException
* in the event of data validation or system error.
*/
protected final void checkAccess(String className, String opName) throws SecurityException
{
if (this.adminSess != null)
{
Permission perm = new Permission(className, opName);
perm.setContextId(this.contextId);
AdminUtil.checkAccess(this.adminSess, perm, this.contextId);
}
}
/**
* Method is called by Manager APIs to load contextual information on {@link FortEntity}.
* <p>
* The information is used to
* <ol>
* <li>
* Load the administrative User's {@link Session} object into entity. This is used for checking to ensure
* administrator has privilege to perform administrative operation.
* </li>
* <li>
* Load the target operation's permission into the audit context. This is used for Fortress audit log stored in
* OpenLDAP
* </li>
* </ol>
*
* @param className contains the class name.
* @param opName contains operation name.
* @param entity used to pass contextual information through Fortress layers for administrative security checks and
* audit.
*/
protected final void setAdminData(String className, String opName, FortEntity entity)
{
if (this.adminSess != null)
{
Permission perm = new Permission(className, opName);
entity.setAdminSession(this.adminSess);
entity.setModCode(AdminUtil.getObjName(perm.getObjName()) + "." + perm.getOpName());
}
entity.setContextId(this.contextId);
}
/**
* Method will throw exception if entity reference is null, otherwise will set the contextId of the tenant onto the
* supplied entity reference.
* @param className contains the class name of caller.
* @param opName contains operation name of caller.
* @param entity used here to pass the tenant id into the Fortress DAO layer..
* @param errorCode contains the error id to use if null.
* @throws ValidationException in the event object is null.
*/
protected final void assertContext( String className, String opName, FortEntity entity, int errorCode ) throws ValidationException
{
VUtil.assertNotNull( entity, errorCode, getFullMethodName( className, opName ) );
entity.setContextId( contextId );
}
/**
* Method will throw exception if entity reference is null, otherwise will set the contextId of the tenant onto the
* supplied entity reference.
*
* @param methodName contains the full method name of caller.
* @param entity used here to pass the tenant id into the Fortress DAO layer..
* @param errorCode contains the error id to use if null.
* @throws ValidationException in the event object is null.
*/
protected final void assertContext( String methodName, FortEntity entity, int errorCode ) throws ValidationException
{
VUtil.assertNotNull( entity, errorCode, methodName );
entity.setContextId( contextId );
}
/**
* This method is used to generate log statements and returns the concatenation of class name to the operation name.
* @param className of the caller
* @param opName of the caller
* @return className + '.' + opName
*/
protected final String getFullMethodName(String className, String opName)
{
return className + "." + opName;
}
}