[ALF-21647] CMIS update does not work via share proxy Created: 06-Jun-16  Updated: 22-Jun-16  Resolved: 22-Jun-16

Status: Closed
Project: Alfresco
Component/s: Web Scripts and Surf
Affects Version/s: Community Edition 201604 GA
Fix Version/s: Community Edition 201605 GA
Security Level: external (External user)

Type: Bug Priority: Critical
Reporter: Ian Wright Assignee: Closed Issues
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to by REPO-537 Investigate CMIS Post/Share proxy issue Closed
Date of First Response:
Resolution Time Custom Field: 2 weeks, 1 day, 19 hours, 25 minutes, 38 seconds

 Description   

Doing a CMIS update via the share proxy does not work.
I suspect that the POST parameters are not being correctly passed through.

e.g.
In the following example the first curl command does not work whereas the second one does (or you can just modify the URL and see it work/not work)
(Auth is for admin/admin - tested against an unmodified SDK build)

DOCID=fe5828a8-9503-47ec-8f8f-2b33c1c0c995
curl 'http://localhost:8080/share/proxy/alfresco-api/default/public/cmis/versions/1.1/browser/root' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8' -H 'Authorization: Basic YWRtaW46YWRtaW4=' --data "cmisaction=update&objectId=${DOCID}%3B1.0&propertyId%5B0%5D=cmis%3Adescription&propertyValue%5B0%5D=&propertyId%5B1%5D=cmis%3Aname&propertyValue%5B1%5D=File1&propertyId%5B2%5D=cm%3Atitle&propertyValue%5B2%5D=file1+title&propertyId%5B3%5D=cm%3Adescription&propertyValue%5B3%5D=description1"

curl 'http://localhost:8080/alfresco/api/default/public/cmis/versions/1.1/browser/root' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8' -H 'Authorization: Basic YWRtaW46YWRtaW4=' --data "cmisaction=update&objectId=${DOCID}%3B1.0&propertyId%5B0%5D=cmis%3Adescription&propertyValue%5B0%5D=&propertyId%5B1%5D=cmis%3Aname&propertyValue%5B1%5D=File1&propertyId%5B2%5D=cm%3Atitle&propertyValue%5B2%5D=file1+title&propertyId%5B3%5D=cm%3Adescription&propertyValue%5B3%5D=description2"



 Comments   
Comment by Steven Glover [X] (Inactive) [ 06-Jun-16 ]

Why are you using it through the Share proxy? Why not just use the CMIS alfresco URI directly?

Comment by Ian Wright [ 06-Jun-16 ]

I'm using it through the share proxy primarily so that the request is authenticated but also I don't currently expose the alfresco endpoint to the world.

You'll note that I'm using the browser binding so that all the CMIS requests can be handled in javascript in the browser so I'm using CMIS directly rather than via a toolkit.

It makes life significantly more complicated if authentication needs to be handled for both the share and alfresco endpoints.
(It's also more complicated by no longer being able to request a ticket which you could prior to 5.0.d (I think, but certainly possible in 4.2))

I do have SSO enabled which means that it is possible, although it means configuring the alfresco endpoint for SSO, which is not otherwise necessary, and, perhaps more significantly, exposing the alfresco end-point to the world.

It also seems less than helpful to expose a partially working endpoint via the proxy - I spent some time trying to work out why the POST to the proxy was not working before trying the alfresco endpoint to see what happened. In my view if it's available then the proxy endpoint should work completely, or at very least, return a helpful message to say that POST is not supported.

Although this bug is logged as CMIS it seems very likely that it's not in the CMIS section of the code but in the proxy code.

Comment by Gavin Cornwell [ 07-Jun-16 ]

The share proxy is meant to be used via Surf/Share so there might be some context not being passed when you're trying the request via curl. Is the same request failing when executed via the browser? Are you calling the CMIS APIs as part of a Share extension/customisation?

I will try and find some time to test this myself, in the meantime it would be useful know whether you get any sort of error or does it silently fail?

Comment by Ian Wright [ 07-Jun-16 ]

I am using it as part of a Share extension but I thought it easier to see by using curl - I extracted the curl command by using Firebug in Firefox and removed some of the headers to make it easier to read.
The extension is on github and I'm in the middle of writing a blog post about it so I could make it available if that helps.

What I see is an exception thrown from the CMIS code saying that there is no value set for cmisaction - see below - with a 405 error code

I couldn't see any POST parameters being set when using a debugger

{"exception":"notSupported","message":"Unknown action","stacktrace":"org.apache.chemistry.opencmis.commons .exceptions.CmisNotSupportedException: Unknown action\n\tat org.apache.chemistry.opencmis.server.impl .browser.CmisBrowserBindingServlet.dispatch(CmisBrowserBindingServlet.java:349)\n\tat org.apache.chemistry .opencmis.server.impl.browser.CmisBrowserBindingServlet.service(CmisBrowserBindingServlet.java:234)\n \tat javax.servlet.http.HttpServlet.service(HttpServlet.java:728)\n\tat org.alfresco.opencmis.CMISServletDispatcher .execute(CMISServletDispatcher.java:188)\n\tat org.alfresco.opencmis.CMISWebScript.execute(CMISWebScript .java:51)\n\tat org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecute(RepositoryContainer .java:437)\n\tat org.alfresco.rest.api.PublicApiRepositoryContainer.transactionedExecute(PublicApiRepositoryContainer .java:45)\n\tat org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecuteAs(RepositoryContainer .java:619)\n\tat org.alfresco.repo.web.scripts.RepositoryContainer.executeScriptInternal(RepositoryContainer .java:399)\n\tat org.alfresco.repo.web.scripts.RepositoryContainer.executeScript(RepositoryContainer .java:280)\n\tat org.alfresco.rest.api.PublicApiRepositoryContainer.access$001(PublicApiRepositoryContainer .java:26)\n\tat org.alfresco.rest.api.PublicApiRepositoryContainer$1.doWork(PublicApiRepositoryContainer .java:81)\n\tat org.alfresco.repo.tenant.TenantUtil.runAsWork(TenantUtil.java:119)\n\tat org.alfresco .repo.tenant.TenantUtil.runAsTenant(TenantUtil.java:88)\n\tat org.alfresco.rest.api.PublicApiRepositoryContainer .executeScript(PublicApiRepositoryContainer.java:77)\n\tat org.springframework.extensions.webscripts .AbstractRuntime.executeScript(AbstractRuntime.java:378)\n\tat org.springframework.extensions.webscripts .AbstractRuntime.executeScript(AbstractRuntime.java:209)\n\tat org.alfresco.repo.web.scripts.TenantWebScriptServlet .service(TenantWebScriptServlet.java:74)\n\tat org.alfresco.rest.api.PublicApiWebScriptServlet.service (PublicApiWebScriptServlet.java:53)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:728 )\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java :305)\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210 )\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)\n\tat org.apache.catalina .core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)\n\tat org.apache.catalina .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)\n\tat org.alfresco.repo.web.filter .beans.NullFilter.doFilter(NullFilter.java:68)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n\tat sun .reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.lang.reflect .Method.invoke(Method.java:498)\n\tat org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1 .invoke(ChainingSubsystemProxyFactory.java:125)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation .proceed(ReflectiveMethodInvocation.java:172)\n\tat org.springframework.aop.framework.JdkDynamicAopProxy .invoke(JdkDynamicAopProxy.java:204)\n\tat com.sun.proxy.$Proxy284.doFilter(Unknown Source)\n\tat org .alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)\n\tat org.apache.catalina .core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)\n\tat org.apache.catalina .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)\n\tat org.alfresco.web.app.servlet .GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:61)\n\tat org.apache.catalina.core.ApplicationFilterChain .internalDoFilter(ApplicationFilterChain.java:243)\n\tat org.apache.catalina.core.ApplicationFilterChain .doFilter(ApplicationFilterChain.java:210)\n\tat org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:222)\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve .java:123)\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502 )\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)\n\tat org.apache .catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)\n\tat org.apache.catalina.valves .AccessLogValve.invoke(AccessLogValve.java:953)\n\tat org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:118)\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter .java:408)\n\tat org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java :1041)\n\tat org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java :603)\n\tat org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)\n\tat java .util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)\n\tat java.util.concurrent .ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)\n\tat java.lang.Thread.run(Thread.java:745 )\n"}
Comment by Gavin Cornwell [ 07-Jun-16 ]

Thanks, that's very useful information, any links you can provide to code/blog posts would be useful too.

POST requests definitely work for other Alfresco repository webscripts via the proxy so this one theoretically should too, having said that Share doesn't call any CMIS endpoints so there may well be some issues lurking we're not aware of.

Comment by Ian Wright [ 07-Jun-16 ]

OK - it's a bit of a work in progress but I've published the post and it should give you enough to work from without having to do too much - quick instructions below.

https://github.com/wrighting/dojoCMIS - build the jar and install it to your share

Get the file First from https://github.com/wrighting/dojoCMIS/tree/master/aikau-example and edit the path to a directory somewhere in your repository (you can use a CMIS query but path is easier)
Upload it to Data Dictionary/Share Resources/Pages and change the type to surf:amdpage and the mimetype to application/json

Then go to /share/page/hrp/p/First

The editable fields auto-save when you change them so you should be able to see the problem.

In more detail at http://tech.wrighting.org/2016/06/aikau-and-cmis/

Comment by Gavin Cornwell [ 08-Jun-16 ]

I've reproduced the problem using your project (I did have to disable the CSRF filter, is that expected?), I'll investigate the cause as time permits.

Comment by Ian Wright [ 09-Jun-16 ]

It's not expected to have to disable the CSRF filter - I haven't had to.

I assume that the targetRoot value in your Aikau definition matches your page URL i.e. http://localhost:8080/share/page/hrp/p/First and http://localhost:8080/share/proxy/alfresco-api/...
(I also assume that you noticed it won't work in Chrome - I've filed another bug about that)

Having said that I was expecting the CSRF filter to kick in when using the example HTML page file:///###your path###/dojoCMIS/example/index.html and it doesn't. (which is convenient but probably not correct) - it's been in the back of my mind to investigate but something of a low priority for me so I probably won't have time.

I've been using the latest SDK with version 5.1.f and have also tried the latest community edition from the installer 5.1.g/5.1.f

It would be useful if I could replicate your CSRF problems as my goal, time permitting, is to get this project to a point where I can release it publicly.

When writing this my expectation was that I would need to use the Aikau CoreXhr.serviceXhr call instead of the dojo equivalents when using Aikau (the library is designed to be used either with or without Aikau) so that the CSRF token could be added to the call, however since I discovered that it worked using the raw dojo calls I haven't allowed for CoreXhr.serviceXhr (yet? - it is a work in progress after all...)

Comment by Kevin Roast [X] (Inactive) [ 13-Jun-16 ]

I would suggest this is assigned to Web Apps team for working on in the next webscripts library update which can be made available for next Community drop.

Comment by Gavin Cornwell [ 13-Jun-16 ]

Ian Wright I do have the targetRoot value set correctly but I am running Share on port 8081, not 8080. Kevin Roast [X] has helped track this issue down, it lies within the webscripts component so I have updated the issue appropriately.

Comment by Ian Wright [ 13-Jun-16 ]

@gcornwell Thanks - I assume that means repo running on 8080 and share on 8081 which would probably explain it

Comment by Kevin Roast [X] (Inactive) [ 13-Jun-16 ]

Hi Ian Wright - I have located the issue, it is indeed a bug in the handling of application/x-www-form-urlencoded POST requests - we don't use them in Share at all so it wasn't noticed. The Share proxy isn't a full web-proxy it is only really engineered for our use-cases for the remote apps we support. However this is certainly a valid use-case so the bug will be fixed to handle it.

Comment by Kevin Roast [X] (Inactive) [ 13-Jun-16 ]

I have fixed the issue and ensured that this use-case works through the Share proxy. I will push this to make it into the next Community release.

Thanks again for raising the issue and reporting with all the information we needed, it is very helpful in getting the issue resolved quickly.

Comment by Kevin Roast [X] (Inactive) [ 22-Jun-16 ]

http://alf-community-nightly.s3-website-eu-west-1.amazonaws.com/

Comment by Kevin Roast [X] (Inactive) [ 22-Jun-16 ]

The next official community release expected by the end of this month will contain this fix, it is also present in the nightly build as above.

Generated at Sat Jan 19 23:14:34 GMT 2019 using JIRA 7.6.3#76005-sha1:8a4e38d34af948780dbf52044e7aafb13a7cae58.