Sending Post request to Gerrit REST API from javascript

651 views
Skip to first unread message

Patrick Bard

unread,
Mar 7, 2017, 11:22:23 AM3/7/17
to Repo and Gerrit Discussion
Hi guys,

I'm working ok an Chrome Extension to improve Gerrit Experience. For that I'm using Gerrit REST API with restful.js.
For all normal requests that method work pretty fine.

But I could not perform a POST request, to submit a review for example.

Please, consider this code:

    api = restful(options.gerritUrl).prefixUrl(options.prefix);
    var obj = {"labels":{"Code-Review":2},"strict_labels":true,"drafts":"PUBLISH_ALL_REVISIONS"};
    api.all("a/changes/{id}/revisions/{revision}/review/").post(obj)
       .then(function(response){
            console.log(response)
        })
       .catch(function (error) {
            console.log(error)
        })

I always get an 403 error saying "Invalid authentication method. In order to authenticate, prefix the REST endpoint URL with /a/ (e.g. http://example.com/a/projects/)."

But as you can see I'm already using "a/changes" as required.

Debugging a real request made by an user interaction I can see a "X-Gerrit-Auth" property on header. But I could not find any specification on how to find it or how to use it on a request

Saša Živkov

unread,
Mar 7, 2017, 11:26:28 AM3/7/17
to Patrick Bard, Repo and Gerrit Discussion
On Tue, Mar 7, 2017 at 5:19 PM, Patrick Bard <patrickt...@gmail.com> wrote:
Hi guys,

I'm working ok an Chrome Extension to improve Gerrit Experience. For that I'm using Gerrit REST API with restful.js.
For all normal requests that method work pretty fine.

What are the "normal" requests?
I guess it worked for all requests where anonymous access was allowed.
 

But I could not perform a POST request, to submit a review for example.

Please, consider this code:

    api = restful(options.gerritUrl).prefixUrl(options.prefix);
    var obj = {"labels":{"Code-Review":2},"strict_labels":true,"drafts":"PUBLISH_ALL_REVISIONS"};
    api.all("a/changes/{id}/revisions/{revision}/review/").post(obj)
       .then(function(response){
            console.log(response)
        })
       .catch(function (error) {
            console.log(error)
        })

I always get an 403 error saying "Invalid authentication method. In order to authenticate, prefix the REST endpoint URL with /a/ (e.g. http://example.com/a/projects/)."

But as you can see I'm already using "a/changes" as required.

There are two ways to authenticate a REST API call. Either use the /a/ prefix and perform the http basic/digest authentication (whatever is configured
for the Gerrit server) or, like the Gerrit UI does, include both the GerritAccount cookie and the X-Gerrit-Auth header in the request.

Debugging a real request made by an user interaction I can see a "X-Gerrit-Auth" property on header. But I could not find any specification on how to find it or how to use it on a request

AFAIK, the value of the X-Gerrit-Auth header is only available in the client JS code.
I don't know if chrome extensions can read it.

 

--
--
To unsubscribe, email repo-discuss+unsubscribe@googlegroups.com
More info at http://groups.google.com/group/repo-discuss?hl=en

---
You received this message because you are subscribed to the Google Groups "Repo and Gerrit Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to repo-discuss+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Patrick Bard

unread,
Mar 7, 2017, 11:46:10 AM3/7/17
to Repo and Gerrit Discussion, patrickt...@gmail.com
What are the "normal" requests?
I guess it worked for all requests where anonymous access was allowed.

Sorry, you are right. I've meant requests allowed to be made anonymously.
 
There are two ways to authenticate a REST API call. Either use the /a/ prefix and perform the http basic/digest authentication (whatever is configured
for the Gerrit server) or, like the Gerrit UI does, include both the GerritAccount cookie and the X-Gerrit-Auth header in the request.

Yes, but I'm doing that



 
AFAIK, the value of the X-Gerrit-Auth header is only available in the client JS code.
I don't know if chrome extensions can read it.

I searched about the Javascript API and could find a way to get that.
Do you know how to get X-Gerrit-Auth on client?
 

Saša Živkov

unread,
Mar 7, 2017, 11:48:27 AM3/7/17
to Patrick Bard, Repo and Gerrit Discussion
On Tue, Mar 7, 2017 at 5:40 PM, Patrick Bard <patrickt...@gmail.com> wrote:
What are the "normal" requests?
I guess it worked for all requests where anonymous access was allowed.

Sorry, you are right. I've meant requests allowed to be made anonymously.
 
There are two ways to authenticate a REST API call. Either use the /a/ prefix and perform the http basic/digest authentication (whatever is configured
for the Gerrit server) or, like the Gerrit UI does, include both the GerritAccount cookie and the X-Gerrit-Auth header in the request.

Yes, but I'm doing that


you are including the /a/ but where is the Authorization header? 



 
AFAIK, the value of the X-Gerrit-Auth header is only available in the client JS code.
I don't know if chrome extensions can read it.

I searched about the Javascript API and could find a way to get that.
Do you know how to get X-Gerrit-Auth on client?
 

--

Saša Živkov

unread,
Mar 7, 2017, 11:50:49 AM3/7/17
to Patrick Bard, Repo and Gerrit Discussion
I am not an expert in this area but I believe that this is not possible.
UI/JS experts please correct me if I am wrong.
The X-Gerrit-Auth value is intended to stay as hidden as possible because it is a protection against XSRF.

Patrick Bard

unread,
Mar 7, 2017, 12:01:16 PM3/7/17
to Repo and Gerrit Discussion, patrickt...@gmail.com
you are including the /a/ but where is the Authorization header?

I know that when doing a post via cURL to use HTTP username and password or --digest, as I've read on the API and here.

But I don't know what I have to set on the header as I don't know to replicate the digest option, and I don't have the X-Gerrit-Auth.
Sorry, I'm kinda new to it. I might not have understood it all.

Patrick Bard

unread,
Mar 7, 2017, 12:01:19 PM3/7/17
to Repo and Gerrit Discussion, patrickt...@gmail.com
I am not an expert in this area but I believe that this is not possible.
UI/JS experts please correct me if I am wrong.
The X-Gerrit-Auth value is intended to stay as hidden as possible because it is a protection against XSRF.

I see, I also think that hiding it is the right way to do it. But I don't know, that's was one of my available options to try in theory

Patrick Bard

unread,
Mar 7, 2017, 3:54:16 PM3/7/17
to Repo and Gerrit Discussion, patrickt...@gmail.com
I think I am close now. I could manage to hava a succesful POST request setting the Authorization header exactly as cURL does.

    var headers = {
        "Authorization": 'Digest username="<username>", realm="Gerrit Code Review", nonce="<NONCE>", uri="/gerrit/a/changes/<id>/revisions/<revision>/review", cnonce="<CNONCE>", nc=00000001, qop=auth, response="<RESPONSE>"'
    };
    var one = api.all("a/changes/<id>/revisions/<revision>/review/");

The only problem is that I don't know from where some of the parameters are comming from, can you help me with that?

What is NONCE, CNONCE and RESPONSE? Also, what is nc, it does look relative to something else but I noticed it's required.

Matthias Sohn

unread,
Mar 7, 2017, 4:35:19 PM3/7/17
to Patrick Bard, Repo and Gerrit Discussion
see digest authentication in https://tools.ietf.org/html/rfc2617#page-20 
Reply all
Reply to author
Forward
0 new messages