Line data Source code
1 : // Copyright (C) 2009 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.httpd; 16 : 17 : import static com.google.inject.Scopes.SINGLETON; 18 : 19 : import com.google.common.base.Strings; 20 : import com.google.gerrit.common.PageLinks; 21 : import com.google.gerrit.entities.Change; 22 : import com.google.gerrit.entities.Project; 23 : import com.google.gerrit.extensions.client.AuthType; 24 : import com.google.gerrit.httpd.RunAsFilter.RunAsFilterModule; 25 : import com.google.gerrit.httpd.raw.AuthorizationCheckServlet; 26 : import com.google.gerrit.httpd.raw.CatServlet; 27 : import com.google.gerrit.httpd.raw.SshInfoServlet; 28 : import com.google.gerrit.httpd.raw.ToolServlet; 29 : import com.google.gerrit.httpd.restapi.AccessRestApiServlet; 30 : import com.google.gerrit.httpd.restapi.AccountsRestApiServlet; 31 : import com.google.gerrit.httpd.restapi.ChangesRestApiServlet; 32 : import com.google.gerrit.httpd.restapi.ConfigRestApiServlet; 33 : import com.google.gerrit.httpd.restapi.GroupsRestApiServlet; 34 : import com.google.gerrit.httpd.restapi.ProjectsRestApiServlet; 35 : import com.google.gerrit.server.config.AuthConfig; 36 : import com.google.inject.Key; 37 : import com.google.inject.internal.UniqueAnnotations; 38 : import com.google.inject.servlet.ServletModule; 39 : import java.io.IOException; 40 : import javax.servlet.http.HttpServlet; 41 : import javax.servlet.http.HttpServletRequest; 42 : import javax.servlet.http.HttpServletResponse; 43 : import org.eclipse.jgit.lib.Constants; 44 : 45 : class UrlModule extends ServletModule { 46 : private AuthConfig authConfig; 47 : 48 99 : UrlModule(AuthConfig authConfig) { 49 99 : this.authConfig = authConfig; 50 99 : } 51 : 52 : @Override 53 : protected void configureServlets() { 54 99 : serve("/cat/*").with(CatServlet.class); 55 : 56 99 : if (authConfig.getAuthType() != AuthType.OAUTH && authConfig.getAuthType() != AuthType.OPENID) { 57 2 : serve("/logout").with(HttpLogoutServlet.class); 58 2 : serve("/signout").with(HttpLogoutServlet.class); 59 : } 60 99 : serve("/ssh_info").with(SshInfoServlet.class); 61 : 62 99 : serve("/Main.class").with(notFound()); 63 99 : serve("/com/google/gerrit/launcher/*").with(notFound()); 64 99 : serve("/servlet/*").with(notFound()); 65 : 66 99 : serve("/all").with(query("status:merged")); 67 99 : serve("/mine").with(screen(PageLinks.MINE)); 68 99 : serve("/open").with(query("status:open")); 69 99 : serve("/watched").with(query("is:watched status:open")); 70 99 : serve("/starred").with(query("is:starred")); 71 : 72 99 : serveRegex("^/settings/?$").with(screen(PageLinks.SETTINGS)); 73 99 : serveRegex("^/register$").with(registerScreen(false)); 74 99 : serveRegex("^/register/(.+)$").with(registerScreen(true)); 75 99 : serveRegex("^/([1-9][0-9]*)/?$").with(NumericChangeIdRedirectServlet.class); 76 99 : serveRegex("^/p/(.*)$").with(queryProjectNew()); 77 99 : serveRegex("^/r/(.+)/?$").with(DirectChangeByCommit.class); 78 : 79 99 : filter("/a/*").through(RequireIdentifiedUserFilter.class); 80 : 81 : // Must be after RequireIdentifiedUserFilter so auth happens before checking 82 : // for RunAs capability. 83 99 : install(new RunAsFilterModule()); 84 : 85 99 : serveRegex("^/(?:a/)?tools/(.*)$").with(ToolServlet.class); 86 : 87 : // Serve auth check. Mainly used by PolyGerrit for checking if a user is still logged in. 88 99 : serveRegex("^/(?:a/)?auth-check$").with(AuthorizationCheckServlet.class); 89 : 90 : // Bind servlets for REST root collections. 91 : // The '/plugins/' root collection is already handled by HttpPluginServlet 92 : // which is bound in HttpPluginModule. We cannot bind it here again although 93 : // this means that plugins can't add REST views on PLUGIN_KIND. 94 99 : serveRegex("^/(?:a/)?access/(.*)$").with(AccessRestApiServlet.class); 95 99 : serveRegex("^/(?:a/)?access$").with(AccessRestApiServlet.class); 96 99 : serveRegex("^/(?:a/)?accounts/(.*)$").with(AccountsRestApiServlet.class); 97 99 : serveRegex("^/(?:a/)?accounts$").with(AccountsRestApiServlet.class); 98 99 : serveRegex("^/(?:a/)?changes/(.*)$").with(ChangesRestApiServlet.class); 99 99 : serveRegex("^/(?:a/)?changes$").with(ChangesRestApiServlet.class); 100 99 : serveRegex("^/(?:a/)?config/(.*)$").with(ConfigRestApiServlet.class); 101 99 : serveRegex("^/(?:a/)?config$").with(ConfigRestApiServlet.class); 102 99 : serveRegex("^/(?:a/)?groups/(.*)?$").with(GroupsRestApiServlet.class); 103 99 : serveRegex("^/(?:a/)?groups$").with(GroupsRestApiServlet.class); 104 99 : serveRegex("^/(?:a/)?projects/(.*)?$").with(ProjectsRestApiServlet.class); 105 99 : serveRegex("^/(?:a/)?projects$").with(ProjectsRestApiServlet.class); 106 : 107 99 : serveRegex("^/Documentation$").with(redirectDocumentation()); 108 99 : serveRegex("^/Documentation/$").with(redirectDocumentation()); 109 99 : filter("/Documentation/*").through(QueryDocumentationFilter.class); 110 99 : } 111 : 112 : private Key<HttpServlet> notFound() { 113 99 : return key( 114 99 : new HttpServlet() { 115 : private static final long serialVersionUID = 1L; 116 : 117 : @Override 118 : protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException { 119 0 : rsp.sendError(HttpServletResponse.SC_NOT_FOUND); 120 0 : } 121 : }); 122 : } 123 : 124 : private Key<HttpServlet> screen(String target) { 125 99 : return key( 126 99 : new HttpServlet() { 127 : private static final long serialVersionUID = 1L; 128 : 129 : @Override 130 : protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException { 131 0 : toGerrit(target, req, rsp); 132 0 : } 133 : }); 134 : } 135 : 136 : private Key<HttpServlet> queryProjectNew() { 137 99 : return key( 138 99 : new HttpServlet() { 139 : private static final long serialVersionUID = 1L; 140 : 141 : @Override 142 : protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException { 143 0 : String name = req.getPathInfo(); 144 0 : if (Strings.isNullOrEmpty(name)) { 145 0 : toGerrit(PageLinks.ADMIN_PROJECTS, req, rsp); 146 0 : return; 147 : } 148 : 149 0 : while (name.endsWith("/")) { 150 0 : name = name.substring(0, name.length() - 1); 151 : } 152 0 : if (name.endsWith(Constants.DOT_GIT_EXT)) { 153 0 : name = 154 0 : name.substring( 155 : 0, // 156 0 : name.length() - Constants.DOT_GIT_EXT.length()); 157 : } 158 0 : while (name.endsWith("/")) { 159 0 : name = name.substring(0, name.length() - 1); 160 : } 161 0 : Project.NameKey project = Project.nameKey(name); 162 0 : toGerrit( 163 0 : PageLinks.toChangeQuery(PageLinks.projectQuery(project, Change.Status.NEW)), 164 : req, 165 : rsp); 166 0 : } 167 : }); 168 : } 169 : 170 : private Key<HttpServlet> query(String query) { 171 99 : return key( 172 99 : new HttpServlet() { 173 : private static final long serialVersionUID = 1L; 174 : 175 : @Override 176 : protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException { 177 0 : toGerrit(PageLinks.toChangeQuery(query), req, rsp); 178 0 : } 179 : }); 180 : } 181 : 182 : private Key<HttpServlet> key(HttpServlet servlet) { 183 99 : final Key<HttpServlet> srv = Key.get(HttpServlet.class, UniqueAnnotations.create()); 184 99 : bind(srv).toProvider(() -> servlet).in(SINGLETON); 185 99 : return srv; 186 : } 187 : 188 : private Key<HttpServlet> registerScreen(final Boolean slash) { 189 99 : return key( 190 99 : new HttpServlet() { 191 : private static final long serialVersionUID = 1L; 192 : 193 : @Override 194 : protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException { 195 0 : String path = String.format("/register%s", slash ? req.getPathInfo() : ""); 196 0 : toGerrit(path, req, rsp); 197 0 : } 198 : }); 199 : } 200 : 201 : private Key<HttpServlet> redirectDocumentation() { 202 99 : return key( 203 99 : new HttpServlet() { 204 : private static final long serialVersionUID = 1L; 205 : 206 : @Override 207 : protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException { 208 0 : String path = "/Documentation/index.html"; 209 0 : toGerrit(path, req, rsp); 210 0 : } 211 : }); 212 : } 213 : 214 : static void toGerrit(String target, HttpServletRequest req, HttpServletResponse rsp) 215 : throws IOException { 216 1 : final StringBuilder url = new StringBuilder(); 217 1 : url.append(req.getContextPath()); 218 1 : url.append(target); 219 1 : rsp.sendRedirect(url.toString()); 220 1 : } 221 : }