diff --git a/cache/crc321300331366.cache b/cache/crc321300331366.cache deleted file mode 100644 index e69de29..0000000 diff --git a/cache/crc322507170282.cache b/cache/crc322507170282.cache deleted file mode 100644 index e69de29..0000000 diff --git a/pyproject.toml b/pyproject.toml index cc36846..71e90a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,8 @@ dependencies = [ "gunicorn", "imgkit", "wkhtmltopdf", - "jinja-markdown2", - "mistune" + "mistune", + "aiohttp-session", + "cryptography" ] diff --git a/src/snek/app.py b/src/snek/app.py index ab19f42..0abf24b 100644 --- a/src/snek/app.py +++ b/src/snek/app.py @@ -17,8 +17,23 @@ from snek.view.login import LoginView from snek.view.login_form import LoginFormView from snek.view.register import RegisterView from snek.view.register_form import RegisterFormView +from snek.view.status import StatusView from snek.view.web import WebView +from aiohttp import web +from aiohttp_session import setup as session_setup, get_session as session_get, session_middleware +from aiohttp_session.cookie_storage import EncryptedCookieStorage +import base64 + +#base64.urlsafe_b64encode( +SESSION_KEY = b'c79a0c5fda4b424189c427d28c9f7c34' + +@web.middleware +async def session_middleware(request, handler): + setattr(request,"session", await session_get(request)) + response = await handler(request) + return response + class Application(BaseApplication): @@ -31,10 +46,13 @@ class Application(BaseApplication): super().__init__( middlewares=middlewares, template_path=self.template_path, *args, **kwargs ) + session_setup(self,EncryptedCookieStorage(SESSION_KEY)) + self._middlewares.append(session_middleware) self.jinja2_env.add_extension(MarkdownExtension) self.setup_router() self.setup_services() + def setup_services(self): self.services = SimpleNamespace(**get_services(app=self)) self.mappers = SimpleNamespace(**get_mappers(app=self)) @@ -51,7 +69,7 @@ class Application(BaseApplication): self.router.add_view("/about.md", AboutMDView) self.router.add_view("/docs.html", DocsHTMLView) self.router.add_view("/docs.md", DocsMDView) - + self.router.add_view("/status.json",StatusView) self.router.add_view("/web.html", WebView) self.router.add_view("/login.html", LoginView) self.router.add_view("/login.json", LoginFormView) diff --git a/src/snek/docs/__pycache__/app.cpython-312.pyc b/src/snek/docs/__pycache__/app.cpython-312.pyc index 087bb64..6f355a6 100644 Binary files a/src/snek/docs/__pycache__/app.cpython-312.pyc and b/src/snek/docs/__pycache__/app.cpython-312.pyc differ diff --git a/src/snek/static/app.js b/src/snek/static/app.js index f06ee24..d8d3a8f 100644 --- a/src/snek/static/app.js +++ b/src/snek/static/app.js @@ -67,7 +67,7 @@ class Room { class InlineAppElement extends HTMLElement { constructor(){ - this. + // this. } } @@ -77,6 +77,45 @@ class Page { } +class RESTClient { + debug = true + + async get(url, params){ + params = params ? params : {} + const encodedParams = new URLSearchParams(params); + if(encodedParams) + url += '?' + encodedParams + const response = await fetch(url,{ + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + }); + const result = await response.json() + if(this.debug){ + console.debug({url:url,params:params,result:result}) + } + return result + } + async post(url, data) { + const response = await fetch(url,{ + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }); + + const result = await response.json() + if(this.debug){ + console.debug({url:url,params:params,result:result}) + } + return result + } +} + +const rest = new RESTClient() + class App { rooms = [] constructor() { @@ -84,7 +123,9 @@ class App { } + async post(url, data){ + } } \ No newline at end of file diff --git a/src/snek/static/generic-form.js b/src/snek/static/generic-form.js index a47c6db..e775bf4 100644 --- a/src/snek/static/generic-form.js +++ b/src/snek/static/generic-form.js @@ -282,8 +282,10 @@ class GenericForm extends HTMLElement { { const isValid = await me.validate() if(isValid){ - const isProcessed = await me.submit() - console.info({processed:isProcessed}) + const saveResult = await me.submit() + if(saveResult.redirect_url){ + window.location.pathname = saveResult.redirect_url + } } } } @@ -315,7 +317,6 @@ class GenericForm extends HTMLElement { if(!field.is_valid){ me.fields[field.name].setInvalid() me.fields[field.name].setErrors(field.errors) - console.info(field.name,"is invalid") }else{ me.fields[field.name].setValid() } @@ -323,10 +324,8 @@ class GenericForm extends HTMLElement { me.fields[field.name].updateAttributes() }) Object.values(form.fields).forEach(field=>{ - console.info(field.errors) me.fields[field.name].setErrors(field.errors) }) - console.info({XX:form}) return form['is_valid'] } async submit(){ diff --git a/src/snek/system/model.py b/src/snek/system/model.py index b41f4ba..98729b2 100644 --- a/src/snek/system/model.py +++ b/src/snek/system/model.py @@ -212,6 +212,14 @@ class DeletedField(ModelField): class UUIDField(ModelField): + @property + def value(self): + return str(self._value) + + @value.setter + def value(self,val): + self._value = str(val) + @property def initial_value(self): return str(uuid.uuid4()) diff --git a/src/snek/system/view.py b/src/snek/system/view.py index 1cf5329..8eebcb0 100644 --- a/src/snek/system/view.py +++ b/src/snek/system/view.py @@ -5,6 +5,13 @@ from snek.system.markdown import render_markdown class BaseView(web.View): + login_required = False + + async def _iter(self): + if self.login_required and not self.session.get("logged_in"): + return web.HTTPFound("/") + return await super()._iter() + @property def app(self): return self.request.app @@ -16,6 +23,10 @@ class BaseView(web.View): async def json_response(self, data): return web.json_response(data) + @property + def session(self): + return self.request.session + async def render_template(self, template_name, context=None): if template_name.endswith(".md"): response = await self.request.app.render_template( @@ -46,7 +57,8 @@ class BaseFormView(BaseView): # Pass pass if post.get("action") == "submit" and result["is_valid"]: - await self.submit(form) + result = await self.submit(form) + return await self.json_response(result) return await self.json_response(result) async def submit(self, model=None): diff --git a/src/snek/templates/base.html b/src/snek/templates/base.html index e00c886..cb8fc5d 100644 --- a/src/snek/templates/base.html +++ b/src/snek/templates/base.html @@ -4,6 +4,7 @@ {% block title %}{% endblock %} + diff --git a/src/snek/templates/web.html b/src/snek/templates/web.html index 0403e1b..5a636f0 100644 --- a/src/snek/templates/web.html +++ b/src/snek/templates/web.html @@ -3,12 +3,13 @@ - Dark Themed Chat Application + Snek +
- +