justpy-org / justpy

An object oriented high-level Python Web Framework that requires no frontend programming
https://justpy.io
Apache License 2.0
1.22k stars 96 forks source link

PlainTextResponse("Bad Session") not executed #645

Closed Phonix88 closed 1 year ago

Phonix88 commented 1 year ago

First of all, I apologize if the way/form of reporting a possible bug is not correct: it's the first time I've done it.

In this Def (located in justpy_app.py):

def handle_session_cookie(self,request) -> typing.Union[bool, Response]:
        # Handle web requests
        session_cookie = request.cookies.get(SESSION_COOKIE_NAME)   
        #print(cookie_signer.unsign(session_cookie).decode("utf-8"))
        new_cookie=None
        if SESSIONS:
            new_cookie = False
            if session_cookie:
                try:
                    session_id = cookie_signer.unsign(session_cookie).decode("utf-8")
                except:
                    return PlainTextResponse("Bad Session") <==============
                request.state.session_id = session_id
                request.session_id = session_id
            else:
                # Create new session_id
                request.state.session_id = str(uuid.uuid4().hex)
                request.session_id = request.state.session_id
                new_cookie = True
                logging.debug(f"New session_id created: {request.session_id}")
        return new_cookie

If you try to have session_id, in this Def, if you need the case in which JustPy should return an error in the session through the writing "Bad Session", now return this error:

AttributeError: 'Request' object has no attribute 'session_id'

Phonix88 commented 1 year ago

A possible fix cold be this:

    def get_response_for_load_page(self,request,load_page):
        """
        get the response for the given webpage

        Args:
            request(Request): the request to handle
            load_page(WebPage): the webpage to wrap with justpy and  
            return as a full HtmlResponse

        Returns:
            Reponse: the response for the given load_page
        """
        page_type = type(load_page)
        if page_type in [PlainTextResponse, JSONResponse, HTMLResponse]: <====== Add
            return(load_page) <========== Add
        assert issubclass(
            page_type, WebPage
        ), f"Function did not return a web page but a {page_type.__name__}"
        if len(load_page) == 0 and not load_page.html:
            error_html="""<span style="color:red">Web page is empty - you might want to add components</span>"""
            return HTMLResponse(error_html, 500)
    def response(self,func:typing.Callable):
        """
        response decorator converts a function to a response

        see also https://github.com/justpy-org/justpy/issues/532
        castAsEndPoint

        Args:
            func(typing.Callable): the function (returning a WebPage) to convert to a response
        """
        async def funcResponse(request)->HTMLResponse:
            """
            decorator function to apply the function to the request and
            return it as a response

            Args:
                request(Request): the request to apply the function to

            Returns:
                Response: a HTMLResponse applying the justpy infrastructure

            """
            new_cookie = self.handle_session_cookie(request)
            wp = await self.get_page_for_func(request, func)
            response = self.get_response_for_load_page(request, wp)
            if type(response) not in [PlainTextResponse, JSONResponse, HTMLResponse]: <=======
                response = self.set_cookie(request, response, wp, new_cookie)
            if LATENCY:
                await asyncio.sleep(LATENCY / 1000)
            return response
WolfgangFahl commented 1 year ago

see also #587 and #180

WolfgangFahl commented 1 year ago

see #685