I'm trying to perform a simple query via the command line using JSON-RPC
Taking what I see being sent in chrome I've tried the following and
several variants:
wget https://gerrit-review.googlesource.com/gerrit/rpc/ChangeListService
--header='Content-Type: application/json'
--post-data='{"jsonrpc":"2.0","method":"allQueryNext","params":["status:open","z",25],"id":1}'
--no-check-certificate
but I keep getting a 400 error.
What else do I need to send/change in order to get this request to work?
Thanks,
~cco3
You are missing header "Accept: application/json". The server refuses
to reply unless the client explicitly accepts application/json.
BTW, curl is better. It understands SNI like other modern browsers and
doesn't need to ignore the SSL certificate check:
$ curl -H 'Content-Type: application/json' -H 'Accept:
application/json' --data
'{"jsonrpc":"2.0","method":"allQueryNext","params":["status:open","z",25],"id":1}'
https://gerrit-review.googlesource.com/gerrit/rpc/ChangeListService
{"jsonrpc":"2.0","id":1,"result":{"accounts":{"accounts":[{"id":1003378},...
I'll probably be back here with questions about json-rpc and
authentication later.
I am guessing that in order to make json-rpc calls that require
authentication, I have to first go through
UserPassAuthService.authentication.
The following gives me "400: Your client has issued a malformed or
illegal request":
curl https://gerrit-review.googlesource.com/gerrit/rpc/UserPassAuthService
-H "Content-Type: application/json" -H "Accept: application/json"
--data '{"jsonrpc": "2.0", "method": "authenticate", "params":
["myuser", "mypassword"]}' -G
I have tried visiting urls that require authentication and entering
the username and password directly. That works fine. (urls like
https://gerrit-review.googlesource.com/p/gerrit)
Does anyone know what's wrong/have suggestions?
It depends on the Gerrit Code Review server as to whether or not this
works. The auth.type has to be set to certain values for this service
to be enabled in the web URL space.
> The following gives me "400: Your client has issued a malformed or
> illegal request":
> curl https://gerrit-review.googlesource.com/gerrit/rpc/UserPassAuthService
> -H "Content-Type: application/json" -H "Accept: application/json"
> --data '{"jsonrpc": "2.0", "method": "authenticate", "params":
> ["myuser", "mypassword"]}' -G
UserPassAuthService is not enabled on
{android,gerrit}-review.googlesource.com. To improve security and user
privacy, we don't accept passwords directly. Passwords for Google
Accounts are only accepted on a secure path of www.google.com, which
issues special cookies for the target URL.
Right now {android,gerrit}-review.googlesource.com can only be
authenticated to by a cookie, or one of the special "HTTP Passwords"
that are generated for you.
> I have tried visiting urls that require authentication and entering
> the username and password directly. That works fine. (urls like
> https://gerrit-review.googlesource.com/p/gerrit)
Authentication for the /p/ subdirectory from a Git client is
different. JSON-RPC request handlers won't accept the same password as
an identifier, even though conceptually both the cookie and the
password identify the user in a secure way. This is currently a
security feature. It means a stolen password only provides access to
upload new changes for review and does not grant access to score +2 or
submit through the web UI (or JSON-RPC). And just for the archives,
lost/stolen passwords can be revoked at
https://www.google.com/accounts/IssuedAuthSubTokens (also reachable
from any Google property top right menu, Account Settings, Authorizing
applications & sites).
I have two answers for you since you are interested in the
{android,gerrit}-review.googlesource.com services.
First, the only current way to authenticate with JSON-RPC is to
emulate a browser and keep track of the cookies. Right now the service
issues three cookies for a signed-in user, "gc", "gi", and "S". You
would need to login in a normal web browser then "borrow" these from
the web browser's cookie store to supply to your JSON-RPC client. When
the cookie expires, you would need to regenerate them and get new
ones. The server may also issue new "gc", "gi" or "S" cookies at any
time, and your client should update itself to use the newly issued
cookies if this happens.
To make matters more difficult, you also need to load "/" while
signed-in with cookies and parse the main HTML page. There is a JSON
block in the HTML which defines a value for xsrfToken. You also need
this value from that page and must embed it in any JSON-RPC request
that includes the "gc", "gi" and "S" cookies. This is a standard
feature of Gerrit and is designed to stop some forms of malicious XSS
attacks.
Second, I know you are a Googler. We should talk about what you are
trying to do here. Clearly Gerrit is not meeting a need, and we may
need to build out additional functionality.
Conley and I met offline. It turns out Conley needs a version of
`gerrit review` available over HTTP. Which we already knew was a
missing feature in Gerrit.
Next week he is going to try to refactor the existing SSH
implementation to a common base class in server, and make a JSON form
of review that is more compatible with a REST notion of calling a
service. This URL would then be able to be password protected, and we
will consider accepting authentication tokens like the Git password as
an HTTP Basic (only over SSL!) credential to access this new JSON
service. This is much cleaner to automate than scraping cookies and
dealing with XSRF tokens in the payload.