]> gitweb.factorcode.org Git - factor.git/commitdiff
More flexible furnace authentication; fix planet
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 13 Jun 2008 05:47:47 +0000 (00:47 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 13 Jun 2008 05:47:47 +0000 (00:47 -0500)
12 files changed:
extra/furnace/actions/actions.factor
extra/furnace/auth/login/login.factor
extra/furnace/furnace.factor
extra/http/server/redirection/redirection.factor
extra/http/server/server.factor
extra/webapps/blogs/blogs.factor
extra/webapps/blogs/posts-by.xml [new file with mode: 0644]
extra/webapps/blogs/user-posts.xml [deleted file]
extra/webapps/blogs/view-post.xml
extra/webapps/pastebin/pastebin.factor
extra/webapps/planet/planet.factor
extra/webapps/wiki/wiki.factor

index 1cef8e24e513e3d714522d48bce0de74908fecff..a2816870963ffb582662b0dad97d60fd31b8ad25 100755 (executable)
@@ -29,14 +29,10 @@ SYMBOL: rest
 \r
 CHLOE: validation-messages drop render-validation-messages ;\r
 \r
-TUPLE: action rest init display validate submit ;\r
+TUPLE: action rest authorize init display validate submit ;\r
 \r
 : new-action ( class -- action )\r
-    new\r
-        [ ] >>init\r
-        [ <400> ] >>display\r
-        [ ] >>validate\r
-        [ <400> ] >>submit ;\r
+    new [ ] >>init [ ] >>validate [ ] >>authorize ; inline\r
 \r
 : <action> ( -- action )\r
     action new-action ;\r
@@ -46,18 +42,28 @@ TUPLE: action rest init display validate submit ;
 \r
 : handle-get ( action -- response )\r
     '[\r
-        ,\r
-        [ init>> call ]\r
-        [ drop flashed-variables restore-flash ]\r
-        [ display>> call ]\r
-        tri\r
+        , dup display>> [\r
+            {\r
+                [ init>> call ]\r
+                [ authorize>> call ]\r
+                [ drop flashed-variables restore-flash ]\r
+                [ display>> call ]\r
+            } cleave\r
+        ] [ drop <400> ] if\r
     ] with-exit-continuation ;\r
 \r
 : validation-failed ( -- * )\r
     request get method>> "POST" = [ f ] [ <400> ] if exit-with ;\r
 \r
 : (handle-post) ( action -- response )\r
-    [ validate>> call ] [ submit>> call ] bi ;\r
+    '[\r
+        , dup submit>> [\r
+            [ validate>> call ]\r
+            [ authorize>> call ]\r
+            [ submit>> call ]\r
+            tri\r
+        ] [ drop <400> ] if\r
+    ] with-exit-continuation ;\r
 \r
 : param ( name -- value )\r
     params get at ;\r
index d0c4e00953a3700c5e0df37982f1aed64895a8bb..a1d2bf47c38c64fb95f3da6452ed7e1f277751ae 100755 (executable)
@@ -49,6 +49,10 @@ TUPLE: login < dispatcher users checksum ;
 \r
 TUPLE: protected < filter-responder description capabilities ;\r
 \r
+: <protected> ( responder -- protected )\r
+    protected new\r
+        swap >>responder ;\r
+\r
 : users ( -- provider )\r
     login get users>> ;\r
 \r
@@ -85,13 +89,17 @@ M: user-saver dispose
     "invalid username or password" validation-error\r
     validation-failed ;\r
 \r
+SYMBOL: description\r
+SYMBOL: capabilities\r
+\r
+: flashed-variables { description capabilities } ;\r
+\r
 : <login-action> ( -- action )\r
     <page-action>\r
         [\r
-            protected fget [\r
-                [ description>> "description" set-value ]\r
-                [ capabilities>> words>strings "capabilities" set-value ] bi\r
-            ] when*\r
+            flashed-variables restore-flash\r
+            description get "description" set-value\r
+            capabilities get words>strings "capabilities" set-value\r
         ] >>init\r
 \r
         { login "login" } >>template\r
@@ -200,7 +208,10 @@ M: user-saver dispose
             drop\r
 \r
             URL" $login" end-aside\r
-        ] >>submit ;\r
+        ] >>submit\r
+\r
+    <protected>\r
+        "edit your profile" >>description ;\r
 \r
 ! ! ! Password recovery\r
 \r
@@ -316,32 +327,36 @@ SYMBOL: lost-password-from
         ] >>submit ;\r
 \r
 ! ! ! Authentication logic\r
-: <protected> ( responder -- protected )\r
-    protected new\r
-        swap >>responder ;\r
-\r
 : show-login-page ( -- response )\r
     begin-aside\r
-    URL" $login/login" { protected } <flash-redirect> ;\r
+    protected get description>> description set\r
+    protected get capabilities>> capabilities set\r
+    URL" $login/login" flashed-variables <flash-redirect> ;\r
+\r
+: login-required ( -- * )\r
+    show-login-page exit-with ;\r
 \r
-: check-capabilities ( responder user -- ? )\r
-    [ capabilities>> ] bi@ subset? ;\r
+: have-capability? ( capability -- ? )\r
+    logged-in-user get capabilities>> member? ;\r
+\r
+: check-capabilities ( responder user/f -- ? )\r
+    dup [ [ capabilities>> ] bi@ subset? ] [ 2drop f ] if ;\r
 \r
 M: protected call-responder* ( path responder -- response )\r
     dup protected set\r
-    uid dup [\r
-        users get-user 2dup check-capabilities [\r
-            [ logged-in-user set ] [ save-user-after ] bi\r
-            call-next-method\r
-        ] [\r
-            3drop show-login-page\r
-        ] if\r
-    ] [\r
-        3drop show-login-page\r
-    ] if ;\r
+    dup logged-in-user get check-capabilities\r
+    [ call-next-method ] [ 2drop show-login-page ] if ;\r
+\r
+: init-user ( -- )\r
+    uid [\r
+        users get-user\r
+        [ logged-in-user set ]\r
+        [ save-user-after ] bi\r
+    ] when* ;\r
 \r
 M: login call-responder* ( path responder -- response )\r
     dup login set\r
+    init-user\r
     call-next-method ;\r
 \r
 : <login-boilerplate> ( responder -- responder' )\r
@@ -359,10 +374,7 @@ M: login call-responder* ( path responder -- response )
 ! ! ! Configuration\r
 \r
 : allow-edit-profile ( login -- login )\r
-    <edit-profile-action> <protected>\r
-        "edit your profile" >>description\r
-    <login-boilerplate>\r
-        "edit-profile" add-responder ;\r
+    <edit-profile-action> <login-boilerplate> "edit-profile" add-responder ;\r
 \r
 : allow-registration ( login -- login )\r
     <register-action> <login-boilerplate>\r
index 6ddd84a2545478012a3f524f1b81741e49029d6e..cdee2821b6a391f93bc5c4fa80b78e0c4bbe494e 100644 (file)
@@ -102,14 +102,15 @@ SYMBOL: exit-continuation
     [ [ "/" ?tail drop "/" ] dip present 3append ] when* ;
 
 : a-url ( tag -- url )
-    dup "value" optional-attr [ ] [
+    dup "value" optional-attr
+    [ value ] [
         <url>
             swap
             [ a-url-path >>path ]
             [ "query" optional-attr parse-query-attr >>query ]
             bi
-    ] ?if
-    adjust-url relative-to-request ;
+        adjust-url relative-to-request
+    ] ?if ;
 
 CHLOE: atom [ children>string ] [ a-url ] bi add-atom-feed ;
 
index 3cd01345aa246f35d7629396c461433a239a7e76..c1d2eaa63ae59c26d4f8728d1899a829ff3fb1b1 100644 (file)
@@ -1,10 +1,14 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel accessors combinators namespaces
+USING: kernel accessors combinators namespaces strings
 logging urls http http.server http.server.responses ;
 IN: http.server.redirection
 
-: relative-to-request ( url -- url' )
+GENERIC: relative-to-request ( url -- url' )
+
+M: string relative-to-request ;
+
+M: url relative-to-request
     request get url>>
         clone
         f >>query
index 642e9f77f09dba8f703388d01349a0bcc5ad1d4c..376889b46b65c0ee940ca3908702e403b2a72860 100755 (executable)
@@ -68,7 +68,7 @@ main-responder global [ <404> <trivial-responder> or ] change-at
             [
                 utf8 [
                     development-mode get
-                    [ http-error. ] [ drop "Response error" throw ] if
+                    [ http-error. ] [ drop "Response error" rethrow ] if
                 ] with-encoded-output
             ] recover
         ] if
index 882584f014192d8a0e98e73af1dbe77ea52b4ce4..100d4226b7849092898d3caa67bf6fc626f6fcff 100644 (file)
@@ -1,24 +1,33 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: kernel accessors sequences sorting math.order math.parser
-urls validators html.components db.types db.tuples calendar
-http.server.dispatchers
-furnace furnace.actions furnace.auth.login furnace.boilerplate
-furnace.sessions furnace.syndication ;
+urls validators html.components db db.types db.tuples calendar
+present http.server.dispatchers
+furnace
+furnace.actions
+furnace.auth
+furnace.auth.login
+furnace.boilerplate
+furnace.sessions
+furnace.syndication ;
 IN: webapps.blogs
 
 TUPLE: blogs < dispatcher ;
 
+SYMBOL: can-administer-blogs?
+
+can-administer-blogs? define-capability
+
 : view-post-url ( id -- url )
-    number>string "$blogs/post/" prepend >url ;
+    present "$blogs/post/" prepend >url ;
 
 : view-comment-url ( parent id -- url )
     [ view-post-url ] dip >>anchor ;
 
 : list-posts-url ( -- url )
-    URL" $blogs/" ;
+    "$blogs/" >url ;
 
-: user-posts-url ( author -- url )
+: posts-by-url ( author -- url )
     "$blogs/by/" prepend >url ;
 
 TUPLE: entity id author date content ;
@@ -39,7 +48,7 @@ M: entity feed-entry-date date>> ;
 TUPLE: post < entity title comments ;
 
 M: post feed-entry-title
-    [ author>> ] [ drop ": " ] [ title>> ] tri 3append ;
+    [ author>> ] [ title>> ] bi ": " swap 3append ;
 
 M: post entity-url
     id>> view-post-url ;
@@ -79,19 +88,16 @@ M: comment entity-url
     [ [ date>> ] compare invert-comparison ] sort ;
 
 : validate-author ( -- )
-    { { "author" [ [ v-username ] v-optional ] } } validate-params ;
+    { { "author" [ v-username ] } } validate-params ;
 
 : list-posts ( -- posts )
     f <post> "author" value >>author
-    select-tuples [ dup id>> f <comment> count-tuples >>comments ] map
+    select-tuples [ dup id>> f <comment> count-tuples >>comments ] map
     reverse-chronological-order ;
 
 : <list-posts-action> ( -- action )
     <page-action>
-        [
-            list-posts "posts" set-value
-        ] >>init
-
+        [ list-posts "posts" set-value ] >>init
         { blogs "list-posts" } >>template ;
 
 : <list-posts-feed-action> ( -- action )
@@ -100,21 +106,24 @@ M: comment entity-url
         [ list-posts ] >>entries
         [ list-posts-url ] >>url ;
 
-: <user-posts-action> ( -- action )
+: <posts-by-action> ( -- action )
     <page-action>
+
         "author" >>rest
+
         [
             validate-author
             list-posts "posts" set-value
         ] >>init
-        { blogs "user-posts" } >>template ;
 
-: <user-posts-feed-action> ( -- action )
+        { blogs "posts-by" } >>template ;
+
+: <posts-by-feed-action> ( -- action )
     <feed-action>
         [ validate-author ] >>init
         [ "Recent Posts by " "author" value append ] >>title
         [ list-posts ] >>entries
-        [ "author" value user-posts-url ] >>url ;
+        [ "author" value posts-by-url ] >>url ;
 
 : <post-feed-action> ( -- action )
     <feed-action>
@@ -125,6 +134,7 @@ M: comment entity-url
 
 : <view-post-action> ( -- action )
     <page-action>
+
         "id" >>rest
 
         [
@@ -147,6 +157,7 @@ M: comment entity-url
 
 : <new-post-action> ( -- action )
     <page-action>
+
         [
             validate-post
             uid "author" set-value
@@ -160,40 +171,76 @@ M: comment entity-url
             [ insert-tuple ] [ entity-url <redirect> ] bi
         ] >>submit
 
-        { blogs "new-post" } >>template ;
+        { blogs "new-post" } >>template
+
+     <protected>
+        "make a new blog post" >>description ;
+
+: authorize-author ( author -- )
+    uid = can-administer-blogs? have-capability? or
+    [ login-required ] unless ;
+
+: do-post-action ( -- )
+    validate-integer-id
+    "id" value <post> select-tuple from-object ;
 
 : <edit-post-action> ( -- action )
     <page-action>
+
         "id" >>rest
 
-        [
-            validate-integer-id
-            "id" value <post> select-tuple from-object
-        ] >>init
+        [ do-post-action ] >>init
 
-        [
-            validate-integer-id
-            validate-post
-        ] >>validate
+        [ do-post-action validate-post ] >>validate
+
+        [ "author" value authorize-author ] >>authorize
 
         [
-            "id" value <post> select-tuple
-                dup { "title" "content" } deposit-slots
+            "id" value <post>
+            dup { "title" "author" "date" "content" } deposit-slots
             [ update-tuple ] [ entity-url <redirect> ] bi
         ] >>submit
 
-        { blogs "edit-post" } >>template ;
-    
+        { blogs "edit-post" } >>template
+
+    <protected>
+        "edit a blog post" >>description ;
+
+: delete-post ( id -- )
+    [ <post> delete-tuples ] [ f <comment> delete-tuples ] bi ;
+
 : <delete-post-action> ( -- action )
     <action>
+
+        [ do-post-action ] >>validate
+
+        [ "author" value authorize-author ] >>authorize
+
         [
-            validate-integer-id
-            { { "author" [ v-username ] } } validate-params
-        ] >>validate
+            [ "id" value delete-post ] with-transaction
+            "author" value posts-by-url <redirect>
+        ] >>submit
+
+     <protected>
+        "delete a blog post" >>description ;
+
+: <delete-author-action> ( -- action )
+    <action>
+
+        [ validate-author ] >>validate
+
+        [ "author" value authorize-author ] >>authorize
+
         [
-            "id" value <post> delete-tuples
-            "author" value user-posts-url <redirect>
-        ] >>submit ;
+            [
+                f <post> "author" value >>author select-tuples [ id>> delete-post ] each
+                f f <comment> "author" value >>author delete-tuples
+            ] with-transaction
+            "author" value posts-by-url <redirect>
+        ] >>submit
+
+     <protected>
+        "delete a blog post" >>description ;
 
 : validate-comment ( -- )
     {
@@ -215,41 +262,44 @@ M: comment entity-url
                 uid >>author
                 now >>date
             [ insert-tuple ] [ entity-url <redirect> ] bi
-        ] >>submit ;
-    
+        ] >>submit
+
+     <protected>
+        "make a comment" >>description ;
+
 : <delete-comment-action> ( -- action )
     <action>
+
         [
             validate-integer-id
             { { "parent" [ v-integer ] } } validate-params
         ] >>validate
+
+        [
+            "parent" value <post> select-tuple
+            author>> authorize-author
+        ] >>authorize
+
         [
             f "id" value <comment> delete-tuples
             "parent" value view-post-url <redirect>
-        ] >>submit ;
-    
+        ] >>submit
+
+        <protected>
+            "delete a comment" >>description ;
+
 : <blogs> ( -- dispatcher )
     blogs new-dispatcher
         <list-posts-action> "" add-responder
         <list-posts-feed-action> "posts.atom" add-responder
-        <user-posts-action> "by" add-responder
-        <user-posts-feed-action> "by.atom" add-responder
+        <posts-by-action> "by" add-responder
+        <posts-by-feed-action> "by.atom" add-responder
         <view-post-action> "post" add-responder
         <post-feed-action> "post.atom" add-responder
-        <new-post-action> <protected>
-            "make a new blog post" >>description
-            "new-post" add-responder
-        <edit-post-action> <protected>
-            "edit a blog post" >>description
-            "edit-post" add-responder
-        <delete-post-action> <protected>
-            "delete a blog post" >>description
-            "delete-post" add-responder
-        <new-comment-action> <protected>
-            "make a comment" >>description
-            "new-comment" add-responder
-        <delete-comment-action> <protected>
-            "delete a comment" >>description
-            "delete-comment" add-responder
+        <new-post-action> "new-post" add-responder
+        <edit-post-action> "edit-post" add-responder
+        <delete-post-action> "delete-post" add-responder
+        <new-comment-action> "new-comment" add-responder
+        <delete-comment-action> "delete-comment" add-responder
     <boilerplate>
         { blogs "blogs-common" } >>template ;
diff --git a/extra/webapps/blogs/posts-by.xml b/extra/webapps/blogs/posts-by.xml
new file mode 100644 (file)
index 0000000..d94b598
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version='1.0' ?>
+
+<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
+
+       <t:atom t:href="$blogs/by" t:rest="author">
+               Recent Posts by <t:label t:name="author" />
+       </t:atom>
+
+       <t:title>
+               Recent Posts by <t:label t:name="author" />
+       </t:title>
+
+       <t:bind-each t:name="posts">
+
+               <h2 class="post-title">
+                       <t:a t:href="$blogs/post" t:rest="id">
+                               <t:label t:name="title" />
+                       </t:a>
+               </h2>
+
+               <p class="posting-body">
+                       <t:farkup t:name="content" />
+               </p>
+
+               <div class="posting-footer">
+                       Post by
+                       <t:a t:href="$blogs/by" t:rest="author">
+                               <t:label t:name="author" />
+                       </t:a>
+                       on
+                       <t:label t:name="date" />
+                       |
+                       <t:a t:href="$blogs/post" t:rest="id">
+                               <t:label t:name="comments" />
+                               comments.
+                       </t:a>
+               </div>
+
+       </t:bind-each>
+
+</t:chloe>
diff --git a/extra/webapps/blogs/user-posts.xml b/extra/webapps/blogs/user-posts.xml
deleted file mode 100644 (file)
index d94b598..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version='1.0' ?>
-
-<t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
-
-       <t:atom t:href="$blogs/by" t:rest="author">
-               Recent Posts by <t:label t:name="author" />
-       </t:atom>
-
-       <t:title>
-               Recent Posts by <t:label t:name="author" />
-       </t:title>
-
-       <t:bind-each t:name="posts">
-
-               <h2 class="post-title">
-                       <t:a t:href="$blogs/post" t:rest="id">
-                               <t:label t:name="title" />
-                       </t:a>
-               </h2>
-
-               <p class="posting-body">
-                       <t:farkup t:name="content" />
-               </p>
-
-               <div class="posting-footer">
-                       Post by
-                       <t:a t:href="$blogs/by" t:rest="author">
-                               <t:label t:name="author" />
-                       </t:a>
-                       on
-                       <t:label t:name="date" />
-                       |
-                       <t:a t:href="$blogs/post" t:rest="id">
-                               <t:label t:name="comments" />
-                               comments.
-                       </t:a>
-               </div>
-
-       </t:bind-each>
-
-</t:chloe>
index fae9ff3e769eb9d77c4e10da57af9e567f95a1a7..55bdd2e8067049914bc0f0ed7624ddd19144fa0c 100644 (file)
@@ -33,7 +33,7 @@
                <hr/>
 
                <p class="comment-header">
-                       Comment by <t:label t:name="author" /> on <t:label t:name="date" />:
+                       <a name="@id">Comment by <t:label t:name="author" /> on <t:label t:name="date" />:</a>
                </p>
 
                <p class="posting-body">
index 2fbe5b4816ce610a2b94007539759a8a0ce69d1c..f6b604c06da3a5cff46b97f52fa98648046bb374 100644 (file)
@@ -19,6 +19,10 @@ IN: webapps.pastebin
 
 TUPLE: pastebin < dispatcher ;
 
+SYMBOL: can-delete-pastes?
+
+can-delete-pastes? define-capability
+
 ! ! !
 ! DOMAIN MODEL
 ! ! !
@@ -170,13 +174,20 @@ M: annotation entity-url
 
 : <delete-paste-action> ( -- action )
     <action>
+
         [ validate-integer-id ] >>validate
 
         [
-            "id" value <paste> delete-tuples
-            "id" value f <annotation> delete-tuples
+            [
+                "id" value <paste> delete-tuples
+                "id" value f <annotation> delete-tuples
+            ] with-transaction
             URL" $pastebin/list" <redirect>
-        ] >>submit ;
+        ] >>submit
+
+        <protected>
+            "delete pastes" >>description
+            { can-delete-pastes? } >>capabilities ;
 
 ! ! !
 ! ANNOTATIONS
@@ -199,6 +210,7 @@ M: annotation entity-url
 
 : <delete-annotation-action> ( -- action )
     <action>
+
         [ { { "id" [ v-number ] } } validate-params ] >>validate
 
         [
@@ -206,11 +218,11 @@ M: annotation entity-url
             [ delete-tuples ]
             [ parent>> paste-url <redirect> ]
             bi
-        ] >>submit ;
+        ] >>submit
 
-SYMBOL: can-delete-pastes?
-
-can-delete-pastes? define-capability
+    <protected>
+        "delete annotations" >>description
+        { can-delete-pastes? } >>capabilities ;
 
 : <pastebin> ( -- responder )
     pastebin new-dispatcher
@@ -219,13 +231,9 @@ can-delete-pastes? define-capability
         <paste-action> "paste" add-responder
         <paste-feed-action> "paste.atom" add-responder
         <new-paste-action> "new-paste" add-responder
-        <delete-paste-action> <protected>
-            "delete pastes" >>description
-            { can-delete-pastes? } >>capabilities "delete-paste" add-responder
+        <delete-paste-action> "delete-paste" add-responder
         <new-annotation-action> "new-annotation" add-responder
-        <delete-annotation-action> <protected>
-            "delete annotations" >>description
-            { can-delete-pastes? } >>capabilities "delete-annotation" add-responder
+        <delete-annotation-action> "delete-annotation" add-responder
     <boilerplate>
         { pastebin "pastebin-common" } >>template ;
 
index 3e780132b4e04cfc8ba096359f17f5ffb8bef243..888d4bd14563ad33911e612518a9d4495a94457a 100755 (executable)
@@ -18,6 +18,10 @@ IN: webapps.planet
 
 TUPLE: planet-factor < dispatcher ;
 
+SYMBOL: can-administer-planet-factor?
+
+can-administer-planet-factor? define-capability
+
 TUPLE: planet-factor-admin < dispatcher ;
 
 TUPLE: blog id name www-url feed-url ;
@@ -30,8 +34,8 @@ blog "BLOGS"
 {
     { "id" "ID" INTEGER +db-assigned-id+ }
     { "name" "NAME" { VARCHAR 256 } +not-null+ }
-    { "www-url" "WWWURL" { VARCHAR 256 } +not-null+ }
-    { "feed-url" "FEEDURL" { VARCHAR 256 } +not-null+ }
+    { "www-url" "WWWURL" URL +not-null+ }
+    { "feed-url" "FEEDURL" URL +not-null+ }
 } define-persistent
 
 TUPLE: posting < entry id ;
@@ -40,7 +44,7 @@ posting "POSTINGS"
 {
     { "id" "ID" INTEGER +db-assigned-id+ }
     { "title" "TITLE" { VARCHAR 256 } +not-null+ }
-    { "url" "LINK" { VARCHAR 256 } +not-null+ }
+    { "url" "LINK" URL +not-null+ }
     { "description" "DESCRIPTION" TEXT +not-null+ }
     { "date" "DATE" TIMESTAMP +not-null+ }
 } define-persistent
@@ -134,6 +138,7 @@ posting "POSTINGS"
 
 : <new-blog-action> ( -- action )
     <page-action>
+
         { planet-factor "new-blog" } >>template
 
         [ validate-blog ] >>validate
@@ -150,9 +155,10 @@ posting "POSTINGS"
             ]
             tri
         ] >>submit ;
-    
+
 : <edit-blog-action> ( -- action )
     <page-action>
+
         [
             validate-integer-id
             "id" value <blog> select-tuple from-object
@@ -184,20 +190,16 @@ posting "POSTINGS"
         <update-action> "update" add-responder
         <new-blog-action> "new-blog" add-responder
         <edit-blog-action> "edit-blog" add-responder
-        <delete-blog-action> "delete-blog" add-responder ;
-
-SYMBOL: can-administer-planet-factor?
-
-can-administer-planet-factor? define-capability
+        <delete-blog-action> "delete-blog" add-responder
+    <protected>
+        "administer Planet Factor" >>description
+        { can-administer-planet-factor? } >>capabilities ;
 
 : <planet-factor> ( -- responder )
     planet-factor new-dispatcher
         <planet-action> "list" add-main-responder
         <planet-feed-action> "feed.xml" add-responder
-        <planet-factor-admin> <protected>
-            "administer Planet Factor" >>description
-            { can-administer-planet-factor? } >>capabilities
-        "admin" add-responder
+        <planet-factor-admin> "admin" add-responder
     <boilerplate>
         { planet-factor "planet-common" } >>template ;
 
index 47912789743c5e0ebcc40bb249a71e4a6d7875be..18130f514433b17276931e60b7e04ea851c53705 100644 (file)
@@ -31,6 +31,10 @@ IN: webapps.wiki
 
 TUPLE: wiki < dispatcher ;
 
+SYMBOL: can-delete-wiki-articles?
+
+can-delete-wiki-articles? define-capability
+
 TUPLE: article title revision ;
 
 article "ARTICLES" {
@@ -81,10 +85,13 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <view-article-action> ( -- action )
     <action>
+
         "title" >>rest
+
         [
             validate-title
         ] >>init
+
         [
             "title" value dup <article> select-tuple [
                 revision>> <revision> select-tuple from-object
@@ -96,13 +103,16 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <view-revision-action> ( -- action )
     <page-action>
+
         "id" >>rest
+
         [
             validate-integer-id
             "id" value <revision>
             select-tuple from-object
             URL" $wiki/view/" adjust-url present relative-link-prefix set
         ] >>init
+
         { wiki "view" } >>template ;
 
 : add-revision ( revision -- )
@@ -117,14 +127,18 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <edit-article-action> ( -- action )
     <page-action>
+
         "title" >>rest
+
         [
             validate-title
             "title" value <article> select-tuple [
                 revision>> <revision> select-tuple from-object
             ] when*
         ] >>init
+
         { wiki "edit" } >>template
+
         [
             validate-title
             { { "content" [ v-required ] } } validate-params
@@ -135,7 +149,10 @@ M: revision feed-entry-url id>> revision-url ;
                 logged-in-user get username>> >>author
                 "content" value >>content
             [ add-revision ] [ title>> view-url <redirect> ] bi
-        ] >>submit ;
+        ] >>submit
+
+    <protected>
+        "edit wiki articles" >>description ;
 
 : list-revisions ( -- seq )
     f <revision> "title" value >>title select-tuples
@@ -143,24 +160,34 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <list-revisions-action> ( -- action )
     <page-action>
+
         "title" >>rest
+
         [
             validate-title
             list-revisions "revisions" set-value
         ] >>init
+
         { wiki "revisions" } >>template ;
 
 : <list-revisions-feed-action> ( -- action )
     <feed-action>
+
         "title" >>rest
+
         [ validate-title ] >>init
+
         [ "Revisions of " "title" value append ] >>title
+
         [ "title" value revisions-url ] >>url
+
         [ list-revisions ] >>entries ;
 
 : <rollback-action> ( -- action )
     <action>
+
         [ validate-integer-id ] >>validate
+
         [
             "id" value <revision> select-tuple clone f >>id
             [ add-revision ] [ title>> view-url <redirect> ] bi
@@ -183,12 +210,18 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <delete-action> ( -- action )
     <action>
+
         [ validate-title ] >>validate
+
         [
             "title" value <article> delete-tuples
             f <revision> "title" value >>title delete-tuples
             URL" $wiki" <redirect>
-        ] >>submit ;
+        ] >>submit
+
+     <protected>
+        "delete wiki articles" >>description
+        { can-delete-wiki-articles? } >>capabilities ;
 
 : <diff-action> ( -- action )
     <page-action>
@@ -207,15 +240,18 @@ M: revision feed-entry-url id>> revision-url ;
             [ [ content>> string-lines ] bi@ diff "diff" set-value ]
             2bi
         ] >>init
+
         { wiki "diff" } >>template ;
 
 : <list-articles-action> ( -- action )
     <page-action>
+
         [
             f <article> select-tuples
             [ [ title>> ] compare ] sort
             "articles" set-value
         ] >>init
+
         { wiki "articles" } >>template ;
 
 : list-user-edits ( -- seq )
@@ -224,11 +260,14 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <user-edits-action> ( -- action )
     <page-action>
+
         "author" >>rest
+
         [
             validate-author
             list-user-edits "user-edits" set-value
         ] >>init
+
         { wiki "user-edits" } >>template ;
 
 : <user-edits-feed-action> ( -- action )
@@ -239,10 +278,6 @@ M: revision feed-entry-url id>> revision-url ;
         [ "author" value user-edits-url ] >>url
         [ list-user-edits ] >>entries ;
 
-SYMBOL: can-delete-wiki-articles?
-
-can-delete-wiki-articles? define-capability
-
 : <article-boilerplate> ( responder -- responder' )
     <boilerplate>
         { wiki "page-common" } >>template ;
@@ -255,18 +290,13 @@ can-delete-wiki-articles? define-capability
         <list-revisions-action> <article-boilerplate> "revisions" add-responder
         <list-revisions-feed-action> "revisions.atom" add-responder
         <diff-action> <article-boilerplate> "diff" add-responder
-        <edit-article-action> <article-boilerplate> <protected>
-            "edit wiki articles" >>description
-            "edit" add-responder
+        <edit-article-action> <article-boilerplate> "edit" add-responder
         <rollback-action> "rollback" add-responder
         <user-edits-action> "user-edits" add-responder
         <list-articles-action> "articles" add-responder
         <list-changes-action> "changes" add-responder
         <user-edits-feed-action> "user-edits.atom" add-responder
         <list-changes-feed-action> "changes.atom" add-responder
-        <delete-action> <protected>
-            "delete wiki articles" >>description
-            { can-delete-wiki-articles? } >>capabilities
-        "delete" add-responder
+        <delete-action> "delete" add-responder
     <boilerplate>
         { wiki "wiki-common" } >>template ;