##// END OF EJS Templates
vcs: register repo_name as specialized middleware variables instead...
marcink -
r757:a5f278c1 default
parent child Browse files
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 middlewares
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(action, user, repo_name, ip_addr)
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