commit | author | age
|
8c9a20
|
1 |
/*
|
JM |
2 |
* Copyright 2011 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 |
*/
|
|
16 |
package com.gitblit;
|
|
17 |
|
13a3f5
|
18 |
import java.io.IOException;
|
JM |
19 |
import java.text.MessageFormat;
|
|
20 |
|
|
21 |
import javax.servlet.FilterChain;
|
|
22 |
import javax.servlet.ServletException;
|
|
23 |
import javax.servlet.ServletRequest;
|
|
24 |
import javax.servlet.ServletResponse;
|
|
25 |
import javax.servlet.http.HttpServletRequest;
|
|
26 |
import javax.servlet.http.HttpServletResponse;
|
|
27 |
|
8c9a20
|
28 |
import com.gitblit.Constants.AccessRestrictionType;
|
13a3f5
|
29 |
import com.gitblit.models.ProjectModel;
|
8c9a20
|
30 |
import com.gitblit.models.RepositoryModel;
|
JM |
31 |
import com.gitblit.models.UserModel;
|
|
32 |
|
892570
|
33 |
/**
|
13a3f5
|
34 |
* The SyndicationFilter is an AuthenticationFilter which ensures that feed
|
JM |
35 |
* requests for projects or view-restricted repositories have proper authentication
|
892570
|
36 |
* credentials and are authorized for the requested feed.
|
JM |
37 |
*
|
|
38 |
* @author James Moger
|
|
39 |
*
|
|
40 |
*/
|
13a3f5
|
41 |
public class SyndicationFilter extends AuthenticationFilter {
|
8c9a20
|
42 |
|
892570
|
43 |
/**
|
JM |
44 |
* Extract the repository name from the url.
|
|
45 |
*
|
|
46 |
* @param url
|
|
47 |
* @return repository name
|
|
48 |
*/
|
13a3f5
|
49 |
protected String extractRequestedName(String url) {
|
565ee0
|
50 |
if (url.indexOf('?') > -1) {
|
JM |
51 |
return url.substring(0, url.indexOf('?'));
|
|
52 |
}
|
8c9a20
|
53 |
return url;
|
JM |
54 |
}
|
|
55 |
|
892570
|
56 |
/**
|
13a3f5
|
57 |
* doFilter does the actual work of preprocessing the request to ensure that
|
JM |
58 |
* the user may proceed.
|
892570
|
59 |
*
|
13a3f5
|
60 |
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
|
JM |
61 |
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
892570
|
62 |
*/
|
8c9a20
|
63 |
@Override
|
13a3f5
|
64 |
public void doFilter(final ServletRequest request, final ServletResponse response,
|
JM |
65 |
final FilterChain chain) throws IOException, ServletException {
|
8c9a20
|
66 |
|
13a3f5
|
67 |
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
JM |
68 |
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
8c9a20
|
69 |
|
13a3f5
|
70 |
String fullUrl = getFullUrl(httpRequest);
|
JM |
71 |
String name = extractRequestedName(fullUrl);
|
8c9a20
|
72 |
|
13a3f5
|
73 |
ProjectModel project = GitBlit.self().getProjectModel(name);
|
JM |
74 |
RepositoryModel model = null;
|
|
75 |
|
|
76 |
if (project == null) {
|
|
77 |
// try loading a repository model
|
|
78 |
model = GitBlit.self().getRepositoryModel(name);
|
|
79 |
if (model == null) {
|
|
80 |
// repository not found. send 404.
|
|
81 |
logger.info(MessageFormat.format("ARF: {0} ({1})", fullUrl,
|
|
82 |
HttpServletResponse.SC_NOT_FOUND));
|
|
83 |
httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
|
|
84 |
return;
|
|
85 |
}
|
|
86 |
}
|
|
87 |
|
|
88 |
// Wrap the HttpServletRequest with the AccessRestrictionRequest which
|
|
89 |
// overrides the servlet container user principal methods.
|
|
90 |
// JGit requires either:
|
|
91 |
//
|
|
92 |
// 1. servlet container authenticated user
|
|
93 |
// 2. http.receivepack = true in each repository's config
|
|
94 |
//
|
|
95 |
// Gitblit must conditionally authenticate users per-repository so just
|
|
96 |
// enabling http.receivepack is insufficient.
|
|
97 |
AuthenticatedRequest authenticatedRequest = new AuthenticatedRequest(httpRequest);
|
|
98 |
UserModel user = getUser(httpRequest);
|
|
99 |
if (user != null) {
|
|
100 |
authenticatedRequest.setUser(user);
|
|
101 |
}
|
|
102 |
|
|
103 |
// BASIC authentication challenge and response processing
|
|
104 |
if (model != null) {
|
|
105 |
if (model.accessRestriction.atLeast(AccessRestrictionType.VIEW)) {
|
|
106 |
if (user == null) {
|
|
107 |
// challenge client to provide credentials. send 401.
|
|
108 |
if (GitBlit.isDebugMode()) {
|
|
109 |
logger.info(MessageFormat.format("ARF: CHALLENGE {0}", fullUrl));
|
|
110 |
}
|
|
111 |
httpResponse.setHeader("WWW-Authenticate", CHALLENGE);
|
|
112 |
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
|
113 |
return;
|
|
114 |
} else {
|
|
115 |
// check user access for request
|
|
116 |
if (user.canAdmin || user.canAccessRepository(model)) {
|
|
117 |
// authenticated request permitted.
|
|
118 |
// pass processing to the restricted servlet.
|
|
119 |
newSession(authenticatedRequest, httpResponse);
|
|
120 |
logger.info(MessageFormat.format("ARF: {0} ({1}) authenticated", fullUrl,
|
|
121 |
HttpServletResponse.SC_CONTINUE));
|
|
122 |
chain.doFilter(authenticatedRequest, httpResponse);
|
|
123 |
return;
|
|
124 |
}
|
|
125 |
// valid user, but not for requested access. send 403.
|
|
126 |
if (GitBlit.isDebugMode()) {
|
|
127 |
logger.info(MessageFormat.format("ARF: {0} forbidden to access {1}",
|
|
128 |
user.username, fullUrl));
|
|
129 |
}
|
|
130 |
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
|
|
131 |
return;
|
|
132 |
}
|
|
133 |
}
|
|
134 |
}
|
|
135 |
|
|
136 |
if (GitBlit.isDebugMode()) {
|
|
137 |
logger.info(MessageFormat.format("ARF: {0} ({1}) unauthenticated", fullUrl,
|
|
138 |
HttpServletResponse.SC_CONTINUE));
|
|
139 |
}
|
|
140 |
// unauthenticated request permitted.
|
|
141 |
// pass processing to the restricted servlet.
|
|
142 |
chain.doFilter(authenticatedRequest, httpResponse);
|
|
143 |
}
|
8c9a20
|
144 |
}
|