TempAttachmentsProvider and Attachments Panel

I’ve create a new portlet view containing an attachments panel which is bound to a TempAttachmentsProvider instance (Managed Bean).

The portlet is working fine as long as I’m logged in while using it (works with both simple MyWebMethods User account and sysadmin).

While trying to upload an attachment as Guest user (not logged in), I always get the following error displayed:

[POP.003.0025] {0} cannot view the content of {1}
com.webMethods.portal.mech.access.PortalAccessException: [POP.003.0025] {0} cannot view the content of {1}.
at com.webMethods.portal.mech.access.impl.AccessMechanics.checkAccess(AccessMechanics.java:251)
at com.webMethods.portal.bizPolicy.command.impl.CommandManager.checkAccess(CommandManager.java:212)
at com.webMethods.portal.bizPolicy.command.impl.CommandManager.getCommand(CommandManager.java:87)
at com.webMethods.portal.bizPolicy.command.impl.CommandManager.getCommand(CommandManager.java:65)
at com.webMethods.portal.bizPolicy.biz.impl.BizPolicy.getCommand(BizPolicy.java:44)
at com.webMethods.portal.bizPolicy.biz.meta.impl.ContainerPolicy.createUniqueName(ContainerPolicy.java:248)
at com.webMethods.caf.faces.data.attachments.TempAttachmentsProvider.createTempFolder(TempAttachmentsProvider.java:131)
at com.webMethods.caf.faces.data.attachments.TempAttachmentsProvider.addAttachment(TempAttachmentsProvider.java:117)
at com.webMethods.caf.faces.component.attachments.view.AttachmentsPage.addAttachmentsButton_action(AttachmentsPage.java:322)
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:585)
at com.sun.faces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:126)
at com.webMethods.caf.faces.application.CAFMethodBinding.invoke(CAFMethodBinding.java:67)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:72)
at javax.faces.component.UICommand.broadcast(UICommand.java:312)
at com.webMethods.caf.faces.component.ViewRoot.broadcastEvents(ViewRoot.java:202)
at com.webMethods.caf.faces.component.ViewRoot.processApplication(ViewRoot.java:116)
at com.webMethods.caf.faces.portlet.PortletLifecycle$InvokeApplicationPhase.execute(PortletLifecycle.java:670)
at com.webMethods.caf.faces.portlet.PortletLifecycle.phase(PortletLifecycle.java:250)
at com.webMethods.caf.faces.portlet.PortletLifecycle.execute(PortletLifecycle.java:145)
at com.webMethods.caf.faces.portlet.FacesPortlet.processAction(FacesPortlet.java:326)
at com.webMethods.portal.framework.portletcontainer.impl.PortletApplicationHandler.process(PortletApplicationHandler.java:477)
at com.webMethods.portal.framework.portletcontainer.servlet.PortletServlet.service(PortletServlet.java:58)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:428)
at org.mortbay.jetty.servlet.WebApplicationHandler.dispatch(WebApplicationHandler.java:473)
at org.mortbay.jetty.servlet.Dispatcher.dispatch(Dispatcher.java:286)
at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:171)
at com.webMethods.portal.framework.portletcontainer.PortletContainer.dispatch(PortletContainer.java:218)
at com.webMethods.portal.framework.portletcontainer.PortletContainer.process(PortletContainer.java:129)
at com.webMethods.portal.framework.portletcontainer.PortletContainer.processPortletAction(PortletContainer.java:107)
at com.webMethods.portal.framework.portlet.beans.rest.RestfulPCAHandler.handle(RestfulPCAHandler.java:182)
at com.webMethods.portal.framework.dispatch.DispatchManager.handle(DispatchManager.java:438)
at com.webMethods.portal.framework.dispatch.DispatchManager.handleDispatch(DispatchManager.java:371)
at com.webMethods.portal.framework.impl.PortalServlet.service(PortalServlet.java:242)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:428)
at org.mortbay.jetty.servlet.WebApplicationHandler$CachedChain.doFilter(WebApplicationHandler.java:830)
at com.webMethods.portal.framework.impl.NTLMFilter.doFilter(NTLMFilter.java:50)
at org.mortbay.jetty.servlet.WebApplicationHandler$CachedChain.doFilter(WebApplicationHandler.java:821)
at com.webMethods.caf.faces.servlet.GZIPFilter.doFilter(GZIPFilter.java:32)
at org.mortbay.jetty.servlet.WebApplicationHandler$CachedChain.doFilter(WebApplicationHandler.java:821)
at com.webMethods.caf.faces.servlet.XSSFilter.doFilter(XSSFilter.java:22)
at org.mortbay.jetty.servlet.WebApplicationHandler$CachedChain.doFilter(WebApplicationHandler.java:821)
at org.mortbay.jetty.servlet.WebApplicationHandler.dispatch(WebApplicationHandler.java:471)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:568)
at org.mortbay.http.HttpContext.handle(HttpContext.java:1530)
at org.mortbay.jetty.servlet.WebApplicationContext.handle(WebApplicationContext.java:633)
at org.mortbay.http.HttpContext.handle(HttpContext.java:1482)
at com.webMethods.portal.webApplication.WmWebAppContext.handle(WmWebAppContext.java:161)
at org.mortbay.http.HttpServer.service(HttpServer.java:909)
at org.mortbay.http.HttpConnection.service(HttpConnection.java:820)
at org.mortbay.http.HttpConnection.handleNext(HttpConnection.java:986)
at org.mortbay.http.HttpConnection.handle(HttpConnection.java:837)
at org.mortbay.http.SocketListener.handleConnection(SocketListener.java:245)
at org.mortbay.util.ThreadedServer.handle(ThreadedServer.java:357)
at org.mortbay.util.ThreadPool$PoolThread.run(ThreadPool.java:534)

Can you please give me a hint? Does the Guest User don’t have enough privileges to upload a file?

I generally wouldn’t recommend allowing the guest user to upload files, since that leaves your server vulerable to abuse.

But if you really need to, the TempAttachmentProvider implementation stores the temporary files in a folder under the current user’s personal folders. The user personal folders are not created until the user logs in the first time. So you would either have to manually login once as the Guest user to get that guest personal folders created, or you could use a different attachment provider that stores the attachments in a location that the guest user has permissions to write to.

Thanks for the prompt answer.

I still get the same error even after logging-in as Guest.
It seems that the TempAttachmentsProvider is not uploading the attachments under /temp/Guest but under a temporary folder (eg. /temp/R3__jsfwmp9968_defaultForm_attachmentsPanel_uploadFile1). This also occurs while uploading files as SysAdmin.

We must allow the Guest user to upload files as we want to create a portal where user can post their problems (with pictures as attachements) without having to register or log-in.

Do you have an example or a link to a sample for using another AttachmentProvider?

I have a couple of questions:

  1. What version of MWS are you running?

  2. Are you using TempAttachmentsProvider, JcrTempAttachmentsProvider, or something custom?

  3. Is the /temp/R3__jsfwmp9968_defaultForm_attachmentsPanel_uploadFile1 path you are referencing the temp file on the OS filesystem? If so, that is different that what I was referring to which were folders in the MWS database.

After you manually login as the guest user then you should be able to open http://[your_hostname_here]:8585/user.current.root to verify that the user’s root folder was created. The temporary attachments would be temporarily stored in a subfolder of that folder.

  1. I’m running MWS 7.1.3 with fix 4 installed and using designer 7.2

  2. I’ve used the TempAttachmentsProvider (drag and drop from the palete to the binding view of the portlet).

  3. Yes, it is the temp folder which is automaticaly created for each upload by the provider on the filesystem.

  4. After a log-in as Guest, I was able to call the user.current.root.

Shall I include the portlet app as zip, so that you can have a look at it?

Hi Frederic,

I found a 7.1.3 environment to test this on and what I see is this error:

[POP.003.0025] guest cannot view the content of createuniquename.

So it looks like the portal command that calculates a new name for the temp folder can’t be called by the anonymous user.

It might be possible to reconfigure the permissions to grant the guest user permissions to call that portal command, but it is not simple to explain and makes maintainance more difficult.

My recommendation would be to use a custom implementation of the attachment provider that stores the files in a temp folder on the MWS server filesystem instead of storing the files in the MWS database. I can send you a sample that demonstrates that technique if that would help you.

Regards,
Eric

I’ve attached the java code for a custom implementation of the IAttachmentProvider interface that stores the attachments only in the MWS filesystem, so you don’t have to deal with the MWS permissions model.

You can add that java class to your project and replace the usages of TempAttachmentProvider with this one.
LocalTempAttachmentProvider.java (12.2 KB)

Hello Eric,
thank for the code snipet. It’s working fine :smiley:

Just one last question:
Is the finalize method of the custom provider called automatically whith the session end / garbage collection? Or do I still have to explicitely clean the temporary uploaded files and temp-folder?

Hi Frederic,

Yes, the finalize would get called when the object is garbage collected. So the temp files should be automatically deleted so manual cleanup is not required.

Regards,
Eric

Hi Eric,

I have one issue with the CustomProvider which I cannot entirely explain. Almost each Time I try to use the “Delete” command Button of the corresponding Attachments Panel, the removeAttachment() method of the provider is called but the attachment is not deleted. Doing this no exception is thrown but the delete() Method from the File obejct returns false. I suppose that there are still handler open on the file (maybe from the file upload or from the addAttachment() method) that prevent the file from beeing deleted.

Do you know any solution for this issue?

PS: I’ve kept the code of the Custom Provider in its original form (the one you’ve uploaded), so the issue should not be only reproducible in my environment.

Thanks and regards,
Frederic

Hi Frederic,

I was able to reproduce that on 7.1.3 as well, but I don’t recall seeing it when I was testing on 8.2.

What seems to be happening is that the file.delete() API call is returning false which means the JVM couldn’t delete the file because some object is still referencing it or something.

I tried a few things to try to get the JVM to release the file locks but the problem still happened sometimes. If you wait long enough for JVM garbage collector to run, it seems to unlock the file. But waiting isn’t a good solution either.

I’ve attached an updated version of the provider that implements a workaround by detecting when this happens and just moves the good attachments to another temp folder and abandons the bad temp folder.

Hopefully that will work for your use case.

Regards,
Eric
LocalTempAttachmentProvider.java (14.9 KB)

Hi Eric,

thanks a lot for the testing and the workaround :D.

Regards
Frederic

Hello All, I’m migrating from 8.2 to 9.8 and tempAttachmentsProvider is deprecated in 9.8.
So, I replaced it for localTempAttachmentsProvider in my class. The problem is when I click the button the file is saved in the temp folder but didn’t list in the portlet. On 8.2 works fine, I don’t know whats happening…

Thanks in advance for your help!
Regards!
localAttachment .txt (20.2 KB)