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