Added session support.
This commit is contained in:
		
							parent
							
								
									dae877113c
								
							
						
					
					
						commit
						5c69e14d7c
					
				
							
								
								
									
										0
									
								
								cache/crc321300331366.cache
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								cache/crc321300331366.cache
									
									
									
									
										vendored
									
									
								
							
							
								
								
									
										0
									
								
								cache/crc322507170282.cache
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								cache/crc322507170282.cache
									
									
									
									
										vendored
									
									
								
							| @ -21,7 +21,8 @@ dependencies = [ | |||||||
|     "gunicorn", |     "gunicorn", | ||||||
|     "imgkit", |     "imgkit", | ||||||
|     "wkhtmltopdf", |     "wkhtmltopdf", | ||||||
|     "jinja-markdown2", |     "mistune", | ||||||
|     "mistune" |     "aiohttp-session", | ||||||
|  |     "cryptography" | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,8 +17,23 @@ from snek.view.login import LoginView | |||||||
| from snek.view.login_form import LoginFormView | from snek.view.login_form import LoginFormView | ||||||
| from snek.view.register import RegisterView | from snek.view.register import RegisterView | ||||||
| from snek.view.register_form import RegisterFormView | from snek.view.register_form import RegisterFormView | ||||||
|  | from snek.view.status import StatusView | ||||||
| from snek.view.web import WebView | 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): | class Application(BaseApplication): | ||||||
| 
 | 
 | ||||||
| @ -31,10 +46,13 @@ class Application(BaseApplication): | |||||||
|         super().__init__( |         super().__init__( | ||||||
|             middlewares=middlewares, template_path=self.template_path, *args, **kwargs |             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.jinja2_env.add_extension(MarkdownExtension) | ||||||
|         self.setup_router() |         self.setup_router() | ||||||
|         self.setup_services() |         self.setup_services() | ||||||
| 
 | 
 | ||||||
|  |      | ||||||
|     def setup_services(self): |     def setup_services(self): | ||||||
|         self.services = SimpleNamespace(**get_services(app=self)) |         self.services = SimpleNamespace(**get_services(app=self)) | ||||||
|         self.mappers = SimpleNamespace(**get_mappers(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("/about.md", AboutMDView) | ||||||
|         self.router.add_view("/docs.html", DocsHTMLView) |         self.router.add_view("/docs.html", DocsHTMLView) | ||||||
|         self.router.add_view("/docs.md", DocsMDView) |         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("/web.html", WebView) | ||||||
|         self.router.add_view("/login.html", LoginView) |         self.router.add_view("/login.html", LoginView) | ||||||
|         self.router.add_view("/login.json", LoginFormView) |         self.router.add_view("/login.json", LoginFormView) | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							| @ -67,7 +67,7 @@ class Room { | |||||||
| class InlineAppElement extends HTMLElement { | class InlineAppElement extends HTMLElement { | ||||||
|      |      | ||||||
|     constructor(){ |     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 { | class App { | ||||||
|     rooms = [] |     rooms = [] | ||||||
|     constructor() { |     constructor() { | ||||||
| @ -84,7 +123,9 @@ class App { | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|  |     async post(url, data){ | ||||||
| 
 | 
 | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| @ -282,8 +282,10 @@ class GenericForm extends HTMLElement { | |||||||
|               { |               { | ||||||
|                 const isValid = await me.validate() |                 const isValid = await me.validate() | ||||||
|                 if(isValid){ |                 if(isValid){ | ||||||
|                   const isProcessed = await me.submit() |                   const saveResult = await me.submit() | ||||||
|                   console.info({processed:isProcessed}) |                   if(saveResult.redirect_url){ | ||||||
|  |                     window.location.pathname = saveResult.redirect_url | ||||||
|  |                   } | ||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
| @ -315,7 +317,6 @@ class GenericForm extends HTMLElement { | |||||||
|         if(!field.is_valid){ |         if(!field.is_valid){ | ||||||
|           me.fields[field.name].setInvalid() |           me.fields[field.name].setInvalid() | ||||||
|           me.fields[field.name].setErrors(field.errors) |           me.fields[field.name].setErrors(field.errors) | ||||||
|           console.info(field.name,"is invalid") |  | ||||||
|         }else{ |         }else{ | ||||||
|           me.fields[field.name].setValid() |           me.fields[field.name].setValid() | ||||||
|         } |         } | ||||||
| @ -323,10 +324,8 @@ class GenericForm extends HTMLElement { | |||||||
|         me.fields[field.name].updateAttributes() |         me.fields[field.name].updateAttributes() | ||||||
|       }) |       }) | ||||||
|       Object.values(form.fields).forEach(field=>{ |       Object.values(form.fields).forEach(field=>{ | ||||||
|         console.info(field.errors) |  | ||||||
|         me.fields[field.name].setErrors(field.errors) |         me.fields[field.name].setErrors(field.errors) | ||||||
|       }) |       }) | ||||||
|       console.info({XX:form}) |  | ||||||
|       return form['is_valid'] |       return form['is_valid'] | ||||||
|     } |     } | ||||||
|     async submit(){ |     async submit(){ | ||||||
|  | |||||||
| @ -212,6 +212,14 @@ class DeletedField(ModelField): | |||||||
| 
 | 
 | ||||||
| class UUIDField(ModelField): | class UUIDField(ModelField): | ||||||
| 
 | 
 | ||||||
|  |     @property | ||||||
|  |     def value(self): | ||||||
|  |         return str(self._value) | ||||||
|  |      | ||||||
|  |     @value.setter | ||||||
|  |     def value(self,val): | ||||||
|  |          self._value = str(val) | ||||||
|  | 
 | ||||||
|     @property |     @property | ||||||
|     def initial_value(self): |     def initial_value(self): | ||||||
|         return str(uuid.uuid4()) |         return str(uuid.uuid4()) | ||||||
|  | |||||||
| @ -5,6 +5,13 @@ from snek.system.markdown import render_markdown | |||||||
| 
 | 
 | ||||||
| class BaseView(web.View): | 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 |     @property | ||||||
|     def app(self): |     def app(self): | ||||||
|         return self.request.app |         return self.request.app | ||||||
| @ -16,6 +23,10 @@ class BaseView(web.View): | |||||||
|     async def json_response(self, data): |     async def json_response(self, data): | ||||||
|         return web.json_response(data) |         return web.json_response(data) | ||||||
| 
 | 
 | ||||||
|  |     @property  | ||||||
|  |     def session(self): | ||||||
|  |         return self.request.session | ||||||
|  | 
 | ||||||
|     async def render_template(self, template_name, context=None): |     async def render_template(self, template_name, context=None): | ||||||
|         if template_name.endswith(".md"): |         if template_name.endswith(".md"): | ||||||
|             response = await self.request.app.render_template( |             response = await self.request.app.render_template( | ||||||
| @ -46,7 +57,8 @@ class BaseFormView(BaseView): | |||||||
|             # Pass |             # Pass | ||||||
|             pass |             pass | ||||||
|         if post.get("action") == "submit" and result["is_valid"]: |         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) |         return await self.json_response(result) | ||||||
| 
 | 
 | ||||||
|     async def submit(self, model=None): |     async def submit(self, model=None): | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ | |||||||
|   <meta charset="UTF-8"> |   <meta charset="UTF-8"> | ||||||
|   <meta name="viewport" content="width=device-width, initial-scale=1.0"> |   <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|   <title>{% block title %}{% endblock %}</title> |   <title>{% block title %}{% endblock %}</title> | ||||||
|  |   <script src="/app.js"></script> | ||||||
|   <style>{{ highlight_styles }}</style> |   <style>{{ highlight_styles }}</style> | ||||||
|   <link rel="stylesheet" href="/style.css"> |   <link rel="stylesheet" href="/style.css"> | ||||||
|    <script src="/fancy-button.js"></script> |    <script src="/fancy-button.js"></script> | ||||||
|  | |||||||
| @ -3,12 +3,13 @@ | |||||||
| <head> | <head> | ||||||
|   <meta charset="UTF-8"> |   <meta charset="UTF-8"> | ||||||
|   <meta name="viewport" content="width=device-width, initial-scale=1.0"> |   <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|   <title>Dark Themed Chat Application</title> |   <title>Snek</title> | ||||||
|  |   <script src="/app.js"></script> | ||||||
|   <link rel="stylesheet" href="base.css"> |   <link rel="stylesheet" href="base.css"> | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
|   <header> |   <header> | ||||||
|     <div class="logo">Molodetz Chat</div> |     <div class="logo">Snek</div> | ||||||
|     <nav> |     <nav> | ||||||
|       <a href="#">Home</a> |       <a href="#">Home</a> | ||||||
|       <a href="#">Rooms</a> |       <a href="#">Rooms</a> | ||||||
|  | |||||||
| @ -9,4 +9,8 @@ class RegisterFormView(BaseFormView): | |||||||
|         result = await self.app.services.user.register( |         result = await self.app.services.user.register( | ||||||
|             form.email.value, form.username.value, form.password.value |             form.email.value, form.username.value, form.password.value | ||||||
|         ) |         ) | ||||||
|         print("SUBMITTED:", result) |         self.request.session["uid"] = result['uid'] | ||||||
|  |         self.request.session["username"] = result['usernmae'] | ||||||
|  |         self.request.session["logged_in"] = True | ||||||
|  | 
 | ||||||
|  |         return dict(redirect_url="/web.html") | ||||||
|  | |||||||
| @ -3,5 +3,7 @@ from snek.system.view import BaseView | |||||||
| 
 | 
 | ||||||
| class WebView(BaseView): | class WebView(BaseView): | ||||||
| 
 | 
 | ||||||
|  |     login_required = True | ||||||
|  | 
 | ||||||
|     async def get(self): |     async def get(self): | ||||||
|         return await self.render_template("web.html") |         return await self.render_template("web.html") | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user