diff options
author | James Moger <james.moger@gitblit.com> | 2011-10-02 15:37:24 -0400 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2011-10-02 15:37:24 -0400 |
commit | 31abc26dd0354bc2dafe27c011c2e54934a89486 (patch) | |
tree | 0bcd3046123eb1a3ccfc095e56a01c80c3e98b19 /src/com/gitblit | |
parent | ca9d0f3cb462e3ff9daa676c9f5e81407fbb79d6 (diff) | |
download | gitblit-31abc26dd0354bc2dafe27c011c2e54934a89486.tar.gz gitblit-31abc26dd0354bc2dafe27c011c2e54934a89486.zip |
Fairly complete json rpc interface to view/control Gitblit data objects.
Diffstat (limited to 'src/com/gitblit')
-rw-r--r-- | src/com/gitblit/Constants.java | 12 | ||||
-rw-r--r-- | src/com/gitblit/FederationPullExecutor.java | 44 | ||||
-rw-r--r-- | src/com/gitblit/GitBlit.java | 27 | ||||
-rw-r--r-- | src/com/gitblit/GitBlitException.java | 30 | ||||
-rw-r--r-- | src/com/gitblit/JsonServlet.java | 31 | ||||
-rw-r--r-- | src/com/gitblit/RpcServlet.java | 75 | ||||
-rw-r--r-- | src/com/gitblit/models/FederationSet.java | 58 | ||||
-rw-r--r-- | src/com/gitblit/utils/FederationUtils.java | 14 | ||||
-rw-r--r-- | src/com/gitblit/utils/JsonUtils.java | 166 | ||||
-rw-r--r-- | src/com/gitblit/utils/RpcUtils.java | 290 |
10 files changed, 649 insertions, 98 deletions
diff --git a/src/com/gitblit/Constants.java b/src/com/gitblit/Constants.java index 3862a9db..5b4b0b6a 100644 --- a/src/com/gitblit/Constants.java +++ b/src/com/gitblit/Constants.java @@ -52,7 +52,7 @@ public class Constants { public static final String SYNDICATION_PATH = "/feed/";
public static final String FEDERATION_PATH = "/federation/";
-
+
public static final String RPC_PATH = "/rpc/";
public static final String BORDER = "***********************************************************";
@@ -202,8 +202,10 @@ public class Constants { */
public static enum RpcRequest {
LIST_REPOSITORIES, CREATE_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY,
- LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER;
-
+ LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER, LIST_REPOSITORY_MEMBERS,
+ SET_REPOSITORY_MEMBERS, LIST_FEDERATION_REGISTRATIONS, LIST_FEDERATION_RESULTS,
+ LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS;
+
public static RpcRequest fromName(String name) {
for (RpcRequest type : values()) {
if (type.name().equalsIgnoreCase(name)) {
@@ -212,11 +214,11 @@ public class Constants { }
return LIST_REPOSITORIES;
}
-
+
public boolean exceeds(RpcRequest type) {
return this.ordinal() > type.ordinal();
}
-
+
@Override
public String toString() {
return name();
diff --git a/src/com/gitblit/FederationPullExecutor.java b/src/com/gitblit/FederationPullExecutor.java index ef089d03..b190e7b5 100644 --- a/src/com/gitblit/FederationPullExecutor.java +++ b/src/com/gitblit/FederationPullExecutor.java @@ -19,6 +19,7 @@ import static org.eclipse.jgit.lib.Constants.DOT_GIT_EXT; import java.io.File;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.net.InetAddress;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -43,6 +44,7 @@ import org.slf4j.LoggerFactory; import com.gitblit.Constants.FederationPullStatus;
import com.gitblit.Constants.FederationStrategy;
+import com.gitblit.GitBlitException.ForbiddenException;
import com.gitblit.models.FederationModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
@@ -81,8 +83,8 @@ public class FederationPullExecutor implements Runnable { *
* @param registrations
* @param isDaemon
- * if true, registrations are rescheduled in perpetuity. if false,
- * the federation pull operation is executed once.
+ * if true, registrations are rescheduled in perpetuity. if
+ * false, the federation pull operation is executed once.
*/
public FederationPullExecutor(List<FederationModel> registrations, boolean isDaemon) {
this.registrations = registrations;
@@ -169,7 +171,7 @@ public class FederationPullExecutor implements Runnable { } else {
repositoryName = registrationFolder + "/" + repository.name;
}
-
+
if (registration.bare) {
// bare repository, ensure .git suffix
if (!repositoryName.toLowerCase().endsWith(DOT_GIT_EXT)) {
@@ -178,7 +180,8 @@ public class FederationPullExecutor implements Runnable { } else {
// normal repository, strip .git suffix
if (repositoryName.toLowerCase().endsWith(DOT_GIT_EXT)) {
- repositoryName = repositoryName.substring(0, repositoryName.indexOf(DOT_GIT_EXT));
+ repositoryName = repositoryName.substring(0,
+ repositoryName.indexOf(DOT_GIT_EXT));
}
}
@@ -190,7 +193,8 @@ public class FederationPullExecutor implements Runnable { StoredConfig config = existingRepository.getConfig();
config.load();
String origin = config.getString("remote", "origin", "url");
- RevCommit commit = JGitUtils.getCommit(existingRepository, "refs/remotes/origin/master");
+ RevCommit commit = JGitUtils.getCommit(existingRepository,
+ "refs/remotes/origin/master");
if (commit != null) {
fetchHead = commit.getName();
}
@@ -209,7 +213,7 @@ public class FederationPullExecutor implements Runnable { Constants.FEDERATION_USER, registration.token);
logger.info(MessageFormat.format("Pulling federated repository {0} from {1} @ {2}",
repository.name, registration.name, registration.url));
-
+
CloneResult result = JGitUtils.cloneRepository(registrationFolderFile, repository.name,
cloneUrl, registration.bare, credentials);
Repository r = GitBlit.self().getRepository(repositoryName);
@@ -255,7 +259,7 @@ public class FederationPullExecutor implements Runnable { // preserve local settings
repository.isFrozen = rm.isFrozen;
repository.federationStrategy = rm.federationStrategy;
-
+
// merge federation sets
Set<String> federationSets = new HashSet<String>();
if (rm.federationSets != null) {
@@ -317,13 +321,12 @@ public class FederationPullExecutor implements Runnable { }
}
}
- } catch (Exception e) {
- // a 403 error code is normal for a PULL_REPOSITORIES token
- if (!e.getMessage().contains("403")) {
- logger.warn(MessageFormat.format(
- "Failed to retrieve USERS from federated gitblit ({0} @ {1})",
- registration.name, registration.url), e);
- }
+ } catch (ForbiddenException e) {
+ // ignore forbidden exceptions
+ } catch (IOException e) {
+ logger.warn(MessageFormat.format(
+ "Failed to retrieve USERS from federated gitblit ({0} @ {1})",
+ registration.name, registration.url), e);
}
try {
@@ -337,13 +340,12 @@ public class FederationPullExecutor implements Runnable { properties.store(os, null);
os.close();
}
- } catch (Exception e) {
- // a 403 error code is normal for a PULL_REPOSITORIES token
- if (!e.getMessage().contains("403")) {
- logger.warn(MessageFormat.format(
- "Failed to retrieve SETTINGS from federated gitblit ({0} @ {1})",
- registration.name, registration.url), e);
- }
+ } catch (ForbiddenException e) {
+ // ignore forbidden exceptions
+ } catch (IOException e) {
+ logger.warn(MessageFormat.format(
+ "Failed to retrieve SETTINGS from federated gitblit ({0} @ {1})",
+ registration.name, registration.url), e);
}
}
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index e86fcf60..73ec29e0 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -59,6 +59,7 @@ import com.gitblit.Constants.FederationStrategy; import com.gitblit.Constants.FederationToken;
import com.gitblit.models.FederationModel;
import com.gitblit.models.FederationProposal;
+import com.gitblit.models.FederationSet;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.FederationUtils;
@@ -874,6 +875,29 @@ public class GitBlit implements ServletContextListener { }
/**
+ * Returns the list of federation sets.
+ *
+ * @return list of federation sets
+ */
+ public List<FederationSet> getFederationSets(String gitblitUrl) {
+ List<FederationSet> list = new ArrayList<FederationSet>();
+ // generate standard tokens
+ for (FederationToken type : FederationToken.values()) {
+ FederationSet fset = new FederationSet(type.toString(), type, getFederationToken(type));
+ fset.repositories = getRepositories(gitblitUrl, fset.token);
+ list.add(fset);
+ }
+ // generate tokens for federation sets
+ for (String set : settings.getStrings(Keys.federation.sets)) {
+ FederationSet fset = new FederationSet(set, FederationToken.REPOSITORIES,
+ getFederationToken(set));
+ fset.repositories = getRepositories(gitblitUrl, fset.token);
+ list.add(fset);
+ }
+ return list;
+ }
+
+ /**
* Returns the list of possible federation tokens for this Gitblit instance.
*
* @return list of federation tokens
@@ -1025,7 +1049,8 @@ public class GitBlit implements ServletContextListener { });
for (File file : files) {
String json = com.gitblit.utils.FileUtils.readContent(file, null);
- FederationProposal proposal = JsonUtils.fromJsonString(json, FederationProposal.class);
+ FederationProposal proposal = JsonUtils.fromJsonString(json,
+ FederationProposal.class);
list.add(proposal);
}
}
diff --git a/src/com/gitblit/GitBlitException.java b/src/com/gitblit/GitBlitException.java index 032e41f7..af32003a 100644 --- a/src/com/gitblit/GitBlitException.java +++ b/src/com/gitblit/GitBlitException.java @@ -15,17 +15,45 @@ */
package com.gitblit;
+import java.io.IOException;
+
/**
* GitBlitException is a marginally useful class. :)
*
* @author James Moger
*
*/
-public class GitBlitException extends Exception {
+public class GitBlitException extends IOException {
private static final long serialVersionUID = 1L;
public GitBlitException(String message) {
super(message);
}
+
+ /**
+ * Exception to indicate that the client should prompt for credentials
+ * because the requested action requires authentication.
+ */
+ public static class UnauthorizedException extends GitBlitException {
+
+ private static final long serialVersionUID = 1L;
+
+ public UnauthorizedException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Exception to indicate that the requested action can not be executed by
+ * the specified user.
+ */
+ public static class ForbiddenException extends GitBlitException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ForbiddenException(String message) {
+ super(message);
+ }
+ }
}
diff --git a/src/com/gitblit/JsonServlet.java b/src/com/gitblit/JsonServlet.java index b1d1053d..ad1d67b6 100644 --- a/src/com/gitblit/JsonServlet.java +++ b/src/com/gitblit/JsonServlet.java @@ -17,6 +17,7 @@ package com.gitblit; import java.io.BufferedReader;
import java.io.IOException;
+import java.lang.reflect.Type;
import java.text.MessageFormat;
import javax.servlet.ServletException;
@@ -27,6 +28,7 @@ import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.gitblit.utils.StringUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -72,6 +74,30 @@ public abstract class JsonServlet extends HttpServlet { protected <X> X deserialize(HttpServletRequest request, HttpServletResponse response,
Class<X> clazz) throws IOException {
+ String json = readJson(request, response);
+ if (StringUtils.isEmpty(json)) {
+ return null;
+ }
+
+ Gson gson = new Gson();
+ X object = gson.fromJson(json.toString(), clazz);
+ return object;
+ }
+
+ protected <X> X deserialize(HttpServletRequest request, HttpServletResponse response, Type type)
+ throws IOException {
+ String json = readJson(request, response);
+ if (StringUtils.isEmpty(json)) {
+ return null;
+ }
+
+ Gson gson = new Gson();
+ X object = gson.fromJson(json.toString(), type);
+ return object;
+ }
+
+ private String readJson(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
BufferedReader reader = request.getReader();
StringBuilder json = new StringBuilder();
String line = null;
@@ -86,10 +112,7 @@ public abstract class JsonServlet extends HttpServlet { response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return null;
}
-
- Gson gson = new Gson();
- X object = gson.fromJson(json.toString(), clazz);
- return object;
+ return json.toString();
}
protected void serialize(HttpServletResponse response, Object o) throws IOException {
diff --git a/src/com/gitblit/RpcServlet.java b/src/com/gitblit/RpcServlet.java index 9d26ee03..4dee3190 100644 --- a/src/com/gitblit/RpcServlet.java +++ b/src/com/gitblit/RpcServlet.java @@ -18,6 +18,7 @@ package com.gitblit; import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -30,6 +31,7 @@ import com.gitblit.Constants.RpcRequest; import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.HttpUtils;
+import com.gitblit.utils.RpcUtils;
/**
* Handles remote procedure calls.
@@ -57,6 +59,7 @@ public class RpcServlet extends JsonServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
RpcRequest reqType = RpcRequest.fromName(request.getParameter("req"));
+ String objectName = request.getParameter("name");
logger.info(MessageFormat.format("Rpc {0} request from {1}", reqType,
request.getRemoteAddr()));
@@ -88,6 +91,78 @@ public class RpcServlet extends JsonServlet { users.add(GitBlit.self().getUserModel(name));
}
result = users;
+ } else if (RpcRequest.CREATE_REPOSITORY.equals(reqType)) {
+ // create repository
+ RepositoryModel model = deserialize(request, response, RepositoryModel.class);
+ GitBlit.self().updateRepositoryModel(model.name, model, true);
+ } else if (RpcRequest.EDIT_REPOSITORY.equals(reqType)) {
+ // edit repository
+ RepositoryModel model = deserialize(request, response, RepositoryModel.class);
+ // name parameter specifies original repository name in event of
+ // rename
+ String repoName = objectName;
+ if (repoName == null) {
+ repoName = model.name;
+ }
+ GitBlit.self().updateRepositoryModel(repoName, model, false);
+ } else if (RpcRequest.DELETE_REPOSITORY.equals(reqType)) {
+ // delete repository
+ RepositoryModel model = deserialize(request, response, RepositoryModel.class);
+ GitBlit.self().deleteRepositoryModel(model);
+ } else if (RpcRequest.CREATE_USER.equals(reqType)) {
+ // create user
+ UserModel model = deserialize(request, response, UserModel.class);
+ GitBlit.self().updateUserModel(model.username, model, true);
+ } else if (RpcRequest.EDIT_USER.equals(reqType)) {
+ // edit user
+ UserModel model = deserialize(request, response, UserModel.class);
+ // name parameter specifies original user name in event of rename
+ String username = objectName;
+ if (username == null) {
+ username = model.username;
+ }
+ GitBlit.self().updateUserModel(username, model, false);
+ } else if (RpcRequest.DELETE_USER.equals(reqType)) {
+ // delete user
+ UserModel model = deserialize(request, response, UserModel.class);
+ GitBlit.self().deleteUser(model.username);
+ } else if (RpcRequest.LIST_REPOSITORY_MEMBERS.equals(reqType)) {
+ // get repository members
+ RepositoryModel model = GitBlit.self().getRepositoryModel(objectName);
+ result = GitBlit.self().getRepositoryUsers(model);
+ } else if (RpcRequest.SET_REPOSITORY_MEMBERS.equals(reqType)) {
+ // update repository access list
+ RepositoryModel model = GitBlit.self().getRepositoryModel(objectName);
+ Collection<String> names = deserialize(request, response, RpcUtils.NAMES_TYPE);
+ List<String> users = new ArrayList<String>(names);
+ if (!GitBlit.self().setRepositoryUsers(model, users)) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ }
+ } else if (RpcRequest.LIST_FEDERATION_REGISTRATIONS.equals(reqType)) {
+ // return the list of federation registrations
+ result = GitBlit.self().getFederationRegistrations();
+ } else if (RpcRequest.LIST_FEDERATION_RESULTS.equals(reqType)) {
+ // return the list of federation result registrations
+ if (GitBlit.canFederate()) {
+ result = GitBlit.self().getFederationResultRegistrations();
+ } else {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ }
+ } else if (RpcRequest.LIST_FEDERATION_PROPOSALS.equals(reqType)) {
+ // return the list of federation proposals
+ if (GitBlit.canFederate()) {
+ result = GitBlit.self().getPendingFederationProposals();
+ } else {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ }
+ } else if (RpcRequest.LIST_FEDERATION_SETS.equals(reqType)) {
+ // return the list of federation sets
+ if (GitBlit.canFederate()) {
+ String gitblitUrl = HttpUtils.getGitblitURL(request);
+ result = GitBlit.self().getFederationSets(gitblitUrl);
+ } else {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ }
}
// send the result of the request
diff --git a/src/com/gitblit/models/FederationSet.java b/src/com/gitblit/models/FederationSet.java new file mode 100644 index 00000000..357689c9 --- /dev/null +++ b/src/com/gitblit/models/FederationSet.java @@ -0,0 +1,58 @@ +/*
+ * Copyright 2011 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.models;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import com.gitblit.Constants.FederationToken;
+
+/**
+ * Represents a group of repositories.
+ */
+public class FederationSet implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public String name;
+
+ public String token;
+
+ public FederationToken tokenType;
+
+ public Map<String, RepositoryModel> repositories;
+
+ /**
+ * The constructor for a federation set.
+ *
+ * @param name
+ * the name of this federation set
+ * @param tokenType
+ * the type of token of this federation set
+ * @param token
+ * the federation token
+ */
+ public FederationSet(String name, FederationToken tokenType, String token) {
+ this.name = name;
+ this.tokenType = tokenType;
+ this.token = token;
+ }
+
+ @Override
+ public String toString() {
+ return "Federation Set (" + name + ")";
+ }
+}
diff --git a/src/com/gitblit/utils/FederationUtils.java b/src/com/gitblit/utils/FederationUtils.java index d04a7a31..324aa67e 100644 --- a/src/com/gitblit/utils/FederationUtils.java +++ b/src/com/gitblit/utils/FederationUtils.java @@ -49,16 +49,13 @@ import com.google.gson.reflect.TypeToken; */
public class FederationUtils {
- public static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() {
+ private static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() {
}.getType();
- public static final Type SETTINGS_TYPE = new TypeToken<Map<String, String>>() {
+ private static final Type SETTINGS_TYPE = new TypeToken<Map<String, String>>() {
}.getType();
- public static final Type USERS_TYPE = new TypeToken<Collection<UserModel>>() {
- }.getType();
-
- public static final Type RESULTS_TYPE = new TypeToken<List<FederationModel>>() {
+ private static final Type USERS_TYPE = new TypeToken<Collection<UserModel>>() {
}.getType();
private static final Logger LOGGER = LoggerFactory.getLogger(FederationUtils.class);
@@ -276,10 +273,11 @@ public class FederationUtils { * @return a collection of UserModel objects
* @throws Exception
*/
- public static Collection<UserModel> getUsers(FederationModel registration) throws Exception {
+ public static List<UserModel> getUsers(FederationModel registration) throws Exception {
String url = asLink(registration.url, registration.token, FederationRequest.PULL_USERS);
Collection<UserModel> models = JsonUtils.retrieveJson(url, USERS_TYPE);
- return models;
+ List<UserModel> list = new ArrayList<UserModel>(models);
+ return list;
}
/**
diff --git a/src/com/gitblit/utils/JsonUtils.java b/src/com/gitblit/utils/JsonUtils.java index a697b7a5..1edfc583 100644 --- a/src/com/gitblit/utils/JsonUtils.java +++ b/src/com/gitblit/utils/JsonUtils.java @@ -16,6 +16,7 @@ package com.gitblit.utils;
import java.io.BufferedReader;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
@@ -36,6 +37,10 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
+import org.eclipse.jgit.util.Base64;
+
+import com.gitblit.GitBlitException.ForbiddenException;
+import com.gitblit.GitBlitException.UnauthorizedException;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.google.gson.Gson;
@@ -43,7 +48,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken;
/**
- * Utility methods for gson calls to a Gitblit server.
+ * Utility methods for json calls to a Gitblit server.
*
* @author James Moger
*
@@ -98,7 +103,7 @@ public class JsonUtils { Gson gson = new Gson();
return gson.fromJson(json, clazz);
}
-
+
/**
* Convert a json string to an object of the specified type.
*
@@ -116,11 +121,27 @@ public class JsonUtils { *
* @param url
* @param type
- * @return
- * @throws Exception
+ * @return the deserialized object
+ * @throws {@link IOException}
*/
- public static <X> X retrieveJson(String url, Type type) throws Exception {
- String json = retrieveJsonString(url);
+ public static <X> X retrieveJson(String url, Type type) throws IOException,
+ UnauthorizedException {
+ return retrieveJson(url, type, null, null);
+ }
+
+ /**
+ * Reads a gson object from the specified url.
+ *
+ * @param url
+ * @param type
+ * @param username
+ * @param password
+ * @return the deserialized object
+ * @throws {@link IOException}
+ */
+ public static <X> X retrieveJson(String url, Type type, String username, char[] password)
+ throws IOException {
+ String json = retrieveJsonString(url, username, password);
if (StringUtils.isEmpty(json)) {
return null;
}
@@ -133,29 +154,42 @@ public class JsonUtils { *
* @param url
* @return the JSON message as a string
- * @throws Exception
+ * @throws {@link IOException}
*/
- public static String retrieveJsonString(String url) throws Exception {
- URL urlObject = new URL(url);
- URLConnection conn = urlObject.openConnection();
- conn.setRequestProperty("Accept-Charset", CHARSET);
- conn.setUseCaches(false);
- conn.setDoInput(true);
- if (conn instanceof HttpsURLConnection) {
- HttpsURLConnection secureConn = (HttpsURLConnection) conn;
- secureConn.setSSLSocketFactory(SSL_CONTEXT.getSocketFactory());
- secureConn.setHostnameVerifier(HOSTNAME_VERIFIER);
- }
- InputStream is = conn.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(is, CHARSET));
- StringBuilder json = new StringBuilder();
- char[] buffer = new char[4096];
- int len = 0;
- while ((len = reader.read(buffer)) > -1) {
- json.append(buffer, 0, len);
+ public static String retrieveJsonString(String url, String username, char[] password)
+ throws IOException {
+ try {
+ URL urlObject = new URL(url);
+ URLConnection conn = urlObject.openConnection();
+ conn.setRequestProperty("Accept-Charset", CHARSET);
+ setAuthorization(conn, username, password);
+ conn.setUseCaches(false);
+ conn.setDoInput(true);
+ if (conn instanceof HttpsURLConnection) {
+ HttpsURLConnection secureConn = (HttpsURLConnection) conn;
+ secureConn.setSSLSocketFactory(SSL_CONTEXT.getSocketFactory());
+ secureConn.setHostnameVerifier(HOSTNAME_VERIFIER);
+ }
+ InputStream is = conn.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is, CHARSET));
+ StringBuilder json = new StringBuilder();
+ char[] buffer = new char[4096];
+ int len = 0;
+ while ((len = reader.read(buffer)) > -1) {
+ json.append(buffer, 0, len);
+ }
+ is.close();
+ return json.toString();
+ } catch (IOException e) {
+ if (e.getMessage().indexOf("401") > -1) {
+ // unauthorized
+ throw new UnauthorizedException(url);
+ } else if (e.getMessage().indexOf("403") > -1) {
+ // requested url is forbidden by the requesting user
+ throw new ForbiddenException(url);
+ }
+ throw e;
}
- is.close();
- return json.toString();
}
/**
@@ -166,29 +200,67 @@ public class JsonUtils { * @param json
* the json message to send
* @return the http request result code
- * @throws Exception
+ * @throws {@link IOException}
*/
- public static int sendJsonString(String url, String json) throws Exception {
- byte[] jsonBytes = json.getBytes(CHARSET);
- URL urlObject = new URL(url);
- URLConnection conn = urlObject.openConnection();
- conn.setRequestProperty("Content-Type", "text/plain;charset=" + CHARSET);
- conn.setRequestProperty("Content-Length", "" + jsonBytes.length);
- conn.setUseCaches(false);
- conn.setDoOutput(true);
- if (conn instanceof HttpsURLConnection) {
- HttpsURLConnection secureConn = (HttpsURLConnection) conn;
- secureConn.setSSLSocketFactory(SSL_CONTEXT.getSocketFactory());
- secureConn.setHostnameVerifier(HOSTNAME_VERIFIER);
- }
+ public static int sendJsonString(String url, String json) throws IOException {
+ return sendJsonString(url, json, null, null);
+ }
- // write json body
- OutputStream os = conn.getOutputStream();
- os.write(jsonBytes);
- os.close();
+ /**
+ * Sends a JSON message.
+ *
+ * @param url
+ * the url to write to
+ * @param json
+ * the json message to send
+ * @param username
+ * @param password
+ * @return the http request result code
+ * @throws {@link IOException}
+ */
+ public static int sendJsonString(String url, String json, String username, char[] password)
+ throws IOException {
+ try {
+ byte[] jsonBytes = json.getBytes(CHARSET);
+ URL urlObject = new URL(url);
+ URLConnection conn = urlObject.openConnection();
+ conn.setRequestProperty("Content-Type", "text/plain;charset=" + CHARSET);
+ conn.setRequestProperty("Content-Length", "" + jsonBytes.length);
+ setAuthorization(conn, username, password);
+ conn.setUseCaches(false);
+ conn.setDoOutput(true);
+ if (conn instanceof HttpsURLConnection) {
+ HttpsURLConnection secureConn = (HttpsURLConnection) conn;
+ secureConn.setSSLSocketFactory(SSL_CONTEXT.getSocketFactory());
+ secureConn.setHostnameVerifier(HOSTNAME_VERIFIER);
+ }
- int status = ((HttpURLConnection) conn).getResponseCode();
- return status;
+ // write json body
+ OutputStream os = conn.getOutputStream();
+ os.write(jsonBytes);
+ os.close();
+
+ int status = ((HttpURLConnection) conn).getResponseCode();
+ return status;
+ } catch (IOException e) {
+ if (e.getMessage().indexOf("401") > -1) {
+ // unauthorized
+ throw new UnauthorizedException(url);
+ } else if (e.getMessage().indexOf("403") > -1) {
+ // requested url is forbidden by the requesting user
+ throw new ForbiddenException(url);
+ }
+ throw e;
+ }
+ }
+
+ private static void setAuthorization(URLConnection conn, String username, char[] password) {
+ if (!StringUtils.isEmpty(username) && (password != null && password.length > 0)) {
+ conn.setRequestProperty(
+ "Authorization",
+ "Basic "
+ + Base64.encodeBytes((username + ":" + new String(password)).getBytes()));
+ }
}
/**
diff --git a/src/com/gitblit/utils/RpcUtils.java b/src/com/gitblit/utils/RpcUtils.java index 919c7bb3..715ecb57 100644 --- a/src/com/gitblit/utils/RpcUtils.java +++ b/src/com/gitblit/utils/RpcUtils.java @@ -15,12 +15,18 @@ */
package com.gitblit.utils;
+import java.io.IOException;
import java.lang.reflect.Type;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import com.gitblit.Constants;
import com.gitblit.Constants.RpcRequest;
+import com.gitblit.models.FederationModel;
+import com.gitblit.models.FederationProposal;
+import com.gitblit.models.FederationSet;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.google.gson.reflect.TypeToken;
@@ -33,10 +39,22 @@ import com.google.gson.reflect.TypeToken; */
public class RpcUtils {
- public static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() {
+ public static final Type NAMES_TYPE = new TypeToken<Collection<String>>() {
}.getType();
- public static final Type USERS_TYPE = new TypeToken<Collection<UserModel>>() {
+ private static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() {
+ }.getType();
+
+ private static final Type USERS_TYPE = new TypeToken<Collection<UserModel>>() {
+ }.getType();
+
+ private static final Type REGISTRATIONS_TYPE = new TypeToken<Collection<FederationModel>>() {
+ }.getType();
+
+ private static final Type PROPOSALS_TYPE = new TypeToken<Collection<FederationProposal>>() {
+ }.getType();
+
+ private static final Type SETS_TYPE = new TypeToken<Collection<FederationSet>>() {
}.getType();
/**
@@ -48,26 +66,45 @@ public class RpcUtils { * @return
*/
public static String asLink(String remoteURL, RpcRequest req) {
+ return asLink(remoteURL, req, null);
+ }
+
+ /**
+ *
+ * @param remoteURL
+ * the url of the remote gitblit instance
+ * @param req
+ * the rpc request type
+ * @param name
+ * the name of the actionable object
+ * @return
+ */
+ public static String asLink(String remoteURL, RpcRequest req, String name) {
if (remoteURL.length() > 0 && remoteURL.charAt(remoteURL.length() - 1) == '/') {
remoteURL = remoteURL.substring(0, remoteURL.length() - 1);
}
if (req == null) {
req = RpcRequest.LIST_REPOSITORIES;
}
- return remoteURL + Constants.RPC_PATH + "?req=" + req.name().toLowerCase();
+ return remoteURL + Constants.RPC_PATH + "?req=" + req.name().toLowerCase()
+ + (name == null ? "" : ("&name=" + name));
}
-
+
/**
* Retrieves a map of the repositories at the remote gitblit instance keyed
* by the repository clone url.
*
* @param serverUrl
+ * @param account
+ * @param password
* @return a map of cloneable repositories
- * @throws Exception
+ * @throws IOException
*/
- public static Map<String, RepositoryModel> getRepositories(String serverUrl) throws Exception {
+ public static Map<String, RepositoryModel> getRepositories(String serverUrl, String account,
+ char[] password) throws IOException {
String url = asLink(serverUrl, RpcRequest.LIST_REPOSITORIES);
- Map<String, RepositoryModel> models = JsonUtils.retrieveJson(url, REPOSITORIES_TYPE);
+ Map<String, RepositoryModel> models = JsonUtils.retrieveJson(url, REPOSITORIES_TYPE,
+ account, password);
return models;
}
@@ -75,12 +112,243 @@ public class RpcUtils { * Tries to pull the gitblit user accounts from the remote gitblit instance.
*
* @param serverUrl
+ * @param account
+ * @param password
* @return a collection of UserModel objects
- * @throws Exception
+ * @throws IOException
*/
- public static Collection<UserModel> getUsers(String serverUrl) throws Exception {
+ public static List<UserModel> getUsers(String serverUrl, String account, char[] password)
+ throws IOException {
String url = asLink(serverUrl, RpcRequest.LIST_USERS);
- Collection<UserModel> models = JsonUtils.retrieveJson(url, USERS_TYPE);
- return models;
+ Collection<UserModel> models = JsonUtils.retrieveJson(url, USERS_TYPE, account, password);
+ List<UserModel> list = new ArrayList<UserModel>(models);
+ return list;
+ }
+
+ /**
+ * Create a repository on the Gitblit server.
+ *
+ * @param repository
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ public static boolean createRepository(RepositoryModel repository, String serverUrl,
+ String account, char[] password) throws IOException {
+ return doAction(RpcRequest.CREATE_REPOSITORY, null, repository, serverUrl, account,
+ password);
+
+ }
+
+ /**
+ * Send a revised version of the repository model to the Gitblit server.
+ *
+ * @param repository
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ public static boolean updateRepository(String repositoryName, RepositoryModel repository,
+ String serverUrl, String account, char[] password) throws IOException {
+ return doAction(RpcRequest.EDIT_REPOSITORY, repositoryName, repository, serverUrl, account,
+ password);
+ }
+
+ /**
+ * Delete a repository from the Gitblit server.
+ *
+ * @param repository
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ public static boolean deleteRepository(RepositoryModel repository, String serverUrl,
+ String account, char[] password) throws IOException {
+ return doAction(RpcRequest.DELETE_REPOSITORY, null, repository, serverUrl, account,
+ password);
+
+ }
+
+ /**
+ * Create a user on the Gitblit server.
+ *
+ * @param user
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ public static boolean createUser(UserModel user, String serverUrl, String account,
+ char[] password) throws IOException {
+ return doAction(RpcRequest.CREATE_USER, null, user, serverUrl, account, password);
+
+ }
+
+ /**
+ * Send a revised version of the user model to the Gitblit server.
+ *
+ * @param user
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ public static boolean updateUser(String username, UserModel user, String serverUrl,
+ String account, char[] password) throws IOException {
+ return doAction(RpcRequest.EDIT_USER, username, user, serverUrl, account, password);
+
+ }
+
+ /**
+ * Deletes a user from the Gitblit server.
+ *
+ * @param user
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ public static boolean deleteUser(UserModel user, String serverUrl, String account,
+ char[] password) throws IOException {
+ return doAction(RpcRequest.DELETE_USER, null, user, serverUrl, account, password);
+ }
+
+ /**
+ * Retrieves the list of users that can access the specified repository.
+ *
+ * @param repository
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return list of members
+ * @throws IOException
+ */
+ public static List<String> getRepositoryMembers(RepositoryModel repository, String serverUrl,
+ String account, char[] password) throws IOException {
+ String url = asLink(serverUrl, RpcRequest.LIST_REPOSITORY_MEMBERS, repository.name);
+ Collection<String> list = JsonUtils.retrieveJson(url, NAMES_TYPE, account, password);
+ return new ArrayList<String>(list);
+ }
+
+ /**
+ * Sets the repository membership list.
+ *
+ * @param repository
+ * @param memberships
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ public static boolean setRepositoryMembers(RepositoryModel repository,
+ List<String> memberships, String serverUrl, String account, char[] password)
+ throws IOException {
+ return doAction(RpcRequest.SET_REPOSITORY_MEMBERS, repository.name, memberships, serverUrl,
+ account, password);
+ }
+
+ /**
+ * Retrieves the list of federation registrations. These are the list of
+ * registrations that this Gitblit instance is pulling from.
+ *
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return a collection of FederationRegistration objects
+ * @throws IOException
+ */
+ public static List<FederationModel> getFederationRegistrations(String serverUrl,
+ String account, char[] password) throws IOException {
+ String url = asLink(serverUrl, RpcRequest.LIST_FEDERATION_REGISTRATIONS);
+ Collection<FederationModel> registrations = JsonUtils.retrieveJson(url, REGISTRATIONS_TYPE,
+ account, password);
+ List<FederationModel> list = new ArrayList<FederationModel>(registrations);
+ return list;
+ }
+
+ /**
+ * Retrieves the list of federation result registrations. These are the
+ * results reported back to this Gitblit instance from a federation client.
+ *
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return a collection of FederationRegistration objects
+ * @throws IOException
+ */
+ public static List<FederationModel> getFederationResultRegistrations(String serverUrl,
+ String account, char[] password) throws IOException {
+ String url = asLink(serverUrl, RpcRequest.LIST_FEDERATION_RESULTS);
+ Collection<FederationModel> registrations = JsonUtils.retrieveJson(url, REGISTRATIONS_TYPE,
+ account, password);
+ List<FederationModel> list = new ArrayList<FederationModel>(registrations);
+ return list;
+ }
+
+ /**
+ * Retrieves the list of federation proposals.
+ *
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return a collection of FederationProposal objects
+ * @throws IOException
+ */
+ public static List<FederationProposal> getFederationProposals(String serverUrl,
+ String account, char[] password) throws IOException {
+ String url = asLink(serverUrl, RpcRequest.LIST_FEDERATION_PROPOSALS);
+ Collection<FederationProposal> proposals = JsonUtils.retrieveJson(url, PROPOSALS_TYPE,
+ account, password);
+ List<FederationProposal> list = new ArrayList<FederationProposal>(proposals);
+ return list;
+ }
+
+ /**
+ * Retrieves the list of federation repository sets.
+ *
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return a collection of FederationSet objects
+ * @throws IOException
+ */
+ public static List<FederationSet> getFederationSets(String serverUrl,
+ String account, char[] password) throws IOException {
+ String url = asLink(serverUrl, RpcRequest.LIST_FEDERATION_SETS);
+ Collection<FederationSet> sets = JsonUtils.retrieveJson(url, SETS_TYPE,
+ account, password);
+ List<FederationSet> list = new ArrayList<FederationSet>(sets);
+ return list;
+ }
+
+ /**
+ * Do the specified administrative action on the Gitblit server.
+ *
+ * @param request
+ * @param name
+ * the name of the object (may be null)
+ * @param object
+ * @param serverUrl
+ * @param account
+ * @param password
+ * @return true if the action succeeded
+ * @throws IOException
+ */
+ protected static boolean doAction(RpcRequest request, String name, Object object,
+ String serverUrl, String account, char[] password) throws IOException {
+ String url = asLink(serverUrl, request, name);
+ String json = JsonUtils.toJsonString(object);
+ int resultCode = JsonUtils.sendJsonString(url, json, account, password);
+ return resultCode == 200;
}
}
|