Show More
@@ -50,7 +50,6 b' from rhodecode.lib.vcs.backends import b' | |||||
50 | from rhodecode.model import meta |
|
50 | from rhodecode.model import meta | |
51 | from rhodecode.model.db import User, Repository |
|
51 | from rhodecode.model.db import User, Repository | |
52 | from rhodecode.model.scm import ScmModel |
|
52 | from rhodecode.model.scm import ScmModel | |
53 | from rhodecode.model.settings import SettingsModel |
|
|||
54 |
|
53 | |||
55 |
|
54 | |||
56 | log = logging.getLogger(__name__) |
|
55 | log = logging.getLogger(__name__) | |
@@ -88,8 +87,10 b' class SimpleVCS(object):' | |||||
88 | self.registry = registry |
|
87 | self.registry = registry | |
89 | self.application = application |
|
88 | self.application = application | |
90 | self.config = config |
|
89 | self.config = config | |
91 |
# re-populated by specialized middleware |
|
90 | # re-populated by specialized middleware | |
|
91 | self.repo_name = None | |||
92 | self.repo_vcs_config = base.Config() |
|
92 | self.repo_vcs_config = base.Config() | |
|
93 | ||||
93 | # base path of repo locations |
|
94 | # base path of repo locations | |
94 | self.basepath = get_rhodecode_base_path() |
|
95 | self.basepath = get_rhodecode_base_path() | |
95 | # authenticate this VCS request using authfunc |
|
96 | # authenticate this VCS request using authfunc | |
@@ -115,9 +116,7 b' class SimpleVCS(object):' | |||||
115 | def _get_by_id(self, repo_name): |
|
116 | def _get_by_id(self, repo_name): | |
116 | """ |
|
117 | """ | |
117 | Gets a special pattern _<ID> from clone url and tries to replace it |
|
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 | with a repository_name for support of _<ID> non changeable urls | |
119 |
|
||||
120 | :param repo_name: |
|
|||
121 | """ |
|
120 | """ | |
122 |
|
121 | |||
123 | data = repo_name.split('/') |
|
122 | data = repo_name.split('/') | |
@@ -234,6 +233,12 b' class SimpleVCS(object):' | |||||
234 | log.debug('User not allowed to proceed, %s', reason) |
|
233 | log.debug('User not allowed to proceed, %s', reason) | |
235 | return HTTPNotAcceptable(reason)(environ, start_response) |
|
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 | ip_addr = get_ip_addr(environ) |
|
242 | ip_addr = get_ip_addr(environ) | |
238 | username = None |
|
243 | username = None | |
239 |
|
244 | |||
@@ -241,17 +246,6 b' class SimpleVCS(object):' | |||||
241 | environ['pylons.status_code_redirect'] = True |
|
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 | # GET ACTION PULL or PUSH |
|
249 | # GET ACTION PULL or PUSH | |
256 | # ====================================================================== |
|
250 | # ====================================================================== | |
257 | action = self._get_action(environ) |
|
251 | action = self._get_action(environ) | |
@@ -265,7 +259,7 b' class SimpleVCS(object):' | |||||
265 | if anonymous_user.active: |
|
259 | if anonymous_user.active: | |
266 | # ONLY check permissions if the user is activated |
|
260 | # ONLY check permissions if the user is activated | |
267 | anonymous_perm = self._check_permission( |
|
261 | anonymous_perm = self._check_permission( | |
268 | action, anonymous_user, repo_name, ip_addr) |
|
262 | action, anonymous_user, self.repo_name, ip_addr) | |
269 | else: |
|
263 | else: | |
270 | anonymous_perm = False |
|
264 | anonymous_perm = False | |
271 |
|
265 | |||
@@ -329,7 +323,8 b' class SimpleVCS(object):' | |||||
329 | return HTTPNotAcceptable(reason)(environ, start_response) |
|
323 | return HTTPNotAcceptable(reason)(environ, start_response) | |
330 |
|
324 | |||
331 | # check permissions for this repository |
|
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 | if not perm: |
|
328 | if not perm: | |
334 | return HTTPForbidden()(environ, start_response) |
|
329 | return HTTPForbidden()(environ, start_response) | |
335 |
|
330 | |||
@@ -337,14 +332,14 b' class SimpleVCS(object):' | |||||
337 | # in hooks executed by rhodecode |
|
332 | # in hooks executed by rhodecode | |
338 | check_locking = _should_check_locking(environ.get('QUERY_STRING')) |
|
333 | check_locking = _should_check_locking(environ.get('QUERY_STRING')) | |
339 | extras = vcs_operation_context( |
|
334 | extras = vcs_operation_context( | |
340 | environ, repo_name=repo_name, username=username, |
|
335 | environ, repo_name=self.repo_name, username=username, | |
341 | action=action, scm=self.SCM, |
|
336 | action=action, scm=self.SCM, | |
342 | check_locking=check_locking) |
|
337 | check_locking=check_locking) | |
343 |
|
338 | |||
344 | # ====================================================================== |
|
339 | # ====================================================================== | |
345 | # REQUEST HANDLING |
|
340 | # REQUEST HANDLING | |
346 | # ====================================================================== |
|
341 | # ====================================================================== | |
347 | str_repo_name = safe_str(repo_name) |
|
342 | str_repo_name = safe_str(self.repo_name) | |
348 | repo_path = os.path.join(safe_str(self.basepath), str_repo_name) |
|
343 | repo_path = os.path.join(safe_str(self.basepath), str_repo_name) | |
349 | log.debug('Repository path is %s', repo_path) |
|
344 | log.debug('Repository path is %s', repo_path) | |
350 |
|
345 | |||
@@ -355,7 +350,7 b' class SimpleVCS(object):' | |||||
355 | action, self.SCM, str_repo_name, safe_str(username), ip_addr) |
|
350 | action, self.SCM, str_repo_name, safe_str(username), ip_addr) | |
356 |
|
351 | |||
357 | return self._generate_vcs_response( |
|
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 | @initialize_generator |
|
355 | @initialize_generator | |
361 | def _generate_vcs_response( |
|
356 | def _generate_vcs_response( |
@@ -24,12 +24,13 b' import logging' | |||||
24 | import tempfile |
|
24 | import tempfile | |
25 | import urlparse |
|
25 | import urlparse | |
26 |
|
26 | |||
|
27 | from webob.exc import HTTPNotFound | |||
|
28 | ||||
27 | import rhodecode |
|
29 | import rhodecode | |
28 | from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled |
|
30 | from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled | |
29 | from rhodecode.lib.middleware.simplegit import SimpleGit, GIT_PROTO_PAT |
|
31 | from rhodecode.lib.middleware.simplegit import SimpleGit, GIT_PROTO_PAT | |
30 | from rhodecode.lib.middleware.simplehg import SimpleHg |
|
32 | from rhodecode.lib.middleware.simplehg import SimpleHg | |
31 | from rhodecode.lib.middleware.simplesvn import SimpleSvn |
|
33 | from rhodecode.lib.middleware.simplesvn import SimpleSvn | |
32 | from rhodecode.lib.vcs.backends import base |
|
|||
33 | from rhodecode.model.settings import VcsSettingsModel |
|
34 | from rhodecode.model.settings import VcsSettingsModel | |
34 |
|
35 | |||
35 | log = logging.getLogger(__name__) |
|
36 | log = logging.getLogger(__name__) | |
@@ -132,8 +133,14 b' class VCSMiddleware(object):' | |||||
132 | self.config = config |
|
133 | self.config = config | |
133 | self.appenlight_client = appenlight_client |
|
134 | self.appenlight_client = appenlight_client | |
134 | self.registry = registry |
|
135 | self.registry = registry | |
135 | self.repo_vcs_config = base.Config() |
|
|||
136 | self.use_gzip = True |
|
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 | def vcs_config(self, repo_name=None): |
|
145 | def vcs_config(self, repo_name=None): | |
139 | """ |
|
146 | """ | |
@@ -141,43 +148,50 b' class VCSMiddleware(object):' | |||||
141 | """ |
|
148 | """ | |
142 | return VcsSettingsModel(repo=repo_name).get_ui_settings_as_config_obj() |
|
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 | if self.use_gzip: |
|
152 | if self.use_gzip: | |
146 | app = GunzipMiddleware(app) |
|
153 | app = GunzipMiddleware(app) | |
147 | return app |
|
154 | return app | |
148 |
|
155 | |||
149 | def _get_handler_app(self, environ): |
|
156 | def _get_handler_app(self, environ): | |
150 | app = None |
|
157 | app = None | |
151 |
|
158 | log.debug('Checking vcs types in order: %r', self.check_middlewares) | ||
152 | if is_hg(environ): |
|
159 | for vcs_type in self.check_middlewares: | |
153 | app = SimpleHg(self.application, self.config, self.registry) |
|
160 | vcs_check, handler = self.checks[vcs_type] | |
154 |
|
161 | if vcs_check(environ): | ||
155 | if is_git(environ): |
|
162 | log.debug( | |
156 | app = SimpleGit(self.application, self.config, self.registry) |
|
163 | 'Found VCS Middleware to handle the request %s', handler) | |
157 |
|
164 | app = handler(self.application, self.config, self.registry) | ||
158 | if is_svn(environ): |
|
165 | break | |
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) |
|
|||
174 |
|
166 | |||
175 | return app |
|
167 | return app | |
176 |
|
168 | |||
177 | def __call__(self, environ, start_response): |
|
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 | vcs_handler = self._get_handler_app(environ) |
|
172 | vcs_handler = self._get_handler_app(environ) | |
180 | if vcs_handler: |
|
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 | return vcs_handler(environ, start_response) |
|
195 | return vcs_handler(environ, start_response) | |
182 |
|
196 | |||
183 | return self.application(environ, start_response) |
|
197 | return self.application(environ, start_response) |
@@ -42,6 +42,10 b' class StubVCSController(simplevcs.Simple' | |||||
42 | SCM = 'hg' |
|
42 | SCM = 'hg' | |
43 | stub_response_body = tuple() |
|
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 | def _get_repository_name(self, environ): |
|
49 | def _get_repository_name(self, environ): | |
46 | return HG_REPO |
|
50 | return HG_REPO | |
47 |
|
51 |
@@ -105,7 +105,7 b' class TestVCSMiddleware(object):' | |||||
105 | 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log' |
|
105 | 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log' | |
106 | } |
|
106 | } | |
107 | application = Mock() |
|
107 | application = Mock() | |
108 | config = {'appenlight': False} |
|
108 | config = {'appenlight': False, 'vcs.backends': ['svn']} | |
109 | registry = Mock() |
|
109 | registry = Mock() | |
110 | middleware = vcs.VCSMiddleware( |
|
110 | middleware = vcs.VCSMiddleware( | |
111 | application, config=config, |
|
111 | application, config=config, | |
@@ -125,7 +125,7 b' class TestVCSMiddleware(object):' | |||||
125 | 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log' |
|
125 | 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log' | |
126 | } |
|
126 | } | |
127 | application = Mock() |
|
127 | application = Mock() | |
128 | config = {'appenlight': False} |
|
128 | config = {'appenlight': False, 'vcs.backends': ['svn']} | |
129 | registry = Mock() |
|
129 | registry = Mock() | |
130 | middleware = vcs.VCSMiddleware( |
|
130 | middleware = vcs.VCSMiddleware( | |
131 | application, config=config, |
|
131 | application, config=config, |
General Comments 0
You need to be logged in to leave comments.
Login now