Ejemplo n.º 1
0
    def _dispatch(cls):
        """ Before executing the endpoint method, add website params on request, such as
                - current website (record)
                - multilang support (set on cookies)
                - geoip dict data are added in the session
            Then follow the parent dispatching.
            Reminder :  Do not use `request.env` before authentication phase, otherwise the env
                        set on request will be created with uid=None (and it is a lazy property)
        """
        first_pass = not hasattr(request, 'website')
        request.website = None
        func = None

        # add signup token or login to the session if given
        if 'auth_signup_token' in request.params:
            request.session['auth_signup_token'] = request.params[
                'auth_signup_token']
        if 'auth_login' in request.params:
            request.session['auth_login'] = request.params['auth_login']

        try:
            if request.httprequest.method == 'GET' and '//' in request.httprequest.path:
                new_url = request.httprequest.path.replace(
                    '//', '/') + '?' + request.httprequest.query_string
                return werkzeug.utils.redirect(new_url, 301)
            func, arguments = cls._find_handler()
            request.website_enabled = func.routing.get('website', False)
        except werkzeug.exceptions.NotFound:
            # either we have a language prefixed route, either a real 404
            # in all cases, website processes them
            request.website_enabled = True

        request.website_multilang = (
            request.website_enabled and func
            and func.routing.get('multilang', func.routing['type'] == 'http'))

        cls._geoip_setup_resolver()
        cls._geoip_resolve()

        # For website routes (only), add website params on `request`
        cook_lang = request.httprequest.cookies.get('website_lang')
        if request.website_enabled:
            try:
                if func:
                    cls._authenticate(func.routing['auth'])
                elif request.uid is None:
                    cls._auth_method_public()
            except Exception as e:
                return cls._handle_exception(e)

            request.redirect = lambda url, code=302: werkzeug.utils.redirect(
                url_for(url), code)
            request.website = request.env['website'].get_current_website(
            )  # can use `request.env` since auth methods are called
            context = dict(request.context)
            context['website_id'] = request.website.id
            langs = [lg[0] for lg in request.website.get_languages()]
            path = request.httprequest.path.split('/')
            if first_pass:
                is_a_bot = cls.is_a_bot()
                nearest_lang = not func and cls.get_nearest_lang(path[1])
                url_lang = nearest_lang and path[1]
                preferred_lang = ((cook_lang if cook_lang in langs else False)
                                  or (not is_a_bot
                                      and cls.get_nearest_lang(request.lang))
                                  or request.website.default_lang_code)

                request.lang = context['lang'] = nearest_lang or preferred_lang
                # if lang in url but not the displayed or default language --> change or remove
                # or no lang in url, and lang to dispay not the default language --> add lang
                # and not a POST request
                # and not a bot or bot but default lang in url
                if ((url_lang and (url_lang != request.lang or url_lang == request.website.default_lang_code))
                        or (not url_lang and request.website_multilang and request.lang != request.website.default_lang_code)
                        and request.httprequest.method != 'POST') \
                        and (not is_a_bot or (url_lang and url_lang == request.website.default_lang_code)):
                    if url_lang:
                        path.pop(1)
                    if request.lang != request.website.default_lang_code:
                        path.insert(1, request.lang)
                    path = '/'.join(path) or '/'
                    request.context = context
                    redirect = request.redirect(
                        path + '?' + request.httprequest.query_string)
                    redirect.set_cookie('website_lang', request.lang)
                    return redirect
                elif url_lang:
                    request.uid = None
                    path.pop(1)
                    request.context = context
                    return cls.reroute('/'.join(path) or '/')
            if request.lang == request.website.default_lang_code:
                context['edit_translations'] = False
            if not context.get('tz'):
                context['tz'] = request.session.get('geoip',
                                                    {}).get('time_zone')
            # bind modified context
            request.context = context
            request.website = request.website.with_context(context)

        # removed cache for auth public
        request.cache_save = False
        resp = super(Http, cls)._dispatch()

        if request.website_enabled and cook_lang != request.lang and hasattr(
                resp, 'set_cookie'):
            resp.set_cookie('website_lang', request.lang)
        return resp
Ejemplo n.º 2
0
    def _dispatch(self):
        """ Before executing the endpoint method, add website params on request, such as
                - current website (record)
                - multilang support (set on cookies)
                - geoip dict data are added in the session
            Then follow the parent dispatching.
            Reminder :  Do not use `request.env` before authentication phase, otherwise the env
                        set on request will be created with uid=None (and it is a lazy property)
        """
        first_pass = not hasattr(request, 'website')
        request.website = None
        func = None
        try:
            if request.httprequest.method == 'GET' and '//' in request.httprequest.path:
                new_url = request.httprequest.path.replace('//', '/') + '?' + request.httprequest.query_string
                return werkzeug.utils.redirect(new_url, 301)
            func, arguments = self._find_handler()
            request.website_enabled = func.routing.get('website', False)
        except werkzeug.exceptions.NotFound:
            # either we have a language prefixed route, either a real 404
            # in all cases, website processes them
            request.website_enabled = True

        request.website_multilang = (
            request.website_enabled and
            func and func.routing.get('multilang', func.routing['type'] == 'http')
        )

        self._geoip_setup_resolver()
        self._geoip_resolve()

        # For website routes (only), add website params on `request`
        cook_lang = request.httprequest.cookies.get('website_lang')
        if request.website_enabled:
            try:
                if func:
                    self._authenticate(func.routing['auth'])
                elif request.uid is None:
                    self._auth_method_public()
            except Exception as e:
                return self._handle_exception(e)

            request.redirect = lambda url, code=302: werkzeug.utils.redirect(url_for(url), code)
            request.website = request.env['website'].get_current_website()  # can use `request.env` since auth methods are called
            request.context['website_id'] = request.website.id
            langs = [lg[0] for lg in request.website.get_languages()]
            path = request.httprequest.path.split('/')
            if first_pass:
                nearest_lang = not func and self.get_nearest_lang(path[1])
                url_lang = nearest_lang and path[1]
                preferred_lang = ((cook_lang if cook_lang in langs else False)
                                  or self.get_nearest_lang(request.lang)
                                  or request.website.default_lang_code)

                is_a_bot = self.is_a_bot()

                request.lang = request.context['lang'] = nearest_lang or preferred_lang
                # if lang in url but not the displayed or default language --> change or remove
                # or no lang in url, and lang to dispay not the default language --> add lang
                # and not a POST request
                # and not a bot or bot but default lang in url
                if ((url_lang and (url_lang != request.lang or url_lang == request.website.default_lang_code))
                        or (not url_lang and request.website_multilang and request.lang != request.website.default_lang_code)
                        and request.httprequest.method != 'POST') \
                        and (not is_a_bot or (url_lang and url_lang == request.website.default_lang_code)):
                    if url_lang:
                        path.pop(1)
                    if request.lang != request.website.default_lang_code:
                        path.insert(1, request.lang)
                    path = '/'.join(path) or '/'
                    redirect = request.redirect(path + '?' + request.httprequest.query_string)
                    redirect.set_cookie('website_lang', request.lang)
                    return redirect
                elif url_lang:
                    request.uid = None
                    path.pop(1)
                    return self.reroute('/'.join(path) or '/')
            if path[1] == request.website.default_lang_code:
                request.context['edit_translations'] = False
            if not request.context.get('tz'):
                request.context['tz'] = request.session.get('geoip', {}).get('time_zone')
            # bind modified context
            request.website = request.website.with_context(request.context)

        # removed cache for auth public
        request.cache_save = False
        resp = super(Http, self)._dispatch()

        if request.website_enabled and cook_lang != request.lang and hasattr(resp, 'set_cookie'):
            resp.set_cookie('website_lang', request.lang)
        return resp