Ejemplo n.º 1
0
    def run_wsgi(self, req):
        try:
            try:
                #log.debug("Inside HgRedmine::run_wsgi : " + str(req.env))


                db = connect(self.dsn)

                self.refresh()
                self.findrepos(db)

                virtual = req.env.get("PATH_INFO", "").strip('/')

                tmpl = self.templater(req)
                ctype = tmpl('mimetype', encoding=encoding.encoding)
                ctype = templater.stringify(ctype)

                # a static file
                if virtual.startswith('static/') or 'static' in req.form:
                    if virtual.startswith('static/'):
                        fname = virtual[7:]
                    else:
                        fname = req.form['static'][0]
                    static = templater.templatepath('static')
                    return (staticfile(static, fname, req),)

                self._user_login(db, req)
                # top-level index
                #if not virtual:
                    ## only administrators can list repositories
                    #if self._is_admin(req):
                        #req.respond(HTTP_OK, ctype)
                        #return self.makeindex(req, tmpl)
                    #else:
                        #self._send_challenge(req)

                # navigate to hgweb
                project_id = virtual.split('/')[0]

                repos = dict(self.repos)

                real = repos.get(project_id)

                if real:
                    req.env['REPO_NAME'] = project_id

                    try:
                        repo = hg.repository(self.ui.copy(), str(real))
                        self._setup_repo(db, repo, project_id)
                        #log.debug("Calling HgWebRedmine with " + str(self.realm) + str(repo))
                        return HgwebRedmine(db, self.realm, repo).run_wsgi(req)
                    except IOError, inst:
                        msg = inst.strerror
                        raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                    except error.RepoError, inst:
                        raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
Ejemplo n.º 2
0
 def clean_style(self):
     """
     Checks the style to see if a path is returned by
     mercurial's templater. If no path is returned
     then the style is assumed to be invalid or not installed.
     """
     from mercurial.templater import templatepath
     if not templatepath(self.cleaned_data["style"]):
         raise forms.ValidationError(_("'%s' is not an available style." % self.cleaned_data["style"]))
     return self.cleaned_data["style"]
Ejemplo n.º 3
0
def static(web, req, tmpl):
    fname = req.form['file'][0]
    # a repo owner may set web.static in .hg/hgrc to get any file
    # readable by the user running the CGI script
    static = web.config("web", "static", None, untrusted=False)
    if not static:
        tp = web.templatepath or templater.templatepath()
        if isinstance(tp, str):
            tp = [tp]
        static = [os.path.join(p, 'static') for p in tp]
    return [staticfile(static, fname, req)]
Ejemplo n.º 4
0
def static(web, req, tmpl):
    fname = req.form['file'][0]
    # a repo owner may set web.static in .hg/hgrc to get any file
    # readable by the user running the CGI script
    static = web.config("web", "static", None, untrusted=False)
    if not static:
        tp = web.templatepath or templater.templatepath()
        if isinstance(tp, str):
            tp = [tp]
        static = [os.path.join(p, 'static') for p in tp]
    return [staticfile(static, fname, req)]
Ejemplo n.º 5
0
def static_file(request, file_name):
    # Handle static files 
    static = templater.templatepath('static')
    response = HttpResponse()
    url = request.path
    req = HgRequestWrapper(
        request,
        response,
        script_name=url,
    )
    response.write(''.join([each for each in (common.staticfile(static, file_name, req))]))
    return response
Ejemplo n.º 6
0
    def run_wsgi(self, req):

        try:
            try:

                virtual = req.env.get("PATH_INFO", "").strip('/')
                tmpl = self.templater(req)
                try:
                    ctype = tmpl('mimetype', encoding=util._encoding)
                    ctype = templater.stringify(ctype)
                except KeyError:
                    # old templates with inline HTTP headers?
                    if 'mimetype' in tmpl:
                        raise
                    header = tmpl('header', encoding=util._encoding)
                    header_file = cStringIO.StringIO(
                        templater.stringify(header))
                    msg = mimetools.Message(header_file, 0)
                    ctype = msg['content-type']

                # a static file
                if virtual.startswith('static/') or 'static' in req.form:
                    static = os.path.join(templater.templatepath(), 'static')
                    if virtual.startswith('static/'):
                        fname = virtual[7:]
                    else:
                        fname = req.form['static'][0]
                    req.write(staticfile(static, fname, req))
                    return

                # top-level index
                elif not virtual:
                    req.respond(HTTP_OK, ctype)
                    req.write(self.makeindex(req, tmpl))
                    return

                # nested indexes and hgwebs

                repos = dict(self.repos)
                while virtual:
                    real = repos.get(virtual)
                    if real:
                        req.env['REPO_NAME'] = virtual
                        try:
                            repo = hg.repository(self.parentui, real)
                            hgweb(repo).run_wsgi(req)
                            return
                        except IOError, inst:
                            msg = inst.strerror
                            raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                        except RepoError, inst:
                            raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
Ejemplo n.º 7
0
    def templater(self, req):
        def header(**map):
            header = tmpl('header', encoding=util._encoding, **map)
            if 'mimetype' not in tmpl:
                # old template with inline HTTP headers
                header_file = cStringIO.StringIO(templater.stringify(header))
                msg = mimetools.Message(header_file, 0)
                header = header_file.read()
            yield header

        def footer(**map):
            yield tmpl("footer", **map)

        def motd(**map):
            if self.motd is not None:
                yield self.motd
            else:
                yield config('web', 'motd', '')

        def config(section, name, default=None, untrusted=True):
            return self.parentui.config(section, name, default, untrusted)

        if self._baseurl is not None:
            req.env['SCRIPT_NAME'] = self._baseurl

        url = req.env.get('SCRIPT_NAME', '')
        if not url.endswith('/'):
            url += '/'

        staticurl = config('web', 'staticurl') or url + 'static/'
        if not staticurl.endswith('/'):
            staticurl += '/'

        style = self.style
        if style is None:
            style = config('web', 'style', '')
        if 'style' in req.form:
            style = req.form['style'][0]
        if self.stripecount is None:
            self.stripecount = int(config('web', 'stripes', 1))
        mapfile = style_map(templater.templatepath(), style)
        tmpl = templater.templater(mapfile,
                                   templatefilters.filters,
                                   defaults={
                                       "header": header,
                                       "footer": footer,
                                       "motd": motd,
                                       "url": url,
                                       "staticurl": staticurl
                                   })
        return tmpl
Ejemplo n.º 8
0
    def run_wsgi(self, req):

        try:
            try:

                virtual = req.env.get("PATH_INFO", "").strip('/')
                tmpl = self.templater(req)
                try:
                    ctype = tmpl('mimetype', encoding=util._encoding)
                    ctype = templater.stringify(ctype)
                except KeyError:
                    # old templates with inline HTTP headers?
                    if 'mimetype' in tmpl:
                        raise
                    header = tmpl('header', encoding=util._encoding)
                    header_file = cStringIO.StringIO(templater.stringify(header))
                    msg = mimetools.Message(header_file, 0)
                    ctype = msg['content-type']

                # a static file
                if virtual.startswith('static/') or 'static' in req.form:
                    static = os.path.join(templater.templatepath(), 'static')
                    if virtual.startswith('static/'):
                        fname = virtual[7:]
                    else:
                        fname = req.form['static'][0]
                    req.write(staticfile(static, fname, req))
                    return

                # top-level index
                elif not virtual:
                    req.respond(HTTP_OK, ctype)
                    req.write(self.makeindex(req, tmpl))
                    return

                # nested indexes and hgwebs

                repos = dict(self.repos)
                while virtual:
                    real = repos.get(virtual)
                    if real:
                        req.env['REPO_NAME'] = virtual
                        try:
                            repo = hg.repository(self.parentui, real)
                            hgweb(repo).run_wsgi(req)
                            return
                        except IOError, inst:
                            msg = inst.strerror
                            raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                        except RepoError, inst:
                            raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
Ejemplo n.º 9
0
    def run_wsgi(self, req):
        try:
            try:
                self.refresh()

                virtual = req.env.get("PATH_INFO", "").strip('/')
                tmpl = self.templater(req)
                ctype = tmpl('mimetype', encoding=encoding.encoding)
                ctype = templater.stringify(ctype)

                # a static file
                if virtual.startswith('static/') or 'static' in req.form:
                    if virtual.startswith('static/'):
                        fname = virtual[7:]
                    else:
                        fname = req.form['static'][0]
                    static = self.ui.config("web",
                                            "static",
                                            None,
                                            untrusted=False)
                    if not static:
                        tp = self.templatepath or templater.templatepath()
                        if isinstance(tp, str):
                            tp = [tp]
                        static = [os.path.join(p, 'static') for p in tp]
                    staticfile(static, fname, req)
                    return []

                # top-level index
                elif not virtual:
                    req.respond(HTTP_OK, ctype)
                    return self.makeindex(req, tmpl)

                # nested indexes and hgwebs

                repos = dict(self.repos)
                virtualrepo = virtual
                while virtualrepo:
                    real = repos.get(virtualrepo)
                    if real:
                        req.env['REPO_NAME'] = virtualrepo
                        try:
                            # ensure caller gets private copy of ui
                            repo = hg.repository(self.ui.copy(), real)
                            return hgweb(repo).run_wsgi(req)
                        except IOError, inst:
                            msg = inst.strerror
                            raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                        except error.RepoError, inst:
                            raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
Ejemplo n.º 10
0
    def templater(self, req):

        def header(**map):
            header = tmpl('header', encoding=util._encoding, **map)
            if 'mimetype' not in tmpl:
                # old template with inline HTTP headers
                header_file = cStringIO.StringIO(templater.stringify(header))
                msg = mimetools.Message(header_file, 0)
                header = header_file.read()
            yield header

        def footer(**map):
            yield tmpl("footer", **map)

        def motd(**map):
            if self.motd is not None:
                yield self.motd
            else:
                yield config('web', 'motd', '')

        def config(section, name, default=None, untrusted=True):
            return self.parentui.config(section, name, default, untrusted)

        if self._baseurl is not None:
            req.env['SCRIPT_NAME'] = self._baseurl

        url = req.env.get('SCRIPT_NAME', '')
        if not url.endswith('/'):
            url += '/'

        staticurl = config('web', 'staticurl') or url + 'static/'
        if not staticurl.endswith('/'):
            staticurl += '/'

        style = self.style
        if style is None:
            style = config('web', 'style', '')
        if 'style' in req.form:
            style = req.form['style'][0]
        if self.stripecount is None:
            self.stripecount = int(config('web', 'stripes', 1))
        mapfile = style_map(templater.templatepath(), style)
        tmpl = templater.templater(mapfile, templatefilters.filters,
                                   defaults={"header": header,
                                             "footer": footer,
                                             "motd": motd,
                                             "url": url,
                                             "staticurl": staticurl})
        return tmpl
Ejemplo n.º 11
0
    def run_wsgi(self, req):
        try:
            try:
                self.refresh()

                virtual = req.env.get("PATH_INFO", "").strip('/')
                tmpl = self.templater(req)
                ctype = tmpl('mimetype', encoding=encoding.encoding)
                ctype = templater.stringify(ctype)

                # a static file
                if virtual.startswith('static/') or 'static' in req.form:
                    if virtual.startswith('static/'):
                        fname = virtual[7:]
                    else:
                        fname = req.form['static'][0]
                    static = self.ui.config("web", "static", None,
                                            untrusted=False)
                    if not static:
                        tp = self.templatepath or templater.templatepath()
                        if isinstance(tp, str):
                            tp = [tp]
                        static = [os.path.join(p, 'static') for p in tp]
                    staticfile(static, fname, req)
                    return []

                # top-level index
                elif not virtual:
                    req.respond(HTTP_OK, ctype)
                    return self.makeindex(req, tmpl)

                # nested indexes and hgwebs

                repos = dict(self.repos)
                virtualrepo = virtual
                while virtualrepo:
                    real = repos.get(virtualrepo)
                    if real:
                        req.env['REPO_NAME'] = virtualrepo
                        try:
                            # ensure caller gets private copy of ui
                            repo = hg.repository(self.ui.copy(), real)
                            return hgweb(repo).run_wsgi(req)
                        except IOError, inst:
                            msg = inst.strerror
                            raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                        except error.RepoError, inst:
                            raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
Ejemplo n.º 12
0
    def run_wsgi(self, req):
        try:
            try:
                db, self.placeholder = connect(self.dsn)

                self.refresh()
                self.findrepos(db)

                virtual = req.env.get("PATH_INFO", "").strip('/')
                tmpl = self.templater(req)
                ctype = tmpl('mimetype', encoding=encoding.encoding)
                ctype = templater.stringify(ctype)

                # a static file
                if virtual.startswith('static/') or 'static' in req.form:
                    if virtual.startswith('static/'):
                        fname = virtual[7:]
                    else:
                        fname = req.form['static'][0]
                    static = templater.templatepath('static')
                    return (staticfile(static, fname, req),)

                self._user_login(db, req)

                # top-level index
                if not virtual:
                    # nobody can list repositories
                    self._send_challenge(req)

                # navigate to hgweb
                repository_path = '/'.join(virtual.split('/')[0:2])

                repos = dict(self.repos)
                real = repos.get(repository_path)

                if real:
                    req.env['REPO_NAME'] = repository_path
                    req.env['PROJECT_ID'], req.env['PROJECT_OWNER_ID'] = self._project_info_from_repo_path(db, repository_path)

                    try:
                        repo = hg.repository(self.ui, real)
                        self._setup_repo(db, repo, repository_path)
                        return HgwebWide(db, self.placeholder, self.realm, repo).run_wsgi(req)
                    except IOError, inst:
                        msg = inst.strerror
                        raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                    except error.RepoError, inst:
                        raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
Ejemplo n.º 13
0
    def __init__(self, repo, name=None):
        if isinstance(repo, str):
            parentui = ui.ui(report_untrusted=False, interactive=False)
            self.repo = hg.repository(parentui, repo)
        else:
            self.repo = repo

        hook.redirect(True)
        self.mtime = -1
        self.reponame = name
        self.archives = 'zip', 'gz', 'bz2'
        self.stripecount = 1
        # a repo owner may set web.templates in .hg/hgrc to get any file
        # readable by the user running the CGI script
        self.templatepath = self.config("web", "templates",
                                        templater.templatepath(),
                                        untrusted=False)
Ejemplo n.º 14
0
    def __init__(self, repo, name=None):
        if isinstance(repo, str):
            parentui = ui.ui(report_untrusted=False, interactive=False)
            self.repo = hg.repository(parentui, repo)
        else:
            self.repo = repo

        hook.redirect(True)
        self.mtime = -1
        self.reponame = name
        self.archives = 'zip', 'gz', 'bz2'
        self.stripecount = 1
        self._capabilities = None
        # a repo owner may set web.templates in .hg/hgrc to get any file
        # readable by the user running the CGI script
        self.templatepath = self.config("web", "templates",
                                        templater.templatepath(),
                                        untrusted=False)
Ejemplo n.º 15
0
    def run_wsgi(self, req):
        try:
            try:
                self.refresh()

                virtual = req.env.get("PATH_INFO", "").strip('/')
                tmpl = self.templater(req)
                ctype = tmpl('mimetype', encoding=encoding.encoding)
                ctype = templater.stringify(ctype)

                # a static file
                if virtual.startswith('static/') or 'static' in req.form:
                    if virtual.startswith('static/'):
                        fname = virtual[7:]
                    else:
                        fname = req.form['static'][0]
                    static = templater.templatepath('static')
                    return (staticfile(static, fname, req), )

                # top-level index
                elif not virtual:
                    req.respond(HTTP_OK, ctype)
                    return self.makeindex(req, tmpl)

                # nested indexes and hgwebs

                repos = dict(self.repos)
                virtualrepo = virtual
                while virtualrepo:
                    real = repos.get(virtualrepo)
                    if real:
                        req.env['REPO_NAME'] = virtualrepo
                        try:
                            repo = hg.repository(self.ui, real)
                            return hgweb(repo).run_wsgi(req)
                        except IOError, inst:
                            msg = inst.strerror
                            raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                        except error.RepoError, inst:
                            raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
Ejemplo n.º 16
0
    def run_wsgi(self, req):
        try:
            try:
                self.refresh()

                virtual = req.env.get("PATH_INFO", "").strip('/')
                tmpl = self.templater(req)
                ctype = tmpl('mimetype', encoding=encoding.encoding)
                ctype = templater.stringify(ctype)

                # a static file
                if virtual.startswith('static/') or 'static' in req.form:
                    if virtual.startswith('static/'):
                        fname = virtual[7:]
                    else:
                        fname = req.form['static'][0]
                    static = templater.templatepath('static')
                    return (staticfile(static, fname, req),)

                # top-level index
                elif not virtual:
                    req.respond(HTTP_OK, ctype)
                    return self.makeindex(req, tmpl)

                # nested indexes and hgwebs

                repos = dict(self.repos)
                virtualrepo = virtual
                while virtualrepo:
                    real = repos.get(virtualrepo)
                    if real:
                        req.env['REPO_NAME'] = virtualrepo
                        try:
                            repo = hg.repository(self.ui, real)
                            return hgweb(repo).run_wsgi(req)
                        except IOError, inst:
                            msg = inst.strerror
                            raise ErrorResponse(HTTP_SERVER_ERROR, msg)
                        except error.RepoError, inst:
                            raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
Ejemplo n.º 17
0
    def templater(self):

        def header(**map):
            yield tmpl('header', encoding=util._encoding, **map)

        def footer(**map):
            yield tmpl("footer", **map)

        def motd(**map):
            if self.motd is not None:
                yield self.motd
            else:
                yield config('web', 'motd', '')

        def config(section, name, default=None, untrusted=True):
            return self.parentui.config(section, name, default, untrusted)

        url = self._baseurl
        if not url.endswith('/'):
            url += '/'

        staticurl = url + 'static/'

        style = self.style
        if style is None:
            style = config('web', 'style', '')
        style = self.request.get("style", style)
        if self.stripecount is None:
            self.stripecount = int(config('web', 'stripes', 1))
        mapfile = style_map(templater.templatepath(), style)
        tmpl = templater.templater(mapfile, templatefilters.filters,
                                   defaults={"header": header,
                                             "footer": footer,
                                             "motd": motd,
                                             "url": url,
                                             "staticurl": staticurl})
        return tmpl
Ejemplo n.º 18
0
def repo_detail(request, username, pattern):
    """
    Repository detail view.
    """
    repo_name = pattern.split('/')[0]
    repo = get_object_or_404(Repository, slug=repo_name, owner__username=username)

    """
    Instance the hgweb wrapper
    """
    response = HttpResponse()
    hgr = HgRequestWrapper(request, response, script_name=repo.get_absolute_url())

    """
    Authenticate on all requests. To authenticate only against 'POST'
    requests
    """

    realm = hgwebproxy_settings.AUTH_REALM

    mercurial_request = is_mercurial(request)
    if mercurial_request:
        """
        If a slash is not present, would be added a slash regardless of
        APPEND_SLASH django setting since hgweb returns 404 if it isn't present.
        """
        if not request.path.endswith('/'):
            new_url = [request.get_host(), request.path + '/']
            if new_url[0]:
                newurl = "%s://%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    new_url[0], urlquote(new_url[1]))
            else:
                newurl = urlquote(new_url[1])
            if request.GET:
                newurl += '?' + request.META['QUERY_STRING']
            return HttpResponseRedirect(newurl)

        authed = basic_auth(request, realm, repo)

    else:
        if not repo.can_browse(request.user):
            raise PermissionDenied(_("You do not have access to this repository"))
        authed = request.user.username

    if not authed:
        response.status_code = 401
        response['WWW-Authenticate'] = '''Basic realm="%s"''' % realm
        if request.META['REQUEST_METHOD']=='POST' and request.META['QUERY_STRING'].startswith("cmd=unbundle"):
            # drain request, this is a fix/workaround for http://mercurial.selenic.com/btw/issue1876
            hgr.drain()
        return response
    else:
        hgr.set_user(authed)


    hgserve = hgweb(str(repo.location))
    hgserve.reponame = repo.slug

    # TODO: is it Possible to charge the settings just for one time?
    hgserve.repo.ui.setconfig('web', 'name', smart_str(hgserve.reponame))
    hgserve.repo.ui.setconfig('web', 'description', smart_str(repo.description))
    hgserve.repo.ui.setconfig('web', 'contact', smart_str(repo.owner.get_full_name()))
    hgserve.repo.ui.setconfig('web', 'allow_archive', repo.allow_archive)


    if os.path.exists(hgwebproxy_settings.STYLES_PATH):
        template_paths = templater.templatepath()
        template_paths.insert(0, hgwebproxy_settings.STYLES_PATH)
        hgserve.repo.ui.setconfig('web', 'templates', template_paths)
        hgserve.templatepath = hgserve.repo.ui.config('web', 'templates', template_paths)

    if hgwebproxy_settings.ALLOW_CUSTOM_STYLE:
        hgserve.repo.ui.setconfig('web', 'style', repo.style)
    else:
        hgserve.repo.ui.setconfig('web', 'style', hgwebproxy_settings.DEFAULT_STYLE)

    hgserve.repo.ui.setconfig('web', 'baseurl', repo.get_absolute_url())
    hgserve.repo.ui.setconfig('web', 'allow_push', authed) #Allow push to the current user
    hgserve.repo.ui.setconfig('web', 'staticurl', hgwebproxy_settings.STATIC_URL)

    if settings.DEBUG:
        hgserve.repo.ui.setconfig('web', 'push_ssl', 'false')
    else:
        hgserve.repo.ui.setconfig('web', 'push_ssl', repo.allow_push_ssl)

    # Catch hgweb error to show as Django Exceptions
    try:
        response.write(''.join(each for each in hgserve.run_wsgi(hgr)))
    except KeyError:
        return HttpResponseServerError('Mercurial has crashed', mimetype='text/html')

    if mercurial_request:
        return response

    # make sure we return the response without wrapping if content-type is
    # either a binary stream or text/plain (for raw changesets).
    if response['content-type'].split(';')[0] in ('application/octet-stream', 'text/plain'):
        return response

    context = {
        'content': response.content,
        'reponame' : hgserve.reponame,
        'static_url' : hgwebproxy_settings.STATIC_URL,
        'slugpath': request.path.replace(repo.get_absolute_url(), ''),
        'is_root': request.path == repo.get_absolute_url(),
        'repo': repo,
    }

    if request.path.endswith(repo_name + '/rss-log') or request.path.endswith(repo_name + '/atom-log'):
        return HttpResponse(response.content, mimetype='application/xml')
    else:
        return render_to_response("hgwebproxy/wrapper.html", context, RequestContext(request))
Ejemplo n.º 19
0
def is_template(template):
    #TODO: Load project mercurial styles
    if templatepath(template):
        return True
    else:
        return False
Ejemplo n.º 20
0
def repo_detail(request, username, pattern):
    """
    Repository detail view.
    """
    repo_name = pattern.split('/')[0]
    repo = get_object_or_404(Repository,
                             slug=repo_name,
                             owner__username=username)
    """
    Instance the hgweb wrapper
    """
    response = HttpResponse()
    hgr = HgRequestWrapper(request,
                           response,
                           script_name=repo.get_absolute_url())
    """
    Authenticate on all requests. To authenticate only against 'POST'
    requests
    """

    realm = hgwebproxy_settings.AUTH_REALM

    mercurial_request = is_mercurial(request)
    if mercurial_request:
        """
        If a slash is not present, would be added a slash regardless of
        APPEND_SLASH django setting since hgweb returns 404 if it isn't present.
        """
        if not request.path.endswith('/'):
            new_url = [request.get_host(), request.path + '/']
            if new_url[0]:
                newurl = "%s://%s%s" % (request.is_secure() and 'https'
                                        or 'http', new_url[0],
                                        urlquote(new_url[1]))
            else:
                newurl = urlquote(new_url[1])
            if request.GET:
                newurl += '?' + request.META['QUERY_STRING']
            return HttpResponseRedirect(newurl)

        authed = basic_auth(request, realm, repo)

    else:
        if not repo.can_browse(request.user):
            raise PermissionDenied(
                _("You do not have access to this repository"))
        authed = request.user.username

    if not authed:
        response.status_code = 401
        response['WWW-Authenticate'] = '''Basic realm="%s"''' % realm
        if request.META['REQUEST_METHOD'] == 'POST' and request.META[
                'QUERY_STRING'].startswith("cmd=unbundle"):
            # drain request, this is a fix/workaround for http://mercurial.selenic.com/btw/issue1876
            hgr.drain()
        return response
    else:
        hgr.set_user(authed)

    hgserve = hgweb(str(repo.location))
    hgserve.reponame = repo.slug

    # TODO: is it Possible to charge the settings just for one time?
    hgserve.repo.ui.setconfig('web', 'name', smart_str(hgserve.reponame))
    hgserve.repo.ui.setconfig('web', 'description',
                              smart_str(repo.description))
    hgserve.repo.ui.setconfig('web', 'contact',
                              smart_str(repo.owner.get_full_name()))
    hgserve.repo.ui.setconfig('web', 'allow_archive', repo.allow_archive)

    if os.path.exists(hgwebproxy_settings.STYLES_PATH):
        template_paths = templater.templatepath()
        template_paths.insert(0, hgwebproxy_settings.STYLES_PATH)
        hgserve.repo.ui.setconfig('web', 'templates', template_paths)
        hgserve.templatepath = hgserve.repo.ui.config('web', 'templates',
                                                      template_paths)

    if hgwebproxy_settings.ALLOW_CUSTOM_STYLE:
        hgserve.repo.ui.setconfig('web', 'style', repo.style)
    else:
        hgserve.repo.ui.setconfig('web', 'style',
                                  hgwebproxy_settings.DEFAULT_STYLE)

    hgserve.repo.ui.setconfig('web', 'baseurl', repo.get_absolute_url())
    hgserve.repo.ui.setconfig('web', 'allow_push',
                              authed)  #Allow push to the current user
    hgserve.repo.ui.setconfig('web', 'staticurl',
                              hgwebproxy_settings.STATIC_URL)

    if settings.DEBUG:
        hgserve.repo.ui.setconfig('web', 'push_ssl', 'false')
    else:
        hgserve.repo.ui.setconfig('web', 'push_ssl', repo.allow_push_ssl)

    # Catch hgweb error to show as Django Exceptions
    try:
        response.write(''.join(each for each in hgserve.run_wsgi(hgr)))
    except KeyError:
        return HttpResponseServerError('Mercurial has crashed',
                                       mimetype='text/html')

    if mercurial_request:
        return response

    # make sure we return the response without wrapping if content-type is
    # either a binary stream or text/plain (for raw changesets).
    if response['content-type'].split(';')[0] in ('application/octet-stream',
                                                  'text/plain'):
        return response

    context = {
        'content': response.content,
        'reponame': hgserve.reponame,
        'static_url': hgwebproxy_settings.STATIC_URL,
        'slugpath': request.path.replace(repo.get_absolute_url(), ''),
        'is_root': request.path == repo.get_absolute_url(),
        'repo': repo,
    }

    if request.path.endswith(repo_name +
                             '/rss-log') or request.path.endswith(repo_name +
                                                                  '/atom-log'):
        return HttpResponse(response.content, mimetype='application/xml')
    else:
        return render_to_response("hgwebproxy/wrapper.html", context,
                                  RequestContext(request))
Ejemplo n.º 21
0
def is_template(template):
    #TODO: Load project mercurial styles
    if templatepath(template):
        return True
    else:
        return False
Ejemplo n.º 22
0
def repo_detail(request, pattern):
    slug = pattern.split('/')[0]
    repo = get_object_or_404(Repository, slug=slug)
    response = HttpResponse()
    hgr = HgRequestWrapper(
        request,
        response,
        script_name=repo.get_absolute_url(),
    )

    """
    Authenticate on all requests. To authenticate only against 'POST'
    requests, uncomment the line below the comment.

    Currently, repositories are only viewable by authenticated users.
    If authentication is only done on 'POST' request, then
    repositories are readable by anyone. but only authenticated users
    can push.
    """

    realm = hgwebproxy_settings.AUTH_REALM # Change if you want.

    if is_mercurial(request):
        # This is a request by a mercurial client 

        # If slash not present then add slash regardless of APPEND_SLASH setting
        # since hgweb returns 404 if it isn't present.
        if not request.path.endswith('/'):
            new_url = [request.get_host(), request.path+'/']
            if new_url[0]:
                newurl = "%s://%s%s" % (
                    request.is_secure() and 'https' or 'http',
                    new_url[0], urlquote(new_url[1]))
            else:
                newurl = urlquote(new_url[1])
            if request.GET:
                newurl += '?' + request.META['QUERY_STRING']
            return HttpResponsePermanentRedirect(newurl)
    
        authed = basic_auth(request, realm, repo)
    else:
        # This is a standard web request
        if not repo.has_view_permission(request.user):
            raise PermissionDenied(_("You do not have access to this repository"))
        authed = request.user.username

        #if not request.user.is_authenticated():
        #    return HttpResponseRedirect('%s?next=%s' %
        #                                (settings.LOGIN_URL,request.path))
        #else:
        #    authed = request.user.username

    if not authed:
        response.status_code = 401
        response['WWW-Authenticate'] = '''Basic realm="%s"''' % realm
        return response
    else:
        hgr.set_user(authed)

    """
    Run the `hgwebdir` method from Mercurial directly, with
    our incognito request wrapper, output will be buffered. Wrapped
    in a try:except: since `hgweb` *can* crash.

    Mercurial now sends the content through as a generator.
    We need to iterate over the output in order to get all of the content
    """

    template_dir = os.path.join(os.path.dirname(__file__), 'templates')
    hgserve = hgweb(str(repo.location))

    hgserve.reponame = repo.slug

    if hgwebproxy_settings.TEMPLATE_PATHS is not None:
        hgserve.templatepath = hgwebproxy_settings.TEMPLATE_PATHS 

    hgserve.repo.ui.setconfig('web', 'description', smart_str(repo.description))
    hgserve.repo.ui.setconfig('web', 'name', smart_str(hgserve.reponame))
    # encode('utf-8') FIX "decoding Unicode is not supported" exception on mercurial
    hgserve.repo.ui.setconfig('web', 'contact', smart_str(repo.owner.get_full_name()))
    hgserve.repo.ui.setconfig('web', 'allow_archive', repo.allow_archive)
    # Set the style
    style = repo.style or hgwebproxy_settings.STYLE
    if not templater.templatepath(style):
        raise ImproperlyConfigured(_("'%s' is not an available style. Please check the HGPROXY_STYLE property in your settings.py" % style))

    hgserve.repo.ui.setconfig('web', 'style', style)
    hgserve.repo.ui.setconfig('web', 'baseurl', repo.get_absolute_url() )
    # Allow push to the current user
    hgserve.repo.ui.setconfig('web', 'allow_push', authed)

    #Allow serving static content from a seperate URL
    if not settings.DEBUG:
        hgserve.repo.ui.setconfig('web', 'staticurl', hgwebproxy_settings.STATIC_URL)

    if settings.DEBUG or hgwebproxy_settings.ALLOW_HTTP_PUSH:
        # Allow pushing in using http when debugging
        hgserve.repo.ui.setconfig('web', 'push_ssl', 'false')

    # Allow hgweb errors to propagate
    response.write(''.join([each for each in hgserve.run_wsgi(hgr)]))
    return response
Ejemplo n.º 23
0
def repo_list(request):
    # Handle repo_detail
    u = ui.ui()
    u.setconfig('ui', 'report_untrusted', 'off')
    u.setconfig('ui', 'interactive', 'off')

    #stripecount = u.config('web', 'stripes', 1)
    stripecount = 1 
    response = HttpResponse()

    #TODO: Is this right?
    url = request.path
    if not url.endswith('/'):
        url += '/'

    def header(**map):
        yield tmpl('header', encoding=encoding.encoding, **map)

    def footer(**map):
        yield tmpl("footer", **map)

    def motd(**map):
        yield "" 

    def archivelist(ui, nodeid, url):
        # TODO: support archivelist
        if 1 == 2:  
            yield ""

    sortdefault = 'name', False
    def entries(sortcolumn="", descending=False, subdir="", **map):
        rows = []
        parity = common.paritygen(stripecount)
        for repo in Repository.objects.has_view_permission(request.user):
            contact = smart_str(repo.owner.get_full_name())

            lastchange = (common.get_mtime(repo.location), util.makedate()[1])
             
            row = dict(contact=contact or "unknown",
                       contact_sort=contact.upper() or "unknown",
                       name=smart_str(repo.name),
                       name_sort=smart_str(repo.name),
                       url=repo.get_absolute_url(),
                       description=smart_str(repo.description) or "unknown",
                       description_sort=smart_str(repo.description.upper()) or "unknown",
                       lastchange=lastchange,
                       lastchange_sort=lastchange[1]-lastchange[0],
                       archives=archivelist(u, "tip", url))
            if (not sortcolumn or (sortcolumn, descending) == sortdefault):
                # fast path for unsorted output
                row['parity'] = parity.next()
                yield row
            else:
                rows.append((row["%s_sort" % sortcolumn], row))

        if rows:
            rows.sort()
            if descending:
                rows.reverse()
            for key, row in rows:
                row['parity'] = parity.next()
                yield row

    defaultstaticurl = request.path + 'static/'
    staticurl = hgwebproxy_settings.STATIC_URL or defaultstaticurl if not settings.DEBUG else defaultstaticurl 

    if hgwebproxy_settings.TEMPLATE_PATHS is not None:
        hgserve.templatepath = hgwebproxy_settings.TEMPLATE_PATHS 

    vars = {}
    start = url[-1] == '?' and '&' or '?'
    sessionvars = webutil.sessionvars(vars, start)
    
    if not templater.templatepath(hgwebproxy_settings.STYLE):
        raise ImproperlyConfigured(_("'%s' is not an available style. Please check the HGPROXY_STYLE property in your settings.py" % hgwebproxy_settings.STYLE))

    mapfile = templater.stylemap(hgwebproxy_settings.STYLE)
    if isinstance(mapfile, tuple):
        mapfile = mapfile[1]
    tmpl = templater.templater(mapfile,
                               defaults={"header": header,
                                         "footer": footer,
                                         "motd": motd,
                                         "url": url,
                                         "staticurl": staticurl,
                                         "sessionvars": sessionvars})

    #Support for descending, sortcolumn etc.
    sortable = ["name", "description", "contact", "lastchange"]
    sortcolumn, descending = sortdefault
    if 'sort' in request.GET:
        sortcolumn = request.GET['sort']
        descending = sortcolumn.startswith('-')
        if descending:
            sortcolumn = sortcolumn[1:]
        if sortcolumn not in sortable:
            sortcolumn = ""

    sort = [("sort_%s" % column,
             "%s%s" % ((not descending and column == sortcolumn)
                        and "-" or "", column))
            for column in sortable]

    chunks = tmpl("index", entries=entries, subdir="",
                    sortcolumn=sortcolumn, descending=descending,
                    **dict(sort))
    
    for chunk in chunks:
        response.write(chunk)
    return response
Ejemplo n.º 24
0
                template = templater.parsestring(template)
            except SyntaxError:
                template = templater.parsestring(template, quoted=False)
        else:
            style = util.expandpath(ui.config('ui', 'style', ''))
    elif template:
        try:
            template = templater.parsestring(template, quoted=False)
        except SyntaxError, e:
            raise util.Abort('bad template: %s' % e.args[0])
    
    mapfile = None
    if style and not template:
        mapfile = style
        if not os.path.split(mapfile)[0]:
            mapname = (templater.templatepath('map-cmdline.' + mapfile)
                       or templater.templatepath(mapfile))
            if mapname:
                mapfile = mapname

    if style or template:
        should_format = False
        long_format = True
        flags = True
    elif long_format:
        if ui.verbose:
            template = ['{mode|lsmode}\0{author}']
        else:
            template = ['{mode|lsmode}\0{author|user}']
        align_columns = ['ll']