KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > ejb > approval > LocalApprovalSessionBean


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13
14 package org.ejbca.core.ejb.approval;
15
16 import java.math.BigInteger JavaDoc;
17 import java.security.cert.X509Certificate JavaDoc;
18 import java.sql.Connection JavaDoc;
19 import java.sql.PreparedStatement JavaDoc;
20 import java.sql.ResultSet JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Date JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Random JavaDoc;
28
29 import javax.ejb.CreateException JavaDoc;
30 import javax.ejb.EJBException JavaDoc;
31 import javax.ejb.FinderException JavaDoc;
32 import javax.ejb.RemoveException JavaDoc;
33 import javax.mail.Message JavaDoc;
34 import javax.mail.Session JavaDoc;
35 import javax.mail.Transport JavaDoc;
36 import javax.mail.internet.InternetAddress JavaDoc;
37
38 import org.apache.commons.lang.StringUtils;
39 import org.apache.log4j.Logger;
40 import org.ejbca.core.ejb.BaseSessionBean;
41 import org.ejbca.core.ejb.JNDINames;
42 import org.ejbca.core.ejb.authorization.IAuthorizationSessionLocal;
43 import org.ejbca.core.ejb.authorization.IAuthorizationSessionLocalHome;
44 import org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocal;
45 import org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocalHome;
46 import org.ejbca.core.ejb.log.ILogSessionLocal;
47 import org.ejbca.core.ejb.log.ILogSessionLocalHome;
48 import org.ejbca.core.ejb.ra.IUserAdminSessionLocal;
49 import org.ejbca.core.ejb.ra.IUserAdminSessionLocalHome;
50 import org.ejbca.core.ejb.ra.raadmin.IRaAdminSessionLocal;
51 import org.ejbca.core.ejb.ra.raadmin.IRaAdminSessionLocalHome;
52 import org.ejbca.core.model.InternalResources;
53 import org.ejbca.core.model.approval.AdminAlreadyApprovedRequestException;
54 import org.ejbca.core.model.approval.Approval;
55 import org.ejbca.core.model.approval.ApprovalDataUtil;
56 import org.ejbca.core.model.approval.ApprovalDataVO;
57 import org.ejbca.core.model.approval.ApprovalException;
58 import org.ejbca.core.model.approval.ApprovalRequest;
59 import org.ejbca.core.model.approval.ApprovalRequestExecutionException;
60 import org.ejbca.core.model.approval.ApprovalRequestExpiredException;
61 import org.ejbca.core.model.authorization.AuthorizationDeniedException;
62 import org.ejbca.core.model.authorization.AvailableAccessRules;
63 import org.ejbca.core.model.log.Admin;
64 import org.ejbca.core.model.log.LogEntry;
65 import org.ejbca.core.model.ra.RAAuthorization;
66 import org.ejbca.core.model.ra.UserDataVO;
67 import org.ejbca.core.model.ra.raadmin.GlobalConfiguration;
68 import org.ejbca.util.CertTools;
69 import org.ejbca.util.JDBCUtil;
70 import org.ejbca.util.NotificationParamGen;
71 import org.ejbca.util.TemplateMimeMessage;
72 import org.ejbca.util.query.IllegalQueryException;
73 import org.ejbca.util.query.Query;
74
75
76
77 /**
78  * Keeps track of approval requests and their approval or rejects.
79  *
80  * Uses JNDI name for datasource as defined in env 'Datasource' in ejb-jar.xml.
81  *
82  * @ejb.bean description="Session bean handling interface with user data sources"
83  * display-name="ApprovalSessionSB"
84  * name="ApprovalSession"
85  * jndi-name="ApprovalSession"
86  * local-jndi-name="ApprovalSessionLocal"
87  * view-type="both"
88  * type="Stateless"
89  * transaction-type="Container"
90  *
91  * @ejb.transaction type="Required"
92  *
93  * @weblogic.enable-call-by-reference True
94  *
95  * @ejb.env-entry name="DataSource"
96  * type="java.lang.String"
97  * value="${datasource.jndi-name-prefix}${datasource.jndi-name}"
98  *
99  * @ejb.env-entry
100  * description="Defines the JNDI name of the mail service used"
101  * name="MailJNDIName"
102  * type="java.lang.String"
103  * value="${mail.jndi-name}"
104  *
105  * @ejb.ejb-external-ref description="The Approval entity bean"
106  * view-type="local"
107  * ref-name="ejb/ApprovalDataLocal"
108  * type="Entity"
109  * home="org.ejbca.core.ejb.approval.ApprovalDataLocalHome"
110  * business="org.ejbca.core.ejb.approval.ApprovalDataLocal"
111  * link="ApprovalData"
112  *
113  * @ejb.ejb-external-ref description="The Certificate store used to store and fetch certificates"
114  * view-type="local"
115  * ref-name="ejb/CertificateStoreSessionLocal"
116  * type="Session"
117  * home="org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocalHome"
118  * business="org.ejbca.core.ejb.ca.store.ICertificateStoreSessionLocal"
119  * link="CertificateStoreSession"
120  *
121  * @ejb.ejb-external-ref description="The Authorization Session Bean"
122  * view-type="local"
123  * ref-name="ejb/AuthorizationSessionLocal"
124  * type="Session"
125  * home="org.ejbca.core.ejb.authorization.IAuthorizationSessionLocalHome"
126  * business="org.ejbca.core.ejb.authorization.IAuthorizationSessionLocal"
127  * link="AuthorizationSession"
128  *
129  * @ejb.ejb-external-ref
130  * description="The Ra Admin session bean"
131  * view-type="local"
132  * ref-name="ejb/RaAdminSessionLocal"
133  * type="Session"
134  * home="org.ejbca.core.ejb.ra.raadmin.IRaAdminSessionLocalHome"
135  * business="org.ejbca.core.ejb.ra.raadmin.IRaAdminSessionLocal"
136  * link="RaAdminSession"
137  *
138  * @ejb.ejb-external-ref
139  * description="The User Admin session bean"
140  * view-type="local"
141  * ref-name="ejb/UserAdminSessionLocal"
142  * type="Session"
143  * home="org.ejbca.core.ejb.ra.IUserAdminSessionLocalHome"
144  * business="org.ejbca.core.ejb.ra.IUserAdminSessionLocal"
145  * link="UserAdminSession"
146  *
147  * @ejb.ejb-external-ref
148  * description="The Certificate Store session bean"
149  * view-type="local"
150  * ref-name="ejb/HardTokenSessionLocal"
151  * type="Session"
152  * home="org.ejbca.core.ejb.hardtoken.IHardTokenSessionLocalHome"
153  * business="org.ejbca.core.ejb.hardtoken.IHardTokenSessionLocal"
154  * link="HardTokenSession"
155  *
156  * @ejb.ejb-external-ref
157  * description="The Key Recovery session bean"
158  * view-type="local"
159  * ref-name="ejb/KeyRecoverySessionLocal"
160  * type="Session"
161  * home="org.ejbca.core.ejb.keyrecovery.IKeyRecoverySessionLocalHome"
162  * business="org.ejbca.core.ejb.keyrecovery.IKeyRecoverySessionLocal"
163  * link="KeyRecoverySession"
164  *
165  * @ejb.ejb-external-ref description="The CAAdmin Session Bean"
166  * view-type="local"
167  * ref-name="ejb/CAAdminSessionLocal"
168  * type="Session"
169  * home="org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocalHome"
170  * business="org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocal"
171  * link="CAAdminSession"
172  *
173  * @ejb.ejb-external-ref description="The log session bean"
174  * view-type="local"
175  * ref-name="ejb/LogSessionLocal"
176  * type="Session"
177  * home="org.ejbca.core.ejb.log.ILogSessionLocalHome"
178  * business="org.ejbca.core.ejb.log.ILogSessionLocal"
179  * link="LogSession"
180  *
181  * @ejb.home extends="javax.ejb.EJBHome"
182  * local-extends="javax.ejb.EJBLocalHome"
183  * local-class="org.ejbca.core.ejb.approval.IApprovalSessionLocalHome"
184  * remote-class="org.ejbca.core.ejb.approval.IApprovalSessionHome"
185  *
186  * @ejb.interface extends="javax.ejb.EJBObject"
187  * local-extends="javax.ejb.EJBLocalObject"
188  * local-class="org.ejbca.core.ejb.approval.IApprovalSessionLocal"
189  * remote-class="org.ejbca.core.ejb.approval.IApprovalSessionRemote"
190  *
191  * @jonas.bean ejb-name="ApprovalSession"
192  */

193 public class LocalApprovalSessionBean extends BaseSessionBean {
194
195     
196     private static final Logger log = Logger.getLogger(LocalApprovalSessionBean.class);
197
198     /** Internal localization of logs and errors */
199     private static final InternalResources intres = InternalResources.getInstance();
200     
201     /**
202      * The local home interface of approval entity bean.
203      */

204     private ApprovalDataLocalHome approvalHome = null;
205
206
207     /**
208      * The local interface of RaAdmin Session Bean.
209      */

210     private IRaAdminSessionLocal raadminsession;
211
212     /**
213      * The local interface of User Admin Session Bean.
214      */

215     private IUserAdminSessionLocal useradminsession;
216     
217     /**
218      * The local interface of authorization session bean
219      */

220     private IAuthorizationSessionLocal authorizationsession = null;
221
222     /**
223      * The remote interface of log session bean
224      */

225     private ILogSessionLocal logsession = null;
226
227
228     /** The local interface of the certificate store session bean */
229     private ICertificateStoreSessionLocal certificatestoresession;
230     
231     /**
232      * Columns in the database used in select
233      */

234     private static final String JavaDoc APPROVALDATA_COL = "id, approvalid, approvaltype, endentityprofileid, caid, reqadmincertissuerdn, reqadmincertsn, status, approvaldata, requestdata, requestdate, expiredate, remainingapprovals";
235
236     
237     /**
238      * Default create for SessionBean without any creation Arguments.
239      *
240      * @throws CreateException if bean instance can't be created
241      */

242     public void ejbCreate() throws CreateException JavaDoc {
243         approvalHome = (ApprovalDataLocalHome) getLocator().getLocalHome(ApprovalDataLocalHome.COMP_NAME);
244     }
245
246
247     /**
248      * Gets connection to log session bean
249      *
250      * @return Connection
251      */

252     private ILogSessionLocal getLogSession() {
253         if (logsession == null) {
254             try {
255                 ILogSessionLocalHome logsessionhome = (ILogSessionLocalHome) getLocator().getLocalHome(ILogSessionLocalHome.COMP_NAME);
256                 logsession = logsessionhome.create();
257             } catch (CreateException JavaDoc e) {
258                 throw new EJBException JavaDoc(e);
259             }
260         }
261         return logsession;
262     } //getLogSession
263

264     /**
265      * Gets connection to ra admin session bean
266      *
267      * @return Connection
268      */

269     private IRaAdminSessionLocal getRAAdminSession() {
270         if (raadminsession == null) {
271             try {
272                 IRaAdminSessionLocalHome raadminsessionhome = (IRaAdminSessionLocalHome) getLocator().getLocalHome(IRaAdminSessionLocalHome.COMP_NAME);
273                 raadminsession = raadminsessionhome.create();
274             } catch (CreateException JavaDoc e) {
275                 throw new EJBException JavaDoc(e);
276             }
277         }
278         return raadminsession;
279     } //getRAAdminSession
280

281     /**
282      * Gets connection to user admin session bean
283      *
284      * @return Connection
285      */

286     private IUserAdminSessionLocal getUserAdminSession() {
287         if (useradminsession == null) {
288             try {
289                 IUserAdminSessionLocalHome useradminsessionhome = (IUserAdminSessionLocalHome) getLocator().getLocalHome(IUserAdminSessionLocalHome.COMP_NAME);
290                 useradminsession = useradminsessionhome.create();
291             } catch (CreateException JavaDoc e) {
292                 throw new EJBException JavaDoc(e);
293             }
294         }
295         return useradminsession;
296     } //getUserAdminSession
297

298     /** Gets connection to certificate store session bean
299      * @return Connection
300      */

301     private ICertificateStoreSessionLocal getCertificateStoreSession() {
302         if(certificatestoresession == null){
303             try{
304                 ICertificateStoreSessionLocalHome home = (ICertificateStoreSessionLocalHome) getLocator().getLocalHome(ICertificateStoreSessionLocalHome.COMP_NAME);
305                 certificatestoresession = home.create();
306             }catch(Exception JavaDoc e){
307                 throw new EJBException JavaDoc(e);
308             }
309         }
310         return certificatestoresession;
311     } //getCertificateStoreSession
312

313     /**
314      * Gets connection to authorization session bean
315      *
316      * @return IAuthorizationSessionLocal
317      */

318     private IAuthorizationSessionLocal getAuthorizationSession() {
319         if (authorizationsession == null) {
320             try {
321                 IAuthorizationSessionLocalHome authorizationsessionhome = (IAuthorizationSessionLocalHome) getLocator().getLocalHome(IAuthorizationSessionLocalHome.COMP_NAME);
322                 authorizationsession = authorizationsessionhome.create();
323             } catch (CreateException JavaDoc e) {
324                 throw new EJBException JavaDoc(e);
325             }
326         }
327         return authorizationsession;
328     } //getAuthorizationSession
329

330
331    /**
332     * Method used to add an approval to database.
333     *
334     * The main key of an approval is the approvalid, which should be unique for
335     * one administrator doing one type of action, requesting the same action twice should
336     * result in the same approvalId
337     *
338     * It the approvalId already exists, it will check the status:
339     * If status is waiting, approved, or rejected an ApprovalException is thrown
340     * otherwise is an new approval requeset added to the database
341     *
342     * @throws ApprovalException
343     *
344     * @ejb.interface-method view-type="both"
345     */

346     public void addApprovalRequest(Admin admin, ApprovalRequest approvalRequest) throws ApprovalException{
347         log.debug(">addApprovalRequest");
348         int approvalId = approvalRequest.generateApprovalId();
349         
350         
351         ApprovalDataVO data = findNonExpiredApprovalRequest(admin, approvalId);
352         if(data != null){
353             getLogSession().log(admin,approvalRequest.getCAId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREQUESTED,"Approval with id : " +approvalId +" already exists");
354             throw new ApprovalException("Approval Request " + approvalId + " already exists in database");
355         } else {
356             // The exists no approval request with status waiting add a new one
357
try {
358                 Integer JavaDoc freeId = this.findFreeApprovalId();
359                 approvalHome.create(freeId,approvalRequest);
360                 GlobalConfiguration gc = getRAAdminSession().loadGlobalConfiguration(admin);
361                 if(gc.getUseApprovalNotifications()){
362                     sendApprovalNotification(admin, gc,
363                                              intres.getLocalizedMessage("notification.newrequest.subject"),
364                                              intres.getLocalizedMessage("notification.newrequest.msg"),
365                                              freeId, approvalRequest.getNumOfRequiredApprovals(), new Date JavaDoc(), approvalRequest,null);
366                 }
367                 getLogSession().log(admin,approvalRequest.getCAId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_INFO_APPROVALREQUESTED,"Approval with id : " +approvalId +" added with status waiting.");
368             } catch (CreateException JavaDoc e1) {
369                 getLogSession().log(admin,approvalRequest.getCAId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREQUESTED,"Approval with id : " +approvalId +" couldn't be created");
370                 log.error("Error creating approval request",e1);
371                 
372             }
373         }
374         log.debug("<addApprovalRequest");
375     }
376     
377
378     /**
379      * Method used to remove an approval from database.
380      *
381      * @param id, the uniqu id of the approvalrequest, not the same as approvalId
382      *
383      * @throws ApprovalException
384      *
385      * @ejb.interface-method view-type="both"
386      */

387      public void removeApprovalRequest(Admin admin, int id) throws ApprovalException{
388         log.debug(">removeApprovalRequest");
389         
390         
391         try {
392             ApprovalDataLocal adl = approvalHome.findByPrimaryKey(new Integer JavaDoc(id));
393             adl.remove();
394             getLogSession().log(admin,admin.getCaId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_INFO_APPROVALREQUESTED,"Approval with unique id : " + id +" removed successfully.");
395         } catch (FinderException JavaDoc e) {
396             getLogSession().log(admin,admin.getCaId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREQUESTED,"Error removing approvalrequest with unique id : " +id +", doesn't exist");
397             throw new ApprovalException("Error removing approvalrequest with unique id : " +id +", doesn't exist");
398         } catch (EJBException JavaDoc e) {
399             getLogSession().log(admin,admin.getCaId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREQUESTED,"Error removing approvalrequest with unique id : " +id);
400             log.error("Error removing approval request",e);
401         } catch (RemoveException JavaDoc e) {
402             getLogSession().log(admin,admin.getCaId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREQUESTED,"Error removing approvalrequest with unique id : " +id);
403             log.error("Error removing approval request",e);
404         }
405
406         log.debug("<removeApprovalRequest");
407      }
408     
409     /**
410      * Method used to approve an approval requests.
411      *
412      * It does the follwing
413      * 1. checks if the approval with the status waiting exists, throws an ApprovalRequestDoesntExistException otherwise
414      *
415      * 2. check if the administrator is authorized using the follwing rules:
416      * 2.1 if getEndEntityProfile is ANY_ENDENTITYPROFILE then check if the admin is
417      * authorized to AvailableAccessRules.REGULAR_APPROVECAACTION othervise AvailableAccessRules.REGULAR_APPORVEENDENTITY
418      * and APPROVAL_RIGHTS for the end entity profile.
419      * 2.2 Checks if the admin is authoried to the approval requests getCAId()
420      *
421      * 3. looks upp the username of the administrator and checks that no approval
422      * have been made by this user earlier.
423      *
424      * 4. Runs the approval command in the end entity bean.
425      *
426      * @param admin
427      * @param approvalId
428      * @param approval
429      * @throws ApprovalRequestExpiredException
430      * @throws ApprovalRequestExecutionException
431      * @throws AuthorizationDeniedException
432      * @throws ApprovalRequestDoesntExistException
433      * @throws ApprovalException
434      * @throws AdminAlreadyApprovedRequestException
435      *
436     *
437     * @ejb.interface-method view-type="both"
438      */

439     public void approve(Admin admin, int approvalId, Approval approval) throws ApprovalRequestExpiredException, ApprovalRequestExecutionException,
440                                                                                AuthorizationDeniedException, ApprovalException, AdminAlreadyApprovedRequestException{
441         log.debug(">approve");
442         ApprovalDataLocal adl;
443         try {
444             adl = isAuthorizedBeforeApproveOrReject(admin,approvalId,approval);
445         } catch (ApprovalException e1) {
446             getLogSession().log(admin,admin.getCaId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALAPPROVED,"Approval request with id : " +approvalId +" doesn't exists.");
447             throw e1;
448         }
449         
450         // Check that the approvers username doesn't exists among the existing usernames.
451
X509Certificate JavaDoc approvingCert = admin.getAdminInformation().getX509Certificate();
452         ApprovalDataVO data = adl.getApprovalDataVO();
453         String JavaDoc username = getCertificateStoreSession().findUsernameByCertSerno(admin,approvingCert.getSerialNumber(),CertTools.getIssuerDN(approvingCert));
454         
455         // Check that the approver isn't the same as requested the action.
456
if(data.getReqadmincertissuerdn() != null){
457             String JavaDoc requsername = getCertificateStoreSession().findUsernameByCertSerno(admin,new BigInteger JavaDoc(data.getReqadmincertsn(),16),data.getReqadmincertissuerdn());
458             if(username.equals(requsername)){
459                 getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALAPPROVED,"Error administrator have already approved, rejected or requested current request, approveId " + approvalId);
460                 throw new AdminAlreadyApprovedRequestException("Error administrator have already approved, rejected or requested current request, approveId : " + approvalId);
461             }
462         }
463         if(username != null){
464             Iterator JavaDoc iter = data.getApprovals().iterator();
465             while(iter.hasNext()){
466                 Approval next = (Approval) iter.next();
467                 if(next.getUsername().equals(username)){
468                     getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALAPPROVED,"Error administrator have already approved or rejected current request, approveId " + approvalId);
469                     throw new AdminAlreadyApprovedRequestException("Error administrator have already approved or rejected current request, approveId : " + approvalId);
470                 }
471             }
472             approval.setApprovalCertificateAndUsername(true, approvingCert,username);
473         }else{
474             getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALAPPROVED,"Approval request with id : " +approvalId +", Error no username exists for the given approver certificate.");
475             throw new ApprovalException("Error no username exists for the given approver or requestor certificate");
476         }
477                 
478         
479         try {
480             adl.approve(approval);
481             GlobalConfiguration gc = getRAAdminSession().loadGlobalConfiguration(admin);
482             if(gc.getUseApprovalNotifications()){
483               if(adl.getApprovalDataVO().getRemainingApprovals() != 0){
484                 sendApprovalNotification(admin, gc,
485                                        intres.getLocalizedMessage("notification.requestconcured.subject"),
486                                        intres.getLocalizedMessage("notification.requestconcured.msg"),
487                                        adl.getId(), adl.getApprovalDataVO().getRemainingApprovals(), adl.getApprovalDataVO().getRequestDate(),
488                                        adl.getApprovalDataVO().getApprovalRequest(),
489                                        approval);
490               }else{
491                  sendApprovalNotification(admin, gc,
492                                intres.getLocalizedMessage("notification.requestapproved.subject"),
493                                intres.getLocalizedMessage("notification.requestapproved.msg"),
494                                adl.getId(), adl.getApprovalDataVO().getRemainingApprovals(), adl.getApprovalDataVO().getRequestDate(),
495                                adl.getApprovalDataVO().getApprovalRequest(),
496                                approval);
497               }
498             }
499             getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_INFO_APPROVALAPPROVED,"Approval request with id : " +approvalId +" have been approved.");
500         } catch (ApprovalRequestExpiredException e) {
501             getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALAPPROVED,"Approval request with id : " +approvalId +" have expired.");
502             throw e;
503         } catch (ApprovalRequestExecutionException e) {
504             getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALAPPROVED,"Approval with id : " +approvalId +" couldn't execute properly");
505             throw e;
506         }
507         log.debug("<approve");
508     }
509     
510     /**
511      * Method used to reject a approval requests.
512      *
513      * It does the follwing
514      * 1. checks if the approval with the status waiting exists, throws an ApprovalRequestDoesntExistException otherwise
515      *
516      * 2. check if the administrator is authorized using the follwing rules:
517      * 2.1 if getEndEntityProfile is ANY_ENDENTITYPROFILE then check if the admin is
518      * authorized to AvailableAccessRules.REGULAR_APPROVECAACTION othervise AvailableAccessRules.REGULAR_APPORVEENDENTITY
519      * and APPROVAL_RIGHTS for the end entity profile.
520      * 2.2 Checks if the admin is authoried to the approval requests getCAId()
521      *
522      * 3. looks upp the username of the administrator and checks that no approval
523      * have been made by this user earlier.
524      *
525      * 4. Runs the approval command in the end entity bean.
526      *
527      * @param admin
528      * @param approvalId
529      * @param approval
530      * @throws ApprovalRequestExpiredException
531      * @throws AuthorizationDeniedException
532      * @throws ApprovalRequestDoesntExistException
533      * @throws ApprovalException
534      * @throws AdminAlreadyApprovedRequestException
535      *
536      *
537      * @ejb.interface-method view-type="both"
538      */

539     public void reject(Admin admin, int approvalId, Approval approval) throws ApprovalRequestExpiredException,
540                                                                                AuthorizationDeniedException, ApprovalException, AdminAlreadyApprovedRequestException{
541         log.debug(">reject");
542         ApprovalDataLocal adl;
543         try {
544             adl = isAuthorizedBeforeApproveOrReject(admin,approvalId,approval);
545         } catch (ApprovalException e1) {
546             getLogSession().log(admin,admin.getCaId(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREJECTED,"Approval request with id : " +approvalId +" doesn't exists.");
547             throw e1;
548         }
549         
550         // Check that the approvers username doesn't exists among the existing usernames.
551
X509Certificate JavaDoc approvingCert = admin.getAdminInformation().getX509Certificate();
552         String JavaDoc username = getCertificateStoreSession().findUsernameByCertSerno(admin,approvingCert.getSerialNumber(),CertTools.getIssuerDN(approvingCert));
553         ApprovalDataVO data = adl.getApprovalDataVO();
554         
555         if(data.getReqadmincertissuerdn() != null){
556             // Check that the approver isn't the same as requested the action.
557
String JavaDoc requsername = getCertificateStoreSession().findUsernameByCertSerno(admin,new BigInteger JavaDoc(data.getReqadmincertsn(),16),data.getReqadmincertissuerdn());
558             if(username.equals(requsername)){
559                 getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREJECTED,"Error administrator have already approved, rejected or requested current request, approveId ");
560                 throw new AdminAlreadyApprovedRequestException("Error administrator have already approved, rejected or requested current request, approveId : " + approvalId);
561             }
562         }
563         if(username != null){
564             Iterator JavaDoc iter = data.getApprovals().iterator();
565             while(iter.hasNext()){
566                 Approval next = (Approval) iter.next();
567                 if(next.getUsername().equals(username)){
568                     getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREJECTED,"Error administrator have already approved or rejected current request, approveId ");
569                     throw new AdminAlreadyApprovedRequestException("Error administrator have already approved or rejected current request, approveId : " + approvalId);
570                 }
571             }
572             approval.setApprovalCertificateAndUsername(false, approvingCert,username);
573         }else{
574             getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREJECTED,"Approval request with id : " +approvalId +", Error no username exists for the given approver certificate.");
575             throw new ApprovalException("Error no username exists for the given approver or requestor certificate");
576         }
577                 
578         
579         try {
580             adl.reject(approval);
581             GlobalConfiguration gc = getRAAdminSession().loadGlobalConfiguration(admin);
582             if(gc.getUseApprovalNotifications()){
583               sendApprovalNotification(admin, gc,
584                                        intres.getLocalizedMessage("notification.requestrejected.subject"),
585                                        intres.getLocalizedMessage("notification.requestrejected.msg"),
586                                        adl.getId(), adl.getApprovalDataVO().getRemainingApprovals(), adl.getApprovalDataVO().getRequestDate(),
587                                        adl.getApprovalDataVO().getApprovalRequest(),
588                                        approval);
589             }
590             getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_INFO_APPROVALREJECTED,"Approval request with id : " +approvalId +" have been rejected.");
591         } catch (ApprovalRequestExpiredException e) {
592             getLogSession().log(admin,adl.getCaid(),LogEntry.MODULE_APPROVAL,new Date JavaDoc(),null,null,LogEntry.EVENT_ERROR_APPROVALREJECTED,"Approval request with id : " +approvalId +" have expired.");
593             throw e;
594         }
595         log.debug("<reject");
596     }
597
598
599     /**
600      * Help method for approve and reject.
601      */

602     private ApprovalDataLocal isAuthorizedBeforeApproveOrReject(Admin admin, int approvalId, Approval approval) throws ApprovalException, AuthorizationDeniedException{
603         ApprovalDataLocal retval = null;
604         
605         retval = findNonExpiredApprovalDataLocal(admin,approvalId);
606         
607         if(retval != null){
608             if(retval.getEndentityprofileid() == ApprovalDataVO.ANY_ENDENTITYPROFILE){
609                 getAuthorizationSession().isAuthorized(admin,AvailableAccessRules.REGULAR_APPROVECAACTION);
610             }else{
611                 getAuthorizationSession().isAuthorized(admin,AvailableAccessRules.REGULAR_APPROVEENDENTITY);
612                 getAuthorizationSession().isAuthorized(admin,AvailableAccessRules.ENDENTITYPROFILEPREFIX + retval.getEndentityprofileid() + AvailableAccessRules.APPROVAL_RIGHTS);
613             }
614             if(retval.getCaid() != ApprovalDataVO.ANY_CA){
615                 getAuthorizationSession().isAuthorized(admin,AvailableAccessRules.CAPREFIX + retval.getCaid());
616             }
617
618
619         } else {
620             throw new ApprovalException("Suitable approval with id : " + approvalId + " doesn't exist");
621         }
622         return retval;
623     }
624     
625     /**
626      * Method that goes through exists approvals in database to see if there
627      * exists any approved action.
628      *
629      * If goes through all approvalrequests with the given Id and checks
630      * their status, if any have status approved it returns true.
631      *
632      * This method should be used by action requiring the requesting administrator
633      * to poll to see if it have been approved.
634      *
635      * @param admin
636      * @param approvalId
637      * @return the number of approvals left, 0 if approved othervis is the ApprovalDataVO.STATUS constants returned indicating the statys.
638      * @throws ApprovalException if approvalId doesn't exists
639      * @throws ApprovalRequestExpiredException Throws this exception one time if one of the approvals have expired, once notified it wount throw it anymore.
640      *
641      * @ejb.interface-method view-type="both"
642      */

643     public int isApproved(Admin admin, int approvalId) throws ApprovalException, ApprovalRequestExpiredException{
644         log.debug(">isApproved, approvalId" + approvalId);
645         int retval = ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED;
646         
647         try {
648             Collection JavaDoc result = approvalHome.findByApprovalId(approvalId);
649             Iterator JavaDoc iter = result.iterator();
650             while(iter.hasNext()){
651                 ApprovalDataLocal adl = (ApprovalDataLocal) iter.next();
652                 retval = adl.isApproved();
653                 if(adl.getStatus() == ApprovalDataVO.STATUS_WAITINGFORAPPROVAL ||
654                    adl.getStatus() == ApprovalDataVO.STATUS_APPROVED ||
655                    adl.getStatus() == ApprovalDataVO.STATUS_REJECTED ){
656                     break;
657                 }
658             }
659             
660         } catch (FinderException JavaDoc e) {
661             throw new ApprovalException("Approval request with id : " + approvalId + " doesn't exists");
662         }
663         
664         log.debug("<isApproved, result" + retval);
665         return retval;
666     }
667     
668     /**
669      * Method returning an approval requests with status 'waiting', 'Approved' or 'Reject'
670      * returns null if no non expirted have exists
671      * @ejb.transaction type="Supports"
672      * @ejb.interface-method view-type="both"
673      */

674     public ApprovalDataVO findNonExpiredApprovalRequest(Admin admin, int approvalId){
675         ApprovalDataVO retval = null;
676         ApprovalDataLocal data = findNonExpiredApprovalDataLocal(admin,approvalId);
677
678         if(data != null){
679             retval = data.getApprovalDataVO();
680         }
681         
682         return retval;
683     }
684     
685     private ApprovalDataLocal findNonExpiredApprovalDataLocal(Admin admin, int approvalId){
686         ApprovalDataLocal retval = null;
687         try {
688             Collection JavaDoc result = approvalHome.findByApprovalIdNonExpired(approvalId);
689             Iterator JavaDoc iter = result.iterator();
690             while(iter.hasNext()){
691                 ApprovalDataLocal next = (ApprovalDataLocal) iter.next();
692                 ApprovalDataVO data = next.getApprovalDataVO();
693                 if(data.getStatus() == ApprovalDataVO.STATUS_WAITINGFORAPPROVAL ||
694                    data.getStatus() == ApprovalDataVO.STATUS_APPROVED ||
695                    data.getStatus() == ApprovalDataVO.STATUS_REJECTED){
696                     retval = next;
697                 }
698                 
699             }
700         } catch (FinderException JavaDoc e) {}
701         
702         return retval;
703     }
704     
705     /**
706      * Method that takes an approvalId and returns all aprovalrequests for
707      * this.
708      *
709      * @param admin
710      * @param approvalId
711      * @return and collection of ApprovalDataVO, empty if no approvals exists.
712      *
713      * @ejb.transaction type="Supports"
714      * @ejb.interface-method view-type="both"
715      */

716     public Collection JavaDoc findApprovalDataVO(Admin admin, int approvalId){
717         log.debug(">findApprovalDataVO");
718         ArrayList JavaDoc retval = new ArrayList JavaDoc();
719         
720         try {
721             Collection JavaDoc result = approvalHome.findByApprovalId(approvalId);
722             Iterator JavaDoc iter = result.iterator();
723             while(iter.hasNext()){
724                 ApprovalDataLocal adl = (ApprovalDataLocal) iter.next();
725                 retval.add(adl.getApprovalDataVO());
726             }
727         } catch (FinderException JavaDoc e) {
728         }
729         
730         log.debug("<findApprovalDataVO");
731         return retval;
732     }
733     
734
735     /**
736      * Method returning a list of approvals from the give query
737      *
738      * @param admin
739      * @param query should be a Query object containing ApprovalMatch and TimeMatch
740      * @param index where the resultset should start.
741      * objects only
742      * @return a List of ApprovalDataVO, never null
743      * @throws AuthorizationDeniedException
744      *
745      * @ejb.transaction type="Supports"
746      * @ejb.interface-method view-type="both"
747      */

748     
749     public List JavaDoc query(Admin admin, Query query, int index, int numberofrows) throws IllegalQueryException, AuthorizationDeniedException {
750         debug(">query(): ");
751         
752         boolean authorizedToApproveCAActions = false; // i.e approvals with endentityprofile ApprovalDataVO.ANY_ENDENTITYPROFILE
753
boolean authorizedToApproveRAActions = false; // i.e approvals with endentityprofile not ApprovalDataVO.ANY_ENDENTITYPROFILE
754

755         try {
756             authorizedToApproveCAActions = getAuthorizationSession().isAuthorizedNoLog(admin, AvailableAccessRules.REGULAR_APPROVECAACTION);
757         } catch (AuthorizationDeniedException e1) {}
758         try {
759             authorizedToApproveRAActions = getAuthorizationSession().isAuthorizedNoLog(admin, AvailableAccessRules.REGULAR_APPROVEENDENTITY);
760         } catch (AuthorizationDeniedException e1) {
761         }
762
763         if(!authorizedToApproveCAActions && !authorizedToApproveRAActions){
764             throw new AuthorizationDeniedException("Not authorized to query apporvals");
765         }
766         
767         ArrayList JavaDoc returnData = new ArrayList JavaDoc();
768         GlobalConfiguration globalconfiguration = getRAAdminSession().loadGlobalConfiguration(admin);
769         RAAuthorization raauthorization = null;
770         String JavaDoc sqlquery = "select " + APPROVALDATA_COL + " from ApprovalData where ";
771
772
773         // Check if query is legal.
774
if (query != null && !query.isLegalQuery())
775             throw new IllegalQueryException();
776
777         if (query != null)
778             sqlquery = sqlquery + query.getQueryString();
779
780         raauthorization = new RAAuthorization(admin, getRAAdminSession(), getAuthorizationSession());
781         String JavaDoc caauthstring = raauthorization.getCAAuthorizationString();
782         String JavaDoc endentityauth = "";
783         if (globalconfiguration.getEnableEndEntityProfileLimitations()){
784             endentityauth = raauthorization.getEndEntityProfileAuthorizationString(true);
785             if(authorizedToApproveCAActions && authorizedToApproveRAActions){
786                 endentityauth = raauthorization.getEndEntityProfileAuthorizationString(true);
787                 if(endentityauth != null){
788                   endentityauth = "(" + raauthorization.getEndEntityProfileAuthorizationString(false) + " OR endEntityprofileId=" + ApprovalDataVO.ANY_ENDENTITYPROFILE + " ) ";
789                 }
790             }else if (authorizedToApproveCAActions) {
791                 endentityauth = " endEntityprofileId=" + ApprovalDataVO.ANY_ENDENTITYPROFILE;
792             }else if (authorizedToApproveRAActions) {
793                 endentityauth = raauthorization.getEndEntityProfileAuthorizationString(true);
794             }
795             
796         }
797
798
799         if (!caauthstring.trim().equals("") && query != null){
800           sqlquery = sqlquery + " AND " + caauthstring;
801         }else{
802           sqlquery = sqlquery + caauthstring;
803         }
804
805         if (StringUtils.isNotEmpty(endentityauth)) {
806           if (caauthstring.trim().equals("") && query == null){
807             sqlquery = sqlquery + endentityauth;
808           }else{
809             sqlquery = sqlquery + " AND " + endentityauth;
810           }
811         }
812
813         
814         Connection JavaDoc con = null;
815         PreparedStatement JavaDoc ps = null;
816         ResultSet JavaDoc rs = null;
817         try {
818                 // Construct SQL query.
819
con = JDBCUtil.getDBConnection(JNDINames.DATASOURCE);
820                 log.debug(sqlquery);
821
822                 ps = con.prepareStatement(sqlquery);
823                 
824                 // Execute query.
825
rs = ps.executeQuery();
826                 int direction = rs.getFetchDirection();
827                 if (direction == ResultSet.FETCH_FORWARD) {
828                     // Special handling for databases that do not support backward moving in the RS, i.e. Hsql
829
if (index < 0) {
830                         throw new Exception JavaDoc("Database does only support forward fetching, but index is "+index);
831                     }
832                     for (int i = 0; i < index; i++) {
833                         rs.next();
834                     }
835                 } else {
836                     // Oracles JDBC driver in Weblogic 9.x does not support ResultSet.relative,
837
// that is why we have to move around manually.
838
boolean forward = true;
839                     if (index < 0) {
840                         forward = false;
841                     }
842                     for (int i = 0; i < index; i++) {
843                         if (forward) {
844                             rs.next();
845                         } else {
846                             rs.previous();
847                         }
848                     }
849                 }
850                 // Assemble result.
851
while (rs.next() && returnData.size() < numberofrows) {
852                     
853                     // Read the variables in order, some databases (i.e. MS-SQL)
854
// seems to not like out-of-order read of columns (i.e. nr 15 before nr 1)
855
int id = rs.getInt(1);
856                     int approvalid = rs.getInt(2);
857                     int approvaltype = rs.getInt(3);
858                     int endentityprofileId = rs.getInt(4);
859                     int caid = rs.getInt(5);
860                     String JavaDoc reqadmincertissuerdn = rs.getString(6);
861                     String JavaDoc reqadmincertserial = rs.getString(7);
862                     int status = rs.getInt(8);
863                     String JavaDoc approvaldatastring = rs.getString(9);
864                     String JavaDoc requestdatastring = rs.getString(10);
865                     long requestdate = rs.getLong(11);
866                     long expiredate = rs.getLong(12);
867                     int remainingapprovals = rs.getInt(13);
868                     ApprovalDataVO data = new ApprovalDataVO(id,approvalid,approvaltype,endentityprofileId,caid,
869                                                              reqadmincertissuerdn, reqadmincertserial, status,
870                                                              ApprovalDataUtil.getApprovals(approvaldatastring),
871                                                              ApprovalDataUtil.getApprovalRequest(requestdatastring),
872                                                              new Date JavaDoc(requestdate), new Date JavaDoc(expiredate), remainingapprovals);
873
874                     returnData.add(data);
875                 }
876             
877             
878             debug("<query()");
879             return returnData;
880
881         } catch (Exception JavaDoc e) {
882             throw new EJBException JavaDoc(e);
883         } finally {
884             JDBCUtil.close(con, ps, rs);
885         }
886
887     } // query
888

889     
890     private void sendApprovalNotification(Admin admin, GlobalConfiguration gc, String JavaDoc notificationSubject, String JavaDoc notificationMsg, Integer JavaDoc id, int numberOfApprovalsLeft, Date JavaDoc requestDate, ApprovalRequest approvalRequest, Approval approval) {
891         debug(">sendNotification approval notification: id="+id);
892         try {
893             String JavaDoc requestAdminEmail = null;
894             String JavaDoc approvalAdminsEmail = null;
895             String JavaDoc fromAddress = null;
896             // Find the email address of the requesting administrator.
897
X509Certificate JavaDoc requestAdminCert = approvalRequest.getRequestAdminCert();
898             String JavaDoc requestAdminDN = null;
899             String JavaDoc requestAdminUsername = null;
900             if(requestAdminCert != null){
901               requestAdminDN = CertTools.getSubjectDN(requestAdminCert);
902               requestAdminUsername = getCertificateStoreSession().findUsernameByCertSerno(admin,requestAdminCert.getSerialNumber(),CertTools.getIssuerDN(requestAdminCert));
903               UserDataVO requestAdminData = getUserAdminSession().findUser(admin, requestAdminUsername);
904               if (requestAdminData == null || requestAdminData.getEmail() == null || requestAdminData.getEmail().equals("")) {
905                 getLogSession().log(admin, approvalRequest.getCAId(), LogEntry.MODULE_APPROVAL, new java.util.Date JavaDoc(),requestAdminUsername, null, LogEntry.EVENT_ERROR_NOTIFICATION, "Error sending notification to administrator requesting approval. Set a correct email to the administrator");
906               }else{
907                 requestAdminEmail = requestAdminData.getEmail();
908               }
909             }else{
910                 requestAdminUsername = intres.getLocalizedMessage("CLITOOL");
911                 requestAdminDN = "CN=" + requestAdminUsername;
912             }
913  
914             
915             // Find the email address of the approving administrators
916
approvalAdminsEmail = gc.getApprovalAdminEmailAddress();
917             // Find the email address that should be used in the from field
918
fromAddress = gc.getApprovalNotificationFromAddress();
919             
920             if(approvalAdminsEmail.equals("") || fromAddress.equals("")){
921                 getLogSession().log(admin, approvalRequest.getCAId(), LogEntry.MODULE_APPROVAL, new java.util.Date JavaDoc(),requestAdminUsername, null, LogEntry.EVENT_ERROR_NOTIFICATION, "Error sending approval notification. The email-addresses, either to approval administrators or from-address isn't configured properly");
922             }else{
923               String JavaDoc approvalURL = gc.getBaseUrl() + "adminweb/approval/approveaction.jsf?uniqueId=" + id;
924               String JavaDoc approvalTypeText = intres.getLocalizedMessage(ApprovalDataVO.APPROVALTYPENAMES[approvalRequest.getApprovalType()]);
925                 
926               String JavaDoc approvalAdminUsername = null;
927               String JavaDoc approvalAdminDN = null;
928               String JavaDoc approveComment = null;
929               if(approval != null){
930                   approvalAdminUsername = approval.getUsername();
931                   X509Certificate JavaDoc approvalCert = (X509Certificate JavaDoc) getCertificateStoreSession().findCertificateByIssuerAndSerno(admin, approval.getAdminCertIssuerDN(), approval.getAdminCertSerialNumber());
932                   approvalAdminDN = CertTools.getSubjectDN(approvalCert);
933                   approveComment = approval.getComment();
934               }
935               String JavaDoc mailJndi = getLocator().getString("java:comp/env/MailJNDIName");
936               Session JavaDoc mailSession = getLocator().getMailSession(mailJndi);
937               Integer JavaDoc numAppr = new Integer JavaDoc(numberOfApprovalsLeft);
938               NotificationParamGen paramGen = new NotificationParamGen(requestDate,id,approvalTypeText,numAppr,
939                                                                        approvalURL, approveComment, requestAdminUsername,
940                                                                        requestAdminDN,approvalAdminUsername,approvalAdminDN);
941               HashMap JavaDoc params = paramGen.getParams();
942
943               Message JavaDoc msg = new TemplateMimeMessage(params, mailSession);
944               msg.setFrom(new InternetAddress JavaDoc(fromAddress));
945               msg.addRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(approvalAdminsEmail, false));
946               if(requestAdminEmail != null){
947                   msg.addRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(requestAdminEmail, false));
948               }
949               msg.setSubject(notificationSubject);
950               msg.setContent(notificationMsg, "text/plain");
951               msg.setHeader("X-Mailer", "JavaMailer");
952               msg.setSentDate(new Date JavaDoc());
953               Transport.send(msg);
954
955               getLogSession().log(admin, approvalRequest.getCAId(), LogEntry.MODULE_APPROVAL, new java.util.Date JavaDoc(), requestAdminUsername, null, LogEntry.EVENT_INFO_NOTIFICATION, "Approval notification with id " + id + " was sent successfully.");
956             }
957         } catch (Exception JavaDoc e) {
958             error("Error when sending notification approving notification", e);
959             try{
960                 getLogSession().log(admin, approvalRequest.getCAId(), LogEntry.MODULE_APPROVAL, new java.util.Date JavaDoc(),null, null, LogEntry.EVENT_ERROR_NOTIFICATION, "Error sending approval notification with id " + id + ".");
961             }catch(Exception JavaDoc f){
962                 throw new EJBException JavaDoc(f);
963             }
964         }
965         debug("<sendNotification approval notification: id="+id);
966         
967     }
968  
969     
970     private Integer JavaDoc findFreeApprovalId() {
971         Random JavaDoc ran = (new Random JavaDoc((new Date JavaDoc()).getTime()));
972         int id = ran.nextInt();
973         boolean foundfree = false;
974
975         while (!foundfree) {
976             try {
977                 if (id > 1)
978                    approvalHome.findByPrimaryKey(new Integer JavaDoc(id));
979                 id = ran.nextInt();
980             } catch (FinderException JavaDoc e) {
981                 foundfree = true;
982             }
983         }
984         return new Integer JavaDoc(id);
985     } // findFreeApprovalId
986

987
988 } // LocalApprovalSessionBean
989
Popular Tags