@@ -122,111 +122,110 @@ class SimpleGit(BaseVCSController):
# quick check if that dir exists...
if is_valid_repo(repo_name, self.basepath) is False:
return HTTPNotFound()(environ, start_response)
#======================================================================
# GET ACTION PULL or PUSH
action = self.__get_action(environ)
# CHECK ANONYMOUS PERMISSION
if action in ['pull', 'push']:
anonymous_user = self.__get_user('default')
username = anonymous_user.username
anonymous_perm = self._check_permission(action, anonymous_user,
repo_name)
if anonymous_perm is not True or anonymous_user.active is False:
if anonymous_perm is not True:
log.debug('Not enough credentials to access this '
'repository as anonymous user')
if anonymous_user.active is False:
log.debug('Anonymous access is disabled, running '
'authentication')
#==============================================================
# DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE
# NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
# Attempting to retrieve username from the container
username = get_container_username(environ, self.config)
# If not authenticated by the container, running basic auth
if not username:
self.authenticate.realm = \
safe_str(self.config['rhodecode_realm'])
result = self.authenticate(environ)
if isinstance(result, str):
AUTH_TYPE.update(environ, 'basic')
REMOTE_USER.update(environ, result)
username = result
else:
return result.wsgi_application(environ, start_response)
# CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME
try:
user = self.__get_user(username)
if user is None or not user.active:
return HTTPForbidden()(environ, start_response)
username = user.username
except:
log.error(traceback.format_exc())
return HTTPInternalServerError()(environ,
start_response)
return HTTPInternalServerError()(environ, start_response)
#check permissions for this repository
perm = self._check_permission(action, user, repo_name)
if perm is not True:
extras = {
'ip': ipaddr,
'username': username,
'action': action,
'repository': repo_name,
'scm': 'git',
}
#===================================================================
# GIT REQUEST HANDLING
repo_path = os.path.join(safe_str(self.basepath), safe_str(repo_name))
log.debug('Repository path is %s' % repo_path)
baseui = make_ui('db')
self.__inject_extras(repo_path, baseui, extras)
# invalidate cache on push
if action == 'push':
self._invalidate_cache(repo_name)
self._handle_githooks(repo_name, action, baseui, environ)
log.info('%s action on GIT repo "%s"' % (action, repo_name))
app = self.__make_app(repo_name, repo_path, username)
return app(environ, start_response)
except Exception:
def __make_app(self, repo_name, repo_path, username):
"""
Make an wsgi application using dulserver
:param repo_name: name of the repository
:param repo_path: full path to the repository
from rhodecode.lib.middleware.pygrack import make_wsgi_app
app = make_wsgi_app(
repo_root=safe_str(self.basepath),
repo_name=repo_name,
username=username,
)
return app
def __get_repository(self, environ):
@@ -25,172 +25,170 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import logging
import traceback
import urllib
from mercurial.error import RepoError
from mercurial.hgweb import hgweb_mod
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
from rhodecode.lib.utils2 import safe_str
from rhodecode.lib.base import BaseVCSController
from rhodecode.lib.auth import get_container_username
from rhodecode.lib.utils import make_ui, is_valid_repo, ui_sections
from rhodecode.model.db import User
from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
log = logging.getLogger(__name__)
def is_mercurial(environ):
Returns True if request's target is mercurial server - header
``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
http_accept = environ.get('HTTP_ACCEPT')
path_info = environ['PATH_INFO']
if http_accept and http_accept.startswith('application/mercurial'):
ishg_path = True
ishg_path = False
log.debug('pathinfo: %s detected as HG %s' % (
path_info, ishg_path)
return ishg_path
class SimpleHg(BaseVCSController):
def _handle_request(self, environ, start_response):
if not is_mercurial(environ):
return self.application(environ, start_response)
ipaddr = self._get_ip_addr(environ)
username = None
# skip passing error to error controller
environ['pylons.status_code_redirect'] = True
# EXTRACT REPOSITORY NAME FROM ENV
repo_name = environ['REPO_NAME'] = self.__get_repository(environ)
log.debug('Extracted repo name is %s' % repo_name)
# extras are injected into mercurial UI object and later available
# in hg hooks executed by rhodecode
'scm': 'hg',
# MERCURIAL REQUEST HANDLING
log.info('%s action on HG repo "%s"' % (action, repo_name))
app = self.__make_app(repo_path, baseui, extras)
except RepoError, e:
if str(e).find('not found') != -1:
def __make_app(self, repo_name, baseui, extras):
Make an wsgi application using hgweb, and inject generated baseui
instance, additionally inject some extras into ui object
return hgweb_mod.hgweb(repo_name, name=repo_name, baseui=baseui)
Get's repository name out of PATH_INFO header
:param environ: environ where PATH_INFO is stored
Status change: