James Moger
2015-11-22 ed552ba47c02779c270ffd62841d6d1048dade70
commit | author | age
b7502e 1 /*
JM 2  * Copyright 2013 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
7bf6e1 16 package com.gitblit.servlet;
b7502e 17
JM 18 import java.io.IOException;
7569e8 19 import java.net.URL;
b7502e 20 import java.text.MessageFormat;
JM 21
22 import javax.servlet.ServletException;
1b34b0 23 import javax.servlet.http.HttpServlet;
b7502e 24 import javax.servlet.http.HttpServletRequest;
JM 25 import javax.servlet.http.HttpServletResponse;
26
7bf6e1 27 import com.gitblit.IStoredSettings;
JM 28 import com.gitblit.Keys;
c5069a 29 import com.gitblit.manager.IAuthenticationManager;
db4f6b 30 import com.gitblit.manager.IRepositoryManager;
JM 31 import com.gitblit.manager.IUserManager;
b7502e 32 import com.gitblit.models.RepositoryModel;
JM 33 import com.gitblit.models.UserModel;
34 import com.gitblit.utils.StringUtils;
b3aabb 35 import com.google.inject.Inject;
JM 36 import com.google.inject.Singleton;
65d5bb 37
b7502e 38 /**
JM 39  * Handles requests for Sparkleshare Invites
699e71 40  *
b7502e 41  * @author James Moger
699e71 42  *
b7502e 43  */
1b34b0 44 @Singleton
JM 45 public class SparkleShareInviteServlet extends HttpServlet {
b7502e 46
JM 47     private static final long serialVersionUID = 1L;
48
65d5bb 49     private IStoredSettings settings;
cacf8b 50
65d5bb 51     private IUserManager userManager;
cacf8b 52
65d5bb 53     private IAuthenticationManager authenticationManager;
cacf8b 54
65d5bb 55     private IRepositoryManager repositoryManager;
cacf8b 56
1b34b0 57     @Inject
JM 58     public SparkleShareInviteServlet(
59             IStoredSettings settings,
60             IUserManager userManager,
61             IAuthenticationManager authenticationManager,
62             IRepositoryManager repositoryManager) {
63
64         this.settings = settings;
65         this.userManager = userManager;
66         this.authenticationManager = authenticationManager;
67         this.repositoryManager = repositoryManager;
b7502e 68     }
699e71 69
b7502e 70     @Override
JM 71     protected void doPost(HttpServletRequest request, HttpServletResponse response)
72             throws ServletException, java.io.IOException {
73         processRequest(request, response);
74     }
75
76     @Override
77     protected void doGet(HttpServletRequest request, HttpServletResponse response)
78             throws ServletException, IOException {
79         processRequest(request, response);
80     }
81
82     protected void processRequest(javax.servlet.http.HttpServletRequest request,
83             javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException,
699e71 84             java.io.IOException {
db4f6b 85
7569e8 86         int sshPort = settings.getInteger(Keys.git.sshPort, 0);
JM 87         if (sshPort == 0) {
88             response.setStatus(HttpServletResponse.SC_FORBIDDEN);
89             response.getWriter().append("SSH is not active on this server!");
90             return;
91         }
b3aabb 92         int sshDisplayPort = settings.getInteger(Keys.git.sshAdvertisedPort, sshPort);
182312 93
b7502e 94         // extract repo name from request
366bec 95         String repoUrl = request.getPathInfo().substring(1);
JM 96
b7502e 97         // trim trailing .xml
366bec 98         if (repoUrl.endsWith(".xml")) {
JM 99             repoUrl = repoUrl.substring(0, repoUrl.length() - 4);
b7502e 100         }
699e71 101
b7502e 102         String username = null;
7569e8 103         String path;
366bec 104         int fetchIndex = repoUrl.indexOf('@');
JM 105         if (fetchIndex > -1) {
7569e8 106             username = repoUrl.substring(0, fetchIndex);
JM 107             path = repoUrl.substring(fetchIndex + 1);
108         } else {
109             path = repoUrl;
b7502e 110         }
7569e8 111
JM 112         String host = request.getServerName();
113         String url = settings.getString(Keys.web.canonicalUrl, "https://localhost:8443");
114         if (!StringUtils.isEmpty(url) && url.indexOf("localhost") == -1) {
115             host = new URL(url).getHost();
182312 116         }
b3aabb 117         String sshDisplayHost = settings.getString(Keys.git.sshAdvertisedHost, "");
182312 118         if(sshDisplayHost.isEmpty()) {
MB 119             sshDisplayHost = host;
7569e8 120         }
JM 121
b7502e 122         UserModel user;
JM 123         if (StringUtils.isEmpty(username)) {
04a985 124             user = authenticationManager.authenticate(request);
b7502e 125         } else {
db4f6b 126             user = userManager.getUserModel(username);
b7502e 127         }
7569e8 128         if (user == null || user.disabled) {
JM 129             response.setStatus(HttpServletResponse.SC_FORBIDDEN);
130             response.getWriter().append("Access is not permitted!");
131             return;
b7502e 132         }
699e71 133
366bec 134         // ensure that the requested repository exists
db4f6b 135         RepositoryModel model = repositoryManager.getRepositoryModel(path);
b7502e 136         if (model == null) {
JM 137             response.setStatus(HttpServletResponse.SC_NOT_FOUND);
138             response.getWriter().append(MessageFormat.format("Repository \"{0}\" not found!", path));
139             return;
140         }
699e71 141
7569e8 142         if (!user.canRewindRef(model)) {
JM 143             response.setStatus(HttpServletResponse.SC_FORBIDDEN);
144             response.getWriter().append(MessageFormat.format("{0} does not have RW+ permissions to \"{1}\"!", user.username, model.name));
145         }
146
699e71 147         StringBuilder sb = new StringBuilder();
366bec 148         sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
JM 149         sb.append("<sparkleshare><invite>\n");
182312 150         sb.append(MessageFormat.format("<address>ssh://{0}@{1}:{2,number,0}/</address>\n", user.username, sshDisplayHost, sshDisplayPort));
7569e8 151         sb.append(MessageFormat.format("<remote_path>/{0}</remote_path>\n", model.name));
JM 152         int fanoutPort = settings.getInteger(Keys.fanout.port, 0);
153         if (fanoutPort > 0) {
366bec 154             // Gitblit is running it's own fanout service for pubsub notifications
7569e8 155             sb.append(MessageFormat.format("<announcements_url>tcp://{0}:{1,number,0}</announcements_url>\n", request.getServerName(), fanoutPort));
b7502e 156         }
366bec 157         sb.append("</invite></sparkleshare>\n");
JM 158
159         // write invite to client
160         response.setContentType("application/xml");
161         response.setContentLength(sb.length());
162         response.getWriter().append(sb.toString());
b7502e 163     }
JM 164 }