Skip to content
Permalink
Browse files

Implement Jira authentication

Reviewed-by: ehelin
  • Loading branch information
Robin Westberg
Robin Westberg committed Nov 5, 2019
1 parent 8c37b49 commit 0e3e711471fcbd91607fecb6047891b87c38da1a
@@ -22,12 +22,13 @@
*/
package org.openjdk.skara.issuetracker.jira;

import org.openjdk.skara.host.*;
import org.openjdk.skara.host.HostUser;
import org.openjdk.skara.issuetracker.*;
import org.openjdk.skara.json.*;
import org.openjdk.skara.network.*;
import org.openjdk.skara.json.JSON;

import java.net.URI;
import java.util.Arrays;

public class JiraHost implements IssueTracker {
private final URI uri;
@@ -42,6 +43,14 @@
request = new RestRequest(baseApi);
}

JiraHost(URI uri, JiraVault jiraVault) {
this.uri = uri;
var baseApi = URIBuilder.base(uri)
.setPath("/rest/api/2/")
.build();
request = new RestRequest(baseApi, () -> Arrays.asList("Cookie", jiraVault.getCookie()));
}

URI getUri() {
return uri;
}
@@ -59,18 +68,44 @@ public IssueProject project(String name) {
return new JiraProject(this, request, name);
}

private JSONObject userData(String name) {
var data = request.get("user")
.param("username", name)
.execute();
return data.asObject();
}

@Override
public HostUser user(String username) {
throw new RuntimeException("needs authentication; not implemented yet");
var data = request.get("user")
.param("username", username)
.execute();
var user = new HostUser(data.get("name").asString(),
data.get("name").asString(),
data.get("displayName").asString());
return user;
}

@Override
public HostUser currentUser() {
throw new RuntimeException("needs authentication; not implemented yet");
var data = request.get("myself").execute();
var user = new HostUser(data.get("name").asString(),
data.get("name").asString(),
data.get("displayName").asString());
return user;
}

@Override
public boolean isMemberOf(String groupId, HostUser user) {
throw new RuntimeException("not implemented yet");
var data = request.get("user")
.param("username", user.id())
.param("expand", "groups")
.execute();
for (var group : data.get("groups").get("items").asArray()) {
if (group.get("name").asString().equals(groupId)) {
return true;
}
}
return false;
}
}
@@ -24,18 +24,22 @@

import org.openjdk.skara.host.*;
import org.openjdk.skara.issuetracker.*;
import org.openjdk.skara.json.*;
import org.openjdk.skara.network.*;
import org.openjdk.skara.json.JSONValue;

import java.net.URI;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

public class JiraIssue implements Issue {
private final JiraProject jiraProject;
private final RestRequest request;
private final JSONValue json;

private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

JiraIssue(JiraProject jiraProject, RestRequest request, JSONValue json) {
this.jiraProject = jiraProject;
this.request = request;
@@ -66,7 +70,10 @@ public String title() {

@Override
public void setTitle(String title) {
throw new RuntimeException("not implemented yet");
var query = JSON.object()
.put("fields", JSON.object()
.put("summary", title));
request.put("").body(query).execute();
}

@Override
@@ -80,52 +87,98 @@ public String body() {

@Override
public void setBody(String body) {
throw new RuntimeException("not implemented yet");
var query = JSON.object()
.put("fields", JSON.object()
.put("description", body));
request.put("").body(query).execute();
}

private Comment parseComment(JSONValue json) {
return new Comment(json.get("id").asString(),
json.get("body").asString(),
new HostUser(json.get("author").get("name").asString(),
json.get("author").get("name").asString(),
json.get("author").get("displayName").asString()),
ZonedDateTime.parse(json.get("created").asString(), dateFormat),
ZonedDateTime.parse(json.get("updated").asString(), dateFormat));
}

@Override
public List<Comment> comments() {
throw new RuntimeException("not implemented yet");
var comments = request.get("/comment")
.param("maxResults", "1000")
.execute();
return comments.get("comments").stream()
.map(this::parseComment)
.collect(Collectors.toList());
}

@Override
public Comment addComment(String body) {
throw new RuntimeException("not implemented yet");
var json = request.post("/comment")
.body("body", body)
.execute();
return parseComment(json);
}

@Override
public Comment updateComment(String id, String body) {
throw new RuntimeException("not implemented yet");
var json = request.put("/comment/" + id)
.body("body", body)
.execute();
return parseComment(json);
}

@Override
public ZonedDateTime createdAt() {
return ZonedDateTime.parse(json.get("fields").get("created").asString());
return ZonedDateTime.parse(json.get("fields").get("created").asString(), dateFormat);
}

@Override
public ZonedDateTime updatedAt() {
return ZonedDateTime.parse(json.get("fields").get("updated").asString());
return ZonedDateTime.parse(json.get("fields").get("updated").asString(), dateFormat);
}

@Override
public void setState(State state) {
throw new RuntimeException("not implemented yet");
var transitions = request.get("/transitions").execute();
var wantedStateName = state == State.CLOSED ? "Closed" : "Open";
for (var transition : transitions.get("transitions").asArray()) {
if (transition.get("to").get("name").asString().equals(wantedStateName)) {
var query = JSON.object()
.put("transition", JSON.object()
.put("id", transition.get("id").asString()));
request.post("/transitions")
.body(query)
.execute();
return;
}
}
}

@Override
public void addLabel(String label) {
throw new RuntimeException("not implemented yet");
var query = JSON.object()
.put("update", JSON.object()
.put("labels", JSON.array().add(JSON.object()
.put("add", label))));
request.put("").body(query).execute();
}

@Override
public void removeLabel(String label) {
throw new RuntimeException("not implemented yet");
var query = JSON.object()
.put("update", JSON.object()
.put("labels", JSON.array().add(JSON.object()
.put("remove", label))));
request.put("").body(query).execute();
}

@Override
public List<String> labels() {
throw new RuntimeException("not implemented yet");
return json.get("fields").get("labels").stream()
.map(JSONValue::asString)
.collect(Collectors.toList());
}

@Override
@@ -137,11 +190,32 @@ public URI webUrl() {

@Override
public List<HostUser> assignees() {
throw new RuntimeException("not implemented yet");
var assignee = json.get("fields").get("assignee");
if (assignee.isNull()) {
return List.of();
}

var user = new HostUser(assignee.get("name").asString(),
assignee.get("name").asString(),
assignee.get("displayName").asString());
return List.of(user);
}

@Override
public void setAssignees(List<HostUser> assignees) {
throw new RuntimeException("not implemented yet");
String assignee;
switch (assignees.size()) {
case 0:
assignee = null;
break;
case 1:
assignee = assignees.get(0).id();
break;
default:
throw new RuntimeException("multiple assignees not supported");
}
request.put("/assignee")
.body("name", assignee)
.execute();
}
}
@@ -25,6 +25,7 @@
import org.openjdk.skara.host.Credential;
import org.openjdk.skara.issuetracker.*;
import org.openjdk.skara.json.JSONObject;
import org.openjdk.skara.network.URIBuilder;

import java.net.URI;

@@ -39,7 +40,13 @@ public IssueTracker create(URI uri, Credential credential, JSONObject configurat
if (credential == null) {
return new JiraHost(uri);
} else {
throw new RuntimeException("authentication not implemented yet");
if (credential.username().startsWith("https://")) {
var vaultUrl = URIBuilder.base(credential.username()).build();
var jiraVault = new JiraVault(vaultUrl, credential.password());
return new JiraHost(uri, jiraVault);
} else {
throw new RuntimeException("basic authentication not implemented yet");
}
}
}
}
@@ -23,7 +23,7 @@
package org.openjdk.skara.issuetracker.jira;

import org.openjdk.skara.issuetracker.*;
import org.openjdk.skara.json.JSON;
import org.openjdk.skara.json.*;
import org.openjdk.skara.network.*;

import java.net.URI;
@@ -34,12 +34,51 @@
private final String projectName;
private final RestRequest request;

private JSONObject projectMetadataCache = null;

JiraProject(JiraHost host, RestRequest request, String projectName) {
this.jiraHost = host;
this.projectName = projectName;
this.request = request;
}

private JSONObject project() {
if (projectMetadataCache == null) {
projectMetadataCache = request.get("project/" + projectName).execute().asObject();
}
return projectMetadataCache;
}

private Map<String, String> issueTypes() {
var ret = new HashMap<String, String>();
for (var type : project().get("issueTypes").asArray()) {
ret.put(type.get("name").asString(), type.get("id").asString());
}
return ret;
}

private Map<String, String> components() {
var ret = new HashMap<String, String>();
for (var type : project().get("components").asArray()) {
ret.put(type.get("name").asString(), type.get("id").asString());
}
return ret;
}

private String projectId() {
return project().get("id").asString();
}

private String defaultIssueType() {
return issueTypes().values().stream()
.min(Comparator.naturalOrder()).orElseThrow();
}

private String defaultComponent() {
return components().values().stream()
.min(Comparator.naturalOrder()).orElseThrow();
}

@Override
public IssueTracker issueTracker() {
return jiraHost;
@@ -52,19 +91,35 @@ public URI webUrl() {

@Override
public Issue createIssue(String title, List<String> body) {
throw new RuntimeException("needs authentication; not implemented yet");
var query = JSON.object()
.put("fields", JSON.object()
.put("project", JSON.object()
.put("id", projectId()))
.put("issuetype", JSON.object()
.put("id", defaultIssueType()))
.put("components", JSON.array()
.add(JSON.object().put("id", defaultComponent())))
.put("summary", title)
.put("description", String.join("\n", body)));

var data = request.post("issue")
.body(query)
.execute();

return issue(data.get("key").asString()).orElseThrow();
}

@Override
public Optional<Issue> issue(String id) {
if (id.indexOf('-') < 0) {
id = projectName.toUpperCase() + "-" + id;
}
var issue = request.get("issue/" + id)
var issueRequest = request.restrict("issue/" + id);
var issue = issueRequest.get("")
.onError(r -> r.statusCode() == 404 ? JSON.object().put("NOT_FOUND", true) : null)
.execute();
if (!issue.contains("NOT_FOUND")) {
return Optional.of(new JiraIssue(this, request, issue));
return Optional.of(new JiraIssue(this, issueRequest, issue));
} else {
return Optional.empty();
}

0 comments on commit 0e3e711

Please sign in to comment.
You can’t perform that action at this time.