예제 #1
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))
예제 #2
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
예제 #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))