from django.core.exceptions import PermissionDenied

def referer_matches_hostname(*netlocs):
    """
    Decorator for views that checks that if the request's HTTP_REFERER matches
    the supplied string. Failure raises a PermissionDenied exception. If
    multiple arguments are supplied the decorator will try to match any of
    them.
    """
    def _dec(view_func):
        def _check_referer(request, *args, **kwargs):
            import urlparse
            referer = request.META.get('HTTP_REFERER', '')
            referer_netloc = urlparse.urlparse(referer).netloc
            if referer_netloc in netlocs:
                return view_func(request, *args, **kwargs)
            raise PermissionDenied()
        _check_referer.__doc__ = view_func.__doc__
        _check_referer.__dict__ = view_func.__dict__        
        return _check_referer
    return _dec

def referer_matches_re(regex):
    """
    Decorator for views that checks that if the request's HTTP_REFERER matches
    the supplied regex pattern. Failure raises a PermissionDenied exception.
    """
    import re
    regex = re.compile(regex)
    def _dec(view_func):
        def _check_referer(request, *args, **kwargs):
            referer = request.META.get('HTTP_REFERER', '')
            if regex.match(referer):
                return view_func(request, *args, **kwargs)
            raise PermissionDenied()
        _check_referer.__doc__ = view_func.__doc__
        _check_referer.__dict__ = view_func.__dict__        
        return _check_referer
    return _dec

from django.contrib.sites.models import Site
local_referer_only = referer_matches_hostname(str(Site.objects.get_current()))
## Same, but using referer_matches_re:
# regex = r'^https?://%s/.*' % Site.objects.get_current()
# local_referer_only = referer_matches_re(regex)
local_referer_only.__doc__ = (
    """
    Decorator for views that checks that if the request's HTTP_REFERER matches
    the current site. If not, a PermissionDenied exception is raised.
    """
)
