SanderRonde / VSCode-Gerrit

Gerrit plugin for VSCode
https://marketplace.visualstudio.com/items?itemName=SanderRonde.vscode--gerrit
MIT License
27 stars 17 forks source link

"Invalid authentication method" on PUT, DELETE requests when GET are working without a problem #76

Closed maciejs closed 3 weeks ago

maciejs commented 1 month ago

Could I ask for help debugging such a strange problem? All the features work until I try to do anything changing the state, such as adding or deleting a comment. The same PUT request made manually with curl does not return an error.

GET request to "https://HOST/a/config/server/version"
GET request to "https://HOST/a/projects/PROJECT/commits/HASH/files/FILE/content"
GET request to "https://HOST/a/changes/"
PUT request to "https://HOST/a/changes/PROJECT~master~ID/revisions/HASH/drafts"
HTTPError: Response code 403 (Forbidden) 403 [object Object] Invalid authentication method. In order to authenticate, prefix the REST endpoint URL with /a/ (e.g. http://example.com/a/projects/).

Invalid response
SanderRonde commented 1 month ago

Maybe a bit of an obvious question but are you sure your authentication settings are configured correctly? Are you also running the PUT request from the same host as where your VSCode is running (I've made this mistake myself before).

maciejs commented 1 month ago

Maybe a bit of an obvious question but are you sure your authentication settings are configured correctly?

I believe so. But how can I be sure of it? The "Gerrit: Check Connection" option returns "Succesfully connected!"

Are you also running the PUT request from the same host as where your VSCode is running (I've made this mistake myself before).

Yes

SanderRonde commented 1 month ago

You're right it's not great that the Check connection command doesn't check authentication. I've made 2 changes that should help a lot:

Both changes are live in the new version (1.2.43). Let me know once you've given it a try, hopefully it'll help you fix your issue.

maciejs commented 1 month ago

Thanks. I've found that GET requests work with only the GerritAccount cookie, but mutation (POST, PUT, DELETE) requests require an additional X-Gerrit-Auth header. Is this supported by VSCode-Gerrit?

I also found a reference: https://gerrit-review.googlesource.com/Documentation/rest-api.html#cors

Auth issue:

$ curl -X PUT --cookie "GerritAccount=COOKIE" https://HOST/a/changes/PROJECT~master~ID/revisions/HASH/drafts
Invalid authentication method. In order to authenticate, prefix the REST endpoint URL with /a/ (e.g. http://example.com/a/projects/).

No auth issue ("path must be non-empty" is expected as no data provided):

$ curl -X PUT --cookie "GerritAccount=COOKIE" -H "x-gerrit-auth: AUTH" https://HOST/a/changes/PROJECT~master~ID/revisions/HASH/drafts
path must be non-empty
SanderRonde commented 1 month ago

Ahh I didn't know that alongside the cookie setting you'd always need an x-gerrit-auth setting. There is the gerrit.extraCookies option, that should work for you. But I wonder if there's a way for me to automatically do this from the extension. Sounds like there isn't, otherwise than maybe a prompt of "enter an XSRF token" during setup...

Can I ask why you're not using plain username+password auth, that circumvents this issue too.

maciejs commented 4 weeks ago

I'm afraid this won't work, as X-Gerrit-Auth is a request header, not a cookie.

As for the use of plain username+password auth, I don't see the HTTP Credentials section in Gerrit's settings, nor the Generate new password option (perhaps blocked by admin?), and storing my main password as open text in the settings doesn't seem like the best idea.

SanderRonde commented 3 weeks ago

Ah of course. And since it's a header that needs to contain a valid XSRF token it's virtually impossible to do that with just a cookie.

But looking at the docs it does look like using an access_token query parameter that contains the cookie does work. So I'll give that a try.

Ah I guess it has indeed been blocked by an admin then. Good point that storing it in plain text does not feel safe, I'll look into the credentials API.

SanderRonde commented 3 weeks ago

I've gotten it to work, turns out I needed the cookie for GET and the access_token queryparam for non-GET. That's why effects with side-effects were the only ones that didn't work.

I've released version 1.2.44, which contains the fix. Using the gerrit.auth.cookie setting will be all you need :)

SanderRonde commented 3 weeks ago

It will now also, as of 1.2.45 store the password and cookie in encrypted storage.

It will fall back to any password or cookie setting so it won't break your existing configuration.