Exemplo n.º 1
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
Exemplo n.º 2
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))
Exemplo n.º 3
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))
Exemplo n.º 4
0
def hgroot(request, *args):
    response = Httpresponseonse()
    hgr = HgRequestWrapper(request, response)

    """
    You want to specify the path to your config file here. Look
    at `hgweb.conf` for a working example.
    """
    config = os.path.join(settings.BASE_DIR, 'hgwebproxy', 'hgweb.conf')
    os.environ['HGRCPATH'] = config

    """
    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.
    """
    #if request.method == "POST":
    realm = 'Basic Auth' # Change if you want.

    if is_mercurial(request):
        # This is a request by a mercurial user
        authed = basic_auth(request, realm)
    else:
        # This is a standard web request
        if not request.user.is_authenticated():
            return HttpresponseonseRedirect('%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
    """
    try:
        response.write(''.join([each for each in hgwrapper(config)]))
    except KeyError:
        response['content-type'] = 'text/html'
        response.write('hgweb crashed.')
        # if hgweb crashed you can do what you like, throw a 404 or continue on
        # hgweb tends to throw these on invalid requests..?
        pass

    """
    In cases of downloading raw files or tarballs, we don't want to
    pass the output to our template, so instead we just return it as-is.
    """
    if response.has_header('content-type'):
        if not response['content-type'].startswith("text/html"):
            return response

    """
    Otherwise, send the content on to the template, for any kind
    of custom layout you want around it.
    """
    return render_to_responseonse("flat.html",
        { 'content': response.content, },
        RequestContext(request))
Exemplo n.º 5
0
    def explore(self, request, id, *args):
        opts = self.model._meta
        app_label = opts.app_label

        response = HttpResponse()
        repo = get_object_or_404(Repository, pk=id)
        if not self.has_view_permission(request, repo):
            raise PermissionDenied

        hgr = HgRequestWrapper(
            request,
            response,
            script_name=repo.get_admin_explore_url(),
        )
        hgr.set_user(request.user.username)

        """
        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
        # TODO: A more flexible way to get the default template path of mercurial
        hgserve.templatepath = (template_dir, '/usr/share/mercurial/templates')

        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)
        hgserve.repo.ui.setconfig('web', 'style', 'monoblue_plain')
        hgserve.repo.ui.setconfig('web', 'baseurl', repo.get_admin_explore_url())
        hgserve.repo.ui.setconfig('web', 'staticurl', STATIC_URL)

        try:
            response.write(''.join([each for each in hgserve.run_wsgi(hgr)]))
        except KeyError:
            response['content-type'] = 'text/html'
            response.write('hgweb crashed.')
            # if hgweb crashed you can do what you like, throw a 404 or continue on
            # hgweb tends to throw these on invalid requests..?
            pass

        context = {
            'app_label': app_label,
            'opts': opts,
            'has_change_permission': self.has_change_permission(request, repo),
            'original': repo,
            'content': response.content,
            'reponame' : hgserve.reponame,
            'static_url' : STATIC_URL,
            'slugpath': request.path.replace(repo.get_admin_explore_url(), '') or 'summary',
            'is_root': request.path == repo.get_admin_explore_url(),
        }

        """
        In cases of downloading raw files or tarballs, we don't want to
        pass the output to our template, so instead we just return it as-is.
        """
        if response.has_header('content-type'):
            if not response['content-type'].startswith("text/html"):
                return response

        """
        Otherwise, send the content on to the template, for any kind
        of custom layout you want around it.
        """
        return render_to_response("admin/hgwebproxy/repository/explore.html", context, RequestContext(request))