/* * Copyright 2013 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; import java.io.IOException; import java.text.MessageFormat; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; /** * Handles requests for Sparkleshare Invites * * @author James Moger * */ public class SparkleShareInviteServlet extends HttpServlet { private static final long serialVersionUID = 1L; public SparkleShareInviteServlet() { super(); } /** * Returns an Sparkleshare invite url to this servlet for the repository. * https://github.com/hbons/SparkleShare/wiki/Invites * * @param baseURL * @param repository * @param username * @return an url */ public static String asLink(String baseURL, String repository, String username) { if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') { baseURL = baseURL.substring(0, baseURL.length() - 1); } String url = baseURL + Constants.SPARKLESHARE_INVITE_PATH + ((StringUtils.isEmpty(username) ? "" : (username + "@"))) + repository + ".xml"; url = url.replace("https://", "sparkleshare://"); url = url.replace("http://", "sparkleshare-unsafe://"); return url; } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void processRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { // extract repo name from request String path = request.getPathInfo(); if (path != null && path.length() > 1) { if (path.charAt(0) == '/') { path = path.substring(1); } } // trim trailing .xml if (path.endsWith(".xml")) { path = path.substring(0, path.length() - 4); } String username = null; int fetch = path.indexOf('@'); if (fetch > -1) { username = path.substring(0, fetch); path = path.substring(fetch + 1); } UserModel user; if (StringUtils.isEmpty(username)) { user = GitBlit.self().authenticate(request); } else { user = GitBlit.self().getUserModel(username); } if (user == null) { user = UserModel.ANONYMOUS; username = ""; } // ensure that the requested repository exists and is sparkleshared RepositoryModel model = GitBlit.self().getRepositoryModel(path); if (model == null) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.getWriter().append(MessageFormat.format("Repository \"{0}\" not found!", path)); return; } else if (!model.isSparkleshared()) { response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.getWriter().append(MessageFormat.format("Repository \"{0}\" is not sparkleshared!", path)); return; } if (GitBlit.getBoolean(Keys.git.enableGitServlet, true) || GitBlit.getInteger(Keys.git.daemonPort, 0) > 0) { // Gitblit as server // determine username for repository url if (model.accessRestriction.exceeds(AccessRestrictionType.NONE)) { if (!user.canRewindRef(model)) { response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.getWriter().append(MessageFormat.format("\"{0}\" does not have RW+ permissions for {1}!", user.username, path)); return; } } if (model.accessRestriction.exceeds(AccessRestrictionType.NONE)) { username = user.username + "@"; } else { username = ""; } String serverPort = ""; if (request.getScheme().equals("https")) { if (request.getServerPort() != 443) { serverPort = ":" + request.getServerPort(); } } else if (request.getScheme().equals("http")) { if (request.getServerPort() != 80) { serverPort = ":" + request.getServerPort(); } } // assume http/https serving String scheme = request.getScheme(); String servletPath = Constants.GIT_PATH; // try to switch to git://, if git servlet disabled and repo has no restrictions if (!GitBlit.getBoolean(Keys.git.enableGitServlet, true) && (GitBlit.getInteger(Keys.git.daemonPort, 0) > 0) && AccessRestrictionType.NONE == model.accessRestriction) { scheme = "git"; servletPath = "/"; serverPort = GitBlit.getString(Keys.git.daemonPort, ""); } // construct Sparkleshare invite StringBuilder sb = new StringBuilder(); sb.append("\n"); sb.append("\n"); sb.append(MessageFormat.format("
{0}://{1}{2}{3}{4}
\n", scheme, username, request.getServerName(), serverPort, request.getContextPath())); sb.append(MessageFormat.format("{0}{1}\n", servletPath, model.name)); if (GitBlit.getInteger(Keys.fanout.port, 0) > 0) { // Gitblit is running it's own fanout service for pubsub notifications sb.append(MessageFormat.format("tcp://{0}:{1}\n", request.getServerName(), GitBlit.getString(Keys.fanout.port, ""))); } sb.append("
\n"); // write invite to client response.setContentType("application/xml"); response.setContentLength(sb.length()); response.getWriter().append(sb.toString()); } else { // Gitblit as viewer, repository access handled externally so // assume RW+ permission List others = GitBlit.getStrings(Keys.web.otherUrls); if (others.size() == 0) { return; } String address = MessageFormat.format(others.get(0), "", username); StringBuilder sb = new StringBuilder(); sb.append("\n"); sb.append("\n"); sb.append(MessageFormat.format("
{0}
\n", address)); sb.append(MessageFormat.format("{0}\n", model.name)); if (GitBlit.getInteger(Keys.fanout.port, 0) > 0) { // Gitblit is running it's own fanout service for pubsub notifications sb.append(MessageFormat.format("tcp://{0}:{1}\n", request.getServerName(), GitBlit.getString(Keys.fanout.port, ""))); } sb.append("
\n"); // write invite to client response.setContentType("application/xml"); response.setContentLength(sb.length()); response.getWriter().append(sb.toString()); } } }