From 42bc93f66ecd585ecdda5de089304b0f61f95336 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 26 Apr 2008 05:49:41 -0500 Subject: [PATCH] Start page flow code --- extra/http/server/auth/login/login.factor | 14 ++--- .../server/boilerplate/boilerplate.factor | 3 + extra/http/server/db/db.factor | 4 +- extra/http/server/flows/flows.factor | 50 +++++++++++++++++ extra/http/server/server.factor | 13 ++++- .../server/sessions/sessions-tests.factor | 6 +- extra/http/server/sessions/sessions.factor | 56 ++++++++++--------- .../http/server/sessions/storage/db/db.factor | 17 ++++-- .../server/sessions/storage/storage.factor | 2 - .../http/server/templating/chloe/chloe.factor | 34 ++++++++--- .../factor-website/factor-website.factor | 46 +++++++-------- extra/webapps/pastebin/pastebin.xml | 2 +- extra/webapps/planet/entry-summary.xml | 2 +- extra/webapps/planet/entry.xml | 4 +- extra/webapps/planet/planet.factor | 8 ++- extra/webapps/planet/planet.xml | 2 +- extra/webapps/todo/todo.xml | 2 +- 17 files changed, 178 insertions(+), 87 deletions(-) create mode 100644 extra/http/server/flows/flows.factor diff --git a/extra/http/server/auth/login/login.factor b/extra/http/server/auth/login/login.factor index 1b6ceeb51b..413e0a3cf4 100755 --- a/extra/http/server/auth/login/login.factor +++ b/extra/http/server/auth/login/login.factor @@ -13,6 +13,7 @@ http.server.auth.providers http.server.auth.providers.null http.server.actions http.server.components +http.server.flows http.server.forms http.server.sessions http.server.boilerplate @@ -22,7 +23,6 @@ http.server.validators ; IN: http.server.auth.login QUALIFIED: smtp -SYMBOL: post-login-url SYMBOL: login-failed? TUPLE: login < dispatcher users ; @@ -60,8 +60,7 @@ M: user-saver dispose : successful-login ( user -- response ) logged-in-user sset - post-login-url sget "$login" or f - f post-login-url sset ; + "$login" end-flow ; :: ( -- action ) [let | form [ ] | @@ -155,8 +154,6 @@ SYMBOL: user-exists? "verify-password" add-field "email" add-field ; -SYMBOL: previous-page - :: ( -- action ) [let | form [ ] | @@ -196,7 +193,7 @@ SYMBOL: previous-page user-profile-changed? on - previous-page sget f + "$login" end-flow ] >>submit ] ; @@ -342,14 +339,15 @@ TUPLE: protected responder ; C: protected +M: protected init-session* responder>> init-session* ; + : show-login-page ( -- response ) - request get request-url post-login-url sset + begin-flow "$login/login" f ; M: protected call-responder ( path responder -- response ) logged-in-user sget dup [ save-user-after - request get request-url previous-page sset responder>> call-responder ] [ 3drop diff --git a/extra/http/server/boilerplate/boilerplate.factor b/extra/http/server/boilerplate/boilerplate.factor index eabcefeb7f..bfa79e1a4e 100644 --- a/extra/http/server/boilerplate/boilerplate.factor +++ b/extra/http/server/boilerplate/boilerplate.factor @@ -5,6 +5,7 @@ io io.streams.string arrays html.elements http http.server +http.server.sessions http.server.templating ; IN: http.server.boilerplate @@ -12,6 +13,8 @@ TUPLE: boilerplate responder template ; : f boilerplate boa ; +M: boilerplate init-session* responder>> init-session* ; + SYMBOL: title : set-title ( string -- ) diff --git a/extra/http/server/db/db.factor b/extra/http/server/db/db.factor index a8b929bc98..0e08705fa8 100755 --- a/extra/http/server/db/db.factor +++ b/extra/http/server/db/db.factor @@ -1,11 +1,13 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: db http.server kernel accessors +USING: db http.server http.server.sessions kernel accessors continuations namespaces destructors ; IN: http.server.db TUPLE: db-persistence responder db params ; +M: db-persistence init-session* responder>> init-session* ; + C: db-persistence : connect-db ( db-persistence -- ) diff --git a/extra/http/server/flows/flows.factor b/extra/http/server/flows/flows.factor new file mode 100644 index 0000000000..f6e8d051ce --- /dev/null +++ b/extra/http/server/flows/flows.factor @@ -0,0 +1,50 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors namespaces sequences arrays kernel +assocs assocs.lib hashtables math.parser +html.elements http http.server http.server.sessions ; +IN: http.server.flows + +TUPLE: flows responder ; + +C: flows + +: begin-flow* ( -- id ) + request get [ path>> ] [ query>> ] bi 2array + flows sget set-at-unique + session-changed ; + +: end-flow* ( default id -- response ) + flows sget at [ first2 ] [ f ] ?if ; + +SYMBOL: flow-id + +: flow-id-key "factorflowid" ; + +: begin-flow ( -- ) + begin-flow* flow-id set ; + +: end-flow ( default -- response ) + flow-id get end-flow* ; + +: add-flow-id ( query -- query' ) + flow-id get [ flow-id-key associate assoc-union ] when* ; + +: flow-form-field ( -- ) + flow-id get [ + + ] when* ; + +M: flows call-responder + [ add-flow-id ] add-link-hook + [ flow-form-field ] add-form-hook + flow-id-key request-params at flow-id set + responder>> call-responder ; + +M: flows init-session* + H{ } clone flows sset + responder>> init-session* ; diff --git a/extra/http/server/server.factor b/extra/http/server/server.factor index 88a748d949..e51cb70de5 100755 --- a/extra/http/server/server.factor +++ b/extra/http/server/server.factor @@ -69,8 +69,11 @@ SYMBOL: base-paths SYMBOL: link-hook +: add-link-hook ( quot -- ) + link-hook [ compose ] change ; inline + : modify-query ( query -- query ) - link-hook get [ ] or call ; + link-hook get call ; : base-path ( string -- path ) dup base-paths get at @@ -93,8 +96,11 @@ SYMBOL: link-hook SYMBOL: form-hook +: add-form-hook ( quot -- ) + form-hook [ compose ] change ; + : hidden-form-field ( -- ) - form-hook get [ ] or call ; + form-hook get call ; : absolute-redirect ( to query -- url ) #! Same host. @@ -226,6 +232,9 @@ SYMBOL: exit-continuation : do-request ( request -- response ) [ H{ } clone base-paths set + [ ] link-hook set + [ ] form-hook set + [ log-request ] [ request set ] [ path>> split-path main-responder get call-responder ] tri diff --git a/extra/http/server/sessions/sessions-tests.factor b/extra/http/server/sessions/sessions-tests.factor index 4d8c93ef67..85adf7e69f 100755 --- a/extra/http/server/sessions/sessions-tests.factor +++ b/extra/http/server/sessions/sessions-tests.factor @@ -3,7 +3,7 @@ USING: tools.test http http.server.sessions http.server.sessions.storage http.server.sessions.storage.db http.server.actions http.server math namespaces kernel accessors prettyprint io.streams.string io.files splitting destructors -sequences db db.sqlite ; +sequences db db.sqlite continuations ; : with-session [ @@ -49,8 +49,12 @@ M: foo call-responder "text/plain" exit-with ] >>display ; +[ "auth-test.db" temp-file sqlite-db delete-file ] ignore-errors + "auth-test.db" temp-file sqlite-db [ + init-sessions-table + [ empty-session 123 >>id session set diff --git a/extra/http/server/sessions/sessions.factor b/extra/http/server/sessions/sessions.factor index 5d0113b225..96d1c3beca 100755 --- a/extra/http/server/sessions/sessions.factor +++ b/extra/http/server/sessions/sessions.factor @@ -10,11 +10,7 @@ http.server.sessions.storage.null html.elements ; IN: http.server.sessions -! ! ! ! ! ! -! WARNING: this session manager is vulnerable to XSRF attacks -! ! ! ! ! ! - -TUPLE: session id user-agent client-addr namespace ; +TUPLE: session id expiry namespace changed? ; : ( id -- session ) session new @@ -24,6 +20,8 @@ GENERIC: init-session* ( responder -- ) M: object init-session* drop ; +M: dispatcher init-session* default>> init-session* ; + TUPLE: session-manager responder sessions ; : new-session-manager ( responder class -- responder' ) @@ -31,18 +29,23 @@ TUPLE: session-manager responder sessions ; null-sessions >>sessions swap >>responder ; inline -SYMBOL: session-changed? +: (session-changed) ( session -- ) + t >>changed? drop ; + +: session-changed ( -- ) + session get (session-changed) ; : sget ( key -- value ) session get namespace>> at ; : sset ( value key -- ) - session get namespace>> set-at - session-changed? on ; + session get + [ namespace>> set-at ] [ (session-changed) ] bi ; : schange ( key quot -- ) - session get namespace>> swap change-at - session-changed? on ; inline + session get + [ namespace>> swap change-at ] keep + (session-changed) ; inline : sessions session-manager get sessions>> ; @@ -51,11 +54,18 @@ SYMBOL: session-changed? : init-session ( session managed -- ) >r session r> '[ , init-session* ] with-variable ; +: timeout 20 minutes ; + +: cutoff-time ( -- time ) + now timeout time+ timestamp>millis ; + +: touch-session ( session -- ) + cutoff-time >>expiry drop ; + : empty-session ( -- session ) f - "" >>user-agent - "" >>client-addr - H{ } clone >>namespace ; + H{ } clone >>namespace + dup touch-session ; : begin-session ( responder -- session ) >r empty-session r> @@ -70,8 +80,9 @@ TUPLE: session-saver session ; C: session-saver M: session-saver dispose - session-changed? get - [ session>> sessions update-session ] [ drop ] if ; + session>> dup changed?>> [ + [ touch-session ] [ sessions update-session ] bi + ] [ drop ] if ; : save-session-after ( session -- ) add-always-destructor ; @@ -80,14 +91,6 @@ M: session-saver dispose [ save-session-after ] [ session set ] bi [ session-manager set ] [ responder>> call-responder ] bi ; -TUPLE: null-sessions < session-manager ; - -: ( responder -- manager ) - null-sessions new-session-manager ; - -M: null-sessions call-responder ( path responder -- response ) - call-responder/session ; - TUPLE: url-sessions < session-manager ; : ( responder -- responder' ) @@ -105,9 +108,8 @@ TUPLE: url-sessions < session-manager ; : session-form-field ( -- ) > =value + session get id>> number>string =value input/> ; : new-url-session ( path responder -- response ) @@ -115,8 +117,8 @@ TUPLE: url-sessions < session-manager ; ; M: url-sessions call-responder ( path responder -- response ) - [ add-session-id ] link-hook set - [ session-form-field ] form-hook set + [ add-session-id ] add-link-hook + [ session-form-field ] add-form-hook dup current-url-session [ call-responder/session ] [ diff --git a/extra/http/server/sessions/storage/db/db.factor b/extra/http/server/sessions/storage/db/db.factor index bddb783c97..637d86670f 100755 --- a/extra/http/server/sessions/storage/db/db.factor +++ b/extra/http/server/sessions/storage/db/db.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: assocs accessors kernel http.server.sessions.storage -http.server.sessions http.server db.tuples db.types math.parser -classes.singleton random ; +http.server.sessions http.server db db.tuples db.types math.parser +math.intervals fry random calendar sequences alarms ; IN: http.server.sessions.storage.db SINGLETON: sessions-in-db @@ -11,8 +11,7 @@ session "SESSIONS" { ! { "id" "ID" +random-id+ system-random-generator } { "id" "ID" INTEGER +native-id+ } - { "user-agent" "USERAGENT" { VARCHAR 256 } +not-null+ } - { "client-addr" "CLIENTADDR" { VARCHAR 256 } +not-null+ } + { "expiry" "EXPIRY" BIG-INTEGER +not-null+ } { "namespace" "NAMESPACE" FACTOR-BLOB } } define-persistent @@ -29,3 +28,13 @@ M: sessions-in-db delete-session ( id storage -- ) M: sessions-in-db new-session ( session storage -- ) drop insert-tuple ; + +: expired-sessions ( -- session ) + f + USE: math now timestamp>millis [ 60 60 * 1000 * - ] keep [a,b] >>expiry + select-tuples ; + +: start-expiring-sessions ( db seq -- ) + '[ + , , [ expired-sessions [ delete-tuple ] each ] with-db + ] 5 minutes every drop ; diff --git a/extra/http/server/sessions/storage/storage.factor b/extra/http/server/sessions/storage/storage.factor index 97d869e60a..c605600f7b 100755 --- a/extra/http/server/sessions/storage/storage.factor +++ b/extra/http/server/sessions/storage/storage.factor @@ -3,8 +3,6 @@ USING: calendar ; IN: http.server.sessions.storage -: timeout 20 minutes ; - GENERIC: get-session ( id storage -- session ) GENERIC: update-session ( session storage -- ) diff --git a/extra/http/server/templating/chloe/chloe.factor b/extra/http/server/templating/chloe/chloe.factor index 3793604929..99d6376fe8 100644 --- a/extra/http/server/templating/chloe/chloe.factor +++ b/extra/http/server/templating/chloe/chloe.factor @@ -4,6 +4,7 @@ io io.files io.encodings.utf8 html.elements unicode.case tuple-syntax xml xml.data xml.writer xml.utilities http.server http.server.auth +http.server.flows http.server.components http.server.sessions http.server.templating @@ -83,14 +84,33 @@ SYMBOL: tags dup empty? [ drop f ] [ "," split [ dup value ] H{ } map>assoc ] if ; +: a-flow-attr ( tag -- ) + "flow" optional-attr { + { "none" [ flow-id off ] } + { "begin" [ begin-flow ] } + { "current" [ ] } + { f [ ] } + } case ; + +: a-session-attr ( tag -- ) + "session" optional-attr { + { "none" [ session off flow-id off ] } + { "current" [ ] } + { f [ ] } + } case ; + : a-start-tag ( tag -- ) - string =href - a> ; + [ + string =href + a> + ] with-scope ; : process-tag-children ( tag -- ) [ process-template ] each ; diff --git a/extra/webapps/factor-website/factor-website.factor b/extra/webapps/factor-website/factor-website.factor index d78fd4b6c2..d6ddeb32bb 100644 --- a/extra/webapps/factor-website/factor-website.factor +++ b/extra/webapps/factor-website/factor-website.factor @@ -4,6 +4,7 @@ USING: accessors kernel sequences assocs io.files io.sockets namespaces db db.sqlite smtp http.server http.server.db +http.server.flows http.server.sessions http.server.auth.login http.server.auth.providers.db @@ -20,27 +21,6 @@ IN: webapps.factor-website : factor-template ( path -- template ) "resource:extra/webapps/factor-website/" swap ".xml" 3append ; -: ( responder -- responder' ) - - users-in-db >>users - allow-registration - allow-password-recovery - allow-edit-profile - - "page" factor-template >>template - - sessions-in-db >>sessions - test-db ; - -: ( -- responder ) - ; - -: ( -- responder ) - ; - -: ( -- responder ) - ; - : init-factor-db ( -- ) test-db [ init-users-table @@ -56,9 +36,20 @@ IN: webapps.factor-website : ( -- responder ) - "todo" add-responder - "pastebin" add-responder - "planet" add-responder ; + "todo" add-responder + "pastebin" add-responder + "planet" add-responder + + users-in-db >>users + allow-registration + allow-password-recovery + allow-edit-profile + + "page" factor-template >>template + + + sessions-in-db >>sessions + test-db ; : init-factor-website ( -- ) "factorcode.org" 25 smtp-server set-global @@ -66,6 +57,9 @@ IN: webapps.factor-website init-factor-db - main-responder set-global + main-responder set-global ; - "planet" main-responder get responders>> at start-update-task ; +: start-factor-website + test-db start-expiring-sessions + "planet" main-responder get responders>> at test-db start-update-task + 8812 httpd ; diff --git a/extra/webapps/pastebin/pastebin.xml b/extra/webapps/pastebin/pastebin.xml index 2d335fe9ce..6b49162637 100644 --- a/extra/webapps/pastebin/pastebin.xml +++ b/extra/webapps/pastebin/pastebin.xml @@ -13,7 +13,7 @@ - | Edit Profile + | Edit Profile diff --git a/extra/webapps/planet/entry-summary.xml b/extra/webapps/planet/entry-summary.xml index a87703252c..905795373b 100644 --- a/extra/webapps/planet/entry-summary.xml +++ b/extra/webapps/planet/entry-summary.xml @@ -4,7 +4,7 @@


- Read More... + Read More...

diff --git a/extra/webapps/planet/entry.xml b/extra/webapps/planet/entry.xml index bc89af3263..0e52c191a5 100644 --- a/extra/webapps/planet/entry.xml +++ b/extra/webapps/planet/entry.xml @@ -3,7 +3,7 @@

- +

@@ -11,7 +11,7 @@

- +

diff --git a/extra/webapps/planet/planet.factor b/extra/webapps/planet/planet.factor index 3cd35be5fb..752db18ee7 100755 --- a/extra/webapps/planet/planet.factor +++ b/extra/webapps/planet/planet.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors sequences sorting locals math calendar alarms logging concurrency.combinators namespaces -sequences.lib db.types db.tuples db +sequences.lib db.types db.tuples db fry rss xml.writer http.server http.server.crud @@ -167,5 +167,7 @@ blog "BLOGS" "planet" planet-template >>template ; -: start-update-task ( planet -- ) - [ update-cached-postings ] curry 10 minutes every drop ; +: start-update-task ( planet db seq -- ) + '[ + , , , [ update-cached-postings ] with-db + ] 10 minutes every drop ; diff --git a/extra/webapps/planet/planet.xml b/extra/webapps/planet/planet.xml index c96a143246..328be84544 100644 --- a/extra/webapps/planet/planet.xml +++ b/extra/webapps/planet/planet.xml @@ -14,7 +14,7 @@ - | Edit Profile + | Edit Profile diff --git a/extra/webapps/todo/todo.xml b/extra/webapps/todo/todo.xml index 70bbb1250b..4e307b7cae 100644 --- a/extra/webapps/todo/todo.xml +++ b/extra/webapps/todo/todo.xml @@ -9,7 +9,7 @@ | Add Item - | Edit Profile + | Edit Profile