Changeset - 62a1d4155f6b
[Not reviewed]
beta
0 1 0
Marcin Kuzminski - 15 years ago 2011-03-13 01:22:29
marcin@python-works.com
let action always return pull command for better security on pull restricted repos
1 file changed with 1 insertions and 1 deletions:
0 comments (0 inline, 0 general)
rhodecode/lib/middleware/simplehg.py
Show inline comments
 
@@ -148,125 +148,125 @@ class SimpleHg(object):
 
        # MERCURIAL REQUEST HANDLING
 
        #===================================================================
 
        environ['PATH_INFO'] = '/'#since we wrap into hgweb, reset the path
 
        self.baseui = make_ui('db')
 
        self.basepath = self.config['base_path']
 
        self.repo_path = os.path.join(self.basepath, self.repo_name)
 

	
 
        #quick check if that dir exists...
 
        if check_repo_fast(self.repo_name, self.basepath):
 
            return HTTPNotFound()(environ, start_response)
 
        try:
 
            app = wsgiapplication(self.__make_app)
 
        except RepoError, e:
 
            if str(e).find('not found') != -1:
 
                return HTTPNotFound()(environ, start_response)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            return HTTPInternalServerError()(environ, start_response)
 

	
 
        #invalidate cache on push
 
        if self.action == 'push':
 
            self.__invalidate_cache(self.repo_name)
 

	
 
        return app(environ, start_response)
 

	
 

	
 
    def __make_app(self):
 
        """Make an wsgi application using hgweb, and my generated baseui
 
        instance
 
        """
 

	
 
        hgserve = hgweb(str(self.repo_path), baseui=self.baseui)
 
        return  self.__load_web_settings(hgserve, self.extras)
 

	
 

	
 
    def __check_permission(self, action, user, repo_name):
 
        """Checks permissions using action (push/pull) user and repository
 
        name
 
        
 
        :param action: push or pull action
 
        :param user: user instance
 
        :param repo_name: repository name
 
        """
 
        if action == 'push':
 
            if not HasPermissionAnyMiddleware('repository.write',
 
                                              'repository.admin')\
 
                                                (user, repo_name):
 
                return False
 

	
 
        else:
 
            #any other action need at least read permission
 
            if not HasPermissionAnyMiddleware('repository.read',
 
                                              'repository.write',
 
                                              'repository.admin')\
 
                                                (user, repo_name):
 
                return False
 

	
 
        return True
 

	
 

	
 
    def __get_repository(self, environ):
 
        """Get's repository name out of PATH_INFO header
 
        
 
        :param environ: environ where PATH_INFO is stored
 
        """
 
        try:
 
            repo_name = '/'.join(environ['PATH_INFO'].split('/')[1:])
 
            if repo_name.endswith('/'):
 
                repo_name = repo_name.rstrip('/')
 
        except:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
        return repo_name
 

	
 
    def __get_user(self, username):
 
        return UserModel().get_by_username(username, cache=True)
 

	
 
    def __get_action(self, environ):
 
        """Maps mercurial request commands into a clone,pull or push command.
 
        This should always return a valid command string
 
        
 
        :param environ:
 
        """
 
        mapping = {'changegroup': 'pull',
 
                   'changegroupsubset': 'pull',
 
                   'stream_out': 'pull',
 
                   'listkeys': 'pull',
 
                   'unbundle': 'push',
 
                   'pushkey': 'push', }
 
        for qry in environ['QUERY_STRING'].split('&'):
 
            if qry.startswith('cmd'):
 
                cmd = qry.split('=')[-1]
 
                if mapping.has_key(cmd):
 
                    return mapping[cmd]
 
                else:
 
                    return cmd
 
                    return 'pull'
 

	
 
    def __invalidate_cache(self, repo_name):
 
        """we know that some change was made to repositories and we should
 
        invalidate the cache to see the changes right away but only for
 
        push requests"""
 
        invalidate_cache('get_repo_cached_%s' % repo_name)
 

	
 

	
 
    def __load_web_settings(self, hgserve, extras={}):
 
        #set the global ui for hgserve instance passed
 
        hgserve.repo.ui = self.baseui
 

	
 
        hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
 

	
 
        #inject some additional parameters that will be available in ui
 
        #for hooks
 
        for k, v in extras.items():
 
            hgserve.repo.ui.setconfig('rhodecode_extras', k, v)
 

	
 
        repoui = make_ui('file', hgrc, False)
 

	
 
        if repoui:
 
            #overwrite our ui instance with the section from hgrc file
 
            for section in ui_sections:
 
                for k, v in repoui.configitems(section):
 
                    hgserve.repo.ui.setconfig(section, k, v)
 

	
 
        return hgserve
0 comments (0 inline, 0 general)