Show More
@@ -4,6 +4,9 b' Provides the BaseController class for su' | |||||
4 | """ |
|
4 | """ | |
5 | import logging |
|
5 | import logging | |
6 | import time |
|
6 | import time | |
|
7 | ||||
|
8 | from paste.auth.basic import AuthBasicAuthenticator | |||
|
9 | ||||
7 | from pylons import config, tmpl_context as c, request, session, url |
|
10 | from pylons import config, tmpl_context as c, request, session, url | |
8 | from pylons.controllers import WSGIController |
|
11 | from pylons.controllers import WSGIController | |
9 | from pylons.controllers.util import redirect |
|
12 | from pylons.controllers.util import redirect | |
@@ -12,8 +15,9 b' from pylons.templating import render_mak' | |||||
12 | from rhodecode import __version__, BACKENDS |
|
15 | from rhodecode import __version__, BACKENDS | |
13 |
|
16 | |||
14 | from rhodecode.lib import str2bool |
|
17 | from rhodecode.lib import str2bool | |
15 | from rhodecode.lib.auth import AuthUser, get_container_username |
|
18 | from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\ | |
16 | from rhodecode.lib.utils import get_repo_slug |
|
19 | HasPermissionAnyMiddleware | |
|
20 | from rhodecode.lib.utils import get_repo_slug, invalidate_cache | |||
17 | from rhodecode.model import meta |
|
21 | from rhodecode.model import meta | |
18 |
|
22 | |||
19 | from rhodecode.model.db import Repository |
|
23 | from rhodecode.model.db import Repository | |
@@ -22,6 +26,60 b' from rhodecode.model.scm import ScmModel' | |||||
22 |
|
26 | |||
23 | log = logging.getLogger(__name__) |
|
27 | log = logging.getLogger(__name__) | |
24 |
|
28 | |||
|
29 | class BaseVCSController(object): | |||
|
30 | ||||
|
31 | def __init__(self, application, config): | |||
|
32 | self.application = application | |||
|
33 | self.config = config | |||
|
34 | # base path of repo locations | |||
|
35 | self.basepath = self.config['base_path'] | |||
|
36 | #authenticate this mercurial request using authfunc | |||
|
37 | self.authenticate = AuthBasicAuthenticator('', authfunc) | |||
|
38 | self.ipaddr = '0.0.0.0' | |||
|
39 | ||||
|
40 | def _invalidate_cache(self, repo_name): | |||
|
41 | """ | |||
|
42 | Set's cache for this repository for invalidation on next access | |||
|
43 | ||||
|
44 | :param repo_name: full repo name, also a cache key | |||
|
45 | """ | |||
|
46 | invalidate_cache('get_repo_cached_%s' % repo_name) | |||
|
47 | ||||
|
48 | def _check_permission(self, action, user, repo_name): | |||
|
49 | """ | |||
|
50 | Checks permissions using action (push/pull) user and repository | |||
|
51 | name | |||
|
52 | ||||
|
53 | :param action: push or pull action | |||
|
54 | :param user: user instance | |||
|
55 | :param repo_name: repository name | |||
|
56 | """ | |||
|
57 | if action == 'push': | |||
|
58 | if not HasPermissionAnyMiddleware('repository.write', | |||
|
59 | 'repository.admin')(user, | |||
|
60 | repo_name): | |||
|
61 | return False | |||
|
62 | ||||
|
63 | else: | |||
|
64 | #any other action need at least read permission | |||
|
65 | if not HasPermissionAnyMiddleware('repository.read', | |||
|
66 | 'repository.write', | |||
|
67 | 'repository.admin')(user, | |||
|
68 | repo_name): | |||
|
69 | return False | |||
|
70 | ||||
|
71 | return True | |||
|
72 | ||||
|
73 | def __call__(self, environ, start_response): | |||
|
74 | start = time.time() | |||
|
75 | try: | |||
|
76 | return self._handle_request(environ, start_response) | |||
|
77 | finally: | |||
|
78 | log = logging.getLogger(self.__class__.__name__) | |||
|
79 | log.debug('Request time: %.3fs' % (time.time() - start)) | |||
|
80 | meta.Session.remove() | |||
|
81 | ||||
|
82 | ||||
25 | class BaseController(WSGIController): |
|
83 | class BaseController(WSGIController): | |
26 |
|
84 | |||
27 | def __before__(self): |
|
85 | def __before__(self): |
@@ -30,7 +30,6 b' import traceback' | |||||
30 |
|
30 | |||
31 | from dulwich import server as dulserver |
|
31 | from dulwich import server as dulserver | |
32 |
|
32 | |||
33 |
|
||||
34 | class SimpleGitUploadPackHandler(dulserver.UploadPackHandler): |
|
33 | class SimpleGitUploadPackHandler(dulserver.UploadPackHandler): | |
35 |
|
34 | |||
36 | def handle(self): |
|
35 | def handle(self): | |
@@ -66,12 +65,12 b' dulserver.DEFAULT_HANDLERS = {' | |||||
66 | from dulwich.repo import Repo |
|
65 | from dulwich.repo import Repo | |
67 | from dulwich.web import HTTPGitApplication |
|
66 | from dulwich.web import HTTPGitApplication | |
68 |
|
67 | |||
69 | from paste.auth.basic import AuthBasicAuthenticator |
|
|||
70 | from paste.httpheaders import REMOTE_USER, AUTH_TYPE |
|
68 | from paste.httpheaders import REMOTE_USER, AUTH_TYPE | |
71 |
|
69 | |||
72 | from rhodecode.lib import safe_str |
|
70 | from rhodecode.lib import safe_str | |
73 | from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware, get_container_username |
|
71 | from rhodecode.lib.base import BaseVCSController | |
74 | from rhodecode.lib.utils import invalidate_cache, is_valid_repo |
|
72 | from rhodecode.lib.auth import get_container_username | |
|
73 | from rhodecode.lib.utils import is_valid_repo | |||
75 | from rhodecode.model.db import User |
|
74 | from rhodecode.model.db import User | |
76 |
|
75 | |||
77 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError |
|
76 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError | |
@@ -91,17 +90,9 b' def is_git(environ):' | |||||
91 | return False |
|
90 | return False | |
92 |
|
91 | |||
93 |
|
92 | |||
94 |
class SimpleGit( |
|
93 | class SimpleGit(BaseVCSController): | |
95 |
|
94 | |||
96 | def __init__(self, application, config): |
|
95 | def _handle_request(self, environ, start_response): | |
97 | self.application = application |
|
|||
98 | self.config = config |
|
|||
99 | # base path of repo locations |
|
|||
100 | self.basepath = self.config['base_path'] |
|
|||
101 | #authenticate this mercurial request using authfunc |
|
|||
102 | self.authenticate = AuthBasicAuthenticator('', authfunc) |
|
|||
103 |
|
||||
104 | def __call__(self, environ, start_response): |
|
|||
105 | if not is_git(environ): |
|
96 | if not is_git(environ): | |
106 | return self.application(environ, start_response) |
|
97 | return self.application(environ, start_response) | |
107 |
|
98 | |||
@@ -132,9 +123,8 b' class SimpleGit(object):' | |||||
132 | if action in ['pull', 'push']: |
|
123 | if action in ['pull', 'push']: | |
133 | anonymous_user = self.__get_user('default') |
|
124 | anonymous_user = self.__get_user('default') | |
134 | username = anonymous_user.username |
|
125 | username = anonymous_user.username | |
135 |
anonymous_perm = self. |
|
126 | anonymous_perm = self._check_permission(action,anonymous_user, | |
136 |
|
|
127 | repo_name) | |
137 | repo_name) |
|
|||
138 |
|
128 | |||
139 | if anonymous_perm is not True or anonymous_user.active is False: |
|
129 | if anonymous_perm is not True or anonymous_user.active is False: | |
140 | if anonymous_perm is not True: |
|
130 | if anonymous_perm is not True: | |
@@ -179,16 +169,11 b' class SimpleGit(object):' | |||||
179 | start_response) |
|
169 | start_response) | |
180 |
|
170 | |||
181 | #check permissions for this repository |
|
171 | #check permissions for this repository | |
182 |
perm = self. |
|
172 | perm = self._check_permission(action, user, | |
183 | repo_name) |
|
173 | repo_name) | |
184 | if perm is not True: |
|
174 | if perm is not True: | |
185 | return HTTPForbidden()(environ, start_response) |
|
175 | return HTTPForbidden()(environ, start_response) | |
186 |
|
176 | |||
187 | extras = {'ip': ipaddr, |
|
|||
188 | 'username': username, |
|
|||
189 | 'action': action, |
|
|||
190 | 'repository': repo_name} |
|
|||
191 |
|
||||
192 | #=================================================================== |
|
177 | #=================================================================== | |
193 | # GIT REQUEST HANDLING |
|
178 | # GIT REQUEST HANDLING | |
194 | #=================================================================== |
|
179 | #=================================================================== | |
@@ -203,7 +188,7 b' class SimpleGit(object):' | |||||
203 | try: |
|
188 | try: | |
204 | #invalidate cache on push |
|
189 | #invalidate cache on push | |
205 | if action == 'push': |
|
190 | if action == 'push': | |
206 |
self. |
|
191 | self._invalidate_cache(repo_name) | |
207 |
|
192 | |||
208 | app = self.__make_app(repo_name, repo_path) |
|
193 | app = self.__make_app(repo_name, repo_path) | |
209 | return app(environ, start_response) |
|
194 | return app(environ, start_response) | |
@@ -225,31 +210,6 b' class SimpleGit(object):' | |||||
225 |
|
210 | |||
226 | return gitserve |
|
211 | return gitserve | |
227 |
|
212 | |||
228 | def __check_permission(self, action, user, repo_name): |
|
|||
229 | """ |
|
|||
230 | Checks permissions using action (push/pull) user and repository |
|
|||
231 | name |
|
|||
232 |
|
||||
233 | :param action: push or pull action |
|
|||
234 | :param user: user instance |
|
|||
235 | :param repo_name: repository name |
|
|||
236 | """ |
|
|||
237 | if action == 'push': |
|
|||
238 | if not HasPermissionAnyMiddleware('repository.write', |
|
|||
239 | 'repository.admin')(user, |
|
|||
240 | repo_name): |
|
|||
241 | return False |
|
|||
242 |
|
||||
243 | else: |
|
|||
244 | #any other action need at least read permission |
|
|||
245 | if not HasPermissionAnyMiddleware('repository.read', |
|
|||
246 | 'repository.write', |
|
|||
247 | 'repository.admin')(user, |
|
|||
248 | repo_name): |
|
|||
249 | return False |
|
|||
250 |
|
||||
251 | return True |
|
|||
252 |
|
||||
253 | def __get_repository(self, environ): |
|
213 | def __get_repository(self, environ): | |
254 | """ |
|
214 | """ | |
255 | Get's repository name out of PATH_INFO header |
|
215 | Get's repository name out of PATH_INFO header | |
@@ -285,10 +245,3 b' class SimpleGit(object):' | |||||
285 | service_cmd if service_cmd else 'other') |
|
245 | service_cmd if service_cmd else 'other') | |
286 | else: |
|
246 | else: | |
287 | return 'other' |
|
247 | return 'other' | |
288 |
|
||||
289 | def __invalidate_cache(self, repo_name): |
|
|||
290 | """we know that some change was made to repositories and we should |
|
|||
291 | invalidate the cache to see the changes right away but only for |
|
|||
292 | push requests""" |
|
|||
293 | invalidate_cache('get_repo_cached_%s' % repo_name) |
|
|||
294 |
|
@@ -31,13 +31,12 b' import traceback' | |||||
31 | from mercurial.error import RepoError |
|
31 | from mercurial.error import RepoError | |
32 | from mercurial.hgweb import hgweb_mod |
|
32 | from mercurial.hgweb import hgweb_mod | |
33 |
|
33 | |||
34 | from paste.auth.basic import AuthBasicAuthenticator |
|
|||
35 | from paste.httpheaders import REMOTE_USER, AUTH_TYPE |
|
34 | from paste.httpheaders import REMOTE_USER, AUTH_TYPE | |
36 |
|
35 | |||
37 | from rhodecode.lib import safe_str |
|
36 | from rhodecode.lib import safe_str | |
38 | from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware, get_container_username |
|
37 | from rhodecode.lib.base import BaseVCSController | |
39 |
from rhodecode.lib. |
|
38 | from rhodecode.lib.auth import get_container_username | |
40 | is_valid_repo, ui_sections |
|
39 | from rhodecode.lib.utils import make_ui, is_valid_repo, ui_sections | |
41 | from rhodecode.model.db import User |
|
40 | from rhodecode.model.db import User | |
42 |
|
41 | |||
43 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError |
|
42 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError | |
@@ -55,18 +54,9 b' def is_mercurial(environ):' | |||||
55 | return False |
|
54 | return False | |
56 |
|
55 | |||
57 |
|
56 | |||
58 |
class SimpleHg( |
|
57 | class SimpleHg(BaseVCSController): | |
59 |
|
58 | |||
60 | def __init__(self, application, config): |
|
59 | def _handle_request(self, environ, start_response): | |
61 | self.application = application |
|
|||
62 | self.config = config |
|
|||
63 | # base path of repo locations |
|
|||
64 | self.basepath = self.config['base_path'] |
|
|||
65 | #authenticate this mercurial request using authfunc |
|
|||
66 | self.authenticate = AuthBasicAuthenticator('', authfunc) |
|
|||
67 | self.ipaddr = '0.0.0.0' |
|
|||
68 |
|
||||
69 | def __call__(self, environ, start_response): |
|
|||
70 | if not is_mercurial(environ): |
|
60 | if not is_mercurial(environ): | |
71 | return self.application(environ, start_response) |
|
61 | return self.application(environ, start_response) | |
72 |
|
62 | |||
@@ -98,9 +88,8 b' class SimpleHg(object):' | |||||
98 | anonymous_user = self.__get_user('default') |
|
88 | anonymous_user = self.__get_user('default') | |
99 |
|
89 | |||
100 | username = anonymous_user.username |
|
90 | username = anonymous_user.username | |
101 |
anonymous_perm = self. |
|
91 | anonymous_perm = self._check_permission(action,anonymous_user, | |
102 |
|
|
92 | repo_name) | |
103 | repo_name) |
|
|||
104 |
|
93 | |||
105 | if anonymous_perm is not True or anonymous_user.active is False: |
|
94 | if anonymous_perm is not True or anonymous_user.active is False: | |
106 | if anonymous_perm is not True: |
|
95 | if anonymous_perm is not True: | |
@@ -145,7 +134,7 b' class SimpleHg(object):' | |||||
145 | start_response) |
|
134 | start_response) | |
146 |
|
135 | |||
147 | #check permissions for this repository |
|
136 | #check permissions for this repository | |
148 |
perm = self. |
|
137 | perm = self._check_permission(action, user, | |
149 | repo_name) |
|
138 | repo_name) | |
150 | if perm is not True: |
|
139 | if perm is not True: | |
151 | return HTTPForbidden()(environ, start_response) |
|
140 | return HTTPForbidden()(environ, start_response) | |
@@ -171,9 +160,9 b' class SimpleHg(object):' | |||||
171 | return HTTPNotFound()(environ, start_response) |
|
160 | return HTTPNotFound()(environ, start_response) | |
172 |
|
161 | |||
173 | try: |
|
162 | try: | |
174 | #invalidate cache on push |
|
163 | # invalidate cache on push | |
175 | if action == 'push': |
|
164 | if action == 'push': | |
176 |
self. |
|
165 | self._invalidate_cache(repo_name) | |
177 |
|
166 | |||
178 | app = self.__make_app(repo_path, baseui, extras) |
|
167 | app = self.__make_app(repo_path, baseui, extras) | |
179 | return app(environ, start_response) |
|
168 | return app(environ, start_response) | |
@@ -192,31 +181,6 b' class SimpleHg(object):' | |||||
192 | return hgweb_mod.hgweb(repo_name, name=repo_name, baseui=baseui) |
|
181 | return hgweb_mod.hgweb(repo_name, name=repo_name, baseui=baseui) | |
193 |
|
182 | |||
194 |
|
183 | |||
195 | def __check_permission(self, action, user, repo_name): |
|
|||
196 | """ |
|
|||
197 | Checks permissions using action (push/pull) user and repository |
|
|||
198 | name |
|
|||
199 |
|
||||
200 | :param action: push or pull action |
|
|||
201 | :param user: user instance |
|
|||
202 | :param repo_name: repository name |
|
|||
203 | """ |
|
|||
204 | if action == 'push': |
|
|||
205 | if not HasPermissionAnyMiddleware('repository.write', |
|
|||
206 | 'repository.admin')(user, |
|
|||
207 | repo_name): |
|
|||
208 | return False |
|
|||
209 |
|
||||
210 | else: |
|
|||
211 | #any other action need at least read permission |
|
|||
212 | if not HasPermissionAnyMiddleware('repository.read', |
|
|||
213 | 'repository.write', |
|
|||
214 | 'repository.admin')(user, |
|
|||
215 | repo_name): |
|
|||
216 | return False |
|
|||
217 |
|
||||
218 | return True |
|
|||
219 |
|
||||
220 | def __get_repository(self, environ): |
|
184 | def __get_repository(self, environ): | |
221 | """ |
|
185 | """ | |
222 | Get's repository name out of PATH_INFO header |
|
186 | Get's repository name out of PATH_INFO header | |
@@ -257,11 +221,6 b' class SimpleHg(object):' | |||||
257 | else: |
|
221 | else: | |
258 | return 'pull' |
|
222 | return 'pull' | |
259 |
|
223 | |||
260 | def __invalidate_cache(self, repo_name): |
|
|||
261 | """we know that some change was made to repositories and we should |
|
|||
262 | invalidate the cache to see the changes right away but only for |
|
|||
263 | push requests""" |
|
|||
264 | invalidate_cache('get_repo_cached_%s' % repo_name) |
|
|||
265 |
|
224 | |||
266 | def __inject_extras(self, repo_path, baseui, extras={}): |
|
225 | def __inject_extras(self, repo_path, baseui, extras={}): | |
267 | """ |
|
226 | """ |
General Comments 0
You need to be logged in to leave comments.
Login now