AnsweredAssumed Answered

Problems with permissions after using a dialog

Question asked by suikak on Nov 22, 2010
Latest reply on Nov 30, 2010 by suikak
Hi everyone, i'm new to Alfresco, i created and tested an action, and now i'm trying to add a confirmation dialog to it


….

public class AprobacionSettingsBean extends AbstractTransactionJob{
   
   transient protected PermissionService permissionService;   
   protected BrowseBean browseBean;
   protected NodeService nodeService;
   protected String id, tipo, dialogMsgId;
   protected ActionEvent event;
   protected NodeRef nodeRef;
   protected boolean actionable;
   
   public NodeService getNodeService() {
      return nodeService;
   }

   public void setNodeService(NodeService nodeService) {
      this.nodeService = nodeService;
   }   
     
   public void setPermissionService(PermissionService permissionService)
   {
      this.permissionService = permissionService;
   }
     
   protected PermissionService getPermissionService()
   {
      if (permissionService == null)
      {
         permissionService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPermissionService();
      }
      return permissionService;
   }
  
   public BrowseBean getBrowseBean() {
      return browseBean;
   }
   
   public void setBrowseBean(BrowseBean browseBean) {
      this.browseBean = browseBean;
   }
   
   protected void setId(String id){
      this.id = id;
   }   
   protected void setTipo(String tipo){
      this.tipo = tipo;
   }   
   protected void setEvent(ActionEvent event){
      this.event = event;
   }
   
   public void setDialogMsgId(String dialogMsgId){
      this.dialogMsgId = dialogMsgId;
   }
   
   protected void setDialogMsgId(){      
      String dialogMsgId = MSG_DIALOG_SOLIC_REV;
                ……
      setDialogMsgId(dialogMsgId);      
   }
   
   public String getDialogMsgId(){
      return dialogMsgId;
   }
   
   public NodeRef getNodeRef(){
      return nodeRef;
   }
   
   public void setNodeRef(){
      try{
         nodeRef = new NodeRef(Repository.getStoreRef(), id);
      } catch (InvalidNodeRefException refErr) {
         Utils.addErrorMessage(MessageFormat.format(Application
               .getMessage(FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF),
               new Object[] { id }));
      }      
   }
   
   public Object getBean(String beanName) {
   
      FacesContext facesContext = FacesContext.getCurrentInstance();
   
      return facesContext.getApplication().createValueBinding(
            "#{" + beanName + "}").getValue(facesContext);   
   }
   
   public AprobacionSettingsBean() {
   }
   
   public void manage(ActionEvent event) {
   
      UIActionLink link = (UIActionLink) event.getComponent();
      Map<String, String> params = link.getParameterMap();
      actionable = false;
      setId(params.get(PARAM_ID));
      setTipo(params.get(PARAM_TIPO));      
      setEvent(event);
      setNodeRef();      
      setDialogMsgId();

     [b]       FacesContext fc = FacesContext.getCurrentInstance();
      fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:confirmAprobacion");
[/b]
//      doAction();

   }
   
   public void doAction(){
      actionable = true;      
      try{
         execute();
      }
      catch(Throwable err){
         //TODO mensaje de error
         System.out.println(err.getMessage());
      }   
   }   
   
   @Override
   protected void doExecute() throws Exception {
      
      if(!actionable)
         return;
      if (tipo != null
            && (tipo.equals(PARAM_TIPO_SOLICITAR_REVISION) ||
                  tipo.equals(PARAM_TIPO_SOLICITAR_APROBACION_DIRECTA) ||
                  tipo.equals(PARAM_TIPO_APROBACION_DIRECTA) ||
                  tipo.equals(PARAM_TIPO_SOLICITAR_APROBACION) ||
                  tipo.equals(PARAM_TIPO_RECHAZAR_REVISION) ||
                  tipo.equals(PARAM_TIPO_APROBACION) ||
                  tipo.equals(PARAM_TIPO_RECHAZAR_APROBACION) ||
                  tipo.equals(PARAM_TIPO_RETIRAR_APROBADO))) {   
   
         
      
         FacesContext fc = FacesContext.getCurrentInstance();
                 
         UserTransaction tx = null;   
         UserTransaction tx2 = null;                         
         try{
                  
            tx = Repository.getUserTransaction(fc);
            tx.begin();

            ActionImpl action = null;
            ActionExecuterAbstractBase actionexecuter = null;
            String msg = null;
            // Publicacion
            if (tipo.equals(PARAM_TIPO_SOLICITAR_REVISION)) {
               action = new ActionImpl(nodeRef, SolicitarRevisionAction.NAME, null);
               actionexecuter = (SolicitarRevisionAction) FacesContextUtils
                     .getRequiredWebApplicationContext(fc).getBean(
                           SolicitarRevisionAction.NAME);
               msg = Application.getMessage(fc, MSG_SUCCESS_SOLICITUD);

               ((SolicitarRevisionAction) actionexecuter).executeImpl(action, nodeRef);
            }            
         
      
            FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
            String formId = Utils.getParentForm(fc,   event.getComponent()).getClientId(fc);
         
            tx.commit();
            fc.addMessage(formId + ':' + PANEL_ID_SPACE_PROPS, facesMsg);            
                  
         } catch (Throwable err) {
            Utils.addErrorMessage(ClusterErrorHandler.getErrorMsg(err), err);
            try {
               if (tx != null)
                  tx.rollback();                  
            } catch (Exception tex) {
            }
         }

         //Eliminamos los permisos dados al usuario actual
         try{
            // Acceso al bean ownableService
             ApplicationContext ctx = AppContext.getApplicationContext();              
             OwnableService ownableService = (OwnableService) ctx.getBean("ownableService");             
            
             if(!ConstantsCluster.USER_ADMIN.equals(ownableService.getOwner(nodeRef))){
               tx2 = Repository.getUserTransaction(fc);
               tx2.begin();
            
               ownableService.setOwner(nodeRef, ConstantsCluster.USER_ADMIN);
               
               tx2.commit();
             }
         }
         catch(Throwable err2){
            Utils.addErrorMessage(MessageFormat.format(Application
                  .getMessage(fc, Repository.ERROR_GENERIC), err2.getMessage()), err2);                  
            try {
               if (tx2 != null)
                  tx2.rollback();                  
            } catch (Exception tex2) {
            }                  
         }   
      
         this.browseBean.getDocument().reset();
         
         //necesito el nodo del espacio para recargarlo                           
         ChildAssociationRef childAssociationRef = this.nodeService.getPrimaryParent(nodeRef);
         NodeRef spaceNodeRef = childAssociationRef.getParentRef();            
         this.browseBean.clickSpace(spaceNodeRef);
      
      }
   }
}

This action change some metadata, permissions and ownership on a nodeRef, and i needed to create and extend AbstractTransactionJob to get rid of authentication problems

public abstract class AbstractTransactionJob { 

      private TransactionService transactionService;
      public void execute() { 
       
        
          AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>() {
              public Object doWork() {
                  executeWithinTransaction();
                  return null;
              }
       
              private void executeWithinTransaction() {
                  getTransactionService().getRetryingTransactionHelper().doInTransaction(
                      new RetryingTransactionCallback<Object>() {
                          public Object execute() throws Exception {
                              try {
                              doExecute();
                              return null;
                          } catch (Throwable t) {
                              throw new Exception();
                          }
                      }
                  });
              }
          }, ConstantsCluster.USER_ADMIN);
      }                
          
     protected abstract void doExecute () throws Exception;
      
     public TransactionService getTransactionService() {
        if(transactionService == null){
         transactionService = (TransactionService)this.getBean("transactionService");         
        }           
         return transactionService;
     }
      
     public void setTransactionService(TransactionService transactionService) {
         this.transactionService = transactionService;
     }
    
     public Object getBean(String beanName) {
   
      FacesContext facesContext = FacesContext.getCurrentInstance();
   
      return facesContext.getApplication().createValueBinding(
            "#{" + beanName + "}").getValue(facesContext);
   
     }        
}

so i execute everything as an admin.
That worked with several user, and after that i tried to add a confirmation message to these actions, and this is what i made

added to my web-client-config-custom

   
                <dialogs>      
                                <dialog name="confirmAprobacion" page="/jsp/extension/dialog/confirm-action.jsp"
            managed-bean="ConfirmAprobacionDialog" icon="/images/icons/check_out_large.gif"
            title-id="confirm_action_info" description-id="confirm_action_description"
            show-ok-button="true" />               
                     
      </dialogs>

create my jsp

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a"%>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r"%>


<%@ page import="org.alfresco.web.app.servlet.BaseServlet"%>
<%@ page import="org.alfresco.web.ui.common.Utils"%>
<%@ page import="org.alfresco.web.app.Application"%>


<%@ page buffer="16kb" contentType="text/html;charset=UTF-8"%>

<h:outputFormat value="#{DialogManager.bean.confirmMessage}" styleClass="mainSubTitle" />

and my DialogBean

public class ConfirmAprobacionDialog extends BaseDialogBean
{

   private static final long serialVersionUID = 1L;
   
   protected AprobacionSettingsBean aprobacionBean;
   public String confirmMessage;   
   
   public void init(Map<String, String> parameters)
   {
      super.init(parameters);
      //Cargamos el bean de la accion a confirmar
      aprobacionBean = (AprobacionSettingsBean) this.getBean("AprobacionSettingsBean");
      //SI la accion se ejecuta desde el espacio, aun no hay document cargado en el BrowseBean
      this.browseBean.setDocument(new Node(aprobacionBean.getNodeRef()));
      //Mensaje final que lee la jsp
      confirmMessage = getConfirmMessage();         
   }
     
   protected String finishImpl(FacesContext context, String outcome) throws Exception
   {
      aprobacionBean.doAction();
      return outcome;
   }

   public boolean getFinishButtonDisabled(){
      return false;
   }
     
   public Object getBean(String beanName) {
      FacesContext facesContext = FacesContext.getCurrentInstance();
      return facesContext.getApplication().createValueBinding(
            "#{" + beanName + "}").getValue(FacesContext.getCurrentInstance());
   }   

   public String getConfirmMessage() {
         Node document = this.browseBean.getDocument();
         String fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), aprobacionBean.getDialogMsgId());        

         return MessageFormat.format(fileConfirmMsg,
               new Object[] {document.getName()});        
      }
   

}

Now it works properly, but only when i'm logged as admin, but if the active user will lose his permissions over the node then i get the following exception, related to versions creation.

org.alfresco.error.AlfrescoRuntimeException: 10220005 Failed to execute transaction-level behaviour public abstract void org.alfresco.repo.node.NodeServicePolicies$OnUpdatePropertiesPolicy.onUpdateProperties(org.alfresco.service.cmr.repository.NodeRef,java.util.Map,java.util.Map) in transaction bf1469b5-958c-48c8-bde4-65899bfc23db
   at org.alfresco.repo.policy.TransactionBehaviourQueue.execute(TransactionBehaviourQueue.java:195)
   at org.alfresco.repo.policy.TransactionBehaviourQueue.beforeCommit(TransactionBehaviourQueue.java:127)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.doBeforeCommit(AlfrescoTransactionSupport.java:738)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.doBeforeCommit(AlfrescoTransactionSupport.java:718)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.beforeCommit(AlfrescoTransactionSupport.java:674)
   at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:927)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:737)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:394)
   at org.alfresco.util.transaction.SpringAwareUserTransaction.commit(SpringAwareUserTransaction.java:472)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:347)
   at org.alfresco.web.bean.dialog.BaseDialogBean.finish(BaseDialogBean.java:124)
   at org.alfresco.web.bean.dialog.DialogManager.finish(DialogManager.java:528)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:132)
   at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:61)
   at javax.faces.component.UICommand.broadcast(UICommand.java:109)
   at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:97)
   at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:171)
   at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
   at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
   at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.web.app.servlet.AuthenticationFilter.doFilter(AuthenticationFilter.java:104)
   at sun.reflect.GeneratedMethodAccessor497.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:116)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy242.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.alfresco.repo.web.filter.beans.NullFilter.doFilter(NullFilter.java:68)
   at sun.reflect.GeneratedMethodAccessor497.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:116)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy242.doFilter(Unknown Source)
   at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
   at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
   at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
   at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1555)
   at java.lang.Thread.run(Thread.java:619)
Caused by: org.alfresco.repo.security.permissions.AccessDeniedException: 10220004 Acceso denegado. No tiene los permisos apropiados para realizar esta operación.
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:47)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditComponentImpl.audit(AuditComponentImpl.java:279)
   at org.alfresco.repo.audit.AuditMethodInterceptor.proceed(AuditMethodInterceptor.java:163)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:140)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:43)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditComponentImpl.audit(AuditComponentImpl.java:279)
   at org.alfresco.repo.audit.AuditMethodInterceptor.proceedWithAudit(AuditMethodInterceptor.java:228)
   at org.alfresco.repo.audit.AuditMethodInterceptor.proceed(AuditMethodInterceptor.java:195)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:140)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy10.setProperty(Unknown Source)
   at org.alfresco.repo.[b]version.Version2ServiceImpl.createVersion[/b](Version2ServiceImpl.java:332)
   at org.alfresco.repo.[b]version.Version2ServiceImpl.createVersion[/b](Version2ServiceImpl.java:139)
   at org.alfresco.repo.[b]version.VersionableAspect.createVersionImpl[/b](VersionableAspect.java:415)
   at org.alfresco.repo.version.VersionableAspect.onUpdateProperties(VersionableAspect.java:395)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.policy.JavaBehaviour$JavaMethodInvocationHandler.invoke(JavaBehaviour.java:173)
   at $Proxy14.onUpdateProperties(Unknown Source)
   at sun.reflect.GeneratedMethodAccessor335.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.policy.TransactionBehaviourQueue.execute(TransactionBehaviourQueue.java:183)
   … 60 more
Caused by: net.sf.acegisecurity.AccessDeniedException: Access is denied.
   at net.sf.acegisecurity.vote.AffirmativeBased.decide(AffirmativeBased.java:86)
   at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:394)
   at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:77)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:43)
   … 92 more

I cant understand why this only happens when i use the dialog, any idea will be appreciated (before my brain explode)

Sorry about my english skills and those codes copy/paste

Outcomes