Show More
@@ -50,7 +50,6 b' from rhodecode.lib.vcs.backends import b' | |||
|
50 | 50 | from rhodecode.model import meta |
|
51 | 51 | from rhodecode.model.db import User, Repository |
|
52 | 52 | from rhodecode.model.scm import ScmModel |
|
53 | from rhodecode.model.settings import SettingsModel | |
|
54 | 53 | |
|
55 | 54 | |
|
56 | 55 | log = logging.getLogger(__name__) |
@@ -88,8 +87,10 b' class SimpleVCS(object):' | |||
|
88 | 87 | self.registry = registry |
|
89 | 88 | self.application = application |
|
90 | 89 | self.config = config |
|
91 |
# re-populated by specialized middleware |
|
|
90 | # re-populated by specialized middleware | |
|
91 | self.repo_name = None | |
|
92 | 92 | self.repo_vcs_config = base.Config() |
|
93 | ||
|
93 | 94 | # base path of repo locations |
|
94 | 95 | self.basepath = get_rhodecode_base_path() |
|
95 | 96 | # authenticate this VCS request using authfunc |
@@ -115,9 +116,7 b' class SimpleVCS(object):' | |||
|
115 | 116 | def _get_by_id(self, repo_name): |
|
116 | 117 | """ |
|
117 | 118 | Gets a special pattern _<ID> from clone url and tries to replace it |
|
118 | with a repository_name for support of _<ID> non changable urls | |
|
119 | ||
|
120 | :param repo_name: | |
|
119 | with a repository_name for support of _<ID> non changeable urls | |
|
121 | 120 | """ |
|
122 | 121 | |
|
123 | 122 | data = repo_name.split('/') |
@@ -234,6 +233,12 b' class SimpleVCS(object):' | |||
|
234 | 233 | log.debug('User not allowed to proceed, %s', reason) |
|
235 | 234 | return HTTPNotAcceptable(reason)(environ, start_response) |
|
236 | 235 | |
|
236 | if not self.repo_name: | |
|
237 | log.warning('Repository name is empty: %s', self.repo_name) | |
|
238 | # failed to get repo name, we fail now | |
|
239 | return HTTPNotFound()(environ, start_response) | |
|
240 | log.debug('Extracted repo name is %s', self.repo_name) | |
|
241 | ||
|
237 | 242 | ip_addr = get_ip_addr(environ) |
|
238 | 243 | username = None |
|
239 | 244 | |
@@ -241,17 +246,6 b' class SimpleVCS(object):' | |||
|
241 | 246 | environ['pylons.status_code_redirect'] = True |
|
242 | 247 | |
|
243 | 248 | # ====================================================================== |
|
244 | # EXTRACT REPOSITORY NAME FROM ENV SET IN `class VCSMiddleware` | |
|
245 | # ====================================================================== | |
|
246 | repo_name = environ['REPO_NAME'] | |
|
247 | log.debug('Extracted repo name is %s', repo_name) | |
|
248 | ||
|
249 | # check for type, presence in database and on filesystem | |
|
250 | if not self.is_valid_and_existing_repo( | |
|
251 | repo_name, self.basepath, self.SCM): | |
|
252 | return HTTPNotFound()(environ, start_response) | |
|
253 | ||
|
254 | # ====================================================================== | |
|
255 | 249 | # GET ACTION PULL or PUSH |
|
256 | 250 | # ====================================================================== |
|
257 | 251 | action = self._get_action(environ) |
@@ -265,7 +259,7 b' class SimpleVCS(object):' | |||
|
265 | 259 | if anonymous_user.active: |
|
266 | 260 | # ONLY check permissions if the user is activated |
|
267 | 261 | anonymous_perm = self._check_permission( |
|
268 | action, anonymous_user, repo_name, ip_addr) | |
|
262 | action, anonymous_user, self.repo_name, ip_addr) | |
|
269 | 263 | else: |
|
270 | 264 | anonymous_perm = False |
|
271 | 265 | |
@@ -329,7 +323,8 b' class SimpleVCS(object):' | |||
|
329 | 323 | return HTTPNotAcceptable(reason)(environ, start_response) |
|
330 | 324 | |
|
331 | 325 | # check permissions for this repository |
|
332 |
perm = self._check_permission( |
|
|
326 | perm = self._check_permission( | |
|
327 | action, user, self.repo_name, ip_addr) | |
|
333 | 328 | if not perm: |
|
334 | 329 | return HTTPForbidden()(environ, start_response) |
|
335 | 330 | |
@@ -337,14 +332,14 b' class SimpleVCS(object):' | |||
|
337 | 332 | # in hooks executed by rhodecode |
|
338 | 333 | check_locking = _should_check_locking(environ.get('QUERY_STRING')) |
|
339 | 334 | extras = vcs_operation_context( |
|
340 | environ, repo_name=repo_name, username=username, | |
|
335 | environ, repo_name=self.repo_name, username=username, | |
|
341 | 336 | action=action, scm=self.SCM, |
|
342 | 337 | check_locking=check_locking) |
|
343 | 338 | |
|
344 | 339 | # ====================================================================== |
|
345 | 340 | # REQUEST HANDLING |
|
346 | 341 | # ====================================================================== |
|
347 | str_repo_name = safe_str(repo_name) | |
|
342 | str_repo_name = safe_str(self.repo_name) | |
|
348 | 343 | repo_path = os.path.join(safe_str(self.basepath), str_repo_name) |
|
349 | 344 | log.debug('Repository path is %s', repo_path) |
|
350 | 345 | |
@@ -355,7 +350,7 b' class SimpleVCS(object):' | |||
|
355 | 350 | action, self.SCM, str_repo_name, safe_str(username), ip_addr) |
|
356 | 351 | |
|
357 | 352 | return self._generate_vcs_response( |
|
358 | environ, start_response, repo_path, repo_name, extras, action) | |
|
353 | environ, start_response, repo_path, self.repo_name, extras, action) | |
|
359 | 354 | |
|
360 | 355 | @initialize_generator |
|
361 | 356 | def _generate_vcs_response( |
@@ -24,12 +24,13 b' import logging' | |||
|
24 | 24 | import tempfile |
|
25 | 25 | import urlparse |
|
26 | 26 | |
|
27 | from webob.exc import HTTPNotFound | |
|
28 | ||
|
27 | 29 | import rhodecode |
|
28 | 30 | from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled |
|
29 | 31 | from rhodecode.lib.middleware.simplegit import SimpleGit, GIT_PROTO_PAT |
|
30 | 32 | from rhodecode.lib.middleware.simplehg import SimpleHg |
|
31 | 33 | from rhodecode.lib.middleware.simplesvn import SimpleSvn |
|
32 | from rhodecode.lib.vcs.backends import base | |
|
33 | 34 | from rhodecode.model.settings import VcsSettingsModel |
|
34 | 35 | |
|
35 | 36 | log = logging.getLogger(__name__) |
@@ -132,8 +133,14 b' class VCSMiddleware(object):' | |||
|
132 | 133 | self.config = config |
|
133 | 134 | self.appenlight_client = appenlight_client |
|
134 | 135 | self.registry = registry |
|
135 | self.repo_vcs_config = base.Config() | |
|
136 | 136 | self.use_gzip = True |
|
137 | # order in which we check the middlewares, based on vcs.backends config | |
|
138 | self.check_middlewares = config['vcs.backends'] | |
|
139 | self.checks = { | |
|
140 | 'hg': (is_hg, SimpleHg), | |
|
141 | 'git': (is_git, SimpleGit), | |
|
142 | 'svn': (is_svn, SimpleSvn), | |
|
143 | } | |
|
137 | 144 | |
|
138 | 145 | def vcs_config(self, repo_name=None): |
|
139 | 146 | """ |
@@ -141,43 +148,50 b' class VCSMiddleware(object):' | |||
|
141 | 148 | """ |
|
142 | 149 | return VcsSettingsModel(repo=repo_name).get_ui_settings_as_config_obj() |
|
143 | 150 | |
|
144 | def wrap_in_gzip_if_enabled(self, app): | |
|
151 | def wrap_in_gzip_if_enabled(self, app, config): | |
|
145 | 152 | if self.use_gzip: |
|
146 | 153 | app = GunzipMiddleware(app) |
|
147 | 154 | return app |
|
148 | 155 | |
|
149 | 156 | def _get_handler_app(self, environ): |
|
150 | 157 | app = None |
|
151 | ||
|
152 | if is_hg(environ): | |
|
153 | app = SimpleHg(self.application, self.config, self.registry) | |
|
154 | ||
|
155 | if is_git(environ): | |
|
156 | app = SimpleGit(self.application, self.config, self.registry) | |
|
157 | ||
|
158 | if is_svn(environ): | |
|
159 | app = SimpleSvn(self.application, self.config, self.registry) | |
|
160 | ||
|
161 | if app: | |
|
162 | # translate the _REPO_ID into real repo NAME for usage | |
|
163 | # in midddleware | |
|
164 | environ['PATH_INFO'] = app._get_by_id(environ['PATH_INFO']) | |
|
165 | repo_name = app._get_repository_name(environ) | |
|
166 | environ['REPO_NAME'] = repo_name | |
|
167 | ||
|
168 | self.repo_vcs_config = self.vcs_config(repo_name) | |
|
169 | app.repo_vcs_config = self.repo_vcs_config | |
|
170 | ||
|
171 | app = self.wrap_in_gzip_if_enabled(app) | |
|
172 | app, _ = wrap_in_appenlight_if_enabled( | |
|
173 | app, self.config, self.appenlight_client) | |
|
158 | log.debug('Checking vcs types in order: %r', self.check_middlewares) | |
|
159 | for vcs_type in self.check_middlewares: | |
|
160 | vcs_check, handler = self.checks[vcs_type] | |
|
161 | if vcs_check(environ): | |
|
162 | log.debug( | |
|
163 | 'Found VCS Middleware to handle the request %s', handler) | |
|
164 | app = handler(self.application, self.config, self.registry) | |
|
165 | break | |
|
174 | 166 | |
|
175 | 167 | return app |
|
176 | 168 | |
|
177 | 169 | def __call__(self, environ, start_response): |
|
178 |
# check if we handle one of interesting protocols |
|
|
170 | # check if we handle one of interesting protocols, optionally extract | |
|
171 | # specific vcsSettings and allow changes of how things are wrapped | |
|
179 | 172 | vcs_handler = self._get_handler_app(environ) |
|
180 | 173 | if vcs_handler: |
|
174 | # translate the _REPO_ID into real repo NAME for usage | |
|
175 | # in middleware | |
|
176 | environ['PATH_INFO'] = vcs_handler._get_by_id(environ['PATH_INFO']) | |
|
177 | repo_name = vcs_handler._get_repository_name(environ) | |
|
178 | ||
|
179 | # check for type, presence in database and on filesystem | |
|
180 | if not vcs_handler.is_valid_and_existing_repo( | |
|
181 | repo_name, vcs_handler.basepath, vcs_handler.SCM): | |
|
182 | return HTTPNotFound()(environ, start_response) | |
|
183 | ||
|
184 | # TODO(marcink): this is probably not needed anymore | |
|
185 | environ['REPO_NAME'] = repo_name | |
|
186 | ||
|
187 | # register repo_name and it's config back to the handler | |
|
188 | vcs_handler.repo_name = repo_name | |
|
189 | vcs_handler.repo_vcs_config = self.vcs_config(repo_name) | |
|
190 | ||
|
191 | vcs_handler = self.wrap_in_gzip_if_enabled( | |
|
192 | vcs_handler, self.config) | |
|
193 | vcs_handler, _ = wrap_in_appenlight_if_enabled( | |
|
194 | vcs_handler, self.config, self.appenlight_client) | |
|
181 | 195 | return vcs_handler(environ, start_response) |
|
182 | 196 | |
|
183 | 197 | return self.application(environ, start_response) |
@@ -42,6 +42,10 b' class StubVCSController(simplevcs.Simple' | |||
|
42 | 42 | SCM = 'hg' |
|
43 | 43 | stub_response_body = tuple() |
|
44 | 44 | |
|
45 | def __init__(self, *args, **kwargs): | |
|
46 | super(StubVCSController, self).__init__(*args, **kwargs) | |
|
47 | self.repo_name = HG_REPO | |
|
48 | ||
|
45 | 49 | def _get_repository_name(self, environ): |
|
46 | 50 | return HG_REPO |
|
47 | 51 |
@@ -105,7 +105,7 b' class TestVCSMiddleware(object):' | |||
|
105 | 105 | 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log' |
|
106 | 106 | } |
|
107 | 107 | application = Mock() |
|
108 | config = {'appenlight': False} | |
|
108 | config = {'appenlight': False, 'vcs.backends': ['svn']} | |
|
109 | 109 | registry = Mock() |
|
110 | 110 | middleware = vcs.VCSMiddleware( |
|
111 | 111 | application, config=config, |
@@ -125,7 +125,7 b' class TestVCSMiddleware(object):' | |||
|
125 | 125 | 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log' |
|
126 | 126 | } |
|
127 | 127 | application = Mock() |
|
128 | config = {'appenlight': False} | |
|
128 | config = {'appenlight': False, 'vcs.backends': ['svn']} | |
|
129 | 129 | registry = Mock() |
|
130 | 130 | middleware = vcs.VCSMiddleware( |
|
131 | 131 | application, config=config, |
General Comments 0
You need to be logged in to leave comments.
Login now