SonarQube How to login with the Web API

2020-04-22 05:03发布

问题:

I'm writing a web application that can display code smell result from the Sonarqube, but I also want it can create custom rules sometimes. Currently, I'm able to get the data from the server using HTTPClient in Java or XMLHttpRequest in Js. However, I'm really stuck on POST message to the server.

In Js, I've tried these code to log in: (the CORS has been disabled in my chrome)

request.open("POST", "http://localhost:9000/api/authentication/login?login=admin&password=admin", true);
request.send();

The response status code is 200 which is successful. However, when I try to perform some action that needs permission

request.open("POST", "http://localhost:9000/api/qualityprofiles/copy?fromKey=" + fromKey + "&toName=" + name, true);
request.send();

The result is 401, unauthorized.

After some research, I've changed my code to

var base64encodedData = ("admin:admin").toString('base64');
request.open("POST", "http://localhost:9000/api/qualityprofiles/copy?fromKey=" + fromKey + "&toName=" + name, true);
request.setRequestHeader("Authorization", "Basic " + base64encodedData);
request.send();

The response is 405, no method found.

After further research, someone mentioned the request.withCredentials should set to true. I added in, then I got CORS problem again. (with the CORS disabled)

(I'm bit confused about the Sonarqube API. The reason I'm saying this is, in my opinion, the purpose of this API is to simplify the method to play with the Sonarqube server externally. However, since it does not allow CORS, does that mean I cannot use the API on my own web page?)

Since there is no luck in Js, I switched to Java.

In Java, I ran this: (I've done login as well)

HttpPost post = new HttpPost("http://localhost:9000/api/qualityprofiles/copy?fromKey=AV7dToVK_BWPTtE1c9vU&toName=testtt");
try(CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse response = httpClient.execute(post);) {

        System.out.println(response.getStatusLine());
}

I got:

HTTP/1.1 401 

Then I change my code follow this link about Basic Authentication with the API

CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials
     = new UsernamePasswordCredentials("admin", "admin");
provider.setCredentials(AuthScope.ANY, credentials);

HttpClient client = HttpClientBuilder.create()
      .setDefaultCredentialsProvider(provider)
      .build();

HttpResponse response = client.execute(
      new HttpPost("http://localhost:9000/api/qualityprofiles/copy?fromKey=AV7dToVK_BWPTtE1c9vU&toName=testtt"));
int statusCode = response.getStatusLine().getStatusCode();
System.out.println(statusCode);

Again, 401

In summary, my question is: How can I use Java code or Js code (preferred) to POST messages to the SonarQube server with authorization?

Appriciate for any help!

UPDATE

I'm now trying with curl, here is what I run in terminal

curl -X POST -u deb3dd4152c571bcdb7b965e1d99b23a4e5c9505: http://localhost:9000/api/qualityprofiles/copy?fromKey=AV7dToVK_BWPTtE1c9vU&toName=test_file

And I got this response, which I don't know how

{"errors":[{"msg":"The 'toName' parameter is missing"}]}

Second Update on CURL

I ran:

curl -X POST -F "fromKey=AV7dToVK_BWPTtE1c9vU;toName=test_file" -v -u deb3dd4152c571bcdb7b965e1d99b23a4e5c9505: http://localhost:9000/api/qualityprofiles/copy

Result:

*   Trying ::1...
* Connected to localhost (::1) port 9000 (#0)
* Server auth using Basic with user 'deb3dd4152c571bcdb7b965e1d99b23a4e5c9505'
> POST /api/qualityprofiles/copy HTTP/1.1
> Host: localhost:9000
> Authorization: Basic ZGViM2RkNDE1MmM1NzFiY2RiN2I5NjVlMWQ5OWIyM2E0ZTVjOTUwNTo=
> User-Agent: curl/7.49.1
> Accept: */*
> Content-Length: 179
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------c22bb5dd76f44ac4
> 
< HTTP/1.1 100 
< HTTP/1.1 400 
< Content-Type: application/json
< Content-Length: 56
< Date: Wed, 04 Oct 2017 00:43:47 GMT
< Connection: close
< 
* Closing connection 0
{"errors":[{"msg":"The 'toName' parameter is missing"}]}

回答1:

For anyone who got the same issue. I've got it working on Java code, Here is my code

HttpPost post = new HttpPost("http://localhost:9000/api/qualityprofiles/copy?fromKey=AV7dToVK_BWPTtE1c9vU&toName=testtt");
post.setHeader("Authorization", "Basic ZGViM2RkNDE1MmM1NzFiY2RiN2I5NjVlMWQ5OWIyM2E0ZTVjOTUwNTo="); 
try(CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = httpClient.execute(post);) {

    System.out.println(response.getStatusLine());
}

You may notice I've added a line which sets the header. I've done something similar before to encode my login and password to this base64 format, but they all not working somehow. This working encoded string was taking from the CURL method. (from my second update)

I've tried some online base64 encoding and decoding tool, but the result doesn't match what I got from the CURL method, So if you are struggling on this, run CURL to get your encoded header and pass it in! If anyone could explain a better version, that would be great!

Also, I'm still interested in get the Js version working. If you know the answer, please share!