From 10177fb0a59cc9fc61fb78c724f7b0816b69b798 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Sat, 01 Oct 2011 15:50:22 -0400
Subject: [PATCH] CSS fixes for palette buttons

---
 src/com/gitblit/utils/FederationUtils.java |  165 ++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 145 insertions(+), 20 deletions(-)

diff --git a/src/com/gitblit/utils/FederationUtils.java b/src/com/gitblit/utils/FederationUtils.java
index 129fe42..fde9557 100644
--- a/src/com/gitblit/utils/FederationUtils.java
+++ b/src/com/gitblit/utils/FederationUtils.java
@@ -26,8 +26,10 @@
 import java.security.SecureRandom;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
+import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Date;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -40,10 +42,16 @@
 import javax.net.ssl.X509TrustManager;
 import javax.servlet.http.HttpServletResponse;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.Constants.FederationProposalResult;
 import com.gitblit.Constants.FederationRequest;
-import com.gitblit.Constants.FederationToken;
 import com.gitblit.FederationServlet;
+import com.gitblit.IStoredSettings;
+import com.gitblit.Keys;
 import com.gitblit.models.FederationModel;
+import com.gitblit.models.FederationProposal;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.UserModel;
 import com.google.gson.Gson;
@@ -76,6 +84,8 @@
 
 	private static final DummyHostnameVerifier HOSTNAME_VERIFIER;
 
+	private static final Logger LOGGER = LoggerFactory.getLogger(FederationUtils.class);
+
 	static {
 		SSLContext context = null;
 		try {
@@ -90,28 +100,143 @@
 	}
 
 	/**
+	 * Returns the list of federated gitblit instances that this instance will
+	 * try to pull.
+	 * 
+	 * @return list of registered gitblit instances
+	 */
+	public static List<FederationModel> getFederationRegistrations(IStoredSettings settings) {
+		List<FederationModel> federationRegistrations = new ArrayList<FederationModel>();
+		List<String> keys = settings.getAllKeys(Keys.federation._ROOT);
+		keys.remove(Keys.federation.name);
+		keys.remove(Keys.federation.passphrase);
+		keys.remove(Keys.federation.allowProposals);
+		keys.remove(Keys.federation.proposalsFolder);
+		keys.remove(Keys.federation.defaultFrequency);
+		keys.remove(Keys.federation.sets);
+		Collections.sort(keys);
+		Map<String, FederationModel> federatedModels = new HashMap<String, FederationModel>();
+		for (String key : keys) {
+			String value = key.substring(Keys.federation._ROOT.length() + 1);
+			List<String> values = StringUtils.getStringsFromValue(value, "\\.");
+			String server = values.get(0);
+			if (!federatedModels.containsKey(server)) {
+				federatedModels.put(server, new FederationModel(server));
+			}
+			String setting = values.get(1);
+			if (setting.equals("url")) {
+				// url of the origin Gitblit instance
+				federatedModels.get(server).url = settings.getString(key, "");
+			} else if (setting.equals("token")) {
+				// token for the origin Gitblit instance
+				federatedModels.get(server).token = settings.getString(key, "");
+			} else if (setting.equals("frequency")) {
+				// frequency of the pull operation
+				federatedModels.get(server).frequency = settings.getString(key, "");
+			} else if (setting.equals("folder")) {
+				// destination folder of the pull operation
+				federatedModels.get(server).folder = settings.getString(key, "");
+			} else if (setting.equals("bare")) {
+				// whether pulled repositories should be bare
+				federatedModels.get(server).bare = settings.getBoolean(key, true);
+			} else if (setting.equals("mirror")) {
+				// are the repositories to be true mirrors of the origin
+				federatedModels.get(server).mirror = settings.getBoolean(key, true);
+			} else if (setting.equals("mergeAccounts")) {
+				// merge remote accounts into local accounts
+				federatedModels.get(server).mergeAccounts = settings.getBoolean(key, false);
+			} else if (setting.equals("sendStatus")) {
+				// send a status acknowledgment to source Gitblit instance
+				// at end of git pull
+				federatedModels.get(server).sendStatus = settings.getBoolean(key, false);
+			} else if (setting.equals("notifyOnError")) {
+				// notify administrators on federation pull failures
+				federatedModels.get(server).notifyOnError = settings.getBoolean(key, false);
+			} else if (setting.equals("exclude")) {
+				// excluded repositories
+				federatedModels.get(server).exclusions = settings.getStrings(key);
+			} else if (setting.equals("include")) {
+				// included repositories
+				federatedModels.get(server).inclusions = settings.getStrings(key);
+			}
+		}
+
+		// verify that registrations have a url and a token
+		for (FederationModel model : federatedModels.values()) {
+			if (StringUtils.isEmpty(model.url)) {
+				LOGGER.warn(MessageFormat.format(
+						"Dropping federation registration {0}. Missing url.", model.name));
+				continue;
+			}
+			if (StringUtils.isEmpty(model.token)) {
+				LOGGER.warn(MessageFormat.format(
+						"Dropping federation registration {0}. Missing token.", model.name));
+				continue;
+			}
+			// set default frequency if unspecified
+			if (StringUtils.isEmpty(model.frequency)) {
+				model.frequency = settings.getString(Keys.federation.defaultFrequency, "60 mins");
+			}
+			federationRegistrations.add(model);
+		}
+		return federationRegistrations;
+	}
+
+	/**
+	 * Sends a federation poke to the Gitblit instance at remoteUrl. Pokes are
+	 * sent by an pulling Gitblit instance to an origin Gitblit instance as part
+	 * of the proposal process. This is to ensure that the pulling Gitblit
+	 * instance has an IP route to the origin instance.
+	 * 
+	 * @param remoteUrl
+	 *            the remote Gitblit instance to send a federation proposal to
+	 * @param proposal
+	 *            a complete federation proposal
+	 * @return true if there is a route to the remoteUrl
+	 */
+	public static boolean poke(String remoteUrl) throws Exception {
+		String url = FederationServlet.asFederationLink(remoteUrl, null, FederationRequest.POKE);
+		Gson gson = new Gson();
+		String json = gson.toJson("POKE");
+		int status = writeJson(url, json);
+		return status == HttpServletResponse.SC_OK;
+	}
+
+	/**
 	 * Sends a federation proposal to the Gitblit instance at remoteUrl
 	 * 
 	 * @param remoteUrl
 	 *            the remote Gitblit instance to send a federation proposal to
-	 * @param tokenType
-	 *            type of the provided federation token
-	 * @param myToken
-	 *            my federation token
-	 * @param myUrl
-	 *            my Gitblit url
-	 * @param myRepositories
-	 *            the repositories I want to share keyed by their clone url
-	 * @return true if the proposal was received
+	 * @param proposal
+	 *            a complete federation proposal
+	 * @return the federation proposal result code
 	 */
-	public static boolean propose(String remoteUrl, FederationToken tokenType, String myToken,
-			String myUrl, Map<String, RepositoryModel> myRepositories) throws Exception {
-		String url = FederationServlet.asFederationLink(remoteUrl, tokenType, myToken,
-				FederationRequest.PROPOSAL, myUrl);
+	public static FederationProposalResult propose(String remoteUrl, FederationProposal proposal)
+			throws Exception {
+		String url = FederationServlet
+				.asFederationLink(remoteUrl, null, FederationRequest.PROPOSAL);
 		Gson gson = new GsonBuilder().setPrettyPrinting().create();
-		String json = gson.toJson(myRepositories);
+		String json = gson.toJson(proposal);
 		int status = writeJson(url, json);
-		return status == HttpServletResponse.SC_OK;
+		switch (status) {
+		case HttpServletResponse.SC_FORBIDDEN:
+			// remote Gitblit Federation disabled
+			return FederationProposalResult.FEDERATION_DISABLED;
+		case HttpServletResponse.SC_BAD_REQUEST:
+			// remote Gitblit did not receive any JSON data
+			return FederationProposalResult.MISSING_DATA;
+		case HttpServletResponse.SC_METHOD_NOT_ALLOWED:
+			// remote Gitblit not accepting proposals
+			return FederationProposalResult.NO_PROPOSALS;
+		case HttpServletResponse.SC_NOT_ACCEPTABLE:
+			// remote Gitblit failed to poke this Gitblit instance
+			return FederationProposalResult.NO_POKE;
+		case HttpServletResponse.SC_OK:
+			// received
+			return FederationProposalResult.ACCEPTED;
+		default:
+			return FederationProposalResult.ERROR;
+		}
 	}
 
 	/**
@@ -126,7 +251,7 @@
 	 */
 	public static Map<String, RepositoryModel> getRepositories(FederationModel registration,
 			boolean checkExclusions) throws Exception {
-		String url = FederationServlet.asPullLink(registration.url, registration.token,
+		String url = FederationServlet.asFederationLink(registration.url, registration.token,
 				FederationRequest.PULL_REPOSITORIES);
 		Map<String, RepositoryModel> models = readGson(url, REPOSITORIES_TYPE);
 		if (checkExclusions) {
@@ -149,7 +274,7 @@
 	 * @throws Exception
 	 */
 	public static Collection<UserModel> getUsers(FederationModel registration) throws Exception {
-		String url = FederationServlet.asPullLink(registration.url, registration.token,
+		String url = FederationServlet.asFederationLink(registration.url, registration.token,
 				FederationRequest.PULL_USERS);
 		Collection<UserModel> models = readGson(url, USERS_TYPE);
 		return models;
@@ -164,7 +289,7 @@
 	 * @throws Exception
 	 */
 	public static Map<String, String> getSettings(FederationModel registration) throws Exception {
-		String url = FederationServlet.asPullLink(registration.url, registration.token,
+		String url = FederationServlet.asFederationLink(registration.url, registration.token,
 				FederationRequest.PULL_SETTINGS);
 		Map<String, String> settings = readGson(url, SETTINGS_TYPE);
 		return settings;

--
Gitblit v1.9.1