/*******************************************************************************
* Copyright (c) 2011, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.git.jobs;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.eclipse.core.internal.preferences.Base64;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.orion.server.core.IOUtilities;
import org.eclipse.orion.server.core.PreferenceHelper;
import org.eclipse.orion.server.core.ProtocolConstants;
import org.eclipse.orion.server.core.ServerStatus;
import org.eclipse.orion.server.core.tasks.TaskJob;
import org.eclipse.orion.server.git.GitActivator;
import org.eclipse.orion.server.git.GitCredentialsProvider;
import org.eclipse.orion.server.git.IGitHubTokenProvider;
import org.eclipse.orion.server.git.objects.PullRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* A job to perform a clone operation in the background
*/
@SuppressWarnings("restriction")
public class ListPullRequestsJob extends TaskJob {
private HttpClient httpClient;
private static final String CLIENT_KEY = "orion.oauth.github.client";
private static final String CLIENT_SECRET = "orion.oauth.github.secret";
private String url;
private Repository db;
private String remote;
private URI cloneLocation;
private String host;
private String hostUser;
private String project;
private Cookie cookie;
private String username;
private String password;
public ListPullRequestsJob(String userRunningTask, String url, URI cloneLocation, String host, String hostUser, String project, String username, String password, Object cookie) {
super(userRunningTask, true);
this.cloneLocation = cloneLocation;
this.host = host;
this.url = url;
this.hostUser = hostUser;
this.project = project;
this.remote = userRunningTask;
this.username = username;
this.password = password;
this.cookie = (Cookie) cookie;
setFinalMessage("Getting Pull Requests Complete.");
setTaskExpirationTime(TimeUnit.DAYS.toMillis(7));
}
private IStatus doList(IProgressMonitor monitor) throws JSONException, URISyntaxException, HttpException, IOException, CoreException {
//JSONArray result = callGitHubAPI(url);
JSONObject returnRes = new JSONObject();
JSONArray resp= new JSONArray();
String toCall = host+"repos/"+hostUser+"/"+project+"/pulls";
String token=null;
Enumeration<IGitHubTokenProvider> providers = GitCredentialsProvider.GetGitHubTokenProviders();
while (providers.hasMoreElements()) {
token = providers.nextElement().getToken(this.url, remote);
if (token != null) {
break;
}
}
GetMethod m;
HttpClient hc = getHttpClient();
if(token!=null){
toCall += "?access_token="+token;
}else{
String client_secret = PreferenceHelper.getString(CLIENT_SECRET);
String client_key = PreferenceHelper.getString(CLIENT_KEY);
toCall += "?client_id="+client_key+"&client_secret="+client_secret+"";
}
m = new GetMethod(toCall);
if(!this.username.isEmpty()&&!this.password.isEmpty()){
String userCredentials = this.username+":"+this.password;
String basicAuth = "Basic " + new String(Base64.encode(userCredentials.getBytes()));
m.setRequestHeader("Authorization", basicAuth);
}
try {
hc.executeMethod(m);
int statusCode =m.getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
String res = IOUtilities.toString(m.getResponseBodyAsStream());
resp= (res.isEmpty())?new JSONArray():new JSONArray(res);
}else if(statusCode == HttpServletResponse.SC_UNAUTHORIZED || statusCode == HttpServletResponse.SC_NOT_FOUND) {
String msg = "Repository not found, might be a private repository that requires authentication.";
if (statusCode == HttpServletResponse.SC_UNAUTHORIZED) {
msg = "Not authorized to get the repository information.";
}
IStatus result = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_UNAUTHORIZED, msg, new JSONObject(), null);
ServerStatus status = ServerStatus.convert(result);
JSONObject data = status.getJsonData();
data.put("Url", this.url); //$NON-NLS-1$
try {
providers = GitCredentialsProvider.GetGitHubTokenProviders();
while (providers.hasMoreElements()) {
String authUrl = providers.nextElement().getAuthUrl(this.url, cookie);
if (authUrl != null) {
data.put("GitHubAuth", authUrl); //$NON-NLS-1$
return result;
}
}
return result;
} catch (Exception ex) {
/* fail silently, no GitHub auth url will be returned */
}
return result;
}
} finally {
m.releaseConnection();
}
ArrayList<JSONObject> list = new ArrayList<JSONObject>();
if (resp != null) {
int len = resp.length();
for (int i=0;i<len;i++){
list.add(new JSONObject(resp.get(i).toString()));
}
}
JSONArray children = new JSONArray();
for(JSONObject prJson:list){
PullRequest pr = new PullRequest(cloneLocation, db, prJson);
children.put(pr.toJSON());
}
returnRes.put(ProtocolConstants.KEY_CHILDREN, children);
returnRes.put(ProtocolConstants.KEY_TYPE, PullRequest.TYPE);
return new ServerStatus(Status.OK_STATUS, HttpServletResponse.SC_OK, returnRes);
}
private HttpClient getHttpClient() {
if (this.httpClient == null)
this.httpClient = new HttpClient();
return this.httpClient;
}
@Override
protected IStatus performJob(IProgressMonitor monitor) {
IStatus result = Status.OK_STATUS;
try {
result = doList(monitor);
} catch (IOException e) {
result = new Status(IStatus.ERROR, GitActivator.PI_GIT, "Error getting pull requests", e);
} catch (CoreException e) {
result = e.getStatus();
} catch (Exception e) {
result = new Status(IStatus.ERROR, GitActivator.PI_GIT, "Error getting pull requests", e);
}
return result;
}
}