Package org.ejbca.core.ejb.approval

Source Code of org.ejbca.core.ejb.approval.ApprovalSessionBean

/*************************************************************************
*                                                                       *
*  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.ejbca.core.ejb.approval;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

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

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.cesecore.core.ejb.log.LogSessionLocal;
import org.ejbca.config.GlobalConfiguration;
import org.ejbca.core.ErrorCode;
import org.ejbca.core.ejb.JndiHelper;
import org.ejbca.core.ejb.authorization.AuthorizationSessionLocal;
import org.ejbca.core.model.InternalResources;
import org.ejbca.core.model.approval.AdminAlreadyApprovedRequestException;
import org.ejbca.core.model.approval.Approval;
import org.ejbca.core.model.approval.ApprovalDataUtil;
import org.ejbca.core.model.approval.ApprovalDataVO;
import org.ejbca.core.model.approval.ApprovalException;
import org.ejbca.core.model.approval.ApprovalNotificationParamGen;
import org.ejbca.core.model.approval.ApprovalRequest;
import org.ejbca.core.model.approval.ApprovalRequestExpiredException;
import org.ejbca.core.model.approval.ApprovedActionAdmin;
import org.ejbca.core.model.authorization.AccessRulesConstants;
import org.ejbca.core.model.authorization.AuthorizationDeniedException;
import org.ejbca.core.model.authorization.Authorizer;
import org.ejbca.core.model.log.Admin;
import org.ejbca.core.model.log.LogConstants;
import org.ejbca.util.Base64;
import org.ejbca.util.CertTools;
import org.ejbca.util.mail.MailSender;
import org.ejbca.util.query.IllegalQueryException;
import org.ejbca.util.query.Query;

/**
* Keeps track of approval requests and their approval or rejects.
*
* @version $Id: ApprovalSessionBean.java 11526 2011-03-16 12:03:24Z netmackan $
*/
@Stateless(mappedName = JndiHelper.APP_JNDI_PREFIX + "ApprovalSessionRemote")
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ApprovalSessionBean implements ApprovalSessionLocal, ApprovalSessionRemote {

    private static final long serialVersionUID = 1L;

    private static final Logger log = Logger.getLogger(ApprovalSessionBean.class);

    /** Internal localization of logs and errors */
    private static final InternalResources intres = InternalResources.getInstance();

    @PersistenceContext(unitName="ejbca")
    private EntityManager entityManager;

    @EJB
    private AuthorizationSessionLocal authorizationSession;
    @EJB
    private LogSessionLocal logSession;

    @Override
    public void addApprovalRequest(Admin admin, ApprovalRequest approvalRequest, GlobalConfiguration gc) throws ApprovalException {
        log.trace(">addApprovalRequest");
        int approvalId = approvalRequest.generateApprovalId();

        ApprovalDataVO data = findNonExpiredApprovalRequest(admin, approvalId);
        if (data != null) {
            logSession.log(admin, approvalRequest.getCAId(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_ERROR_APPROVALREQUESTED,
                    "Approval with id : " + approvalId + " already exists");
            throw new ApprovalException(ErrorCode.APPROVAL_ALREADY_EXISTS, "Approval Request " + approvalId + " already exists in database");
        } else {
            // There exists no approval request with status waiting. Add a new one
            try {
                final Integer freeId = findFreeApprovalId();
                final ApprovalData approvalData = new ApprovalData(freeId);
                approvalData.setApprovalid(approvalRequest.generateApprovalId());
                approvalData.setApprovaltype(approvalRequest.getApprovalType());
                approvalData.setEndentityprofileid(approvalRequest.getEndEntityProfileId());       
                approvalData.setCaid(approvalRequest.getCAId());
            if(approvalRequest.getRequestAdminCert() != null){
              approvalData.setReqadmincertissuerdn(CertTools.getIssuerDN(approvalRequest.getRequestAdminCert()));
              approvalData.setReqadmincertsn(CertTools.getSerialNumberAsString(approvalRequest.getRequestAdminCert()));
            }
            setApprovalRequest(approvalData, approvalRequest);
            setApprovals(approvalData, new ArrayList<Approval>());
            approvalData.setExpiredate((new Date()).getTime() + approvalRequest.getRequestValidity());
            approvalData.setRemainingapprovals(approvalRequest.getNumOfRequiredApprovals());
                entityManager.persist(approvalData);
                if (gc.getUseApprovalNotifications()) {
                    sendApprovalNotification(admin, gc.getApprovalAdminEmailAddress(), gc.getApprovalNotificationFromAddress(), gc.getBaseUrl()
                            + "adminweb/approval/approveaction.jsf?uniqueId=" + freeId, intres.getLocalizedMessage("notification.newrequest.subject"), intres
                            .getLocalizedMessage("notification.newrequest.msg"), freeId, approvalRequest.getNumOfRequiredApprovals(), new Date(),
                            approvalRequest, null);
                }
                logSession.log(admin, approvalRequest.getCAId(), LogConstants.MODULE_APPROVAL, new Date(), null, null,
                        LogConstants.EVENT_INFO_APPROVALREQUESTED, "Approval with id : " + approvalId + " added with status waiting.");
            } catch (Exception e1) {
                logSession.log(admin, approvalRequest.getCAId(), LogConstants.MODULE_APPROVAL, new Date(), null, null,
                        LogConstants.EVENT_ERROR_APPROVALREQUESTED, "Approval with id : " + approvalId + " couldn't be created");
                log.error("Error creating approval request", e1);
            }
        }
        log.trace("<addApprovalRequest");
    }

    @Override
    public void removeApprovalRequest(Admin admin, int id) throws ApprovalException {
        log.trace(">removeApprovalRequest");
        try {
          ApprovalData ad = ApprovalData.findById(entityManager, Integer.valueOf(id));
          if (ad != null) {
            entityManager.remove(ad);
                logSession.log(admin, admin.getCaId(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_INFO_APPROVALREQUESTED,
                        "Approval with unique id : " + id + " removed successfully.");
          } else {
                logSession.log(admin, admin.getCaId(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_ERROR_APPROVALREQUESTED,
                        "Error removing approvalrequest with unique id : " + id + ", doesn't exist");
                throw new ApprovalException(ErrorCode.APPROVAL_REQUEST_ID_NOT_EXIST, "Error removing approvalrequest with unique id : " + id + ", doesn't exist");
          }
        } catch (Exception e) {
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_ERROR_APPROVALREQUESTED,
                    "Error removing approvalrequest with unique id : " + id);
            log.error("Error removing approval request", e);
        }
        log.trace("<removeApprovalRequest");
    }

    @Override
    public void reject(Admin admin, int approvalId, Approval approval, GlobalConfiguration gc) throws ApprovalRequestExpiredException,
            AuthorizationDeniedException, ApprovalException, AdminAlreadyApprovedRequestException {
        log.trace(">reject");
        ApprovalData adl;
        try {
            adl = isAuthorizedBeforeApproveOrReject(admin, approvalId);
        } catch (ApprovalException e1) {
            logSession.log(admin, admin.getCaId(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_ERROR_APPROVALREJECTED,
                    "Approval request with id : " + approvalId + " doesn't exists.");
            throw e1;
        }

        checkExecutionPossibility(admin, adl);
        approval.setApprovalAdmin(false, admin);

        try {
            reject(adl, approval);
            if (gc.getUseApprovalNotifications()) {
              final ApprovalDataVO approvalDataVO = getApprovalDataVO(adl);
                sendApprovalNotification(admin, gc.getApprovalAdminEmailAddress(), gc.getApprovalNotificationFromAddress(), gc.getBaseUrl()
                        + "adminweb/approval/approveaction.jsf?uniqueId=" + adl.getId(), intres.getLocalizedMessage("notification.requestrejected.subject"),
                        intres.getLocalizedMessage("notification.requestrejected.msg"), adl.getId(), approvalDataVO.getRemainingApprovals(),
                        approvalDataVO.getRequestDate(), approvalDataVO.getApprovalRequest(), approval);
            }
            logSession.log(admin, adl.getCaid(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_INFO_APPROVALREJECTED,
                    "Approval request with id : " + approvalId + " have been rejected.");
        } catch (ApprovalRequestExpiredException e) {
            logSession.log(admin, adl.getCaid(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_ERROR_APPROVALREJECTED,
                    "Approval request with id : " + approvalId + " have expired.");
            throw e;
        }
        log.trace("<reject");
    }
   
    @Override
    public void checkExecutionPossibility(Admin admin, ApprovalData adl) throws AdminAlreadyApprovedRequestException{
        // Check that the approvers username doesn't exists among the existing
        // usernames.
        ApprovalDataVO data = getApprovalDataVO(adl);
        String username = admin.getUsername();
        if (data.getReqadmincertissuerdn() != null) {
            // Check that the approver isn't the same as requested the action.
            boolean sameAsRequester = false;
            String requsername = getRequestAdminUsername(adl);
            if(username != null) {
              if(username.equals(requsername)) {
                sameAsRequester=true;
              }
            } else {
              if(admin.getAdminData().equals(getApprovalRequest(adl).getRequestAdmin().getAdminData())) {
                sameAsRequester=true;
              }
            }
            if (sameAsRequester) {
                logSession.log(admin, adl.getCaid(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_ERROR_APPROVALREJECTED,
                        "Error administrator have already approved, rejected or requested current request, approveId ");
                throw new AdminAlreadyApprovedRequestException("Error administrator have already approved, rejected or requested current request, approveId : "
                        + /*approvalId*/ adl.getApprovalid());
            }
        }
        //Check that his admin has not approved this this request before
        Iterator<Approval> iter = data.getApprovals().iterator();
        while (iter.hasNext()) {
          Approval next = iter.next();
            if ((next.getAdmin().getUsername()!=null && username!=null && next.getAdmin().getUsername().equals(username)) || ((next.getAdmin().getUsername()==null || username==null) && admin.getAdminData().equals(next.getAdmin().getAdminData()))) {
                logSession.log(admin, adl.getCaid(), LogConstants.MODULE_APPROVAL, new Date(), null, null, LogConstants.EVENT_ERROR_APPROVALREJECTED,
                        "Error administrator have already approved or rejected current request, approveId ");
                throw new AdminAlreadyApprovedRequestException("Error administrator have already approved or rejected current request, approveId : "
                        + /*approvalId*/ adl.getApprovalid());
            }
        }
    }

    @Override
    public ApprovalData isAuthorizedBeforeApproveOrReject(Admin admin, int approvalId) throws ApprovalException, AuthorizationDeniedException {
        ApprovalData retval = findNonExpiredApprovalDataLocal(approvalId);
        if (retval != null) {
            if (retval.getEndentityprofileid() == ApprovalDataVO.ANY_ENDENTITYPROFILE) {
                if(!authorizationSession.isAuthorized(admin, AccessRulesConstants.REGULAR_APPROVECAACTION)) {
                    Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_APPROVECAACTION, null);
                }
            } else {
                if(!authorizationSession.isAuthorized(admin, AccessRulesConstants.REGULAR_APPROVEENDENTITY)) {
                    Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_APPROVEENDENTITY, null);
                }
                if(!authorizationSession.isAuthorized(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + retval.getEndentityprofileid()
                        + AccessRulesConstants.APPROVAL_RIGHTS)) {
                    Authorizer.throwAuthorizationException(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + retval.getEndentityprofileid()
                            + AccessRulesConstants.APPROVAL_RIGHTS, null);
                }
            }
            if (retval.getCaid() != ApprovalDataVO.ANY_CA) {
                if(!authorizationSession.isAuthorized(admin, AccessRulesConstants.CAPREFIX + retval.getCaid())) {
                    Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX + retval.getCaid(), null);
                }
            }
        } else {
            throw new ApprovalException(ErrorCode.APPROVAL_REQUEST_ID_NOT_EXIST, "Suitable approval with id : " + approvalId + " doesn't exist");
        }
        return retval;
    }

    @Override
    public int isApproved(Admin admin, int approvalId, int step) throws ApprovalException, ApprovalRequestExpiredException {
        if (log.isTraceEnabled()) {
            log.trace(">isApproved, approvalId" + approvalId);
        }
        int retval = ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED;
        Collection<ApprovalData> result = ApprovalData.findByApprovalId(entityManager, approvalId);
        if (result.size() == 0) {
          throw new ApprovalException(ErrorCode.APPROVAL_REQUEST_ID_NOT_EXIST, "Approval request with id : " + approvalId + " doesn't exists");
        }
        Iterator<ApprovalData> iter = result.iterator();
        while (iter.hasNext()) {
          ApprovalData adl = iter.next();
          retval = isApproved(adl, step);
          if (adl.getStatus() == ApprovalDataVO.STATUS_WAITINGFORAPPROVAL || adl.getStatus() == ApprovalDataVO.STATUS_APPROVED
              || adl.getStatus() == ApprovalDataVO.STATUS_REJECTED) {
            break;
          }
        }
        if (log.isTraceEnabled()) {
            log.trace("<isApproved, result" + retval);
        }
        return retval;
    }

    @Override
    public int isApproved(Admin admin, int approvalId) throws ApprovalException, ApprovalRequestExpiredException {
        return isApproved(admin, approvalId, 0);
    }

    @Override
    public void markAsStepDone(Admin admin, int approvalId, int step) throws ApprovalException, ApprovalRequestExpiredException {
        if (log.isTraceEnabled()) {
            log.trace(">markAsStepDone, approvalId" + approvalId + ", step " + step);
        }
        Collection<ApprovalData> result = ApprovalData.findByApprovalId(entityManager, approvalId);
        Iterator<ApprovalData> iter = result.iterator();
        if (result.size() == 0) {
          throw new ApprovalException(ErrorCode.APPROVAL_REQUEST_ID_NOT_EXIST, "Approval request with id : " + approvalId + " doesn't exists");
        }
        while (iter.hasNext()) {
          ApprovalData adl = iter.next();
          markStepAsDone(adl, step);
        }
        log.trace("<markAsStepDone.");
    }

    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    @Override
    public ApprovalDataVO findNonExpiredApprovalRequest(Admin admin, int approvalId) {
        ApprovalDataVO retval = null;
        ApprovalData data = findNonExpiredApprovalDataLocal(approvalId);
        if (data != null) {
            retval = getApprovalDataVO(data);
        }
        return retval;
    }

    private ApprovalData findNonExpiredApprovalDataLocal(int approvalId) {
        ApprovalData retval = null;
        Collection<ApprovalData> result = ApprovalData.findByApprovalIdNonExpired(entityManager, approvalId);
        log.debug("Found number of approvalIdNonExpired: " + result.size());
        Iterator<ApprovalData> iter = result.iterator();
        while (iter.hasNext()) {
          ApprovalData next = iter.next();
          ApprovalDataVO data = getApprovalDataVO(next);
          if (data.getStatus() == ApprovalDataVO.STATUS_WAITINGFORAPPROVAL || data.getStatus() == ApprovalDataVO.STATUS_APPROVED
              || data.getStatus() == ApprovalDataVO.STATUS_REJECTED) {
            retval = next;
          }
        }
        return retval;
    }

    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    @Override
    public Collection<ApprovalDataVO> findApprovalDataVO(Admin admin, int approvalId) {
        log.trace(">findApprovalDataVO");
        ArrayList<ApprovalDataVO> retval = new ArrayList<ApprovalDataVO>();
        Collection<ApprovalData> result = ApprovalData.findByApprovalId(entityManager, approvalId);
        Iterator<ApprovalData> iter = result.iterator();
        while (iter.hasNext()) {
          ApprovalData adl = iter.next();
          retval.add(getApprovalDataVO(adl));
        }
        log.trace("<findApprovalDataVO");
        return retval;
    }

    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    @Override
    public List<ApprovalDataVO> query(Admin admin, Query query, int index, int numberofrows, String caAuthorizationString, String endEntityProfileAuthorizationString)
            throws AuthorizationDeniedException, IllegalQueryException {
        log.trace(">query()");
        String customQuery = "";
        // Check if query is legal.
        if (query != null && !query.isLegalQuery()) {
            throw new IllegalQueryException();
        }
        if (query != null) {
            customQuery += query.getQueryString();
        }
        if (!caAuthorizationString.equals("") && query != null) {
            customQuery += " AND " + caAuthorizationString;
        } else {
            customQuery += caAuthorizationString;
        }
        if (StringUtils.isNotEmpty(endEntityProfileAuthorizationString)) {
            if (caAuthorizationString.equals("") && query == null) {
                customQuery += endEntityProfileAuthorizationString;
            } else {
                customQuery += " AND " + endEntityProfileAuthorizationString;
            }
        }
        final List<ApprovalData> approvalDataList = ApprovalData.findByCustomQuery(entityManager, index, numberofrows, customQuery);
        final List<ApprovalDataVO> returnData = new ArrayList<ApprovalDataVO>(approvalDataList.size());
        for (ApprovalData approvalData : approvalDataList) {
          returnData.add(getApprovalDataVO(approvalData));
        }
        log.trace("<query()");
        return returnData;
    }

    @Override
    public void sendApprovalNotification(Admin admin, String approvalAdminsEmail, String approvalNotificationFromAddress, String approvalURL,
            String notificationSubject, String notificationMsg, Integer id, int numberOfApprovalsLeft, Date requestDate, ApprovalRequest approvalRequest,
            Approval approval) {
        if (log.isTraceEnabled()) {
            log.trace(">sendNotification approval notification: id=" + id);
        }
        try {
            Admin sendAdmin = admin;
            if (admin.getAdminType() == Admin.TYPE_CLIENTCERT_USER) {
                sendAdmin = new ApprovedActionAdmin(admin.getAdminInformation().getX509Certificate(), admin.getUsername(), admin.getEmail());
            }
            Certificate requestAdminCert = approvalRequest.getRequestAdminCert();
            String requestAdminDN = null;
            String requestAdminUsername = null;
            if (requestAdminCert != null) {
                requestAdminDN = CertTools.getSubjectDN(requestAdminCert);
                requestAdminUsername = sendAdmin.getUsername();
            } else {
                requestAdminUsername = intres.getLocalizedMessage("CLITOOL");
                requestAdminDN = "CN=" + requestAdminUsername;
            }
            if (approvalAdminsEmail.equals("") || approvalNotificationFromAddress.equals("")) {
                logSession
                        .log(sendAdmin, approvalRequest.getCAId(), LogConstants.MODULE_APPROVAL, new java.util.Date(), requestAdminUsername, null,
                                LogConstants.EVENT_ERROR_NOTIFICATION,
                                "Error sending approval notification. The email-addresses, either to approval administrators or from-address isn't configured properly");
            } else {
                String approvalTypeText = intres.getLocalizedMessage(ApprovalDataVO.APPROVALTYPENAMES[approvalRequest.getApprovalType()]);

                String approvalAdminUsername = null;
                String approvalAdminDN = null;
                String approveComment = null;
                if (approval != null) {
                    approvalAdminUsername = approval.getAdmin().getUsername();
                    approvalAdminDN = CertTools.getSubjectDN(approval.getAdmin().getAdminInformation().getX509Certificate());
                    approveComment = approval.getComment();
                }
                Integer numAppr = Integer.valueOf(numberOfApprovalsLeft);
                ApprovalNotificationParamGen paramGen = new ApprovalNotificationParamGen(requestDate, id, approvalTypeText, numAppr, approvalURL,
                        approveComment, requestAdminUsername, requestAdminDN, approvalAdminUsername, approvalAdminDN);
                String subject = paramGen.interpolate(notificationSubject);
                String message = paramGen.interpolate(notificationMsg);
                List<String> toList = Arrays.asList(approvalAdminsEmail);
                if (sendAdmin.getEmail() == null || sendAdmin.getEmail().length() == 0) {
                    logSession.log(sendAdmin, approvalRequest.getCAId(), LogConstants.MODULE_APPROVAL, new java.util.Date(), requestAdminUsername, null,
                            LogConstants.EVENT_ERROR_NOTIFICATION,
                            "Error sending notification to administrator requesting approval. Set a correct email to the administrator");
                } else {
                    toList = Arrays.asList(approvalAdminsEmail, sendAdmin.getEmail());
                }
                MailSender.sendMailOrThrow(approvalNotificationFromAddress, toList, MailSender.NO_CC, subject, message, MailSender.NO_ATTACHMENTS);
                logSession.log(sendAdmin, approvalRequest.getCAId(), LogConstants.MODULE_APPROVAL, new java.util.Date(), requestAdminUsername, null,
                        LogConstants.EVENT_INFO_NOTIFICATION, "Approval notification with id " + id + " was sent successfully.");
            }
        } catch (Exception e) {
           log.error("Error when sending notification approving notification", e);
            try {
                logSession.log(admin, approvalRequest.getCAId(), LogConstants.MODULE_APPROVAL, new java.util.Date(), null, null,
                        LogConstants.EVENT_ERROR_NOTIFICATION, "Error sending approval notification with id " + id + ".");
            } catch (Exception f) {
                throw new EJBException(f);
            }
        }
        if (log.isTraceEnabled()) {
            log.trace("<sendNotification approval notification: id=" + id);
        }
    }

    private Integer findFreeApprovalId() {
        Random ran = new Random((new Date()).getTime());
        int id = ran.nextInt();
        boolean foundfree = false;
        while (!foundfree) {
                if (id > 1) {
                  if (ApprovalData.findByApprovalId(entityManager, id).size() == 0) {
                        foundfree = true;
                  }
                }
                id = ran.nextInt();
        }
        return Integer.valueOf(id);
    }

  /**
   * Method that rejects an approval.
   * After someone have rejected the request no-one else can approve it
   */
  private void reject(final ApprovalData approvalData, final Approval approval) throws ApprovalRequestExpiredException,  ApprovalException {
    if(approvalData.haveRequestOrApprovalExpired()){
      throw new ApprovalRequestExpiredException();
    }
    if(approvalData.getStatus() != ApprovalDataVO.STATUS_WAITINGFORAPPROVAL){
      throw new ApprovalException("Wrong status of approval request.");
    }
    final int numberofapprovalsleft = approvalData.getRemainingapprovals() -1;
    if(numberofapprovalsleft < 0){
      throw new ApprovalException("Error already enough approvals have been done on this request.");
    }
    approvalData.setRemainingapprovals(0);
    final Collection<Approval> approvals = getApprovals(approvalData);
    approvals.add(approval);
    setApprovals(approvalData, approvals);
    if(getApprovalRequest(approvalData).isExecutable()){
      approvalData.setStatus(ApprovalDataVO.STATUS_EXECUTIONDENIED);
      approvalData.setExpireDate(new Date());               
    }else{
      approvalData.setStatus(ApprovalDataVO.STATUS_REJECTED);
      approvalData.setExpiredate((new Date()).getTime() + getApprovalRequest(approvalData).getApprovalValidity());      
    }
  }

  /**
   * Method used to mark an non-executable approval as done
   * if the last step is performed will the status be set as
   * expired.
   *
   * @throws ApprovalRequestExpiredException if the step have already been executed
   */
  private void markStepAsDone(final ApprovalData approvalData, final int step) throws ApprovalRequestExpiredException {
    final ApprovalRequest ar = getApprovalRequest(approvalData);
    if (!ar.isExecutable() && approvalData.getStatus() == ApprovalDataVO.STATUS_APPROVED) {
      if (!ar.isStepDone(step)) {
        ar.markStepAsDone(step);
        setApprovalRequest(approvalData, ar);
        if (step == ar.getNumberOfApprovalSteps()-1) {
          approvalData.setStatus(ApprovalDataVO.STATUS_EXPIRED);
        }
      } else {
        throw new ApprovalRequestExpiredException("Error step " + step + " of approval with id " + approvalData.getApprovalid() + " have alread been performed");
      }
    }
  }

  /**
   * Method used by the requestadmin to check if an approval request have been approved
   *
   * @return the number of approvals left, 0 if approved othervis is the ApprovalDataVO.STATUS constants returned indicating the statys.
   * @throws ApprovalRequestExpiredException if the request or approval have expired, the status will be EXPIREDANDNOTIFIED in this case.
   */
  private int isApproved(final ApprovalData approvalData, final int step) throws ApprovalRequestExpiredException {     
    if(getApprovalRequest(approvalData).isStepDone(step)){
      return ApprovalDataVO.STATUS_EXPIRED;
    }
    if(approvalData.haveRequestOrApprovalExpired()){
      if(approvalData.getStatus() != ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED &&
          approvalData.getStatus() != ApprovalDataVO.STATUS_EXECUTED &&
          approvalData.getStatus() != ApprovalDataVO.STATUS_EXECUTIONDENIED &&
          approvalData.getStatus() != ApprovalDataVO.STATUS_EXECUTIONFAILED){
        approvalData.setStatus(ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED);
        throw new ApprovalRequestExpiredException();
      }
      return ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED;
    }
    if(approvalData.getStatus() == ApprovalDataVO.STATUS_WAITINGFORAPPROVAL){
      return approvalData.getRemainingapprovals();
    }
    return approvalData.getStatus();
  }

    /**
     * Method that returns the approval data. This method currently extracts the ApprovalRequest object.
     */
    private String getRequestAdminUsername(final ApprovalData approvalData) {
      return getApprovalRequest(approvalData).getRequestAdmin().getUsername();
    }

    @Override
    public ApprovalRequest getApprovalRequest(final ApprovalData approvalData) {
    return ApprovalDataUtil.getApprovalRequest(approvalData.getRequestdata());
  }

  private final void setApprovalRequest(final ApprovalData approvalData, final ApprovalRequest approvalRequest){
    try{
      final ByteArrayOutputStream baos = new ByteArrayOutputStream();
      final ObjectOutputStream oos = new ObjectOutputStream(baos);
      oos.writeObject(approvalRequest);
      oos.flush();
      approvalData.setRequestdata(new String(Base64.encode(baos.toByteArray(),false)));
    }catch(IOException e){
      log.error("Error building approval request.",e);
      throw new RuntimeException(e);      
    }
  }

  @Override
  public ApprovalDataVO getApprovalDataVO(ApprovalData approvalData) {
    approvalData.haveRequestOrApprovalExpired();
    return new ApprovalDataVO(approvalData.getId(), approvalData.getApprovalid(), approvalData.getApprovaltype(),
        approvalData.getEndentityprofileid(), approvalData.getCaid(), approvalData.getReqadmincertissuerdn(),
        approvalData.getReqadmincertsn(), approvalData.getStatus(), getApprovals(approvalData), getApprovalRequest(approvalData),
        approvalData.getRequestDate(), approvalData.getExpireDate(), approvalData.getRemainingapprovals());
  }

  @Override
  public Collection<Approval> getApprovals(ApprovalData approvalData) {  
    return ApprovalDataUtil.getApprovals(approvalData.getApprovaldata());
  }

  @Override
  public void setApprovals(ApprovalData approvalData, final Collection<Approval> approvals){
    try{
      final ByteArrayOutputStream baos = new ByteArrayOutputStream();
      final ObjectOutputStream oos = new ObjectOutputStream(baos);
      final int size = approvals.size();
      oos.writeInt(size);
      final Iterator<Approval> iter = approvals.iterator();
      while(iter.hasNext()){
        final Approval next = iter.next();
        oos.writeObject(next);
      }
      oos.flush();
      approvalData.setApprovaldata(new String(Base64.encode(baos.toByteArray(),false)));
    } catch (IOException e) {
      log.error("Error building approvals.",e);
      throw new RuntimeException(e);
    }
  }
}
TOP

Related Classes of org.ejbca.core.ejb.approval.ApprovalSessionBean

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.