def __create_repo(self, repo_name, alias, new_parent_id, clone_uri=False): """ makes repository on filesystem. It's group aware means it'll create a repository within a group, and alter the paths accordingly of group location :param repo_name: :param alias: :param parent_id: :param clone_uri: """ from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group if new_parent_id: paths = RepoGroup.get(new_parent_id).full_path.split(RepoGroup.url_sep()) new_parent_path = os.sep.join(paths) else: new_parent_path = "" # we need to make it str for mercurial repo_path = os.path.join(*map(lambda x: safe_str(x), [self.repos_path, new_parent_path, repo_name])) # check if this path is not a repository if is_valid_repo(repo_path, self.repos_path): raise Exception("This path %s is a valid repository" % repo_path) # check if this path is a group if is_valid_repos_group(repo_path, self.repos_path): raise Exception("This path %s is a valid group" % repo_path) log.info("creating repo %s in %s @ %s" % (repo_name, safe_unicode(repo_path), clone_uri)) backend = get_backend(alias) backend(repo_path, create=True, src_url=clone_uri)
def check_repo(environ, match_dict): """ check for valid repository for proper 404 handling :param environ: :param match_dict: """ repo_name = match_dict.get('repo_name') return is_valid_repo(repo_name, config['base_path'])
def is_valid(cls, repo_name): """ returns True if given repo name is a valid filesystem repository :param cls: :param repo_name: """ from rhodecode.lib.utils import is_valid_repo return is_valid_repo(repo_name, cls.base_path())
def __create_repo(self, repo_name, alias, parent, clone_uri=False, repo_store_location=None): """ makes repository on filesystem. It's group aware means it'll create a repository within a group, and alter the paths accordingly of group location :param repo_name: :param alias: :param parent_id: :param clone_uri: :param repo_path: """ from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group from rhodecode.model.scm import ScmModel if parent: new_parent_path = os.sep.join(parent.full_path_splitted) else: new_parent_path = '' if repo_store_location: _paths = [repo_store_location] else: _paths = [self.repos_path, new_parent_path, repo_name] # we need to make it str for mercurial repo_path = os.path.join(*map(lambda x: safe_str(x), _paths)) # check if this path is not a repository if is_valid_repo(repo_path, self.repos_path): raise Exception('This path %s is a valid repository' % repo_path) # check if this path is a group if is_valid_repos_group(repo_path, self.repos_path): raise Exception('This path %s is a valid group' % repo_path) log.info( 'creating repo %s in %s @ %s' % (repo_name, safe_unicode(repo_path), obfuscate_url_pw(clone_uri))) backend = get_backend(alias) if alias == 'hg': repo = backend(repo_path, create=True, src_url=clone_uri) elif alias == 'git': repo = backend(repo_path, create=True, src_url=clone_uri, bare=True) # add rhodecode hook into this repo ScmModel().install_git_hook(repo=repo) else: raise Exception('Undefined alias %s' % alias) return repo
def _get_repository_name(self, environ): """ Gets repository name out of PATH_INFO header :param environ: environ where PATH_INFO is stored """ path = environ['PATH_INFO'].split('!') repo_name = path[0].strip('/') # SVN includes the whole path in it's requests, including # subdirectories inside the repo. Therefore we have to search for # the repo root directory. if not is_valid_repo(repo_name, self.basepath, self.SCM): current_path = '' for component in repo_name.split('/'): current_path += component if is_valid_repo(current_path, self.basepath, self.SCM): return current_path current_path += '/' return repo_name
def __create_repo(self, repo_name, alias, parent, clone_uri=False, repo_store_location=None): """ makes repository on filesystem. It's group aware means it'll create a repository within a group, and alter the paths accordingly of group location :param repo_name: :param alias: :param parent_id: :param clone_uri: :param repo_path: """ from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group from rhodecode.model.scm import ScmModel if parent: new_parent_path = os.sep.join(parent.full_path_splitted) else: new_parent_path = '' if repo_store_location: _paths = [repo_store_location] else: _paths = [self.repos_path, new_parent_path, repo_name] # we need to make it str for mercurial repo_path = os.path.join(*map(lambda x: safe_str(x), _paths)) # check if this path is not a repository if is_valid_repo(repo_path, self.repos_path): raise Exception('This path %s is a valid repository' % repo_path) # check if this path is a group if is_valid_repos_group(repo_path, self.repos_path): raise Exception('This path %s is a valid group' % repo_path) log.info('creating repo %s in %s @ %s' % ( repo_name, safe_unicode(repo_path), obfuscate_url_pw(clone_uri) ) ) backend = get_backend(alias) if alias == 'hg': repo = backend(repo_path, create=True, src_url=clone_uri) elif alias == 'git': repo = backend(repo_path, create=True, src_url=clone_uri, bare=True) # add rhodecode hook into this repo ScmModel().install_git_hook(repo=repo) else: raise Exception('Undefined alias %s' % alias) return repo
def is_valid_and_existing_repo(self, repo_name, base_path, scm_type): db_repo = Repository.get_by_repo_name(repo_name) if not db_repo: log.debug('Repository `%s` not found inside the database.', repo_name) return False if db_repo.repo_type != scm_type: log.warning( 'Repository `%s` have incorrect scm_type, expected %s got %s', repo_name, db_repo.repo_type, scm_type) return False return is_valid_repo(repo_name, base_path, expect_scm=scm_type)
def check_repo(environ, match_dict): """ check for valid repository for proper 404 handling :param environ: :param match_dict: """ from rhodecode.model.db import Repository repo_name = match_dict.get('repo_name') try: by_id = repo_name.split('_') if len(by_id) == 2 and by_id[1].isdigit() and by_id[0] == '': repo_name = Repository.get(by_id[1]).repo_name match_dict['repo_name'] = repo_name except: pass return is_valid_repo(repo_name, config['base_path'])
def check_repo(environ, match_dict): """ check for valid repository for proper 404 handling :param environ: :param match_dict: """ from rhodecode.model.db import Repository repo_name = match_dict.get('repo_name') try: by_id = repo_name.split('_') if len(by_id) == 2 and by_id[1].isdigit(): repo_name = Repository.get(by_id[1]).repo_name match_dict['repo_name'] = repo_name except: pass return is_valid_repo(repo_name, config['base_path'])
def check_repo(environ, match_dict): """ check for valid repository for proper 404 handling :param environ: :param match_dict: """ from rhodecode.model.db import Repository repo_name = match_dict.get('repo_name') if match_dict.get('f_path'): #fix for multiple initial slashes that causes errors match_dict['f_path'] = match_dict['f_path'].lstrip('/') try: by_id = repo_name.split('_') if len(by_id) == 2 and by_id[1].isdigit() and by_id[0] == '': repo_name = Repository.get(by_id[1]).repo_name match_dict['repo_name'] = repo_name except Exception: pass return is_valid_repo(repo_name, config['base_path'])
def __create_repo(self, repo_name, alias, new_parent_id, clone_uri=False): """ makes repository on filesystem. It's group aware means it'll create a repository within a group, and alter the paths accordingly of group location :param repo_name: :param alias: :param parent_id: :param clone_uri: """ from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group if new_parent_id: paths = RepoGroup.get(new_parent_id)\ .full_path.split(RepoGroup.url_sep()) new_parent_path = os.sep.join(paths) else: new_parent_path = '' # we need to make it str for mercurial repo_path = os.path.join(*map(lambda x: safe_str( x), [self.repos_path, new_parent_path, repo_name])) # check if this path is not a repository if is_valid_repo(repo_path, self.repos_path): raise Exception('This path %s is a valid repository' % repo_path) # check if this path is a group if is_valid_repos_group(repo_path, self.repos_path): raise Exception('This path %s is a valid group' % repo_path) log.info('creating repo %s in %s @ %s' % (repo_name, safe_unicode(repo_path), clone_uri)) backend = get_backend(alias) backend(repo_path, create=True, src_url=clone_uri)
def _handle_request(self, environ, start_response): if not is_git(environ): return self.application(environ, start_response) if not self._check_ssl(environ, start_response): return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response) ipaddr = self._get_ip_addr(environ) username = None self._git_first_op = False # skip passing error to error controller environ['pylons.status_code_redirect'] = True #====================================================================== # EXTRACT REPOSITORY NAME FROM ENV #====================================================================== try: repo_name = self.__get_repository(environ) log.debug('Extracted repo name is %s' % repo_name) except: return HTTPInternalServerError()(environ, start_response) # quick check if that dir exists... if is_valid_repo(repo_name, self.basepath, 'git') 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) #check permissions for this repository perm = self._check_permission(action, user, repo_name) if perm is not True: return HTTPForbidden()(environ, start_response) # extras are injected into UI object and later available # in hooks executed by rhodecode from rhodecode import CONFIG extras = { 'ip': ipaddr, 'username': username, 'action': action, 'repository': repo_name, 'scm': 'git', 'config': CONFIG['__file__'], 'make_lock': None, 'locked_by': [None, None] } #=================================================================== # GIT REQUEST HANDLING #=================================================================== repo_path = os.path.join(safe_str(self.basepath), safe_str(repo_name)) log.debug('Repository path is %s' % repo_path) # CHECK LOCKING only if it's not ANONYMOUS USER if username != User.DEFAULT_USER: log.debug('Checking locking on repository') (make_lock, locked, locked_by) = self._check_locking_state( environ=environ, action=action, repo=repo_name, user_id=user.user_id ) # store the make_lock for later evaluation in hooks extras.update({'make_lock': make_lock, 'locked_by': locked_by}) # set the environ variables for this request os.environ['RC_SCM_DATA'] = json.dumps(extras) fix_PATH() log.debug('HOOKS extras is %s' % extras) baseui = make_ui('db') self.__inject_extras(repo_path, baseui, extras) try: # 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, extras) return app(environ, start_response) except HTTPLockedRC, e: log.debug('Repositry LOCKED ret code 423!') return e(environ, start_response)
def _handle_request(self, environ, start_response): if not is_mercurial(environ): return self.application(environ, start_response) if not self._check_ssl(environ, start_response): return HTTPNotAcceptable('SSL REQUIRED !')(environ, start_response) ip_addr = self._get_ip_addr(environ) username = None # skip passing error to error controller environ['pylons.status_code_redirect'] = True #====================================================================== # EXTRACT REPOSITORY NAME FROM ENV #====================================================================== try: repo_name = environ['REPO_NAME'] = self.__get_repository(environ) log.debug('Extracted repo name is %s' % repo_name) except Exception: return HTTPInternalServerError()(environ, start_response) # quick check if that dir exists... if not is_valid_repo(repo_name, self.basepath, 'hg'): 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, ip_addr) if not anonymous_perm or not anonymous_user.active: if not anonymous_perm: log.debug('Not enough credentials to access this ' 'repository as anonymous user') if not anonymous_user.active: 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 Exception: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) #check permissions for this repository perm = self._check_permission(action, user, repo_name, ip_addr) if not perm: return HTTPForbidden()(environ, start_response) # extras are injected into mercurial UI object and later available # in hg hooks executed by rhodecode from rhodecode import CONFIG server_url = get_server_url(environ) extras = { 'ip': ip_addr, 'username': username, 'action': action, 'repository': repo_name, 'scm': 'hg', 'config': CONFIG['__file__'], 'server_url': server_url, 'make_lock': None, 'locked_by': [None, None] } #====================================================================== # MERCURIAL REQUEST HANDLING #====================================================================== str_repo_name = safe_str(repo_name) repo_path = os.path.join(safe_str(self.basepath), str_repo_name) log.debug('Repository path is %s' % repo_path) # CHECK LOCKING only if it's not ANONYMOUS USER if username != User.DEFAULT_USER: log.debug('Checking locking on repository') (make_lock, locked, locked_by) = self._check_locking_state(environ=environ, action=action, repo=repo_name, user_id=user.user_id) # store the make_lock for later evaluation in hooks extras.update({'make_lock': make_lock, 'locked_by': locked_by}) fix_PATH() log.debug('HOOKS extras is %s' % extras) baseui = make_ui('db') self.__inject_extras(repo_path, baseui, extras) try: log.info('%s action on HG repo "%s" by "%s" from %s' % (action, str_repo_name, safe_str(username), ip_addr)) app = self.__make_app(repo_path, baseui, extras) return app(environ, start_response) except RepoError, e: if str(e).find('not found') != -1: return HTTPNotFound()(environ, start_response)
def __call__(self, environ, start_response): if not is_mercurial(environ): return self.application(environ, start_response) proxy_key = "HTTP_X_REAL_IP" def_key = "REMOTE_ADDR" ipaddr = environ.get(proxy_key, environ.get(def_key, "0.0.0.0")) # skip passing error to error controller environ["pylons.status_code_redirect"] = True # ====================================================================== # EXTRACT REPOSITORY NAME FROM ENV # ====================================================================== try: repo_name = environ["REPO_NAME"] = self.__get_repository(environ) log.debug("Extracted repo name is %s" % repo_name) except: return HTTPInternalServerError()(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 # ============================================================== if not REMOTE_USER(environ): 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) else: return result.wsgi_application(environ, start_response) # ============================================================== # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME FROM # BASIC AUTH # ============================================================== if action in ["pull", "push"]: username = REMOTE_USER(environ) try: user = self.__get_user(username) username = user.username except: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) # check permissions for this repository perm = self.__check_permission(action, user, repo_name) if perm is not True: return HTTPForbidden()(environ, start_response) extras = {"ip": ipaddr, "username": username, "action": action, "repository": repo_name} # ====================================================================== # MERCURIAL REQUEST HANDLING # ====================================================================== repo_path = safe_str(os.path.join(self.basepath, repo_name)) log.debug("Repository path is %s" % repo_path) baseui = make_ui("db") self.__inject_extras(repo_path, baseui, extras) # quick check if that dir exists... if is_valid_repo(repo_name, self.basepath) is False: return HTTPNotFound()(environ, start_response) try: # invalidate cache on push if action == "push": self.__invalidate_cache(repo_name) app = self.__make_app(repo_path, baseui, extras) return app(environ, start_response) except RepoError, e: if str(e).find("not found") != -1: return HTTPNotFound()(environ, start_response)
def __call__(self, environ, start_response): if not is_git(environ): return self.application(environ, start_response) proxy_key = 'HTTP_X_REAL_IP' def_key = 'REMOTE_ADDR' ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0')) username = None # skip passing error to error controller environ['pylons.status_code_redirect'] = True #====================================================================== # EXTRACT REPOSITORY NAME FROM ENV #====================================================================== try: repo_name = self.__get_repository(environ) log.debug('Extracted repo name is %s' % repo_name) except: return HTTPInternalServerError()(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 #============================================================== if not REMOTE_USER(environ): 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) else: return result.wsgi_application(environ, start_response) #============================================================== # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME FROM # BASIC AUTH #============================================================== if action in ['pull', 'push']: username = REMOTE_USER(environ) try: user = self.__get_user(username) username = user.username except: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) #check permissions for this repository perm = self.__check_permission(action, user, repo_name) if perm is not True: return HTTPForbidden()(environ, start_response) extras = {'ip': ipaddr, 'username': username, 'action': action, 'repository': repo_name} #=================================================================== # GIT REQUEST HANDLING #=================================================================== repo_path = safe_str(os.path.join(self.basepath, repo_name)) log.debug('Repository path is %s' % repo_path) # quick check if that dir exists... if is_valid_repo(repo_name, self.basepath) is False: return HTTPNotFound()(environ, start_response) try: #invalidate cache on push if action == 'push': self.__invalidate_cache(repo_name) app = self.__make_app(repo_name, repo_path) return app(environ, start_response) except Exception: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response)
def _handle_request(self, environ, start_response): if not is_mercurial(environ): return self.application(environ, start_response) ipaddr = self._get_ip_addr(environ) # skip passing error to error controller environ['pylons.status_code_redirect'] = True #====================================================================== # EXTRACT REPOSITORY NAME FROM ENV #====================================================================== try: repo_name = environ['REPO_NAME'] = self.__get_repository(environ) log.debug('Extracted repo name is %s' % repo_name) except: return HTTPInternalServerError()(environ, start_response) # 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 #============================================================== if action in ['pull', 'push']: 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) #check permissions for this repository perm = self._check_permission(action, user, repo_name) if perm is not True: return HTTPForbidden()(environ, start_response) # extras are injected into mercurial UI object and later available # in hg hooks executed by rhodecode extras = { 'ip': ipaddr, 'username': username, 'action': action, 'repository': repo_name, 'scm': 'hg', } #====================================================================== # MERCURIAL 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) try: # invalidate cache on push if action == 'push': self._invalidate_cache(repo_name) log.info('%s action on HG repo "%s"' % (action, repo_name)) app = self.__make_app(repo_path, baseui, extras) return app(environ, start_response) except RepoError, e: if str(e).find('not found') != -1: return HTTPNotFound()(environ, start_response)
def _handle_request(self, environ, start_response): if not is_mercurial(environ): return self.application(environ, start_response) if not self._check_ssl(environ, start_response): return HTTPNotAcceptable("SSL REQUIRED !")(environ, start_response) ip_addr = self._get_ip_addr(environ) username = None # skip passing error to error controller environ["pylons.status_code_redirect"] = True # ====================================================================== # EXTRACT REPOSITORY NAME FROM ENV # ====================================================================== try: repo_name = environ["REPO_NAME"] = self.__get_repository(environ) log.debug("Extracted repo name is %s" % repo_name) except Exception: return HTTPInternalServerError()(environ, start_response) # quick check if that dir exists... if not is_valid_repo(repo_name, self.basepath, "hg"): 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, ip_addr) if not anonymous_perm or not anonymous_user.active: if not anonymous_perm: log.debug("Not enough credentials to access this " "repository as anonymous user") if not anonymous_user.active: 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 Exception: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) # check permissions for this repository perm = self._check_permission(action, user, repo_name, ip_addr) if not perm: return HTTPForbidden()(environ, start_response) # extras are injected into mercurial UI object and later available # in hg hooks executed by rhodecode from rhodecode import CONFIG server_url = get_server_url(environ) extras = { "ip": ip_addr, "username": username, "action": action, "repository": repo_name, "scm": "hg", "config": CONFIG["__file__"], "server_url": server_url, "make_lock": None, "locked_by": [None, None], } # ====================================================================== # MERCURIAL REQUEST HANDLING # ====================================================================== str_repo_name = safe_str(repo_name) repo_path = os.path.join(safe_str(self.basepath), str_repo_name) log.debug("Repository path is %s" % repo_path) # CHECK LOCKING only if it's not ANONYMOUS USER if username != User.DEFAULT_USER: log.debug("Checking locking on repository") (make_lock, locked, locked_by) = self._check_locking_state( environ=environ, action=action, repo=repo_name, user_id=user.user_id ) # store the make_lock for later evaluation in hooks extras.update({"make_lock": make_lock, "locked_by": locked_by}) # set the environ variables for this request os.environ["RC_SCM_DATA"] = json.dumps(extras) fix_PATH() log.debug("HOOKS extras is %s" % extras) baseui = make_ui("db") self.__inject_extras(repo_path, baseui, extras) try: log.info('%s action on HG repo "%s" by "%s" from %s' % (action, str_repo_name, safe_str(username), ip_addr)) app = self.__make_app(repo_path, baseui, extras) return app(environ, start_response) except RepoError, e: if str(e).find("not found") != -1: return HTTPNotFound()(environ, start_response)
def _create_filesystem_repo(self, repo_name, repo_type, repo_group, clone_uri=None, repo_store_location=None, use_global_config=False): """ makes repository on filesystem. It's group aware means it'll create a repository within a group, and alter the paths accordingly of group location :param repo_name: :param alias: :param parent: :param clone_uri: :param repo_store_location: """ from rhodecode.lib.utils import is_valid_repo, is_valid_repo_group from rhodecode.model.scm import ScmModel if Repository.NAME_SEP in repo_name: raise ValueError('repo_name must not contain groups got `%s`' % repo_name) if isinstance(repo_group, RepoGroup): new_parent_path = os.sep.join(repo_group.full_path_splitted) else: new_parent_path = repo_group or '' if repo_store_location: _paths = [repo_store_location] else: _paths = [self.repos_path, new_parent_path, repo_name] # we need to make it str for mercurial repo_path = os.path.join(*map(lambda x: safe_str(x), _paths)) # check if this path is not a repository if is_valid_repo(repo_path, self.repos_path): raise Exception('This path %s is a valid repository' % repo_path) # check if this path is a group if is_valid_repo_group(repo_path, self.repos_path): raise Exception('This path %s is a valid group' % repo_path) log.info('creating repo %s in %s from url: `%s`', repo_name, safe_unicode(repo_path), obfuscate_url_pw(clone_uri)) backend = get_backend(repo_type) config_repo = None if use_global_config else repo_name if config_repo and new_parent_path: config_repo = Repository.NAME_SEP.join( (new_parent_path, config_repo)) config = make_db_config(clear_session=False, repo=config_repo) config.set('extensions', 'largefiles', '') # patch and reset hooks section of UI config to not run any # hooks on creating remote repo config.clear_section('hooks') # TODO: johbo: Unify this, hardcoded "bare=True" does not look nice if repo_type == 'git': repo = backend(repo_path, config=config, create=True, src_url=clone_uri, bare=True) else: repo = backend(repo_path, config=config, create=True, src_url=clone_uri) ScmModel().install_hooks(repo, repo_type=repo_type) log.debug('Created repo %s with %s backend', safe_unicode(repo_name), safe_unicode(repo_type)) return repo