Package org.cesecore.core.ejb.authorization

Source Code of org.cesecore.core.ejb.authorization.AdminGroupSessionBean

/*************************************************************************
*                                                                       *
*  EJBCA: The OpenSource Certificate Authority                          *
*                                                                       *
*  This software is free software; you can redistribute it and/or       *
*  modify it under the terms of the GNU Lesser General Public           *
*  License as published by the Free Software Foundation; either         *
*  version 2.1 of the License, or any later version.                    *
*                                                                       *
*  See terms of license at gnu.org.                                     *
*                                                                       *
*************************************************************************/
package org.cesecore.core.ejb.authorization;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import javax.ejb.EJB;
import javax.ejb.FinderException;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.log4j.Logger;
import org.cesecore.core.ejb.log.LogSessionLocal;
import org.ejbca.core.ejb.JndiHelper;
import org.ejbca.core.ejb.authorization.AdminGroupData;
import org.ejbca.core.ejb.authorization.AuthorizationSessionLocal;
import org.ejbca.core.model.InternalResources;
import org.ejbca.core.model.authorization.AccessRule;
import org.ejbca.core.model.authorization.AccessRulesConstants;
import org.ejbca.core.model.authorization.AdminEntity;
import org.ejbca.core.model.authorization.AdminGroup;
import org.ejbca.core.model.authorization.AdminGroupExistsException;
import org.ejbca.core.model.log.Admin;
import org.ejbca.core.model.log.LogConstants;

/**
* Handles AdminGroup entities.
*
* @version $Id: AdminGroupSessionBean.java 11337 2011-02-10 22:37:15Z jeklund $
*/
@Stateless(mappedName = JndiHelper.APP_JNDI_PREFIX + "AdminGroupSessionRemote")
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class AdminGroupSessionBean implements AdminGroupSessionLocal, AdminGroupSessionRemote{

    private final static Logger LOG = Logger.getLogger(AdminGroupSessionBean.class);
   
    /** Internal localization of logs and errors */
    private static final InternalResources INTRES = InternalResources.getInstance();

    @PersistenceContext(unitName = "ejbca")
    private EntityManager entityManager;
   
    @EJB
    private LogSessionLocal logSession;
    @EJB
    private AuthorizationSessionLocal authSession;
    @EJB
    private AdminEntitySessionLocal admEntitySession;
    @EJB
    private AuthorizationTreeUpdateDataSessionLocal authTreeSession;
   
    @Override
    public void init(final Admin admin, final int caid, final String superAdminCN) throws AdminGroupExistsException {
        // Check if admingroup table is empty, if so insert default superuser
        // and create "special edit accessrules count group"
        final Collection<AdminGroupData> result = AdminGroupData.findAll(entityManager);
        if (result.isEmpty()) {    
            // Authorization table is empty, fill with default and special
            // admingroups.
            addAdminGroup(admin, AdminGroup.TEMPSUPERADMINGROUP);
            final ArrayList<AdminEntity> adminentities = new ArrayList<AdminEntity>();
            adminentities.add(new AdminEntity(AdminEntity.WITH_COMMONNAME, AdminEntity.TYPE_EQUALCASEINS, superAdminCN, caid));
            admEntitySession.addAdminEntities(admin, AdminGroup.TEMPSUPERADMINGROUP, adminentities);
            final ArrayList<AccessRule> accessrules = new ArrayList<AccessRule>();
            accessrules.add(new AccessRule(AccessRulesConstants.ROLE_SUPERADMINISTRATOR, AccessRule.RULE_ACCEPT, false));
            addAccessRules(admin, AdminGroup.TEMPSUPERADMINGROUP, accessrules);
    
        }
        // Add Special Admin Group
        // Special admin group is a group that is not authenticated with client
        // certificate, such as batch tool etc
        if (AdminGroupData.findByGroupName(entityManager, AdminGroup.DEFAULTGROUPNAME) == null) {
            LOG.debug("initialize: FinderEx, add default group.");
            // Add Default Special Admin Group
            try {
                final AdminGroupData agdl = new AdminGroupData(Integer.valueOf(findFreeAdminGroupId()), AdminGroup.DEFAULTGROUPNAME);
                entityManager.persist(agdl);

                final ArrayList<AdminEntity> adminentities = new ArrayList<AdminEntity>();
                adminentities.add(new AdminEntity(AdminEntity.SPECIALADMIN_BATCHCOMMANDLINEADMIN));
                adminentities.add(new AdminEntity(AdminEntity.SPECIALADMIN_CACOMMANDLINEADMIN));
                adminentities.add(new AdminEntity(AdminEntity.SPECIALADMIN_RAADMIN));
                adminentities.add(new AdminEntity(AdminEntity.SPECIALADMIN_INTERNALUSER));
                agdl.addAdminEntities(entityManager, adminentities);

                final ArrayList<AccessRule> accessrules = new ArrayList<AccessRule>();
                accessrules.add(new AccessRule(AccessRulesConstants.ROLE_ADMINISTRATOR, AccessRule.RULE_ACCEPT, true));
                accessrules.add(new AccessRule(AccessRulesConstants.ROLE_SUPERADMINISTRATOR, AccessRule.RULE_ACCEPT, false));

                accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_CAFUNCTIONALTY, AccessRule.RULE_ACCEPT, true));
                accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_RAFUNCTIONALITY, AccessRule.RULE_ACCEPT, true));
                accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_LOGFUNCTIONALITY, AccessRule.RULE_ACCEPT, true));
                accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_SYSTEMFUNCTIONALITY, AccessRule.RULE_ACCEPT, true));
                accessrules.add(new AccessRule(AccessRulesConstants.HARDTOKEN_HARDTOKENFUNCTIONALITY, AccessRule.RULE_ACCEPT, true));
                accessrules.add(new AccessRule(AccessRulesConstants.CABASE, AccessRule.RULE_ACCEPT, true));
                accessrules.add(new AccessRule(AccessRulesConstants.ENDENTITYPROFILEBASE, AccessRule.RULE_ACCEPT, true));

                agdl.addAccessRules(entityManager, accessrules);

                authTreeSession.signalForAuthorizationTreeUpdate();
            } catch (Exception ce) {
                LOG.error("initialize continues after Exception: ", ce);
            }
        }
        // Add Public Web Group
        final AdminGroupData agl = AdminGroupData.findByGroupName(entityManager, AdminGroup.PUBLICWEBGROUPNAME);
        if (agl == null) {
            LOG.debug("initialize: Can't find public web group");
            try {
                final AdminGroupData agdl = new AdminGroupData(Integer.valueOf(findFreeAdminGroupId()), AdminGroup.PUBLICWEBGROUPNAME);
                entityManager.persist(agdl);
                addDefaultPublicWebGroupRules(agdl);
                authTreeSession.signalForAuthorizationTreeUpdate();
            } catch (Exception ce) {
                LOG.error("initialize continues after Exception: ", ce);
            }
        } else {
            removeAndAddDefaultPublicWebGroupRules(agl);
        }
        if (LOG.isTraceEnabled()) {
            LOG.trace("<initialize, caid: " + caid);
        }
   
    }
  
    @Override
    public void addAccessRules(final Admin admin, final String admingroupname, final Collection<AccessRule> accessrules) {
        if (!admingroupname.equals(AdminGroup.DEFAULTGROUPNAME)) {
            try {
                final AdminGroupData agd = AdminGroupData.findByGroupName(entityManager, admingroupname);
                if (agd == null) {
                    throw new FinderException("Could not find admin group " + admingroupname);
                }
                agd.addAccessRules(entityManager, accessrules);
                authTreeSession.signalForAuthorizationTreeUpdate();
                final String msg = INTRES.getLocalizedMessage("authorization.accessrulesadded", admingroupname);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_INFO_EDITEDADMINISTRATORPRIVILEGES, msg);
            } catch (Exception e) {
                final String msg = INTRES.getLocalizedMessage("authorization.erroraddaccessrules", admingroupname);
                LOG.error(msg, e);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_ERROR_EDITEDADMINISTRATORPRIVILEGES, msg);
            }
        }
    }
  
    @Override
    public void addAdminGroup(final Admin admin, final String admingroupname) throws AdminGroupExistsException {
        if (!(admingroupname.equals(AdminGroup.DEFAULTGROUPNAME))) {
            boolean success = false;
            if (AdminGroupData.findByGroupName(entityManager, admingroupname) == null) {
                try {
                    entityManager.persist(new AdminGroupData(Integer.valueOf(findFreeAdminGroupId()), admingroupname));
                    success = true;
                } catch (Exception e) {
                    final String msg = INTRES.getLocalizedMessage("authorization.erroraddadmingroup", admingroupname);
                    LOG.error(msg, e);
                }
            }
            if (success) {
                final String msg = INTRES.getLocalizedMessage("authorization.admingroupadded", admingroupname);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_INFO_EDITEDADMINISTRATORPRIVILEGES, msg);
            } else {
                final String msg = INTRES.getLocalizedMessage("authorization.erroraddadmingroup", admingroupname);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_ERROR_EDITEDADMINISTRATORPRIVILEGES, msg);
                throw new AdminGroupExistsException();
            }
        }
    }
   
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    @Override
    public boolean existsAdministratorInGroup(final Admin admin, final int admingrouppk) {
        boolean returnval = false;
        final AdminGroupData agdl = AdminGroupData.findByPrimeKey(entityManager, Integer.valueOf(admingrouppk));
        if (agdl != null) {
            for(AdminEntity ae : agdl.getAdminGroup().getAdminEntities()) {    
                returnval = returnval || ae.match(admin.getAdminInformation());
            }
        }
        return returnval;
    }
   
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    @Override
    public AdminGroup getAdminGroup(final Admin admin, final String admingroupname) {
        AdminGroup returnval = null;
        final AdminGroupData agd = AdminGroupData.findByGroupName(entityManager, admingroupname);
        if (agd == null) {
            LOG.info("Can't get admingroup: " + admingroupname);
        } else {
            returnval = agd.getAdminGroup();
        }
        return returnval;
    }

    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    @Override
    public Collection<AdminGroup> getAuthorizedAdminGroupNames(final Admin admin, final Collection<Integer> availableCaIds) {
        final ArrayList<AdminGroup> returnval = new ArrayList<AdminGroup>();
        boolean issuperadmin = false;
   
        issuperadmin = authSession.isAuthorizedNoLog(admin, AccessRulesConstants.ROLE_SUPERADMINISTRATOR);
    
        final HashSet<Integer> authorizedcaids = new HashSet<Integer>();
        final HashSet<Integer> allcaids = new HashSet<Integer>();
        if (!issuperadmin) {
            authorizedcaids.addAll(authSession.getAuthorizedCAIds(admin, availableCaIds));
            allcaids.addAll(availableCaIds);
        }

        final ArrayList<Integer> groupcaids = new ArrayList<Integer>();
        for (AdminGroupData agdl : AdminGroupData.findAll(entityManager)) {

            boolean allauthorized = false;
            boolean carecursive = false;
            boolean superadmingroup = false;
            boolean authtogroup = false;
            groupcaids.clear();
            if (!issuperadmin) {
                // Is admin authorized to all group caid. This is true if admin
                // is authorized to all CAs used by the different admins.
                final Collection<AdminEntity> admins = agdl.getAdminEntityObjects();
                final Iterator<AdminEntity> adminsIterator = admins.iterator();
                boolean onlyAuthCAIds = true;
                while (adminsIterator.hasNext()) {
                    final AdminEntity adminEntity = adminsIterator.next();
                    if (!authorizedcaids.contains(adminEntity.getCaId())) {
                        onlyAuthCAIds = false;
                        break;
                    }
                }
                if (onlyAuthCAIds) {
                    authtogroup = true;
                    // check access rules
                    final Iterator<AccessRule> iter = agdl.getAccessRuleObjects().iterator();
                    while (iter.hasNext()) {
                        final AccessRule accessrule = iter.next();
                        final String rule = accessrule.getAccessRule();
                        if (rule.equals(AccessRulesConstants.ROLE_SUPERADMINISTRATOR) && accessrule.getRule() == AccessRule.RULE_ACCEPT) {
                            superadmingroup = true;
                            break;
                        }
                        if (rule.equals(AccessRulesConstants.CABASE)) {
                            if (accessrule.getRule() == AccessRule.RULE_ACCEPT && accessrule.isRecursive() && authorizedcaids.containsAll(allcaids)) {
                              carecursive = true;
                            }
                        } else {
                            if (rule.startsWith(AccessRulesConstants.CAPREFIX) && accessrule.getRule() == AccessRule.RULE_ACCEPT) {
                                groupcaids.add(Integer.valueOf(rule.substring(AccessRulesConstants.CAPREFIX.length())));
                            }
                        }
                    }
                }
            }
            allauthorized = authorizedcaids.containsAll(groupcaids);

            if (issuperadmin || ((allauthorized || carecursive) && authtogroup && !superadmingroup)) {
                if (!agdl.getAdminGroupName().equals(AdminGroup.PUBLICWEBGROUPNAME) && !(agdl.getAdminGroupName().equals(AdminGroup.DEFAULTGROUPNAME))) {
                    returnval.add(agdl.getAdminGroupNames());
                }
            }
        }
        return returnval;
    }

    @Override
    public void removeAdminGroup(final Admin admin, final String admingroupname) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Removing admin group " + admingroupname);
        }
        if (!(admingroupname.equals(AdminGroup.DEFAULTGROUPNAME))) {
            try {
                final AdminGroupData agl = AdminGroupData.findByGroupName(entityManager, admingroupname);
                if (agl == null) {
                    throw new FinderException("No Admin Group w name " + admingroupname);
                }
                removeEntitiesAndRulesFromGroup(agl);
                entityManager.remove(agl);
                authTreeSession.signalForAuthorizationTreeUpdate();

                final String msg = INTRES.getLocalizedMessage("authorization.admingroupremoved", admingroupname);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_INFO_EDITEDADMINISTRATORPRIVILEGES, msg);
            } catch (Exception e) {
                final String msg = INTRES.getLocalizedMessage("authorization.errorremoveadmingroup", admingroupname);
                LOG.error(msg, e);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_ERROR_EDITEDADMINISTRATORPRIVILEGES, msg);
            }
        }
    }

    @Override
    public void removeAccessRules(final Admin admin, final String admingroupname, final List<String> accessrules) {
        if (!admingroupname.equals(AdminGroup.DEFAULTGROUPNAME)) {
            try {
                final AdminGroupData agd = AdminGroupData.findByGroupName(entityManager, admingroupname);
                if (agd == null) {
                    throw new FinderException("Could not find admin group " + admingroupname);
                }
                agd.removeAccessRules(entityManager, accessrules);
                authTreeSession.signalForAuthorizationTreeUpdate();
                final String msg = INTRES.getLocalizedMessage("authorization.accessrulesremoved", admingroupname);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_INFO_EDITEDADMINISTRATORPRIVILEGES, msg);
            } catch (Exception e) {
                final String msg = INTRES.getLocalizedMessage("authorization.errorremoveaccessrules", admingroupname);
                LOG.error(msg, e);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_INFO_EDITEDADMINISTRATORPRIVILEGES, msg);
            }
        }
    }

    @Override
    public void replaceAccessRules(final Admin admin, final String admingroupname, final Collection<AccessRule> accessrules) {
        if (!admingroupname.equals(AdminGroup.DEFAULTGROUPNAME)) {
            try {
                final AdminGroupData agdl = AdminGroupData.findByGroupName(entityManager, admingroupname);
                if (agdl == null) {
                    throw new FinderException("Could not find admin group " + admingroupname);
                }
                final Collection<AccessRule> currentrules = agdl.getAdminGroup().getAccessRules();
                final ArrayList<String> removerules = new ArrayList<String>();
                final Iterator<AccessRule> iter = currentrules.iterator();
                while (iter.hasNext()) {
                    removerules.add(iter.next().getAccessRule());
                }
                agdl.removeAccessRules(entityManager, removerules);
                agdl.addAccessRules(entityManager, accessrules);
                authTreeSession.signalForAuthorizationTreeUpdate();
                final String msg = INTRES.getLocalizedMessage("authorization.accessrulesreplaced", admingroupname);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_INFO_EDITEDADMINISTRATORPRIVILEGES, msg);
            } catch (Exception e) {
                final String msg = INTRES.getLocalizedMessage("authorization.errorreplaceaccessrules", admingroupname);
                LOG.error(msg, e);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_INFO_EDITEDADMINISTRATORPRIVILEGES, msg);
            }
        }
    }
 
    @Override
    public void renameAdminGroup(final Admin admin, final String oldname, final String newname) throws AdminGroupExistsException {
        if (!(oldname.equals(AdminGroup.DEFAULTGROUPNAME))) {
            boolean success = false;
            AdminGroupData agl = AdminGroupData.findByGroupName(entityManager, newname);
            if (agl == null) {
                try {
                    agl = AdminGroupData.findByGroupName(entityManager, oldname);
                    if (agl == null) {
                        throw new FinderException("Cant find admin group w name " + oldname);
                    }
                    agl.setAdminGroupName(newname);
                    authTreeSession.signalForAuthorizationTreeUpdate();
                    success = true;
                } catch (Exception e) {
                    LOG.error("Can't rename admingroup: ", e);
                }
            } else {
                throw new AdminGroupExistsException();
            }
            if (success) {
              final String msg = INTRES.getLocalizedMessage("authorization.admingrouprenamed", oldname, newname);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_INFO_EDITEDADMINISTRATORPRIVILEGES, msg);
            } else {
              final String msg = INTRES.getLocalizedMessage("authorization.errorrenameadmingroup", oldname, newname);
                logSession.log(admin, LogConstants.INTERNALCAID, LogConstants.MODULE_RA, new java.util.Date(), null, null,
                        LogConstants.EVENT_ERROR_EDITEDADMINISTRATORPRIVILEGES, msg);
            }
        }
    }
   
    private void addDefaultPublicWebGroupRules(final AdminGroupData agdl) {
        LOG.debug("create public web group");
        final ArrayList<AdminEntity> adminentities = new ArrayList<AdminEntity>();
        adminentities.add(new AdminEntity(AdminEntity.SPECIALADMIN_PUBLICWEBUSER));
        agdl.addAdminEntities(entityManager, adminentities);

        final ArrayList<AccessRule> accessrules = new ArrayList<AccessRule>();
        accessrules.add(new AccessRule(AccessRulesConstants.ROLE_PUBLICWEBUSER, AccessRule.RULE_ACCEPT, false));

        accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_CABASICFUNCTIONS, AccessRule.RULE_ACCEPT, false));
        accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_VIEWCERTIFICATE, AccessRule.RULE_ACCEPT, false));
        accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_CREATECERTIFICATE, AccessRule.RULE_ACCEPT, false));
        accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_STORECERTIFICATE, AccessRule.RULE_ACCEPT, false));
        accessrules.add(new AccessRule(AccessRulesConstants.REGULAR_VIEWENDENTITY, AccessRule.RULE_ACCEPT, false));
        accessrules.add(new AccessRule(AccessRulesConstants.CABASE, AccessRule.RULE_ACCEPT, true));
        accessrules.add(new AccessRule(AccessRulesConstants.ENDENTITYPROFILEBASE, AccessRule.RULE_ACCEPT, true));

        agdl.addAccessRules(entityManager, accessrules);
    }
   
    private int findFreeAdminGroupId() {
      final Random random = new Random();
        int id = random.nextInt();
        boolean foundfree = false;
        while (!foundfree) {
            if (AdminGroupData.findByPrimeKey(entityManager, Integer.valueOf(id)) == null) {
                foundfree = true;
            }
            id = random.nextInt();
        }
        return id;
    }
   
    private void removeEntitiesAndRulesFromGroup(final AdminGroupData agl) {
        LOG.debug("removing entities and rules for " + agl.getAdminGroupName());
        // Remove groups user entities.
        agl.removeAdminEntities(entityManager, agl.getAdminEntityObjects());

        // Remove groups accessrules.
        final Iterator<AccessRule> iter = agl.getAccessRuleObjects().iterator();
        final ArrayList<String> remove = new ArrayList<String>();
        while (iter.hasNext()) {
            remove.add(iter.next().getAccessRule());
        }
        agl.removeAccessRules(entityManager, remove);
    }

    private void removeAndAddDefaultPublicWebGroupRules(final AdminGroupData agl) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Removing old and adding new accessrules and admin entitites to admin group " + agl.getAdminGroupName());
        }
        removeEntitiesAndRulesFromGroup(agl);
        addDefaultPublicWebGroupRules(agl);
        authTreeSession.signalForAuthorizationTreeUpdate();
    }
}
TOP

Related Classes of org.cesecore.core.ejb.authorization.AdminGroupSessionBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.