
3 changed files with 148 additions and 0 deletions
@ -0,0 +1,18 @@ |
|||||||
|
""" schemas package """ |
||||||
|
|
||||||
|
from deform import Form |
||||||
|
from pkg_resources import resource_filename |
||||||
|
|
||||||
|
|
||||||
|
def includeme(config): |
||||||
|
""" Defining form templates overrides |
||||||
|
|
||||||
|
Activate this setup using ``config.include('ordr3.schemas')``. |
||||||
|
""" |
||||||
|
# this allows to use the request object like this: |
||||||
|
# request.flash(channel, message, description) |
||||||
|
ordr_templates = resource_filename("ordr3", "templates/deform") |
||||||
|
deform_templates = resource_filename("deform", "templates") |
||||||
|
search_path = (ordr_templates, deform_templates) |
||||||
|
# search_path = (ordr_templates, ) |
||||||
|
Form.set_zpt_renderer(search_path) |
@ -0,0 +1,81 @@ |
|||||||
|
""" Schemas for form input and validation """ |
||||||
|
|
||||||
|
import deform |
||||||
|
import colander |
||||||
|
|
||||||
|
from .base import CSRFSchema |
||||||
|
|
||||||
|
|
||||||
|
@colander.deferred |
||||||
|
def deferred_unique_username_validator(node, kw): |
||||||
|
""" checks if an username is not registered already """ |
||||||
|
|
||||||
|
def validate_unique_username(node, value): |
||||||
|
request = kw.get("request") |
||||||
|
try: |
||||||
|
request.repo.get_user_by_username(value) |
||||||
|
raise colander.Invalid(node, "User name already registered") |
||||||
|
except StopIteration: |
||||||
|
pass |
||||||
|
|
||||||
|
return validate_unique_username |
||||||
|
|
||||||
|
|
||||||
|
@colander.deferred |
||||||
|
def deferred_unique_email_validator(node, kw): |
||||||
|
""" checks if an email is not registered already """ |
||||||
|
email_validator = colander.Email() |
||||||
|
|
||||||
|
def validate_unique_email(node, value): |
||||||
|
email_validator(node, value) # raises exception on invalid address |
||||||
|
request = kw.get("request") |
||||||
|
try: |
||||||
|
request.repo.get_user_by_email(value) |
||||||
|
raise colander.Invalid(node, "Email address in use") |
||||||
|
except StopIteration: |
||||||
|
pass |
||||||
|
|
||||||
|
return validate_unique_email |
||||||
|
|
||||||
|
|
||||||
|
class RegistrationSchema(CSRFSchema): |
||||||
|
""" new user registration """ |
||||||
|
|
||||||
|
user_name = colander.SchemaNode( |
||||||
|
colander.String(), |
||||||
|
widget=deform.widget.TextInputWidget( |
||||||
|
template="textinput_disabled.pt", css_class="o3-reg-username" |
||||||
|
), |
||||||
|
description="automagically generated for you", |
||||||
|
validator=deferred_unique_username_validator, |
||||||
|
) |
||||||
|
first_name = colander.SchemaNode( |
||||||
|
colander.String(), |
||||||
|
widget=deform.widget.TextInputWidget( |
||||||
|
css_class="o3-reg-firstname o3-reg-username-source" |
||||||
|
), |
||||||
|
) |
||||||
|
last_name = colander.SchemaNode( |
||||||
|
colander.String(), |
||||||
|
widget=deform.widget.TextInputWidget( |
||||||
|
css_class="o3-reg-lastname o3-reg-username-source" |
||||||
|
), |
||||||
|
) |
||||||
|
email = colander.SchemaNode( |
||||||
|
colander.String(), |
||||||
|
validator=deferred_unique_email_validator, |
||||||
|
widget=deform.widget.TextInputWidget(template="email.pt",), |
||||||
|
) |
||||||
|
password = colander.SchemaNode( |
||||||
|
colander.String(), |
||||||
|
widget=deform.widget.PasswordWidget(template="viewable_password.pt"), |
||||||
|
) |
||||||
|
|
||||||
|
@classmethod |
||||||
|
def as_form(cls, request, **override): |
||||||
|
settings = { |
||||||
|
"buttons": ("Create Account", "Cancel"), |
||||||
|
"css_class": "form-horizontal registration", |
||||||
|
} |
||||||
|
settings.update(override) |
||||||
|
return super().as_form(request, **settings) |
@ -0,0 +1,49 @@ |
|||||||
|
""" Schemas for form input and validation """ |
||||||
|
|
||||||
|
import deform |
||||||
|
import colander |
||||||
|
from pyramid.csrf import get_csrf_token, check_csrf_token |
||||||
|
|
||||||
|
|
||||||
|
@colander.deferred |
||||||
|
def deferred_csrf_default(node, kw): |
||||||
|
""" sets the current csrf token """ |
||||||
|
request = kw.get("request") |
||||||
|
return get_csrf_token(request) |
||||||
|
|
||||||
|
|
||||||
|
@colander.deferred |
||||||
|
def deferred_csrf_validator(node, kw): |
||||||
|
""" validates a submitted csrf token """ |
||||||
|
|
||||||
|
def validate_csrf(node, value): |
||||||
|
request = kw.get("request") |
||||||
|
if not check_csrf_token(request, raises=False): |
||||||
|
raise colander.Invalid(node, "Bad CSRF token") |
||||||
|
|
||||||
|
return validate_csrf |
||||||
|
|
||||||
|
|
||||||
|
# Base Schema |
||||||
|
|
||||||
|
|
||||||
|
class CSRFSchema(colander.Schema): |
||||||
|
""" base class for schemas with csrf validation """ |
||||||
|
|
||||||
|
csrf_token = colander.SchemaNode( |
||||||
|
colander.String(), |
||||||
|
default=deferred_csrf_default, |
||||||
|
validator=deferred_csrf_validator, |
||||||
|
widget=deform.widget.HiddenWidget(), |
||||||
|
) |
||||||
|
|
||||||
|
@classmethod |
||||||
|
def as_form(cls, request, **kwargs): |
||||||
|
""" returns the schema as a form """ |
||||||
|
url = kwargs.pop("url", None) |
||||||
|
if not url: |
||||||
|
url = request.resource_url(request.context, request.view_name) |
||||||
|
schema = cls().bind(request=request) |
||||||
|
settings = {"template": "form.pt"} |
||||||
|
settings.update(kwargs) |
||||||
|
return deform.Form(schema, action=url, **settings) |
Loading…
Reference in new issue