Пример #1
0
        def wrapper(request, *args, **kwargs):
            try:
                callback = getattr(self, view)
                response = callback(request, *args, **kwargs)
                
                varies = getattr(self._meta.cache, "varies", [])

                if varies:
                    patch_vary_headers(response, varies)

                if self._meta.cache.cacheable(request, response):
                    if self._meta.cache.cache_control():
                        patch_cache_control(response, **self._meta.cache.cache_control())
                
                if request.is_ajax():
                    patch_cache_control(response, no_cache=True)
               
               
                if request.method == "OPTIONS":
#                     response = HttpResponse("")
                    response['Access-Control-Allow-Origin'] = "*"
                    response['Access-Control-Allow-Methods'] = "POST, OPTIONS"
                    response['Access-Control-Allow-Headers'] = "X-Requested-With"
                    response['Access-Control-Max-Age'] = "1800"
                else:
                    response['Access-Control-Allow-Origin'] = "*"
                
                
                return response
            except (BadRequest, ApiFieldError), e:
                return http.HttpBadRequest(json.dumps({"status":False,"code": 400, "message": str(e) }))
Пример #2
0
def fudge_headers(response, stats):
    """Alter cache headers. Don't cache content where data could be missing."""
    if not stats:
        add_never_cache_headers(response)
    else:
        seven_days = 60 * 60 * 24 * 7
        patch_cache_control(response, max_age=seven_days)
Пример #3
0
def add_shared_cache_control(response, **kwargs):
    """
    Adds a Cache-Control header for shared caches, like CDNs, to the
    provided response.

    Default settings (which can be overridden or extended):
    - max-age=0 - Don't use browser cache without asking if still valid
    - s-maxage=CACHE_CONTROL_DEFAULT_SHARED_MAX_AGE - Cache in the shared
      cache for the default perioid of time
    - public - Allow intermediate proxies to cache response
    """
    nocache = (response.has_header('Cache-Control') and
               ('no-cache' in response['Cache-Control'] or
                'no-store' in response['Cache-Control']))
    if nocache:
        return

    # Set the default values.
    cc_kwargs = {
        'public': True,
        'max_age': 0,
        's_maxage': settings.CACHE_CONTROL_DEFAULT_SHARED_MAX_AGE
    }
    # Override the default values and/or add new ones.
    cc_kwargs.update(kwargs)

    patch_cache_control(response, **cc_kwargs)
Пример #4
0
def qrcode(req, width):
    import qr

    url = req.GET.get('url')
    if url is None:
        raise Http404

    try:
        data = url.encode('ascii')
    except UnicodeError:
        # only supports URLs properly urlencoded
        raise Http404

    if width == "480":
        magnify = 8
    else:
        magnify = 4

    buf = StringIO()
    try:
        qr.qrcode(data, buf, format=qr.GIF, magnify=magnify)
    except ValueError:
        # qr module wasn't be compiled with GD library
        raise Http404

    content = buf.getvalue()

    CACHE_TIMEOUT = 86400
    res = HttpResponse(content, content_type='image/gif')
    res['Content-Length'] = str(len(content))
    res['ETag']           = '"%s"' % md5(content).hexdigest()
    res['Last-Modified']  = http_date()
    res['Expires'] = http_date(time.time() + CACHE_TIMEOUT)
    patch_cache_control(res, max_age=CACHE_TIMEOUT)
    return res
Пример #5
0
    def process_request(self, request):
        if not MEDIA_DEV_MODE:
            return

        # We refresh the dev names only once every 30 seconds, so all
        # media_url() calls are cached.
        # This allows for every "page load" to go very quickly, but does not require a
        # server restart to get new file paths and versions.
        global _REFRESH_DEV_NAMES_DONE_AT
        if (_REFRESH_DEV_NAMES_DONE_AT + 15) < time.time():
            _refresh_dev_names()
            _REFRESH_DEV_NAMES_DONE_AT = time.time()

        if not request.path.startswith(DEV_MEDIA_URL):
            return

        filename = request.path[len(DEV_MEDIA_URL) :]

        try:
            backend = _backend_mapping[filename]
        except KeyError:
            raise Http404('No such media file "%s"' % filename)
        content, mimetype = backend.get_dev_output(filename)
        if isinstance(content, unicode):
            content = content.encode("utf-8")
        response = HttpResponse(content, content_type=mimetype)
        response["Content-Length"] = len(content)

        # Cache manifest files MUST NEVER be cached or you'll be unable to update
        # your cached app!!!
        if response["Content-Type"] != "text/cache-manifest" and response.status_code == 200:
            patch_cache_control(response, public=True, max_age=self.MAX_AGE)
            response["Expires"] = http_date(time.time() + self.MAX_AGE)
        return response
Пример #6
0
 def process_response(self, request, response):
     patch_cache_control(response,
         no_cache=True,
         no_store=True,
         must_revalidate=True,
         )
     return response
Пример #7
0
def tracker_response(request, template='tracker/index.html', qdict=None, status=200, delegate=None):
    qdict = tracker_context(request, qdict)
    try:
        starttime = time.time()
        if delegate:
            resp = delegate(request, template, context=qdict, status=status)
        else:
            resp = render(request, template, context=qdict, status=status)
        render_time = time.time() - starttime
        if 'queries' in request.GET and request.user.has_perm('tracker.view_queries'):
            resp = HttpResponse(json.dumps(connection.queries, ensure_ascii=False,
                                           indent=1), content_type='application/json;charset=utf-8')
        cache_control = {}
        if request.user.is_anonymous():
            cache_control['public'] = True
        else:
            resp['X-Render-Time'] = render_time
            cache_control['private'] = True
            cache_control['max-age'] = 0
        patch_cache_control(resp, **cache_control)
        return resp
    except Exception, e:
        if request.user.is_staff and not settings.DEBUG:
            return HttpResponse(unicode(type(e)) + '\n\n' + unicode(e), content_type='text/plain', status=500)
        raise
Пример #8
0
def update_response_headers(request, response):
    if not getattr(response, "override_serialization", False):
        serialization = request.serialization
        if serialization == "xml":
            response["Content-Type"] = "application/xml; charset=UTF-8"
        elif serialization == "json":
            response["Content-Type"] = "application/json; charset=UTF-8"
        elif serialization == "text":
            response["Content-Type"] = "text/plain; charset=UTF-8"
        else:
            raise ValueError("Unknown serialization format '%s'" %
                             serialization)

    if settings.DEBUG or getattr(settings, "TEST", False):
        response["Date"] = format_date_time(time())

    if not response.has_header("Content-Length") and \
       isinstance(response, HttpResponse):
        response["Content-Length"] = len(response.content)

    cache.add_never_cache_headers(response)
    # Fix Vary and Cache-Control Headers. Issue: #3448
    cache.patch_vary_headers(response, ('X-Auth-Token',))
    cache.patch_cache_control(response, no_cache=True, no_store=True,
                              must_revalidate=True)
Пример #9
0
    def process_request(self, request):
        if not MEDIA_DEV_MODE:
            return

        # We refresh the dev names only once for the whole request, so all
        # media_url() calls are cached.
        _refresh_dev_names()

        if not request.path.startswith(DEV_MEDIA_URL):
            return

        filename = request.path[len(DEV_MEDIA_URL):]

        try:
            backend = _backend_mapping[filename]
        except KeyError:
            raise Http404('The mediagenerator could not find the media file "%s"'
                          % filename)
        content, mimetype = backend.get_dev_output(filename)
        if not mimetype:
            mimetype = 'application/octet-stream'
        if isinstance(content, unicode):
            content = content.encode('utf-8')
        if mimetype.startswith('text/') or mimetype in TEXT_MIME_TYPES:
            mimetype += '; charset=utf-8'
        response = HttpResponse(content, content_type=mimetype)
        response['Content-Length'] = len(content)

        # Cache manifest files MUST NEVER be cached or you'll be unable to update
        # your cached app!!!
        if response['Content-Type'] != 'text/cache-manifest' and \
                response.status_code == 200:
            patch_cache_control(response, public=True, max_age=self.MAX_AGE)
            response['Expires'] = http_date(time.time() + self.MAX_AGE)
        return response
Пример #10
0
    def get(self, request, *args, **kwargs):
        cache_max_age = 31536000
        image_type = kwargs.get('image_type')
        image_hash = kwargs.get('hash')
        size = kwargs.get('size')

        not_found_response = JsonResponse({'detail': 'Not Found.'}, status=status.HTTP_404_NOT_FOUND)

        try:
            if image_type == EventImage.IMAGE_TYPE_IN_URL:
                image_url = EventImage.objects.get(hash=image_hash).get_url()
            elif image_type == PlaceImage.IMAGE_TYPE_IN_URL:
                image_url = PlaceImage.objects.get(hash=image_hash).get_url()
            elif image_type == XeroxMachine.IMAGE_TYPE_IN_URL:
                image_url = XeroxMachine().get(image_hash)
                cache_max_age = 604800
        except ObjectDoesNotExist:
            return not_found_response

        try:
            image = transform_external_image(image_url, size)
            response = HttpResponse(content_type='image/jpeg')
            image.save(response, 'jpeg')
        except IOError:
            return not_found_response

        patch_cache_control(response, max_age=cache_max_age)

        return response
Пример #11
0
def update_response_headers(request, response):
    if not getattr(response, "override_serialization", False):
        serialization = request.serialization
        if serialization == "xml":
            response["Content-Type"] = "application/xml; charset=UTF-8"
        elif serialization == "json":
            response["Content-Type"] = "application/json; charset=UTF-8"
        elif serialization == "text":
            response["Content-Type"] = "text/plain; charset=UTF-8"
        else:
            raise ValueError("Unknown serialization format '%s'" %
                             serialization)

    if settings.DEBUG or getattr(settings, "TEST", False):
        response["Date"] = format_date_time(time())

    if not response.has_header("Content-Length"):
        _base_content_is_iter = getattr(response, '_base_content_is_iter',
                                        None)
        if (_base_content_is_iter is not None and not _base_content_is_iter):
            response["Content-Length"] = len(response.content)
        else:
            if not (response.has_header('Content-Type') and
                    response['Content-Type'].startswith(
                        'multipart/byteranges')):
                # save response content from been consumed if it is an iterator
                response._container, data = itertools.tee(response._container)
                response["Content-Length"] = len(str(data))

    cache.add_never_cache_headers(response)
    # Fix Vary and Cache-Control Headers. Issue: #3448
    cache.patch_vary_headers(response, ('X-Auth-Token',))
    cache.patch_cache_control(response, no_cache=True, no_store=True,
                              must_revalidate=True)
Пример #12
0
def msgs(request):
    "List all messages in json format starting just after the last msg_id"
    if request.method == 'GET': # Check if form has been submitted
        form = ListMsgsForm(request.GET)
        if form.is_valid(): # All validation rules pass (msg_id is int)
            m_id = form.cleaned_data['msg_id']

            # Get 10 latest msgs since ``m_id``
            msg_author = Msg.objects.latest_msgs(m_id, 10).values('id', 'msg_text', 'author__name')
            # Convert msgs to list
            msg_list = list(msg_author)

            # Format data into json
            data_json = json.dumps(msg_list, indent=2)

            # Output response as json content
            response = HttpResponse(data_json, content_type='text/json')

            # Make sure browser doesn't cache this request (not sure if needed)
            patch_cache_control(response, no_cache=True)

            return response
        else:
            pass
    else:
        pass
    raise Http404
Пример #13
0
def animated(request, id, extension):

    image_id = int(id.replace("/", ""))

    try:
        image = Image.objects.get(id=image_id)
    except Image.DoesNotExist:
        raise Http404

    if not image.animated:
        raise Http404

    if check_not_modified(request=request, last_modified=image.last_modified):
        # Avoid hitting storage backend on cache update
        resp = HttpResponseNotModified()
    else:
        try:
            image_blob = image.get_animated(extension=extension)
        except Exception:
            logger.exception("Animated error")
            return HttpResponseServerError("Animated error")

        resp = _image_response(image_blob, extension=extension)

    patch_cache_control(resp, max_age=settings.BETTY_CACHE_CROP_SEC)
    return resp
Пример #14
0
 def process_response(self, request, response):
     if request.is_ajax():
         # IE excessively caches XMLHttpRequests, so we're disabling
         # the browser cache here.
         # See http://www.enhanceie.com/ie/bugs.asp for details.
         patch_cache_control(response, no_cache=True)
     return response
Пример #15
0
    def process_request(self, request):
        if not MEDIA_DEV_MODE:
            return

        # We refresh the dev names only once for the whole request, so all
        # media_url() calls are cached.
        _refresh_dev_names()

        if not request.path.startswith(DEV_MEDIA_URL):
            return

        filename = request.path[len(DEV_MEDIA_URL):]

        try:
            backend = _backend_mapping[filename]
        except KeyError:
            raise Http404('No such media file "%s"' % filename)
        content, mimetype = backend.get_dev_output(filename)
        response = HttpResponse(content, content_type=mimetype)
        response['Content-Length'] = len(content)

        # Cache manifest files MUST NEVER be cached or you'll be unable to update
        # your cached app!!!
        if response['Content-Type'] != 'text/cache-manifest' and \
                response.status_code == 200:
            patch_cache_control(response, public=True, max_age=self.MAX_AGE)
            response['Expires'] = http_date(time.time() + self.MAX_AGE)
        return response
Пример #16
0
    def process_request(self, request):
        # Find locale, app
        prefixer = urlresolvers.Prefixer(request)
        if settings.DEBUG:
            redirect_type = HttpResponseRedirect
        else:
            redirect_type = HttpResponsePermanentRedirect
        urlresolvers.set_url_prefix(prefixer)
        full_path = prefixer.fix(prefixer.shortened_path)

        if (prefixer.app == amo.MOBILE.short and
                request.path.rstrip('/').endswith('/' + amo.MOBILE.short)):
            return redirect_type(request.path.replace('/mobile', '/android'))

        if ('lang' in request.GET and not re.match(
                settings.SUPPORTED_NONAPPS_NONLOCALES_REGEX,
                prefixer.shortened_path)):
            # Blank out the locale so that we can set a new one.  Remove lang
            # from query params so we don't have an infinite loop.
            prefixer.locale = ''
            new_path = prefixer.fix(prefixer.shortened_path)
            query = dict((force_bytes(k), request.GET[k]) for k in request.GET)
            query.pop('lang')
            return redirect_type(urlparams(new_path, **query))

        if full_path != request.path:
            query_string = request.META.get('QUERY_STRING', '')
            full_path = urllib.quote(full_path.encode('utf-8'))

            if query_string:
                query_string = query_string.decode('utf-8', 'ignore')
                full_path = u'%s?%s' % (full_path, query_string)

            response = redirect_type(full_path)
            # Cache the redirect for a year.
            if not settings.DEBUG:
                patch_cache_control(response, max_age=60 * 60 * 24 * 365)

            # Vary on Accept-Language or User-Agent if we changed the locale or
            # app.
            old_app = prefixer.app
            old_locale = prefixer.locale
            new_locale, new_app, _ = prefixer.split_path(full_path)

            if old_locale != new_locale:
                patch_vary_headers(response, ['Accept-Language'])
            if old_app != new_app:
                patch_vary_headers(response, ['User-Agent'])
            return response

        request.path_info = '/' + prefixer.shortened_path
        request.LANG = prefixer.locale or prefixer.get_language()
        activate(request.LANG)
        request.APP = amo.APPS.get(prefixer.app, amo.FIREFOX)

        # Match legacy api requests too - IdentifyAPIRequestMiddleware is v3+
        # TODO - remove this when legacy_api goes away
        # https://github.com/mozilla/addons-server/issues/9274
        request.is_legacy_api = request.path_info.startswith('/api/')
Пример #17
0
def border(req, style, rgb):
    import gd
    rgb = tuple(map(lambda x: int(x, 16), (rgb[0:2], rgb[2:4], rgb[4:6])))

    try:
        width = int(req.GET.get('w', 228))
    except (ValueError, TypeError):
        width = 228

    try:
        height = int(req.GET.get('h', 1))
    except (ValueError, TypeError):
        height = 1

    if width < 1 or height < 1:
        raise Http404

    if rgb != (0, 0, 0):
        # if line is black, then use white(#FFFFF) as background color
        backcolor = (255, 255, 255)
    else:
        backcolor = (0, 0, 0)

    # TODO
    # check display width
    img = gd.image((width, height))

    back = img.colorAllocate(backcolor)
    img.colorTransparent(back)

    color = img.colorAllocate(rgb)

    if style == 'dotted':
        pattern = (color, color, back, back)
    elif style == 'dashed':
        pattern = (color, color, color, back, back, back)
    else:
        # solid
        pattern = (color,)

    img.setStyle(pattern)
    for y in xrange(height):
        img.line((0, y), (width, y), gd.gdStyled)

    fp = StringIO()
    img.writeGif(fp)
    content = fp.getvalue()
    fp.close()

    content_type = 'image/gif'
    res = HttpResponse(content, content_type=content_type)
    res['Content-Type']   = content_type
    res['Content-Length'] = str(len(content))
    res['ETag']           = '"%s"' % md5(content).hexdigest()
    res['Last-Modified']  = http_date()
    res['Expires'] = http_date(time.time() + CACHE_TIMEOUT)
    patch_cache_control(res, max_age=CACHE_TIMEOUT)

    return res
	def get(self,request,*args,**kwargs):
		response=TemplateResponse(request,self.template_name,{'number':1,'number_2':2})
		response.__setitem__('x-uuid',uuid.uuid4().hex)		#set header explicitly
		response.__setitem__('status',200)
		response.__setitem__('page_id',str(uuid.uuid4().hex))
		patch_vary_headers(response,['Etag','Cookie','User-Agent'])
		patch_cache_control(response)
		return response
Пример #19
0
 def render_listview_to_response(self, request=None):
     """
     Renders the listview to a response, preventing caching in the
     process.
     """
     response = HttpResponse(unicode(self.render_listview()))
     patch_cache_control(response, no_cache=True, no_store=True, max_age=0, must_revalidate=True)
     return response
Пример #20
0
        def wrapper(request, *args, **kwargs):
            callback = getattr(self, view)
            response = callback(request, *args, **kwargs)

            if request.is_ajax():
                patch_cache_control(response, no_cache=True)

            return response
    def handle_cache_control(self, request, response):    
        if request.is_ajax() and not response.has_header("Cache-Control"):
            # IE excessively caches XMLHttpRequests, so we're disabling
            # the browser cache here.
            # See http://www.enhanceie.com/ie/bugs.asp for details.
            patch_cache_control(response, no_cache=True)

        return response
Пример #22
0
 def process_response(self, request, response):
     if 'Expires' not in response and \
             'Cache-Control' not in response and \
             hasattr(request, 'session') and \
             request.user.is_authenticated():
         patch_cache_control(response,
             no_store=True, no_cache=True, must_revalidate=True, max_age=0)
     return response
Пример #23
0
 def _cache_controlled(request, *args, **kw):
     response = viewfunc(request, *args, **kw)
     copied = kwargs
     if kwargs.get("max_age") and callable(kwargs["max_age"]):
         max_age = kwargs["max_age"](request, *args, **kw)
         # Can't re-use, have to create a shallow clone.
         copied = dict(kwargs, max_age=max_age)
     patch_cache_control(response, **copied)
     return response
Пример #24
0
 def process_response(self, request, response):
     if (
         "Expires" not in response
         and "Cache-Control" not in response
         and hasattr(request, "session")
         and request.user.is_authenticated()
     ):
         patch_cache_control(response, no_store=True, no_cache=True, must_revalidate=True, max_age=0)
     return response
Пример #25
0
def esi(request, app_label=None, model_name=None, object_id=None, timeout=900, template=None):
    """
    Using the app_label, module_name and object_id parameters create an object and render it using `template_name` or `template_dir`.
    
    Parameters:
        :app_label: `Name of a app (i.e. auth)`
        :model_name: `Name of a model (i.e. user)`
        :object_id: `This's objects primary key id`
        :timeout: `Time in secondsfor this objects max_age. [default 900]`
        :template: `a path to a template directory or a template`
        
    Context:
        `object`
            The object that was returned
        `model_name`
            If you are using a User object `user` will be in the context.
    
    Templates:
        if `template` is a directory:
            A file called `app_label`.`model_name`.html ,along with any other models'
            content types that the object extends, will be looked for in the `template`
            directory falling back to `template`/default.html 
            if none can be found.
        if `template` is a file:
            The file `template` will be loaded and rendered.
            
        If no template is provided `settings`.ESI_DEFAULT_TEMPLATE and `settings`.ESI_DEFAULT_DIRECTORY
        will be checked with the same logic as above.
        
    """
    default_template = getattr(settings, 'ESI_DEFAULT_TEMPLATE', None)
    default_template_dir = getattr(settings, 'ESI_DEFAULT_DIRECTORY', None)
    obj, model = get_object(app_label, model_name, object_id)
    template_list = []
    if template is not None:
        template_list.extend(get_template_list(obj, template))
    else:
        if default_template is not None:
            temp_t =  get_template_list(obj, default_template)
            if temp_t is not None:
                template_list.extend(get_template_list(obj, default_template))
        if default_template_dir is not None and len(template_list) == 0:
            temp_t =  get_template_list(obj, default_template_dir)
            if temp_t is not None:
                template_list.extend(get_template_list(obj, default_template_dir))
    if len(template_list) == 0:
        raise Http404
    t = loader.select_template(template_list)
    context = {
        'object': obj,
        model_name: obj
    }
    c = RequestContext(request, context)
    response = HttpResponse(t.render(c))
    populate_xheaders(request, response, model, getattr(obj, model._meta.pk.name))
    patch_cache_control(response, max_age=timeout)
    return response
Пример #26
0
    def create_response(self, request, data, **response_kwargs):
        response = (super(ClientCachedResource, self)
                    .create_response(request, data, **response_kwargs))

        if (request.method == 'GET' and response.status_code == 200
            and hasattr(self.Meta, 'cache_control')):
            patch_cache_control(response, **self.Meta.cache_control)

        return response
Пример #27
0
def blocklist_json(request):
    key = 'blocklist:json'
    cache.add('blocklist:keyversion', 1)
    version = cache.get('blocklist:keyversion')
    response = cache.get(key, version=version)
    if response is None:
        response = _blocklist_json(request)
        cache.set(key, response, 60 * 60, version=version)
    patch_cache_control(response, max_age=60 * 60)
    return response
Пример #28
0
 def process_response(self, request, response):
     if getattr(response, "_unvarying", False):
         try:
             del response["Vary"]
         except KeyError:
             pass
     else:
         from django.utils.cache import patch_cache_control
         patch_cache_control(response, private=True)
     return response
Пример #29
0
    def process_request(self, request):
        # Find locale, app
        prefixer = urlresolvers.Prefixer(request)
        if settings.DEBUG:
            redirect_type = HttpResponseRedirect
        else:
            redirect_type = HttpResponsePermanentRedirect
        urlresolvers.set_url_prefix(prefixer)
        full_path = prefixer.fix(prefixer.shortened_path)
        # In mkt, don't vary headers on User-Agent.
        with_app = not getattr(settings, 'MARKETPLACE', False)

        if (prefixer.app == amo.MOBILE.short and
                request.path.rstrip('/').endswith('/' + amo.MOBILE.short)):
            # TODO: Eventually put MOBILE in RETIRED_APPS, but not yet.
            return redirect_type(request.path.replace('/mobile', '/android'))

        if 'lang' in request.GET:
            # Blank out the locale so that we can set a new one.  Remove lang
            # from query params so we don't have an infinite loop.
            prefixer.locale = ''
            new_path = prefixer.fix(prefixer.shortened_path)
            query = dict((smart_str(k), request.GET[k]) for k in request.GET)
            query.pop('lang')
            return redirect_type(urlparams(new_path, **query))

        if full_path != request.path:
            query_string = request.META.get('QUERY_STRING', '')
            full_path = urllib.quote(full_path.encode('utf-8'))

            if query_string:
                full_path = "%s?%s" % (full_path, query_string)

            response = redirect_type(full_path)
            # Cache the redirect for a year.
            if not settings.DEBUG:
                patch_cache_control(response, max_age=60 * 60 * 24 * 365)

            # Vary on Accept-Language or User-Agent if we changed the locale or
            # app.
            old_app = prefixer.app
            old_locale = prefixer.locale
            new_locale, new_app, _ = prefixer.split_path(full_path)

            if old_locale != new_locale:
                patch_vary_headers(response, ['Accept-Language'])
            if with_app and old_app != new_app:
                patch_vary_headers(response, ['User-Agent'])
            return response

        request.path_info = '/' + prefixer.shortened_path
        tower.activate(prefixer.locale)
        request.APP = amo.APPS.get(prefixer.app, amo.FIREFOX)
        request.LANG = prefixer.locale
Пример #30
0
 def process_response(self, request, response):
     if request.is_ajax() and response.status_code in (301, 302):
         return HttpResponse(json.dumps({
             'location': response['Location'],
             'status_code': response.status_code,
             'redirect': True,
         }))
     if hasattr(request, "_feincms_page"):
         patch_cache_control(response, max_age=60)
         patch_vary_headers(response, ['Accept', 'X-Requested-With'])
     return response
Пример #31
0
def home_real(request):
    # type: (HttpRequest) -> HttpResponse
    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    user_profile = request.user
    request._email = request.user.email
    request.client = get_client("website")

    # If a user hasn't signed the current Terms of Service, send them there
    if settings.TERMS_OF_SERVICE is not None and settings.TOS_VERSION is not None and \
       int(settings.TOS_VERSION.split('.')[0]) > user_profile.major_tos_version():
        return accounts_accept_terms(request)

    narrow = []  # type: List[List[Text]]
    narrow_stream = None
    narrow_topic = request.GET.get("topic")
    if request.GET.get("stream"):
        try:
            narrow_stream = get_stream(request.GET.get("stream"),
                                       user_profile.realm)
            assert (narrow_stream is not None)
            assert (narrow_stream.is_public())
            narrow = [["stream", narrow_stream.name]]
        except Exception:
            logging.exception("Narrow parsing")
        if narrow_topic is not None:
            narrow.append(["topic", narrow_topic])

    register_ret = do_events_register(user_profile,
                                      request.client,
                                      apply_markdown=True,
                                      narrow=narrow)
    user_has_messages = (register_ret['max_message_id'] != -1)

    # Reset our don't-spam-users-with-email counter since the
    # user has since logged in
    if not user_profile.last_reminder is None:
        user_profile.last_reminder = None
        user_profile.save(update_fields=["last_reminder"])

    # Brand new users get the tutorial
    needs_tutorial = settings.TUTORIAL_ENABLED and \
        user_profile.tutorial_status != UserProfile.TUTORIAL_FINISHED

    first_in_realm = realm_user_count(user_profile.realm) == 1
    # If you are the only person in the realm and you didn't invite
    # anyone, we'll continue to encourage you to do so on the frontend.
    prompt_for_invites = first_in_realm and \
        not PreregistrationUser.objects.filter(referred_by=user_profile).count()

    if user_profile.pointer == -1 and user_has_messages:
        # Put the new user's pointer at the bottom
        #
        # This improves performance, because we limit backfilling of messages
        # before the pointer.  It's also likely that someone joining an
        # organization is interested in recent messages more than the very
        # first messages on the system.

        register_ret['pointer'] = register_ret['max_message_id']
        user_profile.last_pointer_updater = request.session.session_key

    if user_profile.pointer == -1:
        latest_read = None
    else:
        try:
            latest_read = UserMessage.objects.get(
                user_profile=user_profile, message__id=user_profile.pointer)
        except UserMessage.DoesNotExist:
            # Don't completely fail if your saved pointer ID is invalid
            logging.warning("%s has invalid pointer %s" %
                            (user_profile.email, user_profile.pointer))
            latest_read = None

    desktop_notifications_enabled = user_profile.enable_desktop_notifications
    if narrow_stream is not None:
        desktop_notifications_enabled = False

    if user_profile.realm.notifications_stream:
        notifications_stream = user_profile.realm.notifications_stream.name
    else:
        notifications_stream = ""

    # Set default language and make it persist
    default_language = register_ret['default_language']
    url_lang = '/{}'.format(request.LANGUAGE_CODE)
    if not request.path.startswith(url_lang):
        translation.activate(default_language)

    request.session[translation.LANGUAGE_SESSION_KEY] = default_language

    # Pass parameters to the client-side JavaScript code.
    # These end up in a global JavaScript Object named 'page_params'.
    page_params = dict(
        zulip_version=ZULIP_VERSION,
        share_the_love=settings.SHARE_THE_LOVE,
        development_environment=settings.DEVELOPMENT,
        debug_mode=settings.DEBUG,
        test_suite=settings.TEST_SUITE,
        poll_timeout=settings.POLL_TIMEOUT,
        login_page=settings.HOME_NOT_LOGGED_IN,
        server_uri=settings.SERVER_URI,
        realm_uri=user_profile.realm.uri,
        maxfilesize=settings.MAX_FILE_UPLOAD_SIZE,
        server_generation=settings.SERVER_GENERATION,
        password_auth_enabled=password_auth_enabled(user_profile.realm),
        have_initial_messages=user_has_messages,
        subbed_info=register_ret['subscriptions'],
        unsubbed_info=register_ret['unsubscribed'],
        neversubbed_info=register_ret['never_subscribed'],
        people_list=register_ret['realm_users'],
        bot_list=register_ret['realm_bots'],
        initial_pointer=register_ret['pointer'],
        initial_presences=register_ret['presences'],
        initial_servertime=time.time(
        ),  # Used for calculating relative presence age
        fullname=user_profile.full_name,
        email=user_profile.email,
        domain=user_profile.realm.domain,
        domains=list_of_domains_for_realm(user_profile.realm),
        realm_name=register_ret['realm_name'],
        realm_invite_required=register_ret['realm_invite_required'],
        realm_invite_by_admins_only=register_ret[
            'realm_invite_by_admins_only'],
        realm_authentication_methods=register_ret[
            'realm_authentication_methods'],
        realm_create_stream_by_admins_only=register_ret[
            'realm_create_stream_by_admins_only'],
        realm_add_emoji_by_admins_only=register_ret[
            'realm_add_emoji_by_admins_only'],
        realm_allow_message_editing=register_ret[
            'realm_allow_message_editing'],
        realm_message_content_edit_limit_seconds=register_ret[
            'realm_message_content_edit_limit_seconds'],
        realm_restricted_to_domain=register_ret['realm_restricted_to_domain'],
        realm_default_language=register_ret['realm_default_language'],
        realm_waiting_period_threshold=register_ret[
            'realm_waiting_period_threshold'],
        enter_sends=user_profile.enter_sends,
        user_id=user_profile.id,
        left_side_userlist=register_ret['left_side_userlist'],
        default_language=register_ret['default_language'],
        default_language_name=get_language_name(
            register_ret['default_language']),
        language_list_dbl_col=get_language_list_for_templates(
            register_ret['default_language']),
        language_list=get_language_list(),
        referrals=register_ret['referrals'],
        realm_emoji=register_ret['realm_emoji'],
        needs_tutorial=needs_tutorial,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        notifications_stream=notifications_stream,
        cross_realm_bots=list(get_cross_realm_dicts()),
        use_websockets=settings.USE_WEBSOCKETS,

        # Stream message notification settings:
        stream_desktop_notifications_enabled=user_profile.
        enable_stream_desktop_notifications,
        stream_sounds_enabled=user_profile.enable_stream_sounds,

        # Private message and @-mention notification settings:
        desktop_notifications_enabled=desktop_notifications_enabled,
        sounds_enabled=user_profile.enable_sounds,
        enable_offline_email_notifications=user_profile.
        enable_offline_email_notifications,
        pm_content_in_desktop_notifications=user_profile.
        pm_content_in_desktop_notifications,
        enable_offline_push_notifications=user_profile.
        enable_offline_push_notifications,
        enable_online_push_notifications=user_profile.
        enable_online_push_notifications,
        twenty_four_hour_time=register_ret['twenty_four_hour_time'],
        enable_digest_emails=user_profile.enable_digest_emails,
        event_queue_id=register_ret['queue_id'],
        last_event_id=register_ret['last_event_id'],
        max_message_id=register_ret['max_message_id'],
        unread_count=approximate_unread_count(user_profile),
        furthest_read_time=sent_time_in_epoch_seconds(latest_read),
        save_stacktraces=settings.SAVE_FRONTEND_STACKTRACES,
        alert_words=register_ret['alert_words'],
        muted_topics=register_ret['muted_topics'],
        realm_filters=register_ret['realm_filters'],
        realm_default_streams=register_ret['realm_default_streams'],
        is_admin=user_profile.is_realm_admin,
        can_create_streams=user_profile.can_create_streams(),
        name_changes_disabled=name_changes_disabled(user_profile.realm),
        has_mobile_devices=num_push_devices_for_user(user_profile) > 0,
        autoscroll_forever=user_profile.autoscroll_forever,
        default_desktop_notifications=user_profile.
        default_desktop_notifications,
        avatar_url=avatar_url(user_profile),
        avatar_url_medium=avatar_url(user_profile, medium=True),
        avatar_source=user_profile.avatar_source,
        mandatory_topics=user_profile.realm.mandatory_topics,
        show_digest_email=user_profile.realm.show_digest_email,
        presence_disabled=user_profile.realm.presence_disabled,
        is_zephyr_mirror_realm=user_profile.realm.is_zephyr_mirror_realm,
    )

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = get_recipient(Recipient.STREAM, narrow_stream.id)
        try:
            initial_pointer = Message.objects.filter(
                recipient=recipient).order_by('id').reverse()[0].id
        except IndexError:
            initial_pointer = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [
            dict(operator=term[0], operand=term[1]) for term in narrow
        ]
        page_params["max_message_id"] = initial_pointer
        page_params["initial_pointer"] = initial_pointer
        page_params["have_initial_messages"] = (initial_pointer != -1)

    statsd.incr('views.home')
    show_invites = True

    # Some realms only allow admins to invite users
    if user_profile.realm.invite_by_admins_only and not user_profile.is_realm_admin:
        show_invites = False

    product_name = "Zulip"
    page_params['product_name'] = product_name
    request._log_data['extra'] = "[%s]" % (register_ret["queue_id"], )
    response = render_to_response('zerver/index.html', {
        'user_profile':
        user_profile,
        'page_params':
        simplejson.encoder.JSONEncoderForHTML().encode(page_params),
        'nofontface':
        is_buggy_ua(request.META.get("HTTP_USER_AGENT", "Unspecified")),
        'avatar_url':
        avatar_url(user_profile),
        'show_debug':
        settings.DEBUG and ('show_debug' in request.GET),
        'pipeline':
        settings.PIPELINE_ENABLED,
        'show_invites':
        show_invites,
        'is_admin':
        user_profile.is_realm_admin,
        'show_webathena':
        user_profile.realm.webathena_enabled,
        'enable_feedback':
        settings.ENABLE_FEEDBACK,
        'embedded':
        narrow_stream is not None,
        'product_name':
        product_name
    },
                                  request=request)
    patch_cache_control(response,
                        no_cache=True,
                        no_store=True,
                        must_revalidate=True)
    return response
Пример #32
0
 def _cache_controlled(request, *args, **kw):
     response = viewfunc(request, *args, **kw)
     if hasattr(response,
                'has_header'):  # check if response is httpresponse
         patch_cache_control(response, **kwargs)
     return response
    def post(self, request, frmName, target=None):
        try:
            if not request.session.get('conUser'):
                raise SessionError("Session invalid or expired.")
            if request.path_info.endswith(('.html', '.html/')):
                template = [
                    item['html'] for item in self.MENU_ITEMS
                    if item['name'] == frmName
                ][0]
                request.session['referer'] = request.META[
                    'HTTP_REFERER']  #stash reference from initial page load
                response = render(request, template,
                                  dict(frmName=frmName, pages=self.MENU_ITEMS))
                response['Pragma'] = 'no-cache'
                response['Expires'] = '0'
                patch_cache_control(response,
                                    no_cache=True,
                                    no_store=True,
                                    must_revalidate=True,
                                    max_age=0)
                return response
            if not target:
                return getattr(self, 'ajax_form')(request, frmName)
            elif target.startswith('fld_'):
                rc = getattr(self, 'ajax_' + target)(request, frmName,
                                                     target[4:])
                return rc
            else:
                return getattr(self, 'ajax_' + target)(request, frmName)

        except SessionError as e:
            if 'application/json' in request.META['HTTP_ACCEPT']:
                return jsonErrorResponse(
                    dict(redirectTo=reverse('capture:sessionErr')), e.message)
            else:
                return HttpResponseRedirect(reverse('capture:sessionErr'))

        except ServerDbError as e:
            trace = [x for x in e.message.split('\n')]
            oraErr, oraMsg = trace[0].split(': ')
            msg = "Database error occurred while processing form ({}/{})\n{}"
            #logging.debug(msg, exc_info=True)
            if 'application/json' in request.META['HTTP_ACCEPT']:
                return jsonErrorResponse(
                    dict(errTitle=e.errTitle, errMsg=oraMsg),
                    msg.format(frmName, target, e.message))
            else:
                request.session['systemError'] = dict(msg=msg.format(
                    frmName, target, oraMsg),
                                                      trace=trace)
                return HttpResponseRedirect(reverse('capture:systemErr'))

        except Exception as e:
            msg = "AQC-0003: Exception while processing form ({}/{})".format(
                frmName, target)
            logging.debug(msg, exc_info=True)
            request.session['systemError'] = dict(msg=msg,
                                                  trace=traceback.format_exc())
            if 'application/json' in request.META['HTTP_ACCEPT']:
                return jsonErrorResponse(
                    dict(redirectTo=reverse('capture:systemErr')), msg)
            else:
                return HttpResponseRedirect(reverse('capture:systemErr'))
Пример #34
0
def download_image(request, datafile_id, region, size, rotation,
                   quality, format=None):  # @ReservedAssignment
    # Get datafile (and return an empty response if absent)
    try:
        datafile = DataFile.objects.get(pk=datafile_id)
    except DataFile.DoesNotExist:
        return HttpResponse('')

    is_public = datafile.is_public()
    if not is_public:
        # Check users has access to datafile
        if not has_datafile_download_access(request=request,
                                            datafile_id=datafile.id):
            return HttpResponse('')

    buf = BytesIO()
    try:
        file_obj = datafile.get_image_data()
        if file_obj is None:
            return HttpResponse('')
        from contextlib import closing
        with closing(file_obj) as f:
            with Image(file=f) as img:
                if len(img.sequence) > 1:
                    img = Image(img.sequence[0])
                # Handle region
                if region != 'full':
                    x, y, w, h = map(int, region.split(','))
                    img.crop(x, y, width=w, height=h)
                # Handle size
                if size != 'full':
                    # Check the image isn't empty
                    if 0 in (img.height, img.width):
                        return _bad_request('size', 'Cannot resize empty image')
                    # Attempt resize
                    if not _do_resize(img, size):
                        return _bad_request('size',
                                            'Invalid size argument: %s' % size)
                # Handle rotation
                if rotation:
                    img.rotate(float(rotation))
                # Handle quality (mostly by rejecting it)
                if quality not in ['native', 'color']:
                    return _get_iiif_error(
                        'quality',
                        'This server does not support greyscale or bitonal quality.')
                # Handle format
                if format:
                    mimetype = mimetypes.types_map['.%s' % format.lower()]
                    img.format = format
                    if mimetype not in ALLOWED_MIMETYPES:
                        return _invalid_media_response()
                else:
                    mimetype = datafile.get_mimetype()
                    # If the native format is not allowed, pretend it doesn't exist.
                    if mimetype not in ALLOWED_MIMETYPES:
                        return HttpResponse('')
                img.save(file=buf)
                response = HttpResponse(buf.getvalue(), content_type=mimetype)
                response['Content-Disposition'] = \
                    'inline; filename="%s.%s"' % (datafile.filename, format)
                # Set Cache
                if is_public:
                    patch_cache_control(response, public=True, max_age=MAX_AGE)
                else:
                    patch_cache_control(response, private=True, max_age=MAX_AGE)
                return response
    except WandException:
        return HttpResponse('')
    except ValueError:
        return HttpResponse('')
    except IOError:
        return HttpResponse('')
Пример #35
0
        def wrapper(request, *args, **kwargs):
            try:
                callback = getattr(self, view)
                response = callback(request, *args, **kwargs)

                # Our response can vary based on a number of factors, use
                # the cache class to determine what we should ``Vary`` on so
                # caches won't return the wrong (cached) version.
                varies = getattr(self._meta.cache, "varies", [])

                if varies:
                    patch_vary_headers(response, varies)

                if self._meta.cache.cacheable(request, response):
                    if self._meta.cache.cache_control():
                        # If the request is cacheable and we have a
                        # ``Cache-Control`` available then patch the header.
                        patch_cache_control(response,
                                            **self._meta.cache.cache_control())

                if request.is_ajax(
                ) and not response.has_header("Cache-Control"):
                    # IE excessively caches XMLHttpRequests, so we're disabling
                    # the browser cache here.
                    # See http://www.enhanceie.com/ie/bugs.asp for details.
                    patch_cache_control(response, no_cache=True)

                return response
            except (BadRequest, fields.ApiFieldError) as e:
                data = {
                    "error": sanitize(e.args[0]) if getattr(e, 'args') else ''
                }
                return self.error_response(request,
                                           data,
                                           response_class=http.HttpBadRequest)
            except ValidationError as e:
                data = {"error": sanitize(e)}

                return self.error_response(request,
                                           data,
                                           response_class=http.HttpBadRequest)
            except Exception as e:
                if hasattr(e, 'response'):
                    return e.response

                # A real, non-expected exception.
                # Handle the case where the full traceback is more helpful
                # than the serialized error.
                if settings.DEBUG and getattr(settings, 'TASTYPIE_FULL_DEBUG',
                                              False):
                    raise

                # Re-raise the error to get a proper traceback when the error
                # happend during a test case
                if request.META.get('SERVER_NAME') == 'testserver':
                    raise

                # Rather than re-raising, we're going to things similar to
                # what Django does. The difference is returning a serialized
                # error message.
                return self._handle_500(request, e)
Пример #36
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    response_timestamp = now()
    if get_cms_setting("PAGE_CACHE") and (
            not hasattr(request, 'toolbar') or
        (not request.toolbar.edit_mode_active
         and not request.toolbar.show_toolbar
         and not request.user.is_authenticated())):
        cache_content = get_page_cache(request)
        if cache_content is not None:
            content, headers, expires_datetime = cache_content
            response = HttpResponse(content)
            response._headers = headers
            # Recalculate the max-age header for this cached response
            max_age = int((expires_datetime -
                           response_timestamp).total_seconds() + 0.5)
            patch_cache_control(response, max_age=max_age)
            return response

    # Get a Page model object from the request
    site = get_current_site()
    page = get_page_from_request(request, use_path=slug)
    toolbar = get_toolbar_from_request(request)
    tree_nodes = TreeNode.objects.get_for_site(site)

    if not page and not slug and not tree_nodes.exists():
        # render the welcome page if the requested path is root "/"
        # and there's no pages
        return _render_welcome_page(request)

    if not page:
        # raise 404
        _handle_no_page(request)

    request.current_page = page

    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list(site_id=site.pk)
    else:
        user_languages = get_public_languages(site_id=site.pk)

    request_language = get_language_from_request(request, check_path=True)

    if not page.is_home and request_language not in user_languages:
        # The homepage is treated differently because
        # when a request goes to the root of the site (/)
        # without a language, Django will redirect to the user's
        # browser language which might not be a valid cms language,
        # this means we need to correctly redirect that request.
        return _handle_no_page(request)

    # get_published_languages will return all languages in draft mode
    # and published only in live mode.
    # These languages are then filtered out by the user allowed languages
    available_languages = [
        language for language in user_languages
        if language in list(page.get_published_languages())
    ]

    own_urls = [
        request.build_absolute_uri(request.path),
        '/%s' % request.path,
        request.path,
    ]

    try:
        redirect_on_fallback = get_redirect_on_fallback(request_language,
                                                        site_id=site.pk)
    except LanguageError:
        redirect_on_fallback = False

    if request_language not in user_languages:
        # Language is not allowed
        # Use the default site language
        default_language = get_default_language_for_site(site.pk)
        fallbacks = get_fallback_languages(default_language, site_id=site.pk)
        fallbacks = [default_language] + fallbacks
    else:
        fallbacks = get_fallback_languages(request_language, site_id=site.pk)

    # Only fallback to languages the user is allowed to see
    fallback_languages = [
        language for language in fallbacks
        if language != request_language and language in available_languages
    ]
    language_is_unavailable = request_language not in available_languages

    if language_is_unavailable and not fallback_languages:
        # There is no page with the requested language
        # and there's no configured fallbacks
        return _handle_no_page(request)
    elif language_is_unavailable and (redirect_on_fallback or page.is_home):
        # There is no page with the requested language and
        # the user has explicitly requested to redirect on fallbacks,
        # so redirect to the first configured / available fallback language
        fallback = fallback_languages[0]
        redirect_url = page.get_absolute_url(fallback, fallback=False)
    else:
        page_path = page.get_absolute_url(request_language)
        page_slug = page.get_path(request_language) or page.get_slug(
            request_language)

        if slug and slug != page_slug and request.path[:len(page_path
                                                            )] != page_path:
            # The current language does not match its slug.
            # Redirect to the current language.
            return HttpResponseRedirect(page_path)
        # Check if the page has a redirect url defined for this language.
        redirect_url = page.get_redirect(request_language,
                                         fallback=False) or ''
        redirect_url = _clean_redirect_url(redirect_url, request_language)

    if redirect_url:
        if request.user.is_staff and toolbar.edit_mode_active:
            toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            # prevent redirect to self
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()),
                                 settings.LOGIN_URL)

    if hasattr(request, 'toolbar'):
        request.toolbar.set_object(page)

    structure_requested = get_cms_setting(
        'CMS_TOOLBAR_URL__BUILD') in request.GET

    if user_can_change_page(request.user, page) and structure_requested:
        return render_object_structure(request, page)
    return render_page(request,
                       page,
                       current_language=request_language,
                       slug=slug)
Пример #37
0
def handler404(request, exception=None, template_name="dpaste/404.html"):
    context = {}
    context.update(config.extra_template_context)
    response = render(request, template_name, context, status=404)
    patch_cache_control(response, max_age=config.CACHE_TIMEOUT)
    return response
Пример #38
0
 def _cache_controlled(request, *args, **kw):
     max_age = calculate_max_age()
     response = viewfunc(request, *args, **kw)
     patch_cache_control(response, public=True, max_age=max_age)
     return response
Пример #39
0
def home_real(request: HttpRequest) -> HttpResponse:
    # Before we do any real work, check if the app is banned.
    client_user_agent = request.META.get("HTTP_USER_AGENT", "")
    (insecure_desktop_app, banned_desktop_app,
     auto_update_broken) = is_outdated_desktop_app(client_user_agent)
    if banned_desktop_app:
        return render(
            request,
            "zerver/insecure_desktop_app.html",
            context={
                "auto_update_broken": auto_update_broken,
            },
        )
    (unsupported_browser,
     browser_name) = is_unsupported_browser(client_user_agent)
    if unsupported_browser:
        return render(
            request,
            "zerver/unsupported_browser.html",
            context={
                "browser_name": browser_name,
            },
        )

    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    if request.user.is_authenticated:
        user_profile = request.user
        realm = user_profile.realm

        # User is logged in and hence no longer `prefers_web_public_view`.
        if "prefers_web_public_view" in request.session.keys():
            del request.session["prefers_web_public_view"]
    else:
        realm = get_valid_realm_from_request(request)

        # TODO: Ideally, we'd open Zulip directly as a spectator if
        # the URL had clicked a link to content on a web-public
        # stream.  We could maybe do this by parsing `next`, but it's
        # not super convenient with Zulip's hash-based URL scheme.

        # The "Access without an account" button on the login page
        # submits a POST to this page with this hidden field set.
        if request.POST.get("prefers_web_public_view") == "true":
            request.session["prefers_web_public_view"] = True
            # We serve a redirect here, rather than serving a page, to
            # avoid browser "Confirm form resubmission" prompts on reload.
            redirect_to = get_safe_redirect_to(request.POST.get("next"),
                                               realm.uri)
            return redirect(redirect_to)

        prefers_web_public_view = request.session.get(
            "prefers_web_public_view")
        if not prefers_web_public_view:
            # For users who haven't opted into the spectator
            # experience, we redirect to the login page.
            return zulip_redirect_to_login(request,
                                           settings.HOME_NOT_LOGGED_IN)

        # For users who have selected public access, we load the
        # spectator experience.  We fall through to the shared code
        # for loading the application, with user_profile=None encoding
        # that we're a spectator, not a logged-in user.
        user_profile = None

    update_last_reminder(user_profile)

    statsd.incr("views.home")

    # If a user hasn't signed the current Terms of Service, send them there
    if need_accept_tos(user_profile):
        return accounts_accept_terms(request)

    narrow, narrow_stream, narrow_topic = detect_narrowed_window(
        request, user_profile)

    if user_profile is not None:
        first_in_realm = realm_user_count(user_profile.realm) == 1
        # If you are the only person in the realm and you didn't invite
        # anyone, we'll continue to encourage you to do so on the frontend.
        prompt_for_invites = (first_in_realm
                              and not PreregistrationUser.objects.filter(
                                  referred_by=user_profile).count())
        needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING

    else:
        first_in_realm = False
        prompt_for_invites = False
        # The current tutorial doesn't super make sense for logged-out users.
        needs_tutorial = False

    queue_id, page_params = build_page_params_for_home_page_load(
        request=request,
        user_profile=user_profile,
        realm=realm,
        insecure_desktop_app=insecure_desktop_app,
        narrow=narrow,
        narrow_stream=narrow_stream,
        narrow_topic=narrow_topic,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        needs_tutorial=needs_tutorial,
    )

    log_data = RequestNotes.get_notes(request).log_data
    assert log_data is not None
    log_data["extra"] = f"[{queue_id}]"

    csp_nonce = secrets.token_hex(24)

    user_permission_info = get_user_permission_info(user_profile)

    response = render(
        request,
        "zerver/app/index.html",
        context={
            "user_profile": user_profile,
            "page_params": page_params,
            "csp_nonce": csp_nonce,
            "color_scheme": user_permission_info.color_scheme,
        },
    )
    patch_cache_control(response,
                        no_cache=True,
                        no_store=True,
                        must_revalidate=True)
    return response
def make_response_cacheable(response):
    """
    Allow response to be public and cached for an hour
    """
    patch_cache_control(response, public=True, max_age=3600)
    return response
Пример #41
0
def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    response_timestamp = now()
    if get_cms_setting("PAGE_CACHE") and (
            not hasattr(request, 'toolbar') or
        (not request.toolbar.edit_mode and not request.toolbar.show_toolbar
         and not request.user.is_authenticated())):
        cache_content = get_page_cache(request)
        if cache_content is not None:
            content, headers, expires_datetime = cache_content
            response = HttpResponse(content)
            response._headers = headers
            # Recalculate the max-age header for this cached response
            max_age = int((expires_datetime -
                           response_timestamp).total_seconds() + 0.5)
            patch_cache_control(response, max_age=max_age)
            return response

    # Get a Page model object from the request
    page = get_page_from_request(request, use_path=slug)
    if not page:
        return _handle_no_page(request, slug)
    current_language = request.GET.get('language', None)
    if not current_language:
        current_language = request.POST.get('language', None)
    if current_language:
        current_language = get_language_code(current_language)
        if current_language not in get_language_list(page.site_id):
            current_language = None
    if current_language is None:
        current_language = get_language_code(
            getattr(request, 'LANGUAGE_CODE', None))
        if current_language:
            current_language = get_language_code(current_language)
            if current_language not in get_language_list(page.site_id):
                current_language = None
    if current_language is None:
        current_language = get_language_code(get_language())
    # Check that the current page is available in the desired (current) language
    available_languages = []
    # this will return all languages in draft mode, and published only in live mode
    page_languages = list(page.get_published_languages())
    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list()
    else:
        user_languages = get_public_languages()
    for frontend_lang in user_languages:
        if frontend_lang in page_languages:
            available_languages.append(frontend_lang)
    # Check that the language is in FRONTEND_LANGUAGES:
    own_urls = [
        'http%s://%s%s' %
        ('s' if request.is_secure() else '', request.get_host(), request.path),
        '/%s' % request.path,
        request.path,
    ]
    if current_language not in user_languages:
        #are we on root?
        if not slug:
            #redirect to supported language
            languages = []
            for language in available_languages:
                languages.append((language, language))
            if languages:
                # get supported language
                new_language = get_language_from_request(request)
                if new_language in get_public_languages():
                    with force_language(new_language):
                        pages_root = reverse('pages-root')
                        if (hasattr(request, 'toolbar')
                                and request.user.is_staff
                                and request.toolbar.edit_mode):
                            request.toolbar.redirect_url = pages_root
                        elif pages_root not in own_urls:
                            return HttpResponseRedirect(pages_root)
            elif not hasattr(request,
                             'toolbar') or not request.toolbar.redirect_url:
                _handle_no_page(request, slug)
        else:
            return _handle_no_page(request, slug)
    if current_language not in available_languages:
        # If we didn't find the required page in the requested (current)
        # language, let's try to find a fallback
        found = False
        for alt_lang in get_fallback_languages(current_language):
            if alt_lang in available_languages:
                if get_redirect_on_fallback(current_language) or slug == "":
                    with force_language(alt_lang):
                        path = page.get_absolute_url(language=alt_lang,
                                                     fallback=True)
                        # In the case where the page is not available in the
                    # preferred language, *redirect* to the fallback page. This
                    # is a design decision (instead of rendering in place)).
                    if (hasattr(request, 'toolbar') and request.user.is_staff
                            and request.toolbar.edit_mode):
                        request.toolbar.redirect_url = path
                    elif path not in own_urls:
                        return HttpResponseRedirect(path)
                else:
                    found = True
        if not found and (not hasattr(request, 'toolbar')
                          or not request.toolbar.redirect_url):
            # There is a page object we can't find a proper language to render it
            _handle_no_page(request, slug)

    if apphook_pool.get_apphooks():
        # There are apphooks in the pool. Let's see if there is one for the
        # current page
        # since we always have a page at this point, applications_page_check is
        # pointless
        # page = applications_page_check(request, page, slug)
        # Check for apphooks! This time for real!
        app_urls = page.get_application_urls(current_language, False)
        skip_app = False
        if (not page.is_published(current_language)
                and hasattr(request, 'toolbar') and request.toolbar.edit_mode):
            skip_app = True
        if app_urls and not skip_app:
            app = apphook_pool.get_apphook(app_urls)
            pattern_list = []
            if app:
                for urlpatterns in get_app_urls(
                        app.get_urls(page, current_language)):
                    pattern_list += urlpatterns
                try:
                    view, args, kwargs = resolve('/', tuple(pattern_list))
                    return view(request, *args, **kwargs)
                except Resolver404:
                    pass
    # Check if the page has a redirect url defined for this language.
    redirect_url = page.get_redirect(language=current_language)
    if redirect_url:
        if (is_language_prefix_patterns_used() and redirect_url[0] == "/"
                and not redirect_url.startswith('/%s/' % current_language)):
            # add language prefix to url
            redirect_url = "/%s/%s" % (current_language,
                                       redirect_url.lstrip("/"))
            # prevent redirect to self

        if hasattr(request, 'toolbar'
                   ) and request.user.is_staff and request.toolbar.edit_mode:
            request.toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated():
        return redirect_to_login(urlquote(request.get_full_path()),
                                 settings.LOGIN_URL)
    if hasattr(request, 'toolbar'):
        request.toolbar.set_object(page)

    response = render_page(request,
                           page,
                           current_language=current_language,
                           slug=slug)
    return response
Пример #42
0
 def test(self):
     request = RequestFactory().get('/')
     response = my_view(request)
     max_age = 3600
     patch_cache_control(response, max_age=max_age)
     self.assertEqual(get_max_age(response), max_age)
Пример #43
0
 def dispatch(self, *args, **kwargs):
     res = super(PaperListView, self).dispatch(*args, **kwargs)
     patch_cache_control(res, public=True, max_age=24 * 60 * 60)
     return res
Пример #44
0
def home_real(request: HttpRequest) -> HttpResponse:
    # Before we do any real work, check if the app is banned.
    client_user_agent = request.META.get("HTTP_USER_AGENT", "")
    (insecure_desktop_app, banned_desktop_app, auto_update_broken) = is_outdated_desktop_app(
        client_user_agent
    )
    if banned_desktop_app:
        return render(
            request,
            "zerver/insecure_desktop_app.html",
            context={
                "auto_update_broken": auto_update_broken,
            },
        )
    (unsupported_browser, browser_name) = is_unsupported_browser(client_user_agent)
    if unsupported_browser:
        return render(
            request,
            "zerver/unsupported_browser.html",
            context={
                "browser_name": browser_name,
            },
        )

    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    if request.user.is_authenticated:
        user_profile = request.user
        realm = user_profile.realm
    else:
        # user_profile=None corresponds to the logged-out "web_public" visitor case.
        user_profile = None
        realm = get_valid_realm_from_request(request)

    update_last_reminder(user_profile)

    statsd.incr("views.home")

    # If a user hasn't signed the current Terms of Service, send them there
    if need_accept_tos(user_profile):
        return accounts_accept_terms(request)

    narrow, narrow_stream, narrow_topic = detect_narrowed_window(request, user_profile)

    if user_profile is not None:
        first_in_realm = realm_user_count(user_profile.realm) == 1
        # If you are the only person in the realm and you didn't invite
        # anyone, we'll continue to encourage you to do so on the frontend.
        prompt_for_invites = (
            first_in_realm
            and not PreregistrationUser.objects.filter(referred_by=user_profile).count()
        )
        needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING

    else:
        first_in_realm = False
        prompt_for_invites = False
        # The current tutorial doesn't super make sense for logged-out users.
        needs_tutorial = False

    queue_id, page_params = build_page_params_for_home_page_load(
        request=request,
        user_profile=user_profile,
        realm=realm,
        insecure_desktop_app=insecure_desktop_app,
        narrow=narrow,
        narrow_stream=narrow_stream,
        narrow_topic=narrow_topic,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        needs_tutorial=needs_tutorial,
    )

    log_data = RequestNotes.get_notes(request).log_data
    assert log_data is not None
    log_data["extra"] = f"[{queue_id}]"

    csp_nonce = secrets.token_hex(24)

    user_permission_info = get_user_permission_info(user_profile)

    response = render(
        request,
        "zerver/app/index.html",
        context={
            "user_profile": user_profile,
            "page_params": page_params,
            "csp_nonce": csp_nonce,
            "color_scheme": user_permission_info.color_scheme,
        },
    )
    patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
    return response
Пример #45
0
def home_real(request: HttpRequest) -> HttpResponse:
    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    user_profile = request.user

    # If a user hasn't signed the current Terms of Service, send them there
    if settings.TERMS_OF_SERVICE is not None and settings.TOS_VERSION is not None and \
       int(settings.TOS_VERSION.split('.')[0]) > user_profile.major_tos_version():
        return accounts_accept_terms(request)

    narrow = []  # type: List[List[str]]
    narrow_stream = None
    narrow_topic = request.GET.get("topic")
    if request.GET.get("stream"):
        try:
            # TODO: We should support stream IDs and PMs here as well.
            narrow_stream_name = request.GET.get("stream")
            (narrow_stream, ignored_rec,
             ignored_sub) = access_stream_by_name(user_profile,
                                                  narrow_stream_name)
            narrow = [["stream", narrow_stream.name]]
        except Exception:
            logging.warning("Invalid narrow requested, ignoring",
                            extra=dict(request=request))
        if narrow_stream is not None and narrow_topic is not None:
            narrow.append(["topic", narrow_topic])

    register_ret = do_events_register(user_profile,
                                      request.client,
                                      apply_markdown=True,
                                      client_gravatar=True,
                                      notification_settings_null=True,
                                      narrow=narrow)
    user_has_messages = (register_ret['max_message_id'] != -1)

    # Reset our don't-spam-users-with-email counter since the
    # user has since logged in
    if user_profile.last_reminder is not None:  # nocoverage
        # TODO: Look into the history of last_reminder; we may have
        # eliminated that as a useful concept for non-bot users.
        user_profile.last_reminder = None
        user_profile.save(update_fields=["last_reminder"])

    # Brand new users get narrowed to PM with welcome-bot
    needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING

    first_in_realm = realm_user_count(user_profile.realm) == 1
    # If you are the only person in the realm and you didn't invite
    # anyone, we'll continue to encourage you to do so on the frontend.
    prompt_for_invites = first_in_realm and \
        not PreregistrationUser.objects.filter(referred_by=user_profile).count()

    if user_profile.pointer == -1 and user_has_messages:
        # Put the new user's pointer at the bottom
        #
        # This improves performance, because we limit backfilling of messages
        # before the pointer.  It's also likely that someone joining an
        # organization is interested in recent messages more than the very
        # first messages on the system.

        register_ret['pointer'] = register_ret['max_message_id']
        user_profile.last_pointer_updater = request.session.session_key

    if user_profile.pointer == -1:
        latest_read = None
    else:
        latest_read = get_usermessage_by_message_id(user_profile,
                                                    user_profile.pointer)
        if latest_read is None:
            # Don't completely fail if your saved pointer ID is invalid
            logging.warning("User %s has invalid pointer %s" %
                            (user_profile.id, user_profile.pointer))

    # We pick a language for the user as follows:
    # * First priority is the language in the URL, for debugging.
    # * If not in the URL, we use the language from the user's settings.
    request_language = translation.get_language_from_path(request.path_info)
    if request_language is None:
        request_language = register_ret['default_language']
    translation.activate(request_language)
    # We also save the language to the user's session, so that
    # something reasonable will happen in logged-in portico pages.
    request.session[
        translation.LANGUAGE_SESSION_KEY] = translation.get_language()

    two_fa_enabled = settings.TWO_FACTOR_AUTHENTICATION_ENABLED

    # Pass parameters to the client-side JavaScript code.
    # These end up in a global JavaScript Object named 'page_params'.
    page_params = dict(
        # Server settings.
        development_environment=settings.DEVELOPMENT,
        debug_mode=settings.DEBUG,
        test_suite=settings.TEST_SUITE,
        poll_timeout=settings.POLL_TIMEOUT,
        login_page=settings.HOME_NOT_LOGGED_IN,
        root_domain_uri=settings.ROOT_DOMAIN_URI,
        max_file_upload_size=settings.MAX_FILE_UPLOAD_SIZE,
        max_avatar_file_size=settings.MAX_AVATAR_FILE_SIZE,
        server_generation=settings.SERVER_GENERATION,
        save_stacktraces=settings.SAVE_FRONTEND_STACKTRACES,
        warn_no_email=settings.WARN_NO_EMAIL,
        server_inline_image_preview=settings.INLINE_IMAGE_PREVIEW,
        server_inline_url_embed_preview=settings.INLINE_URL_EMBED_PREVIEW,
        password_min_length=settings.PASSWORD_MIN_LENGTH,
        password_min_guesses=settings.PASSWORD_MIN_GUESSES,
        jitsi_server_url=settings.JITSI_SERVER_URL,
        search_pills_enabled=settings.SEARCH_PILLS_ENABLED,
        server_avatar_changes_disabled=settings.AVATAR_CHANGES_DISABLED,
        server_name_changes_disabled=settings.NAME_CHANGES_DISABLED,

        # Misc. extra data.
        have_initial_messages=user_has_messages,
        initial_servertime=time.time(
        ),  # Used for calculating relative presence age
        default_language_name=get_language_name(
            register_ret['default_language']),
        language_list_dbl_col=get_language_list_for_templates(
            register_ret['default_language']),
        language_list=get_language_list(),
        needs_tutorial=needs_tutorial,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        furthest_read_time=sent_time_in_epoch_seconds(latest_read),
        has_mobile_devices=num_push_devices_for_user(user_profile) > 0,
        bot_types=get_bot_types(user_profile),
        two_fa_enabled=two_fa_enabled,
        # Adding two_fa_enabled as condition saves us 3 queries when
        # 2FA is not enabled.
        two_fa_enabled_user=two_fa_enabled
        and bool(default_device(user_profile)),
    )

    undesired_register_ret_fields = [
        'streams',
    ]
    for field_name in set(
            register_ret.keys()) - set(undesired_register_ret_fields):
        page_params[field_name] = register_ret[field_name]

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = narrow_stream.recipient
        try:
            initial_pointer = Message.objects.filter(
                recipient=recipient).order_by('id').reverse()[0].id
        except IndexError:
            initial_pointer = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [
            dict(operator=term[0], operand=term[1]) for term in narrow
        ]
        page_params["max_message_id"] = initial_pointer
        page_params["pointer"] = initial_pointer
        page_params["have_initial_messages"] = (initial_pointer != -1)
        page_params["enable_desktop_notifications"] = False

    statsd.incr('views.home')
    show_invites, show_add_streams = compute_show_invites_and_add_streams(
        user_profile)

    show_billing = False
    show_plans = False
    if settings.CORPORATE_ENABLED:
        from corporate.models import Customer, CustomerPlan
        if user_profile.is_billing_admin or user_profile.is_realm_admin:
            customer = Customer.objects.filter(
                realm=user_profile.realm).first()
            if customer is not None and CustomerPlan.objects.filter(
                    customer=customer).exists():
                show_billing = True
        if user_profile.realm.plan_type == Realm.LIMITED:
            show_plans = True

    request._log_data['extra'] = "[%s]" % (register_ret["queue_id"], )

    page_params['translation_data'] = {}
    if request_language != 'en':
        page_params['translation_data'] = get_language_translation_data(
            request_language)

    csp_nonce = generate_random_token(48)
    emojiset = user_profile.emojiset
    if emojiset == UserProfile.TEXT_EMOJISET:
        # If current emojiset is `TEXT_EMOJISET`, then fallback to
        # GOOGLE_EMOJISET for picking which spritesheet's CSS to
        # include (and thus how to display emojis in the emoji picker
        # and composebox typeahead).
        emojiset = UserProfile.GOOGLE_BLOB_EMOJISET

    navbar_logo_url = compute_navbar_logo_url(page_params)

    response = render(
        request,
        'zerver/app/index.html',
        context={
            'user_profile': user_profile,
            'emojiset': emojiset,
            'page_params': page_params,
            'csp_nonce': csp_nonce,
            'avatar_url': avatar_url(user_profile),
            'show_debug': settings.DEBUG and ('show_debug' in request.GET),
            'search_pills_enabled': settings.SEARCH_PILLS_ENABLED,
            'show_invites': show_invites,
            'show_add_streams': show_add_streams,
            'show_billing': show_billing,
            'show_plans': show_plans,
            'is_admin': user_profile.is_realm_admin,
            'is_guest': user_profile.is_guest,
            'night_mode': user_profile.night_mode,
            'navbar_logo_url': navbar_logo_url,
            'show_webathena': user_profile.realm.webathena_enabled,
            'embedded': narrow_stream is not None,
            'invite_as': PreregistrationUser.INVITE_AS,
            'max_file_upload_size': settings.MAX_FILE_UPLOAD_SIZE,
        },
    )
    patch_cache_control(response,
                        no_cache=True,
                        no_store=True,
                        must_revalidate=True)
    return response
Пример #46
0
    contents = context.data()

    for name in names[1:]:
        name = os.path.join("%s/" % base, name)
        # TODO: warn if mimetype of names[1:] is different from names[0]
        try:
            context = repo_context[name]
        except KeyError, e:
            raise Http404("No resource '%s'" % name)
        contents += context.data()
    
    response = HttpResponse(contents, mimetype=mimetype)

    response["Content-Length"] = len(contents)
    response["Cache-Control"] = "public"

    #  Cache
    if revision:
        #  cache for a long time
        WEEK = 60 * 60 * 24 * 7
        ttl = 52 * WEEK
    else:
        #  do not cache (revision may have been 'tip' or somesuch)
        ttl = 0
        response['ETag'] = '"%s"' % md5_constructor(response.content).hexdigest()

    response['Expires'] = http_date(time.time() + ttl)
    cache.patch_cache_control(response, max_age=ttl)

    return response
Пример #47
0
 def finalize_response(self, request, response, *args, **kwargs):
     response = super(StaticCategoryView,
                      self).finalize_response(request, response, *args,
                                              **kwargs)
     patch_cache_control(response, max_age=60 * 60 * 6)
     return response
Пример #48
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     patch_cache_control(self,
                         public=True,
                         max_age=settings.PERMANENT_REDIRECT_CACHE_TIME)
Пример #49
0
def home_real(request: HttpRequest) -> HttpResponse:
    # Before we do any real work, check if the app is banned.
    client_user_agent = request.META.get("HTTP_USER_AGENT", "")
    (insecure_desktop_app, banned_desktop_app, auto_update_broken) = is_outdated_desktop_app(
        client_user_agent)
    if banned_desktop_app:
        return render(
            request,
            'zerver/insecure_desktop_app.html',
            context={
                "auto_update_broken": auto_update_broken,
            }
        )
    (unsupported_browser, browser_name) = is_unsupported_browser(client_user_agent)
    if unsupported_browser:
        return render(
            request,
            'zerver/unsupported_browser.html',
            context={
                "browser_name": browser_name,
            }
        )

    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    if request.user.is_authenticated:
        user_profile = request.user
    else:  # nocoverage
        # This code path should not be reachable because of zulip_login_required above.
        user_profile = None

    # If a user hasn't signed the current Terms of Service, send them there
    if need_accept_tos(user_profile):
        return accounts_accept_terms(request)

    narrow, narrow_stream, narrow_topic = detect_narrowed_window(request, user_profile)

    register_ret = do_events_register(user_profile, request.client,
                                      apply_markdown=True, client_gravatar=True,
                                      slim_presence=True,
                                      notification_settings_null=True,
                                      narrow=narrow)
    user_has_messages = (register_ret['max_message_id'] != -1)
    update_last_reminder(user_profile)

    if user_profile is not None:
        first_in_realm = realm_user_count(user_profile.realm) == 1
        # If you are the only person in the realm and you didn't invite
        # anyone, we'll continue to encourage you to do so on the frontend.
        prompt_for_invites = (
            first_in_realm and
            not PreregistrationUser.objects.filter(referred_by=user_profile).count()
        )
        needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING
    else:  # nocoverage
        first_in_realm = False
        prompt_for_invites = False
        # The current tutorial doesn't super make sense for logged-out users.
        needs_tutorial = False

    if user_has_messages and user_profile.pointer == -1:
        # Put the new user's pointer at the bottom
        #
        # This improves performance, because we limit backfilling of messages
        # before the pointer.  It's also likely that someone joining an
        # organization is interested in recent messages more than the very
        # first messages on the system.

        register_ret['pointer'] = register_ret['max_message_id']

    furthest_read_time = get_furthest_read_time(user_profile)

    # We pick a language for the user as follows:
    # * First priority is the language in the URL, for debugging.
    # * If not in the URL, we use the language from the user's settings.
    request_language = translation.get_language_from_path(request.path_info)
    if request_language is None:
        request_language = register_ret['default_language']
    translation.activate(request_language)
    # We also save the language to the user's session, so that
    # something reasonable will happen in logged-in portico pages.
    request.session[translation.LANGUAGE_SESSION_KEY] = translation.get_language()

    two_fa_enabled = settings.TWO_FACTOR_AUTHENTICATION_ENABLED and user_profile is not None

    # Pass parameters to the client-side JavaScript code.
    # These end up in a global JavaScript Object named 'page_params'.
    page_params = dict(
        # Server settings.
        debug_mode                      = settings.DEBUG,
        test_suite                      = settings.TEST_SUITE,
        poll_timeout                    = settings.POLL_TIMEOUT,
        insecure_desktop_app            = insecure_desktop_app,
        login_page                      = settings.HOME_NOT_LOGGED_IN,
        root_domain_uri                 = settings.ROOT_DOMAIN_URI,
        save_stacktraces                = settings.SAVE_FRONTEND_STACKTRACES,
        warn_no_email                   = settings.WARN_NO_EMAIL,
        search_pills_enabled            = settings.SEARCH_PILLS_ENABLED,

        # Misc. extra data.
        have_initial_messages = user_has_messages,
        initial_servertime    = time.time(),  # Used for calculating relative presence age
        default_language_name = get_language_name(register_ret['default_language']),
        language_list_dbl_col = get_language_list_for_templates(register_ret['default_language']),
        language_list         = get_language_list(),
        needs_tutorial        = needs_tutorial,
        first_in_realm        = first_in_realm,
        prompt_for_invites    = prompt_for_invites,
        furthest_read_time    = furthest_read_time,
        has_mobile_devices    = user_profile is not None and num_push_devices_for_user(user_profile) > 0,
        bot_types             = get_bot_types(user_profile),
        two_fa_enabled        = two_fa_enabled,
        # Adding two_fa_enabled as condition saves us 3 queries when
        # 2FA is not enabled.
        two_fa_enabled_user   = two_fa_enabled and bool(default_device(user_profile)),
    )

    undesired_register_ret_fields = [
        'streams',
    ]
    for field_name in set(register_ret.keys()) - set(undesired_register_ret_fields):
        page_params[field_name] = register_ret[field_name]

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = narrow_stream.recipient
        try:
            initial_pointer = Message.objects.filter(recipient=recipient).order_by('id').reverse()[0].id
        except IndexError:
            initial_pointer = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [dict(operator=term[0], operand=term[1]) for term in narrow]
        page_params["max_message_id"] = initial_pointer
        page_params["pointer"] = initial_pointer
        page_params["have_initial_messages"] = (initial_pointer != -1)
        page_params["enable_desktop_notifications"] = False

    statsd.incr('views.home')
    show_invites, show_add_streams = compute_show_invites_and_add_streams(user_profile)

    show_billing = False
    show_plans = False
    if settings.CORPORATE_ENABLED and user_profile is not None:
        from corporate.models import Customer, CustomerPlan
        if user_profile.is_billing_admin or user_profile.is_realm_admin:
            customer = Customer.objects.filter(realm=user_profile.realm).first()
            if customer is not None and CustomerPlan.objects.filter(customer=customer).exists():
                show_billing = True
        if user_profile.realm.plan_type == Realm.LIMITED:
            show_plans = True

    request._log_data['extra'] = "[%s]" % (register_ret["queue_id"],)

    page_params['translation_data'] = {}
    if request_language != 'en':
        page_params['translation_data'] = get_language_translation_data(request_language)

    csp_nonce = generate_random_token(48)
    if user_profile is not None:
        night_mode = user_profile.night_mode
        is_guest = user_profile.is_guest
        is_realm_admin = user_profile.is_realm_admin
        show_webathena = user_profile.realm.webathena_enabled
    else:  # nocoverage
        night_mode = False
        is_guest = False
        is_realm_admin = False
        show_webathena = False

    navbar_logo_url = compute_navbar_logo_url(page_params)

    response = render(request, 'zerver/app/index.html',
                      context={'user_profile': user_profile,
                               'page_params': page_params,
                               'csp_nonce': csp_nonce,
                               'search_pills_enabled': settings.SEARCH_PILLS_ENABLED,
                               'show_invites': show_invites,
                               'show_add_streams': show_add_streams,
                               'show_billing': show_billing,
                               'corporate_enabled': settings.CORPORATE_ENABLED,
                               'show_plans': show_plans,
                               'is_admin': is_realm_admin,
                               'is_guest': is_guest,
                               'night_mode': night_mode,
                               'navbar_logo_url': navbar_logo_url,
                               'show_webathena': show_webathena,
                               'embedded': narrow_stream is not None,
                               'invite_as': PreregistrationUser.INVITE_AS,
                               'max_file_upload_size_mib': settings.MAX_FILE_UPLOAD_SIZE,
                               },)
    patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
    return response
Пример #50
0
def download_file(request, file_id, download_type=None, **kwargs):
    """
    Download the file identified by `file_id` parameter.

    If the file is disabled or belongs to an unlisted version, requires an
    add-on developer or appropriate reviewer for the channel. If the file is
    deleted or belongs to a deleted version or add-on, reviewers can still
    access but developers can't.
    """

    def is_appropriate_reviewer(addon, channel):
        return (
            acl.is_reviewer(request, addon)
            if channel == amo.RELEASE_CHANNEL_LISTED
            else acl.check_unlisted_addons_viewer_or_reviewer(request)
        )

    file_ = get_object_or_404(File.objects, pk=file_id)
    # Include deleted add-ons in the queryset, we'll check for that below.
    addon = get_object_or_404(
        Addon.unfiltered.all().no_transforms(), pk=file_.version.addon_id
    )
    version = file_.version
    channel = version.channel

    if version.deleted or addon.is_deleted:
        # Only the appropriate reviewer can see deleted things.
        has_permission = is_appropriate_reviewer(addon, channel)
        apply_georestrictions = False
    elif (
        addon.is_disabled
        or file_.status == amo.STATUS_DISABLED
        or channel == amo.RELEASE_CHANNEL_UNLISTED
    ):
        # Only the appropriate reviewer or developers of the add-on can see
        # disabled or unlisted things.
        has_permission = is_appropriate_reviewer(
            addon, channel
        ) or acl.check_addon_ownership(
            request,
            addon,
            allow_developer=True,
            allow_mozilla_disabled_addon=True,
            allow_site_permission=True,
        )
        apply_georestrictions = False
    else:
        # Public case: we're either directly downloading the file or
        # redirecting, but in any case we have permission in the general sense,
        # though georestrictions are in effect.
        has_permission = True
        apply_georestrictions = True

    region_code = request.META.get('HTTP_X_COUNTRY_CODE', None)
    # Whether to set Content-Disposition: attachment header or not, to force
    # the file to be downloaded rather than installed (used by admin/reviewer
    # tools).
    attachment = download_type == 'attachment'
    if not has_permission:
        log.debug(
            'download file {file_id}: addon/version/file not public and '
            'user {user_id} does not have relevant permissions.'.format(
                file_id=file_id, user_id=request.user.pk
            )
        )
        response = http.HttpResponseNotFound()
    elif (
        apply_georestrictions
        and region_code
        and AddonRegionalRestrictions.objects.filter(
            addon=addon, excluded_regions__contains=region_code.upper()
        ).exists()
    ):
        response = http.HttpResponse(status=451)
        url = 'https://www.mozilla.org/about/policy/transparency/'
        response['Link'] = f'<{url}>; rel="blocked-by"'
    else:
        # We're returning a X-Accel-Redirect, we can set
        # Content-Disposition: attachment ourselves in HttpResponseXSendFile:
        # nginx won't override it if present.
        response = HttpResponseXSendFile(
            request,
            file_.current_file_path,
            content_type='application/x-xpinstall',
            attachment=attachment,
        )
    # Always add a few headers to the response (even errors).
    patch_cache_control(response, max_age=60 * 60 * 24)
    patch_vary_headers(response, ['X-Country-Code'])
    response['Access-Control-Allow-Origin'] = '*'
    return response
Пример #51
0
from django.test import RequestFactory, TestCase
from django.utils.cache import get_max_age, patch_cache_control
from .views import my_view
"""
https://docs.djangoproject.com/en/dev/ref/utils/#django.utils.cache.patch_cache_control

patch_cache_control(response, **kwargs)
"""


class Test(TestCase):
    def test(self):
        request = RequestFactory().get('/')
        response = my_view(request)
        max_age = 3600
        patch_cache_control(response, max_age=max_age)
        self.assertEqual(get_max_age(response), max_age)
Пример #52
0
 def _cache_controlled(request, *args, **kw):
     response = viewfunc(request, *args, **kw)
     patch_cache_control(response, **kwargs)
     return response
Пример #53
0
def fudge_headers(response, stats):
    """Alter cache headers. Don't cache content where data could be missing."""
    if not stats:
        add_never_cache_headers(response)
    else:
        patch_cache_control(response, max_age=seven_days)
Пример #54
0
def add_paper_cache_control(response):
    patch_cache_control(response,
                        public=True,
                        max_age=settings.PAPER_CACHE_SECONDS)
    return response
Пример #55
0
def esi(request,
        app_label=None,
        model_name=None,
        object_id=None,
        timeout=900,
        template=None):
    """
    Using the app_label, module_name and object_id parameters create an object and render it using `template_name` or `template_dir`.
    
    Parameters:
        :app_label: `Name of a app (i.e. auth)`
        :model_name: `Name of a model (i.e. user)`
        :object_id: `This's objects primary key id`
        :timeout: `Time in secondsfor this objects max_age. [default 900]`
        :template: `a path to a template directory or a template`
        
    Context:
        `object`
            The object that was returned
        `model_name`
            If you are using a User object `user` will be in the context.
    
    Templates:
        if `template` is a directory:
            A file called `app_label`.`model_name`.html ,along with any other models'
            content types that the object extends, will be looked for in the `template`
            directory falling back to `template`/default.html 
            if none can be found.
        if `template` is a file:
            The file `template` will be loaded and rendered.
            
        If no template is provided `settings`.ESI_DEFAULT_TEMPLATE and `settings`.ESI_DEFAULT_DIRECTORY
        will be checked with the same logic as above.
        
    """
    default_template = getattr(settings, 'ESI_DEFAULT_TEMPLATE', None)
    default_template_dir = getattr(settings, 'ESI_DEFAULT_DIRECTORY', None)
    obj, model = get_object(app_label, model_name, object_id)
    template_list = []
    if template is not None:
        template_list.extend(get_template_list(obj, template))
    else:
        if default_template is not None:
            temp_t = get_template_list(obj, default_template)
            if temp_t is not None:
                template_list.extend(get_template_list(obj, default_template))
        if default_template_dir is not None and len(template_list) == 0:
            temp_t = get_template_list(obj, default_template_dir)
            if temp_t is not None:
                template_list.extend(
                    get_template_list(obj, default_template_dir))
    if len(template_list) == 0:
        raise Http404
    t = loader.select_template(template_list)
    context = {'object': obj, model_name: obj}
    c = RequestContext(request, context)
    response = HttpResponse(t.render(c))
    populate_xheaders(request, response, model,
                      getattr(obj, model._meta.pk.name))
    patch_cache_control(response, max_age=timeout)
    return response
Пример #56
0
def home_real(request: HttpRequest) -> HttpResponse:
    # Before we do any real work, check if the app is banned.
    client_user_agent = request.META.get("HTTP_USER_AGENT", "")
    (insecure_desktop_app, banned_desktop_app,
     auto_update_broken) = is_outdated_desktop_app(client_user_agent)
    if banned_desktop_app:
        return render(
            request,
            'zerver/insecure_desktop_app.html',
            context={
                "auto_update_broken": auto_update_broken,
            },
        )
    (unsupported_browser,
     browser_name) = is_unsupported_browser(client_user_agent)
    if unsupported_browser:
        return render(
            request,
            'zerver/unsupported_browser.html',
            context={
                "browser_name": browser_name,
            },
        )

    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    if request.user.is_authenticated:
        user_profile = request.user
    else:  # nocoverage
        # This code path should not be reachable because of zulip_login_required above.
        user_profile = None

    update_last_reminder(user_profile)

    statsd.incr('views.home')

    # If a user hasn't signed the current Terms of Service, send them there
    if need_accept_tos(user_profile):
        return accounts_accept_terms(request)

    narrow, narrow_stream, narrow_topic = detect_narrowed_window(
        request, user_profile)

    if user_profile is not None:
        first_in_realm = realm_user_count(user_profile.realm) == 1
        # If you are the only person in the realm and you didn't invite
        # anyone, we'll continue to encourage you to do so on the frontend.
        prompt_for_invites = (first_in_realm
                              and not PreregistrationUser.objects.filter(
                                  referred_by=user_profile).count())
        needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING

    else:  # nocoverage
        first_in_realm = False
        prompt_for_invites = False
        # The current tutorial doesn't super make sense for logged-out users.
        needs_tutorial = False

    has_mobile_devices = user_profile is not None and num_push_devices_for_user(
        user_profile) > 0

    queue_id, page_params = build_page_params_for_home_page_load(
        request=request,
        user_profile=user_profile,
        insecure_desktop_app=insecure_desktop_app,
        has_mobile_devices=has_mobile_devices,
        narrow=narrow,
        narrow_stream=narrow_stream,
        narrow_topic=narrow_topic,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        needs_tutorial=needs_tutorial,
    )

    show_invites, show_add_streams = compute_show_invites_and_add_streams(
        user_profile)

    billing_info = get_billing_info(user_profile)

    request._log_data['extra'] = "[{}]".format(queue_id)

    csp_nonce = secrets.token_hex(24)

    user_permission_info = get_user_permission_info(user_profile)

    navbar_logo_url = compute_navbar_logo_url(page_params)

    response = render(request,
                      'zerver/app/index.html',
                      context={
                          'user_profile':
                          user_profile,
                          'page_params':
                          page_params,
                          'csp_nonce':
                          csp_nonce,
                          'search_pills_enabled':
                          settings.SEARCH_PILLS_ENABLED,
                          'show_invites':
                          show_invites,
                          'show_add_streams':
                          show_add_streams,
                          'show_billing':
                          billing_info.show_billing,
                          'corporate_enabled':
                          settings.CORPORATE_ENABLED,
                          'show_plans':
                          billing_info.show_plans,
                          'is_owner':
                          user_permission_info.is_realm_owner,
                          'is_admin':
                          user_permission_info.is_realm_admin,
                          'is_guest':
                          user_permission_info.is_guest,
                          'color_scheme':
                          user_permission_info.color_scheme,
                          'navbar_logo_url':
                          navbar_logo_url,
                          'show_webathena':
                          user_permission_info.show_webathena,
                          'embedded':
                          narrow_stream is not None,
                          'invite_as':
                          PreregistrationUser.INVITE_AS,
                          'max_file_upload_size_mib':
                          settings.MAX_FILE_UPLOAD_SIZE,
                      })
    patch_cache_control(response,
                        no_cache=True,
                        no_store=True,
                        must_revalidate=True)
    return response
Пример #57
0
def home_real(request: HttpRequest) -> HttpResponse:
    # Before we do any real work, check if the app is banned.
    client_user_agent = request.META.get("HTTP_USER_AGENT", "")
    (insecure_desktop_app, banned_desktop_app,
     auto_update_broken) = is_outdated_desktop_app(client_user_agent)
    if banned_desktop_app:
        return render(
            request,
            "zerver/insecure_desktop_app.html",
            context={
                "auto_update_broken": auto_update_broken,
            },
        )
    (unsupported_browser,
     browser_name) = is_unsupported_browser(client_user_agent)
    if unsupported_browser:
        return render(
            request,
            "zerver/unsupported_browser.html",
            context={
                "browser_name": browser_name,
            },
        )

    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    if request.user.is_authenticated:
        user_profile = request.user
        realm = user_profile.realm
    else:
        # user_profile=None corresponds to the logged-out "web_public" visitor case.
        user_profile = None
        realm = get_valid_realm_from_request(request)

    update_last_reminder(user_profile)

    statsd.incr("views.home")

    # If a user hasn't signed the current Terms of Service, send them there
    if need_accept_tos(user_profile):
        return accounts_accept_terms(request)

    narrow, narrow_stream, narrow_topic = detect_narrowed_window(
        request, user_profile)

    if user_profile is not None:
        first_in_realm = realm_user_count(user_profile.realm) == 1
        # If you are the only person in the realm and you didn't invite
        # anyone, we'll continue to encourage you to do so on the frontend.
        prompt_for_invites = (first_in_realm
                              and not PreregistrationUser.objects.filter(
                                  referred_by=user_profile).count())
        needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING

    else:
        first_in_realm = False
        prompt_for_invites = False
        # The current tutorial doesn't super make sense for logged-out users.
        needs_tutorial = False

    queue_id, page_params = build_page_params_for_home_page_load(
        request=request,
        user_profile=user_profile,
        realm=realm,
        insecure_desktop_app=insecure_desktop_app,
        narrow=narrow,
        narrow_stream=narrow_stream,
        narrow_topic=narrow_topic,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        needs_tutorial=needs_tutorial,
    )

    show_invites, show_add_streams = compute_show_invites_and_add_streams(
        user_profile)

    billing_info = get_billing_info(user_profile)

    request._log_data["extra"] = "[{}]".format(queue_id)

    csp_nonce = secrets.token_hex(24)

    user_permission_info = get_user_permission_info(user_profile)

    navbar_logo_url = compute_navbar_logo_url(page_params)

    response = render(
        request,
        "zerver/app/index.html",
        context={
            "user_profile": user_profile,
            "page_params": page_params,
            "csp_nonce": csp_nonce,
            "search_pills_enabled": settings.SEARCH_PILLS_ENABLED,
            "show_invites": show_invites,
            "show_add_streams": show_add_streams,
            "promote_sponsoring_zulip":
            promote_sponsoring_zulip_in_realm(realm),
            "show_billing": billing_info.show_billing,
            "corporate_enabled": settings.CORPORATE_ENABLED,
            "show_plans": billing_info.show_plans,
            "is_owner": user_permission_info.is_realm_owner,
            "is_admin": user_permission_info.is_realm_admin,
            "is_guest": user_permission_info.is_guest,
            "color_scheme": user_permission_info.color_scheme,
            "zulip_version": ZULIP_VERSION,
            "zulip_merge_base": ZULIP_MERGE_BASE,
            "navbar_logo_url": navbar_logo_url,
            "show_webathena": user_permission_info.show_webathena,
            "embedded": narrow_stream is not None,
            "invite_as": PreregistrationUser.INVITE_AS,
            "max_file_upload_size_mib": settings.MAX_FILE_UPLOAD_SIZE,
        },
    )
    patch_cache_control(response,
                        no_cache=True,
                        no_store=True,
                        must_revalidate=True)
    return response
Пример #58
0
def home_real(request):
    # type: (HttpRequest) -> HttpResponse
    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    user_profile = request.user

    # If a user hasn't signed the current Terms of Service, send them there
    if settings.TERMS_OF_SERVICE is not None and settings.TOS_VERSION is not None and \
       int(settings.TOS_VERSION.split('.')[0]) > user_profile.major_tos_version():
        return accounts_accept_terms(request)

    narrow = []  # type: List[List[Text]]
    narrow_stream = None
    narrow_topic = request.GET.get("topic")
    if request.GET.get("stream"):
        try:
            narrow_stream_name = request.GET.get("stream")
            (narrow_stream, ignored_rec, ignored_sub) = access_stream_by_name(
                user_profile, narrow_stream_name)
            narrow = [["stream", narrow_stream.name]]
        except Exception:
            logging.exception("Narrow parsing")
        if narrow_stream is not None and narrow_topic is not None:
            narrow.append(["topic", narrow_topic])

    register_ret = do_events_register(user_profile, request.client,
                                      apply_markdown=True, narrow=narrow)
    user_has_messages = (register_ret['max_message_id'] != -1)

    # Reset our don't-spam-users-with-email counter since the
    # user has since logged in
    if user_profile.last_reminder is not None:
        user_profile.last_reminder = None
        user_profile.save(update_fields=["last_reminder"])

    # Brand new users get narrowed to PM with welcome-bot
    needs_tutorial = user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING

    first_in_realm = realm_user_count(user_profile.realm) == 1
    # If you are the only person in the realm and you didn't invite
    # anyone, we'll continue to encourage you to do so on the frontend.
    prompt_for_invites = first_in_realm and \
        not PreregistrationUser.objects.filter(referred_by=user_profile).count()

    if user_profile.pointer == -1 and user_has_messages:
        # Put the new user's pointer at the bottom
        #
        # This improves performance, because we limit backfilling of messages
        # before the pointer.  It's also likely that someone joining an
        # organization is interested in recent messages more than the very
        # first messages on the system.

        register_ret['pointer'] = register_ret['max_message_id']
        user_profile.last_pointer_updater = request.session.session_key

    if user_profile.pointer == -1:
        latest_read = None
    else:
        try:
            latest_read = UserMessage.objects.get(user_profile=user_profile,
                                                  message__id=user_profile.pointer)
        except UserMessage.DoesNotExist:
            # Don't completely fail if your saved pointer ID is invalid
            logging.warning("%s has invalid pointer %s" % (user_profile.email, user_profile.pointer))
            latest_read = None

    # Set default language and make it persist
    default_language = register_ret['default_language']
    url_lang = '/{}'.format(request.LANGUAGE_CODE)
    if not request.path.startswith(url_lang):
        translation.activate(default_language)
        request.session[translation.LANGUAGE_SESSION_KEY] = translation.get_language()

    # Pass parameters to the client-side JavaScript code.
    # These end up in a global JavaScript Object named 'page_params'.
    page_params = dict(
        # Server settings.
        development_environment = settings.DEVELOPMENT,
        debug_mode            = settings.DEBUG,
        test_suite            = settings.TEST_SUITE,
        poll_timeout          = settings.POLL_TIMEOUT,
        login_page            = settings.HOME_NOT_LOGGED_IN,
        root_domain_uri       = settings.ROOT_DOMAIN_URI,
        maxfilesize           = settings.MAX_FILE_UPLOAD_SIZE,
        max_avatar_file_size  = settings.MAX_AVATAR_FILE_SIZE,
        server_generation     = settings.SERVER_GENERATION,
        use_websockets        = settings.USE_WEBSOCKETS,
        save_stacktraces      = settings.SAVE_FRONTEND_STACKTRACES,
        server_inline_image_preview = settings.INLINE_IMAGE_PREVIEW,
        server_inline_url_embed_preview = settings.INLINE_URL_EMBED_PREVIEW,
        password_min_length = settings.PASSWORD_MIN_LENGTH,
        password_min_guesses  = settings.PASSWORD_MIN_GUESSES,

        # Misc. extra data.
        have_initial_messages = user_has_messages,
        initial_servertime    = time.time(),  # Used for calculating relative presence age
        default_language_name = get_language_name(register_ret['default_language']),
        language_list_dbl_col = get_language_list_for_templates(register_ret['default_language']),
        language_list         = get_language_list(),
        needs_tutorial        = needs_tutorial,
        first_in_realm        = first_in_realm,
        prompt_for_invites    = prompt_for_invites,
        furthest_read_time    = sent_time_in_epoch_seconds(latest_read),
        has_mobile_devices    = num_push_devices_for_user(user_profile) > 0,
    )

    undesired_register_ret_fields = [
        'streams',
    ]
    for field_name in set(register_ret.keys()) - set(undesired_register_ret_fields):
        page_params[field_name] = register_ret[field_name]

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = get_recipient(Recipient.STREAM, narrow_stream.id)
        try:
            initial_pointer = Message.objects.filter(recipient=recipient).order_by('id').reverse()[0].id
        except IndexError:
            initial_pointer = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [dict(operator=term[0], operand=term[1]) for term in narrow]
        page_params["max_message_id"] = initial_pointer
        page_params["pointer"] = initial_pointer
        page_params["have_initial_messages"] = (initial_pointer != -1)
        page_params["enable_desktop_notifications"] = False

    statsd.incr('views.home')
    show_invites = True

    # Some realms only allow admins to invite users
    if user_profile.realm.invite_by_admins_only and not user_profile.is_realm_admin:
        show_invites = False

    request._log_data['extra'] = "[%s]" % (register_ret["queue_id"],)
    response = render(request, 'zerver/index.html',
                      context={'user_profile': user_profile,
                               'page_params': simplejson.encoder.JSONEncoderForHTML().encode(page_params),
                               'nofontface': is_buggy_ua(request.META.get("HTTP_USER_AGENT", "Unspecified")),
                               'avatar_url': avatar_url(user_profile),
                               'show_debug':
                               settings.DEBUG and ('show_debug' in request.GET),
                               'pipeline': settings.PIPELINE_ENABLED,
                               'show_invites': show_invites,
                               'is_admin': user_profile.is_realm_admin,
                               'show_webathena': user_profile.realm.webathena_enabled,
                               'enable_feedback': settings.ENABLE_FEEDBACK,
                               'embedded': narrow_stream is not None,
                               },)
    patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
    return response
Пример #59
0
 def decorated_function(*args, **kwargs):
     request = args[0]
     response = function(*args, **kwargs)
     cache.patch_response_headers(response, ttl)
     cache.patch_cache_control(response, public=True)
     return response
Пример #60
0
def qsd(request, url):

    #   Extract the 'action' from the supplied URL if there is one
    url_parts = url.split('/')
    page_name = url_parts[-1]
    page_name_parts = page_name.split('.')
    if len(page_name_parts) > 1:
        action = page_name_parts[-1]
        page_name_base = '.'.join(page_name_parts[:-1])
    else:
        action = 'read'
        page_name_base = page_name
    base_url = '/'.join(url_parts[:-1] + [page_name_base])

    # Detect edit authorizations
    have_read = True

    if not have_read and action == 'read':
        raise Http403, "You do not have permission to access this page."

    # Fetch the QSD object
    try:
        qsd_rec = QuasiStaticData.objects.get_by_url(base_url)
        if qsd_rec == None:
            raise QuasiStaticData.DoesNotExist
        if qsd_rec.disabled:
            raise QuasiStaticData.DoesNotExist

    except QuasiStaticData.DoesNotExist:
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        if have_edit:
            if action in ('edit','create',):
                qsd_rec = QuasiStaticData()
                qsd_rec.url = base_url
                qsd_rec.nav_category = default_navbarcategory()
                qsd_rec.title = 'New Page'
                qsd_rec.content = 'Please insert your text here'
                qsd_rec.create_date = datetime.now()
                qsd_rec.keywords = ''
                qsd_rec.description = ''
                action = 'edit'

            if (action == 'read'):
                edit_link = '/' + base_url + '.edit.html'
                response = render_to_response('qsd/nopage_create.html', request, {'edit_link': edit_link}, use_request_context=False)
                response.status_code = 404 # Make sure we actually 404, so that if there is a redirect the middleware can catch it.
                return response
        else:
            if action == 'read':
                raise Http404, 'This page does not exist.'
            else:
                raise Http403, 'Sorry, you can not modify <tt>%s</tt>.' % request.path

    if action == 'create':
        action = 'edit'

    # Detect the standard read verb
    if action == 'read':
        if not have_read:
            raise Http403, 'You do not have permission to read this page.'

        # Render response
        response = render_to_response('qsd/qsd.html', request, {
            'title': qsd_rec.title,
            'nav_category': qsd_rec.nav_category,
            'content': qsd_rec.html(),
            'settings': settings,
            'qsdrec': qsd_rec,
            'have_edit': True,  ## Edit-ness is determined client-side these days
            'edit_url': '/' + base_url + ".edit.html" }, use_request_context=False)

#        patch_vary_headers(response, ['Cookie'])
#        if have_edit:
#            add_never_cache_headers(response)
#            patch_cache_control(response, no_cache=True, no_store=True)
#        else:
        patch_cache_control(response, max_age=3600, public=True)

        return response


    # Detect POST
    if 'post_edit' in request.POST:
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        if not have_edit:
            raise Http403, "Sorry, you do not have permission to edit this page."

        nav_category_target = NavBarCategory.objects.get(id=request.POST['nav_category'])

        # Since QSD now uses reversion, we want to only modify the data if we've actually changed something
        # The revision will automatically be created upon calling the save function of the model object
        copy_map = {
            'url': base_url,
            'nav_category': nav_category_target,
            'content': request.POST['content'],
            'title': request.POST['title'],
            'description': request.POST['description'],
            'keywords': request.POST['keywords'],
        }
        diff_found = False
        for field, new_value in copy_map.items():
            if getattr(qsd_rec, field) != new_value:
                setattr(qsd_rec, field, new_value)
                diff_found = True

        if diff_found:
            qsd_rec.load_cur_user_time(request)
            qsd_rec.save()

            # We should also purge the cache
            purge_page(qsd_rec.url+".html")


    # Detect the edit verb
    if action == 'edit':
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        # Enforce authorizations (FIXME: SHOW A REAL ERROR!)
        if not have_edit:
            raise Http403, "You don't have permission to edit this page."

        # Render an edit form
        return render_to_response('qsd/qsd_edit.html', request, {
            'title'        : qsd_rec.title,
            'content'      : qsd_rec.content,
            'keywords'     : qsd_rec.keywords,
            'description'  : qsd_rec.description,
            'nav_category' : qsd_rec.nav_category,
            'nav_categories': NavBarCategory.objects.all(),
            'qsdrec'       : qsd_rec,
            'qsd'          : True,
            'target_url'   : base_url.split("/")[-1] + ".edit.html",
            'return_to_view': base_url.split("/")[-1] + ".html#refresh" },
            use_request_context=False)

    # Operation Complete!
    raise Http404('Unexpected QSD operation')