Mercurial > kallithea
comparison rhodecode/lib/base.py @ 2726:aa17c7a1b8a5 beta
Implemented basic locking functionality.
- Reimplemented how githooks behave
- emaulate pre-receive hook
- install missing git hooks if they aren't already in repo
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Wed, 22 Aug 2012 00:30:02 +0200 |
parents | 9bce679a3f49 |
children | 6d904a0cd48d |
comparison
equal
deleted
inserted
replaced
2725:3853e37db97c | 2726:aa17c7a1b8a5 |
---|---|
6 import time | 6 import time |
7 import traceback | 7 import traceback |
8 | 8 |
9 from paste.auth.basic import AuthBasicAuthenticator | 9 from paste.auth.basic import AuthBasicAuthenticator |
10 from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden | 10 from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden |
11 from webob.exc import HTTPClientError | |
11 from paste.httpheaders import WWW_AUTHENTICATE | 12 from paste.httpheaders import WWW_AUTHENTICATE |
12 | 13 |
13 from pylons import config, tmpl_context as c, request, session, url | 14 from pylons import config, tmpl_context as c, request, session, url |
14 from pylons.controllers import WSGIController | 15 from pylons.controllers import WSGIController |
15 from pylons.controllers.util import redirect | 16 from pylons.controllers.util import redirect |
16 from pylons.templating import render_mako as render | 17 from pylons.templating import render_mako as render |
17 | 18 |
18 from rhodecode import __version__, BACKENDS | 19 from rhodecode import __version__, BACKENDS |
19 | 20 |
20 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict | 21 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\ |
22 safe_str | |
21 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\ | 23 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\ |
22 HasPermissionAnyMiddleware, CookieStoreWrapper | 24 HasPermissionAnyMiddleware, CookieStoreWrapper |
23 from rhodecode.lib.utils import get_repo_slug, invalidate_cache | 25 from rhodecode.lib.utils import get_repo_slug, invalidate_cache |
24 from rhodecode.model import meta | 26 from rhodecode.model import meta |
25 | 27 |
26 from rhodecode.model.db import Repository, RhodeCodeUi | 28 from rhodecode.model.db import Repository, RhodeCodeUi, User |
27 from rhodecode.model.notification import NotificationModel | 29 from rhodecode.model.notification import NotificationModel |
28 from rhodecode.model.scm import ScmModel | 30 from rhodecode.model.scm import ScmModel |
31 from rhodecode.model.meta import Session | |
29 | 32 |
30 log = logging.getLogger(__name__) | 33 log = logging.getLogger(__name__) |
31 | 34 |
32 | 35 |
33 def _get_ip_addr(environ): | 36 def _get_ip_addr(environ): |
156 if require_ssl and org_proto == 'http': | 159 if require_ssl and org_proto == 'http': |
157 log.debug('proto is %s and SSL is required BAD REQUEST !' | 160 log.debug('proto is %s and SSL is required BAD REQUEST !' |
158 % org_proto) | 161 % org_proto) |
159 return False | 162 return False |
160 return True | 163 return True |
164 | |
165 def _check_locking_state(self, environ, action, repo, user_id): | |
166 """ | |
167 Checks locking on this repository, if locking is enabled and lock is | |
168 present returns a tuple of make_lock, locked, locked_by. | |
169 make_lock can have 3 states None (do nothing) True, make lock | |
170 False release lock, This value is later propagated to hooks, which | |
171 do the locking. Think about this as signals passed to hooks what to do. | |
172 | |
173 """ | |
174 locked = False | |
175 make_lock = None | |
176 repo = Repository.get_by_repo_name(repo) | |
177 user = User.get(user_id) | |
178 | |
179 # this is kind of hacky, but due to how mercurial handles client-server | |
180 # server see all operation on changeset; bookmarks, phases and | |
181 # obsolescence marker in different transaction, we don't want to check | |
182 # locking on those | |
183 obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',] | |
184 locked_by = repo.locked | |
185 if repo and repo.enable_locking and not obsolete_call: | |
186 if action == 'push': | |
187 #check if it's already locked !, if it is compare users | |
188 user_id, _date = repo.locked | |
189 if user.user_id == user_id: | |
190 log.debug('Got push from user, now unlocking' % (user)) | |
191 # unlock if we have push from user who locked | |
192 make_lock = False | |
193 else: | |
194 # we're not the same user who locked, ban with 423 ! | |
195 locked = True | |
196 if action == 'pull': | |
197 if repo.locked[0] and repo.locked[1]: | |
198 locked = True | |
199 else: | |
200 log.debug('Setting lock on repo %s by %s' % (repo, user)) | |
201 make_lock = True | |
202 | |
203 else: | |
204 log.debug('Repository %s do not have locking enabled' % (repo)) | |
205 | |
206 return make_lock, locked, locked_by | |
161 | 207 |
162 def __call__(self, environ, start_response): | 208 def __call__(self, environ, start_response): |
163 start = time.time() | 209 start = time.time() |
164 try: | 210 try: |
165 return self._handle_request(environ, start_response) | 211 return self._handle_request(environ, start_response) |