com.pureinfo.ark.auth2.domain.impl.Auth2MgrImplBase.java Source code

Java tutorial

Introduction

Here is the source code for com.pureinfo.ark.auth2.domain.impl.Auth2MgrImplBase.java

Source

/**
 * PureInfo Ark
 * @(#)Auth2MgrImplBase.java   1.0 2006-9-29
 * 
 * Copyright(c) 2004-2005, PureInfo Information Technology Corp. Ltd. 
 * All rights reserved, see the license file.
 * 
 * www.pureinfo.com.cn
 */

package com.pureinfo.ark.auth2.domain.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;

import com.pureinfo.ark.ArkExceptionTypes;
import com.pureinfo.ark.auth.model.IUser;
import com.pureinfo.ark.auth2.domain.IAuth2Mgr;
import com.pureinfo.ark.auth2.model.ActionDef;
import com.pureinfo.ark.auth2.model.BaseDef;
import com.pureinfo.ark.auth2.model.IActionDictionary;
import com.pureinfo.ark.auth2.model.ResourceDef;
import com.pureinfo.ark.auth2.model.RightDef;
import com.pureinfo.ark.auth2.model.RightsConfig;
import com.pureinfo.ark.content.model.ArkContent;
import com.pureinfo.dolphin.query.logic.ISQLLogic;
import com.pureinfo.dolphin.query.logic.SQLCondition;
import com.pureinfo.dolphin.query.logic.SQLLogicBuilder;
import com.pureinfo.dolphin.query.logic.SQLLogicString;
import com.pureinfo.force.exception.PureException;
import com.pureinfo.force.io.ClassResourceUtil;
import com.pureinfo.force.xml.XMLUtil;

/**
 * <P>
 * Created on 2006-9-29 21:07:47 <BR>
 * Last modified on 2006-9-29
 * </P>
 * Auth2MgrImplBase: another implementation for authorization manager.
 * 
 * @author Why
 * @version 1.0, 2006-9-29
 * @since Ark 1.2
 */
public abstract class Auth2MgrImplBase implements IAuth2Mgr {
    //logger
    private final static Logger logger = Logger.getLogger(Auth2MgrImplBase.class.getName());

    //configuraiton files path
    private String m_sConfigFile = "auth-rights2.cfg.xml";

    //base definitions: <[type], BaseDef>
    private Map m_hBaseDefs = null;

    //right definitions: <[type.role],RightDef>
    private Map m_hRightDefs = null;

    //action dictionary
    private IActionDictionary m_actionDictionary;

    /**
     * Constructor: default
     */
    public Auth2MgrImplBase() {
        super();
    }

    /**
     * Returns the user roles (name array).
     * 
     * @param _user
     *            the specified user
     * @return the role name array
     * @throws PureException
     *             if failed.
     */
    abstract public String[] getRoles(IUser _user) throws PureException;

    /**
     * @see com.pureinfo.force.container.IClearable#clear()
     */
    public void clear() {
        if (m_hBaseDefs != null) {
            m_hBaseDefs.clear();
        }
        if (m_hRightDefs != null) {
            m_hRightDefs.clear();
        }
        if (m_actionDictionary != null) {
            m_actionDictionary.clear();
        }
    }

    /**
     * Returns the configuration file path name.
     * 
     * @return the configuration file path name.
     */
    public String getConfigFile() {
        return m_sConfigFile;
    }

    /**
     * @see com.pureinfo.ark.auth2.domain.IAuth2Mgr#setConfigPath(java.lang.String)
     */
    public void setConfigFile(String _sConfigFile) {
        logger.debug("set configuration file: " + _sConfigFile);
        m_sConfigFile = _sConfigFile;
    }

    /**
     * @see com.pureinfo.ark.auth2.domain.IAuth2Mgr#getActionDictionary()
     */
    public IActionDictionary getActionDictionary() {
        return m_actionDictionary;
    }

    /**
     * Makes a key for the cached right definition.
     * 
     * @param _nResourceType
     *            the specified resource type
     * @param _sRole
     *            the role
     * @return the key for cache.
     */
    private Object makeKey(int _nResourceType, String _sRole) {
        return (char) _nResourceType + "." + _sRole;
    }

    /**
     * Returns the base definition of the specified resource type.
     * 
     * @param _nResourceType
     *            the resource type
     * @return the base definition
     * @throws PureException
     *             if failed.
     */
    public BaseDef lookupBaseDef(int _nResourceType) throws PureException {
        this.insureReady();
        Object oKey = new Integer(_nResourceType);
        return (BaseDef) m_hBaseDefs.get(oKey);
    }

    /**
     * Lookups the right definition on the specified resource type and role.
     * 
     * @param _nResourceType
     *            the resource type
     * @param _sRole
     *            the role
     * @return the right definition
     * @throws PureException
     *             if failed.
     */
    public RightDef lookupRightDef(int _nResourceType, String _sRole) throws PureException {
        this.insureReady();
        Object oKey = makeKey(_nResourceType, _sRole);
        return (RightDef) m_hRightDefs.get(oKey);
    }

    /**
     * Insures this manager is ready.
     * 
     * @throws PureException
     *             if failed to load configuration.
     */
    protected void insureReady() throws PureException {
        if (m_hRightDefs == null) {
            synchronized (this) {
                if (m_hRightDefs == null) {
                    this.reloadConfig();
                }
            }
        }
    }

    /**
     * Reloads the configuration.
     * 
     * @throws PureException
     *             if failed.
     */
    public synchronized void reloadConfig() throws PureException {
        // 1. init or clear
        if (m_hRightDefs == null) {
            m_hBaseDefs = new HashMap();
            m_hRightDefs = new HashMap();
            m_actionDictionary = new ActionDictionary();
        } else if (m_hRightDefs.size() > 0) {
            m_hBaseDefs.clear();
            m_hRightDefs.clear();
            m_actionDictionary.clear();
        }

        //2. to load configuration from file
        String sPath = ClassResourceUtil.mapFullPath(m_sConfigFile, true);
        logger.debug("to load rights config from " + sPath);

        RightsConfig config = new RightsConfig();
        config.fromXML(XMLUtil.fileToElement(sPath));

        //3. to cache base actions
        ActionDef[] actions = config.getActions();
        if (actions != null) {
            for (int i = 0; i < actions.length; i++) {
                m_actionDictionary.put(actions[i]);
            }
        }

        //4. to cache right definitions
        ResourceDef[] resources = config.getResources();
        ResourceDef resource;
        RightDef[] rights;
        BaseDef base;
        RightDef right;
        StringTokenizer stRoles;
        Object oKey;
        for (int i = 0; i < resources.length; i++) {
            resource = resources[i];
            // to cache base def
            base = resource.getBase();
            if (base != null) {
                // to parse right value
                base.parseRight(m_actionDictionary);
                // to cache base
                oKey = new Integer(resource.getTypeId());
                m_hBaseDefs.put(oKey, base);
            }

            //to cache right def
            rights = resource.getRights();
            if (rights == null || rights.length == 0)
                continue; //skip
            for (int j = 0; j < rights.length; j++) {
                right = rights[j];
                right.parseRight(m_actionDictionary);
                stRoles = new StringTokenizer(right.getRoles(), ",");
                while (stRoles.hasMoreElements()) {
                    oKey = makeKey(resource.getTypeId(), (String) stRoles.nextElement());
                    //logger.debug("RightDef cached: "+oKey);
                    m_hRightDefs.put(oKey, right);
                } //endwhile
            }
        } //endfor
    }

    //=========================================================================
    //implements of IAuth2Mgr

    /**
     * @see com.pureinfo.ark.auth2.domain.IAuth2Mgr#hasRole(com.pureinfo.ark.auth.model.IUser,
     *      java.lang.String)
     */
    public boolean hasRole(IUser _user, String _sRole) throws PureException {
        String[] roles = getRoles(_user);
        return roles != null && ArrayUtils.indexOf(roles, _sRole, 0) >= 0;
    }

    /**
     * @see com.pureinfo.ark.auth2.domain.IAuth2Mgr#indexOfAction(java.lang.String,
     *      boolean)
     */
    public int indexOfAction(String _sActionName, boolean _bRequired) throws PureException {
        insureReady();
        return m_actionDictionary.indexOfAction(_sActionName, _bRequired);
    }

    /**
     * @see com.pureinfo.ark.auth2.domain.IAuth2Mgr#hasRight(com.pureinfo.ark.auth.model.IUser,
     *      com.pureinfo.ark.content.model.ArkContent, int, boolean)
     */
    public boolean hasRight(IUser _loginUser, ArkContent _resource, int _nActionIndex, boolean _bRequired)
            throws PureException {
        //to check the base
        BaseDef base = this.lookupBaseDef(_resource.getArkType());
        if (base != null && base.hasRight(_loginUser, _resource, _nActionIndex) == Boolean.FALSE)
            return false;

        //to check super-admin
        if (isSuperAdmin(_loginUser))
            return true;

        //else
        String[] roles = getRoles(_loginUser);
        for (int i = 0; i < roles.length; i++) {
            RightDef def = this.lookupRightDef(_resource.getArkType(), roles[i]);
            if (def != null && def.hasRight(_loginUser, _resource, _nActionIndex) == Boolean.TRUE) {
                return true;
            }
        }

        //else, no right
        if (_bRequired) {
            throw new PureException(ArkExceptionTypes.AUTH_NO_RIGHT, "current user [" + _loginUser.getName()
                    + "] has no right to do action-" + _nActionIndex + " on " + _resource.display());
        }

        //else
        return false;
    }

    /**
     * @see com.pureinfo.ark.auth2.domain.IAuth2Mgr#hasPath(IUser, ArkContent,
     *      int)
     */
    public boolean hasPath(IUser _loginUser, ArkContent _resource, int _nActionIndex) throws PureException {
        // to check the base
        BaseDef base = this.lookupBaseDef(_resource.getArkType());
        if (base != null && base.hasPath(_loginUser, _resource, _nActionIndex) == Boolean.FALSE)
            return false;

        // to check super-admin
        if (isSuperAdmin(_loginUser))
            return true;

        // else
        String[] roles = getRoles(_loginUser);
        for (int i = 0; i < roles.length; i++) {
            RightDef def = this.lookupRightDef(_resource.getArkType(), roles[i]);
            if (def != null && def.hasPath(_loginUser, _resource, _nActionIndex) == Boolean.TRUE) {
                return true;
            }
        }

        // else
        return false;
    }

    /**
     * @see com.pureinfo.ark.auth2.domain.IAuth2Mgr#hasEntry(com.pureinfo.ark.auth.model.IUser,
     *      com.pureinfo.ark.content.model.ArkContent, java.lang.String,
     *      boolean)
     */
    public boolean hasEntry(IUser _loginUser, ArkContent _resource, int _nActionIndex, boolean _bRequired)
            throws PureException {
        //to check the base
        BaseDef base = this.lookupBaseDef(_resource.getArkType());
        if (base != null && base.hasEntry(_resource, _nActionIndex) == Boolean.FALSE)
            return false;

        //to check super-admin
        if (isSuperAdmin(_loginUser))
            return true;

        //else
        String[] roles = getRoles(_loginUser);
        for (int i = 0; i < roles.length; i++) {
            RightDef def = this.lookupRightDef(_resource.getArkType(), roles[i]);
            if (def != null && def.hasEntry(_resource, _nActionIndex) == Boolean.TRUE) {
                return true;
            }
        }

        //else, no right
        if (_bRequired) {
            throw new PureException(ArkExceptionTypes.AUTH_NO_RIGHT, "current user [" + _loginUser.getName()
                    + "] has no right to do action-" + _nActionIndex + " on " + _resource.display());
        }

        //else
        return false;
    }

    /**
     * @see com.pureinfo.ark.auth2.domain.IAuth2Mgr#getSQLLogicRule(com.pureinfo.ark.auth.model.IUser,
     *      int, int)
     */
    public ISQLLogic getSQLLogicRule(IUser _loginUser, ArkContent _resource, int _nActionIndex)
            throws PureException {
        // to check the base rule
        BaseDef base = this.lookupBaseDef(_resource.getArkType());
        ISQLLogic baseLogic;
        if (base == null) {
            baseLogic = SQLLogicString.TRUE;
        } else {
            baseLogic = base.getSQLLogicRule(_loginUser, _resource, _nActionIndex);
            if (baseLogic == SQLLogicString.FALSE) {
                return SQLLogicString.FALSE;
            }
        }

        // to check the role rule
        ISQLLogic roleLogic = getSQLLogicRule0(_loginUser, _resource, _nActionIndex);

        // to merge the base rule and role rule
        return baseLogic == null ? roleLogic : SQLLogicBuilder.and(baseLogic, roleLogic);
    }

    private ISQLLogic getSQLLogicRule0(IUser _loginUser, ArkContent _resource, int _nActionIndex)
            throws PureException {
        // to check super-admin
        if (isSuperAdmin(_loginUser))
            return SQLLogicString.TRUE;

        //else
        insureReady();
        String[] roles = getRoles(_loginUser);
        SQLCondition condition = new SQLCondition(false, roles.length);
        for (int i = 0; i < roles.length; i++) {
            RightDef def = this.lookupRightDef(_resource.getArkType(), roles[i]);
            if (def == null)
                continue;

            //else
            ISQLLogic logic = def.getSQLLogicRule(_loginUser, _resource, _nActionIndex);
            if (logic == SQLLogicString.TRUE) {
                return SQLLogicString.TRUE;
            }
            //else
            if (logic != null && logic != SQLLogicString.FALSE) {
                condition.append(logic);
            }
        }

        //else
        switch (condition.size()) {
        case 0:
            return SQLLogicString.FALSE;
        case 1: {
            ISQLLogic logic = (ISQLLogic) condition.getConditions().get(0);
            condition.clear();
            return logic;
        }
        default:
            return condition;
        }
    }

}