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)