Exemple #1
0
class ProductVersionView(ListView):
    template_name = 'security/product-advisories.html'
    context_object_name = 'product_versions'
    allow_empty = False

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(ProductVersionView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        slug = u'{product}-{version}'.format(**self.kwargs)
        qfilter = Q(slug__startswith=slug + '.')
        dots = slug.count('.')
        if dots < 2:
            # add exact match if not point release
            if slug.endswith('.0'):
                # stip trailing .0 as products are stored without them
                slug = slug[:-2]
            qfilter |= Q(slug__exact=slug)
        versions = Product.objects.filter(qfilter)
        return sorted(versions, reverse=True)

    def get_context_data(self, **kwargs):
        cxt = super(ProductVersionView, self).get_context_data(**kwargs)
        prod_name, version = self.kwargs['product'], self.kwargs['version']
        cxt['is_obsolete'] = product_is_obsolete(prod_name, version)
        cxt['product_name'] = '{0} {1}'.format(cxt['product_versions'][0].product, version)
        cxt['product_slug'] = prod_name
        return cxt
Exemple #2
0
class CachedRedirectView(RedirectView):
    permanent = True

    @method_decorator(cache_control_expires(24 * 30))  # 30 days
    def dispatch(self, request, *args, **kwargs):
        return super(CachedRedirectView,
                     self).dispatch(request, *args, **kwargs)
Exemple #3
0
class ProductView(ListView):
    template_name = 'security/product-advisories.html'
    context_object_name = 'product_versions'
    allow_empty = False
    minimum_versions = {
        'firefox': Version('4.0'),
        'thunderbird': Version('6.0'),
        'seamonkey': Version('2.3'),
    }

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(ProductView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        product_slug = self.kwargs.get('slug')
        versions = Product.objects.filter(product_slug=product_slug)
        min_version = self.minimum_versions.get(product_slug)
        if min_version:
            versions = [vers for vers in versions if vers.version >= min_version]
        return sorted(versions, reverse=True)

    def get_context_data(self, **kwargs):
        cxt = super(ProductView, self).get_context_data(**kwargs)
        cxt['product_name'] = cxt['product_versions'][0].product
        return cxt
Exemple #4
0
class AdvisoryView(DetailView):
    model = SecurityAdvisory
    template_name = 'security/advisory.html'
    context_object_name = 'advisory'

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(AdvisoryView, self).dispatch(request, *args, **kwargs)
Exemple #5
0
class AdvisoriesView(ListView):
    template_name = 'security/advisories.html'
    queryset = SecurityAdvisory.objects.only('id', 'impact', 'title', 'announced')
    context_object_name = 'advisories'

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(AdvisoriesView, self).dispatch(request, *args, **kwargs)
Exemple #6
0
class ProductVersionView(ListView):
    template_name = 'security/product-advisories.html'
    context_object_name = 'product_versions'
    allow_empty = False

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(ProductVersionView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        slug = self.kwargs['slug']
        qfilter = Q(slug__startswith=slug + '.')
        dots = slug.count('.')
        if dots == 1:
            # minor version. add exact match.
            qfilter |= Q(slug__exact=slug)
        versions = Product.objects.filter(qfilter)
        return sorted(versions, reverse=True)
Exemple #7
0
class ProductVersionView(ListView):
    template_name = 'security/product-advisories.html'
    context_object_name = 'product_versions'
    allow_empty = False

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(ProductVersionView,
                     self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        slug = self.kwargs['slug']
        qfilter = Q(slug__startswith=slug + '.')
        dots = slug.count('.')
        if dots < 2:
            # add exact match if not point release
            if slug.endswith('.0'):
                # stip trailing .0 as products are stored without them
                slug = slug[:-2]
            qfilter |= Q(slug__exact=slug)
        versions = Product.objects.filter(qfilter)
        return sorted(versions, reverse=True)
Exemple #8
0
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

from bedrock.mozorg.decorators import cache_control_expires
from bedrock.sitemaps.models import NO_LOCALE, SitemapURL


@method_decorator(cache_control_expires(1), name="dispatch")
class SitemapView(TemplateView):
    content_type = "text/xml"

    def _get_locale(self):
        if self.kwargs["is_none"]:
            # is_none here refers to the sitemap_none.xml URL. the value of that kwarg
            # when on that URL will be "_none" and will be None if not on that URL.
            # For that page we set the locale to the special value as that is what the entries
            # in the DB have recorded for locale for URLs that don't have a locale.
            locale = NO_LOCALE
        else:
            # can come back as empty string
            # should be None here if not a real locale because
            # None will mean that we should show the index of sitemaps
            # instead of a sitemap for a locale.
            locale = getattr(self.request, "locale", None)

        return locale
Exemple #9
0
def redirect(pattern, to, permanent=True, locale_prefix=True, anchor=None, name=None,
             query=None, vary=None, cache_timeout=12, decorators=None, re_flags=None,
             to_args=None, to_kwargs=None, prepend_locale=True, merge_query=False):
    """
    Return a url matcher suited for urlpatterns.

    pattern: the regex against which to match the requested URL.
    to: either a url name that `reverse` will find, a url that will simply be returned,
        or a function that will be given the request and url captures, and return the
        destination.
    permanent: boolean whether to send a 301 or 302 response.
    locale_prefix: automatically prepend `pattern` with a regex for an optional locale
        in the url. This locale (or None) will show up in captured kwargs as 'locale'.
    anchor: if set it will be appended to the destination url after a '#'.
    name: if used in a `urls.py` the redirect URL will be available as the name
        for use in calls to `reverse()`. Does _NOT_ work if used in a `redirects.py` file.
    query: a dict of query params to add to the destination url.
    vary: if you used an HTTP header to decide where to send users you should include that
        header's name in the `vary` arg.
    cache_timeout: number of hours to cache this redirect. just sets the proper `cache-control`
        and `expires` headers.
    decorators: a callable (or list of callables) that will wrap the view used to redirect
        the user. equivalent to adding a decorator to any other view.
    re_flags: a string of any of the characters: "iLmsux". Will modify the `pattern` regex
        based on the documented meaning of the flags (see python re module docs).
    to_args: a tuple or list of args to pass to reverse if `to` is a url name.
    to_kwargs: a dict of keyword args to pass to reverse if `to` is a url name.
    prepend_locale: if true the redirect URL will be prepended with the locale from the
        requested URL.
    merge_query: merge the requested query params from the `query` arg with any query params
        from the request.

    Usage:
    urlpatterns = [
        redirect(r'projects/$', 'mozorg.product'),
        redirect(r'^projects/seamonkey$', 'mozorg.product', locale_prefix=False),
        redirect(r'apps/$', 'https://marketplace.firefox.com'),
        redirect(r'firefox/$', 'firefox.new', name='firefox'),
        redirect(r'the/dude$', 'abides', query={'aggression': 'not_stand'}),
    ]
    """
    if permanent:
        redirect_class = HttpResponsePermanentRedirect
    else:
        redirect_class = HttpResponseRedirect

    if locale_prefix:
        pattern = pattern.lstrip('^/')
        pattern = LOCALE_RE + pattern

    if re_flags:
        pattern = '(?{})'.format(re_flags) + pattern

    view_decorators = []
    if cache_timeout is not None:
        view_decorators.append(cache_control_expires(cache_timeout))

    if vary:
        if isinstance(vary, basestring):
            vary = [vary]
        view_decorators.append(vary_on_headers(*vary))

    if decorators:
        if callable(decorators):
            view_decorators.append(decorators)
        else:
            view_decorators.extend(decorators)

    def _view(request, *args, **kwargs):
        # don't want to have 'None' in substitutions
        kwargs = {k: v or '' for k, v in kwargs.items()}
        args = [x or '' for x in args]

        # If it's a callable, call it and get the url out.
        if callable(to):
            to_value = to(request, *args, **kwargs)
        else:
            to_value = to

        if to_value.startswith('/') or HTTP_RE.match(to_value):
            redirect_url = to_value
        else:
            try:
                redirect_url = reverse(to_value, args=to_args, kwargs=to_kwargs)
            except NoReverseMatch:
                # Assume it's a URL
                redirect_url = to_value

        if prepend_locale and redirect_url.startswith('/') and kwargs.get('locale'):
            redirect_url = '/{locale}' + redirect_url.lstrip('/')

        # use info from url captures.
        if args or kwargs:
            redirect_url = strip_tags(force_text(redirect_url).format(*args, **kwargs))

        if query:
            if merge_query:
                req_query = parse_qs(request.META.get('QUERY_STRING'))
                req_query.update(query)
                querystring = urlencode(req_query, doseq=True)
            else:
                querystring = urlencode(query, doseq=True)
        elif query is None:
            querystring = request.META.get('QUERY_STRING')
        else:
            querystring = ''

        if querystring:
            redirect_url = '?'.join([redirect_url, querystring])

        if anchor:
            redirect_url = '#'.join([redirect_url, anchor])

        if PROTOCOL_RELATIVE_RE.match(redirect_url):
            redirect_url = '/' + redirect_url.lstrip('/')

        return redirect_class(redirect_url)

    # Apply decorators
    try:
        # Decorators should be applied in reverse order so that input
        # can be sent in the order your would write nested decorators
        # e.g. dec1(dec2(_view)) -> [dec1, dec2]
        for decorator in reversed(view_decorators):
            _view = decorator(_view)
    except TypeError:
        log.exception('decorators not iterable or does not contain '
                      'callable items')

    return url(pattern, _view, name=name)
Exemple #10
0
def redirect(pattern, to, permanent=True, locale_prefix=True, anchor=None, name=None,
             query=None, vary=None, cache_timeout=12, decorators=None, re_flags=None,
             to_args=None, to_kwargs=None, prepend_locale=True, merge_query=False):
    """
    Return a url matcher suited for urlpatterns.

    pattern: the regex against which to match the requested URL.
    to: either a url name that `reverse` will find, a url that will simply be returned,
        or a function that will be given the request and url captures, and return the
        destination.
    permanent: boolean whether to send a 301 or 302 response.
    locale_prefix: automatically prepend `pattern` with a regex for an optional locale
        in the url. This locale (or None) will show up in captured kwargs as 'locale'.
    anchor: if set it will be appended to the destination url after a '#'.
    name: if used in a `urls.py` the redirect URL will be available as the name
        for use in calls to `reverse()`. Does _NOT_ work if used in a `redirects.py` file.
    query: a dict of query params to add to the destination url.
    vary: if you used an HTTP header to decide where to send users you should include that
        header's name in the `vary` arg.
    cache_timeout: number of hours to cache this redirect. just sets the proper `cache-control`
        and `expires` headers.
    decorators: a callable (or list of callables) that will wrap the view used to redirect
        the user. equivalent to adding a decorator to any other view.
    re_flags: a string of any of the characters: "iLmsux". Will modify the `pattern` regex
        based on the documented meaning of the flags (see python re module docs).
    to_args: a tuple or list of args to pass to reverse if `to` is a url name.
    to_kwargs: a dict of keyword args to pass to reverse if `to` is a url name.
    prepend_locale: if true the redirect URL will be prepended with the locale from the
        requested URL.
    merge_query: merge the requested query params from the `query` arg with any query params
        from the request.

    Usage:
    urlpatterns = [
        redirect(r'projects/$', 'mozorg.product'),
        redirect(r'^projects/seamonkey$', 'mozorg.product', locale_prefix=False),
        redirect(r'apps/$', 'https://marketplace.firefox.com'),
        redirect(r'firefox/$', 'firefox.new', name='firefox'),
        redirect(r'the/dude$', 'abides', query={'aggression': 'not_stand'}),
    ]
    """
    if permanent:
        redirect_class = HttpResponsePermanentRedirect
    else:
        redirect_class = HttpResponseRedirect

    if locale_prefix:
        pattern = pattern.lstrip('^/')
        pattern = LOCALE_RE + pattern

    if re_flags:
        pattern = '(?{})'.format(re_flags) + pattern

    view_decorators = []
    if cache_timeout is not None:
        view_decorators.append(cache_control_expires(cache_timeout))

    if vary:
        if isinstance(vary, basestring):
            vary = [vary]
        view_decorators.append(vary_on_headers(*vary))

    if decorators:
        if callable(decorators):
            view_decorators.append(decorators)
        else:
            view_decorators.extend(decorators)

    def _view(request, *args, **kwargs):
        # don't want to have 'None' in substitutions
        kwargs = {k: v or '' for k, v in kwargs.items()}
        args = [x or '' for x in args]

        # If it's a callable, call it and get the url out.
        if callable(to):
            to_value = to(request, *args, **kwargs)
        else:
            to_value = to

        if to_value.startswith('/') or HTTP_RE.match(to_value):
            redirect_url = to_value
        else:
            try:
                redirect_url = reverse(to_value, args=to_args, kwargs=to_kwargs)
            except NoReverseMatch:
                # Assume it's a URL
                redirect_url = to_value

        if prepend_locale and redirect_url.startswith('/') and kwargs.get('locale'):
            redirect_url = '/{locale}' + redirect_url.lstrip('/')

        # use info from url captures.
        if args or kwargs:
            redirect_url = strip_tags(force_text(redirect_url).format(*args, **kwargs))

        if query:
            if merge_query:
                req_query = parse_qs(request.META.get('QUERY_STRING', ''))
                req_query.update(query)
                querystring = urlencode(req_query, doseq=True)
            else:
                querystring = urlencode(query, doseq=True)
        elif query is None:
            querystring = request.META.get('QUERY_STRING', '')
        else:
            querystring = ''

        if querystring:
            redirect_url = '?'.join([redirect_url, querystring])

        if anchor:
            redirect_url = '#'.join([redirect_url, anchor])

        if PROTOCOL_RELATIVE_RE.match(redirect_url):
            redirect_url = '/' + redirect_url.lstrip('/')

        return redirect_class(redirect_url)

    # Apply decorators
    try:
        # Decorators should be applied in reverse order so that input
        # can be sent in the order your would write nested decorators
        # e.g. dec1(dec2(_view)) -> [dec1, dec2]
        for decorator in reversed(view_decorators):
            _view = decorator(_view)
    except TypeError:
        log.exception('decorators not iterable or does not contain '
                      'callable items')

    return url(pattern, _view, name=name)