def simpleSessionRouter(): # type: () -> Tuple[sessions, errors, str, str, StubTreq] """ Construct a simple router. """ sessions = [] exceptions = [] mss = MemorySessionStore.fromAuthorizers([memoryAuthorizer]) router = Klein() token = "X-Test-Session-Token" cookie = "X-Test-Session-Cookie" sproc = SessionProcurer( mss, secureTokenHeader=b"X-Test-Session-Token", secureCookie=b"X-Test-Session-Cookie", ) @router.route("/") @inlineCallbacks def route(request): # type: (IRequest) -> Deferred try: sessions.append((yield sproc.procureSession(request))) except NoSuchSession as nss: exceptions.append(nss) returnValue(b"ok") requirer = Requirer() @requirer.prerequisite([ISession]) def procure(request): # type: (IRequest) -> Deferred return sproc.procureSession(request) @requirer.require(router.route("/test"), simple=Authorization(ISimpleTest)) def testRoute(simple): # type: (SimpleTest) -> str return "ok: " + str(simple.doTest() + 4) @requirer.require(router.route("/denied"), nope=Authorization(IDenyMe)) def testDenied(nope): # type: (IDenyMe) -> str return "bad" treq = StubTreq(router.resource()) return sessions, exceptions, token, cookie, treq
def simpleFormRouter() -> Tuple[Klein, List[Tuple[str, int]]]: """ Create a simple router hooked up to a field handler. """ router = Klein() requirer = Requirer() calls = [] @requirer.require( router.route("/getme", methods=["GET"]), name=Field.text(), value=Field.number(), custom=Field(formInputType="number", converter=int, required=False), ) def justGet(name: str, value: int, custom: int) -> bytes: calls.append((name, value or custom)) return b"got" return router, calls
def simpleFormRouter(): # type: () -> Tuple[Klein, List[Tuple[str, int]]] """ Create a simple router hooked up to a field handler. """ router = Klein() requirer = Requirer() calls = [] @requirer.require( router.route("/getme", methods=['GET']), name=Field.text(), value=Field.number(), custom=Field(formInputType='number', converter=int, required=False), ) def justGet(name, value, custom): # type: (str, int, int) -> bytes calls.append((name, value or custom)) return b'got' return router, calls
class TestObject(object): sessionStore = attr.ib(type=ISessionStore) calls = attr.ib(attr.Factory(list), type=List) router = Klein() requirer = Requirer() @requirer.prerequisite([ISession]) @inlineCallbacks def procureASession(self, request): # type: (IRequest) -> Any try: yield (SessionProcurer( self.sessionStore, secureTokenHeader=b"X-Test-Session").procureSession(request)) except NoSuchSession: # Intentionally slightly buggy - if a session can't be procured, # simply leave it out and rely on checkCSRF to ensure the session # component is present before proceeding. pass @requirer.require( router.route("/dangling-param", methods=["POST"]), dangling=DanglingField(lambda x: x, "text"), ) def danglingParameter(self, dangling): # type: (str) -> None "..." @requirer.require( router.route("/handle", methods=["POST"]), name=Field.text(), value=Field.number(), ) def handler(self, name, value): # type: (Text, float) -> bytes self.calls.append((name, value)) return b"yay" @requirer.require( router.route("/handle-submit", methods=["POST"]), name=Field.text(), button=Field.submit("OK"), ) def handlerWithSubmit(self, name, button): # type: (str, str) -> None """ Form with a submit button. """ @requirer.require(router.route("/password-field", methods=["POST"]), pw=Field.password()) def gotPassword(self, pw): # type: (Text) -> bytes self.calls.append(("password", pw)) return b"password received" @requirer.require( router.route("/notrequired", methods=["POST"]), name=Field.text(), value=Field.number(required=False, default=7.0), ) def notRequired(self, name, value): # type: (IRequest, Text, float) -> bytes self.calls.append((name, value)) return b"okay" @requirer.require( router.route("/constrained", methods=["POST"]), goldilocks=Field.number(minimum=3, maximum=9), ) def constrained(self, goldilocks): # type: (int) -> bytes self.calls.append(("constrained", goldilocks)) return b"got it" @requirer.require( router.route("/render", methods=["GET"]), form=Form.rendererFor(handler, action="/handle"), ) def renderer(self, form): # type: (IRequest, Form) -> Form return form @requirer.require( router.route("/render-submit", methods=["GET"]), form=Form.rendererFor(handlerWithSubmit, action="/handle-submit"), ) def submitRenderer(self, form): # type: (IRequest, RenderableForm) -> RenderableForm return form @requirer.require( router.route("/render-custom", methods=["GET"]), form=Form.rendererFor(handler, action="/handle"), ) def customFormRender(self, form): # type: (RenderableForm) -> Any """ Include just the glue necessary for CSRF protection and let the application render the rest of the form. """ return Element(loader=TagLoader(tags.html(tags.body(form.glue())))) @requirer.require( router.route("/render-cascade", methods=["GET"]), form=Form.rendererFor(handler, action="/handle"), ) def cascadeRenderer(self, form): # type: (RenderableForm) -> RenderableForm class CustomElement(Element): @renderer def customize(self, request, tag): # type: (IRequest, Any) -> Any return tag("customized") form.validationErrors[form._form.fields[0]] = ValidationError( message=(tags.div(class_="checkme", render="customize"))) return CustomElement(loader=TagLoader(form)) @requirer.require( router.route("/handle-validation", methods=["POST"]), value=Field.number(maximum=10), ) def customValidation(self, value): # type: (int) -> None """ never called. """ @requirer.require(Form.onValidationFailureFor(customValidation)) def customFailureHandling(self, values): # type: (RenderableForm) -> bytes """ Handle validation failure. """ self.calls.append(("validation", values)) return b"~special~" @requirer.require( router.route("/handle-empty", methods=["POST"]), ) def emptyHandler(self): # type: () -> bytes """ Empty form handler; just for testing rendering. """ @requirer.require( router.route("/render-empty", methods=["GET"]), form=Form.rendererFor(emptyHandler, action="/handle-empty"), ) def emptyRenderer(self, form): # type: (RenderableForm) -> RenderableForm return form
from twisted.web.template import slot, tags from klein import Field, Form, Klein, Plating, Requirer, SessionProcurer from klein.interfaces import ISession from klein.storage.memory import MemorySessionStore app = Klein() sessions = MemorySessionStore() requirer = Requirer() @requirer.prerequisite([ISession]) def procurer(request): return SessionProcurer(sessions).procureSession(request) style = Plating(tags=tags.html(tags.head(tags.title("yay")), tags.body(tags.div(slot(Plating.CONTENT))))) @requirer.require( style.routed( app.route("/", methods=["POST"]), tags.h1("u did it: ", slot("an-form-arg")), ), foo=Field.number(minimum=3, maximum=10), bar=Field.text(), ) def postHandler(foo, bar):
from twisted.web.template import tags, slot from klein import Klein, Plating, Form, Field, Requirer, SessionProcurer from klein.interfaces import ISession from klein.storage.memory import MemorySessionStore app = Klein() sessions = MemorySessionStore() requirer = Requirer() @requirer.prerequisite([ISession]) def procurer(request): return SessionProcurer(sessions).procureSession(request) style = Plating(tags=tags.html( tags.head(tags.title("yay")), tags.body(tags.div(slot(Plating.CONTENT)))) ) @style.routed( requirer.require( app.route("/", methods=["POST"]), foo=Field.integer(minimum=3, maximum=10), bar=Field.text(), ), tags.h1('u did it: ', slot("an-form-arg")) ) def postHandler(foo, bar): return {"an-form-arg": foo}