This was actually an interesting problem to solve. Atlassian don’t seem to want anyone returning all of the users in an Jira instance through the API. There’s supposedly a method for doing this, but it doesn’t work if you’re running the script through a Connect app like ScriptRunner. This is another method that only works with an external script, as was the case with managing Cloud Confluence Space permissions.
Instead what we do is run an empty query through the user search. However, this presents its own set of challenges, as the body is only returned in a raw format. That is, instead of returning JSON, the HTTP request is returned as a byte stream.
So after running the query, we turn it into text and then use the JSON Slurper to turn it into a JSON object with which we can work.
Despite the strangeness of the raw response, pagination, startAt, and maxResults still work, and are necessary to get all of the results. Additionally, there is no flag in the HTTP response that pertains to the last page of results, such as “lastPage”. Therefor we must determine the final page of results ourselves.
The script starts by asserting that the lastPage flag is false. That is, the main script loop will run until this is no longer true. It also asserts that page is 0; we’ll increment this to get every subsequent set of results. By default, only 50 results are returned. The main program loop is then initiated.
Next, an HTTP GET request is made with an empty user search query. This will give us a bytestream containing all of the users.
That bytestream is then read into a string, which in turn is JSONified, so that we may work with its elements.
For each resulting user in the JSON blob, we simply note the result in the logs. Any action could be taken at this point, using the user’s account ID.
We’re incrementing by 200 results each time. Therefor if the results returned contained less than 200 users, it must be the last page of results, and we can end the loop by setting the lastPage flag to true. If it’s not the last page, we increment the page results by 200 and loop again.
import groovy.json.JsonSlurper
def page = 0
def lastPage = false
while (lastPage == false) {
//run this loop until we detect the last page of results
def x = 0
//Every time the loop runs, set x to 0. We use x to count the number of users returned in this batch of results
def getUsers = get("/rest/api/2/user/search?query=&maxResults=200&startAt=" + page)
.header('Content-Type', 'application/json')
.asJson()
//Get the current batch of users as an HTTP GET request
def content = getUsers.properties.rawBody
//Get the body contents of the HTTP response
InputStream inputStream = new ByteArrayInputStream(content.getBytes());
String text = new String(inputStream.readAllBytes());
def parser = new JsonSlurper()
def json = parser.parseText(text)
//Convert the resulting bytestream first to a string, and then to JSON So we can work with it
json.each{userAccount ->
//For each result in the JSON
logger.warn(userAccount.accountId.toString())
//write the user account ID to the log
}
logger.warn("Current batch of users contained: " + json.size().toString())
if (json.size() < 200) {
lastPage = true
logger.warn("Setting lastPage to true")
//If the number of users in the current batch is less than 200, we must have reached the end and we can kill the loop
}else{
page += 200
//Otherwise, increase pagination by 200 and keep going
}
}
Leave a Reply