Fossil SCM
Improvements to login/logout processing: (1) When the user is "nobody", show hyperlinks to pages that require "anonymous" but have those links redirect to the /login page. (2) Clean up the /login page - less verbage. (3) Redirects from /login to /tarball or /zip provide a button to press, rather than immediately starting the download.
Commit
653dd402eafe152df9168ebf4a680fcac1ff6078
Parent
c62e94f8a3da2ac…
41 files changed
+4
-4
+4
-4
+4
-4
+4
-4
+4
-4
+4
-4
+4
-4
+4
-4
+22
-10
+3
-3
+3
-3
+2
-2
+1
-1
+1
-1
+1
-1
+1
-1
+2
-2
+1
-1
+13
-13
+152
-106
+6
-1
+4
-1
+2
-2
+1
-1
+7
-4
+33
-18
+6
-3
+2
-1
+3
-3
+1
-1
+10
-2
+2
-2
+12
-1
+11
-5
+6
-3
+18
-9
+11
-8
+1
-1
+18
-18
+4
-2
+12
-1
~
skins/black_and_white/header.txt
~
skins/default/header.txt
~
skins/eagle/header.txt
~
skins/enhanced1/header.txt
~
skins/etienne1/header.txt
~
skins/khaki/header.txt
~
skins/plain_gray/header.txt
~
skins/rounded1/header.txt
~
src/attach.c
~
src/branch.c
~
src/browse.c
~
src/cache.c
~
src/descendants.c
~
src/diff.c
~
src/diffcmd.c
~
src/doc.c
~
src/event.c
~
src/finfo.c
~
src/info.c
~
src/login.c
~
src/main.c
~
src/moderate.c
~
src/name.c
~
src/path.c
~
src/report.c
~
src/setup.c
~
src/shun.c
~
src/skins.c
~
src/stat.c
~
src/statrep.c
~
src/style.c
~
src/tag.c
~
src/tar.c
~
src/th_main.c
~
src/timeline.c
~
src/tkt.c
~
src/tktsetup.c
~
src/user.c
~
src/wiki.c
~
src/xfersetup.c
~
src/zip.c
+4
-4
| --- skins/black_and_white/header.txt | ||
| +++ skins/black_and_white/header.txt | ||
| @@ -26,21 +26,21 @@ | ||
| 26 | 26 | <th1> |
| 27 | 27 | html "<a href='$home$index_page'>Home</a>\n" |
| 28 | 28 | if {[anycap jor]} { |
| 29 | 29 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 30 | 30 | } |
| 31 | -if {[hascap oh]} { | |
| 31 | +if {[anoncap oh]} { | |
| 32 | 32 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 33 | 33 | } |
| 34 | -if {[hascap o]} { | |
| 34 | +if {[anoncap o]} { | |
| 35 | 35 | html "<a href='$home/brlist'>Branches</a>\n" |
| 36 | 36 | html "<a href='$home/taglist'>Tags</a>\n" |
| 37 | 37 | } |
| 38 | -if {[hascap r]} { | |
| 38 | +if {[anoncap r]} { | |
| 39 | 39 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 40 | 40 | } |
| 41 | -if {[hascap j]} { | |
| 41 | +if {[anoncap j]} { | |
| 42 | 42 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 43 | 43 | } |
| 44 | 44 | if {[hascap s]} { |
| 45 | 45 | html "<a href='$home/setup'>Admin</a>\n" |
| 46 | 46 | } elseif {[hascap a]} { |
| 47 | 47 |
| --- skins/black_and_white/header.txt | |
| +++ skins/black_and_white/header.txt | |
| @@ -26,21 +26,21 @@ | |
| 26 | <th1> |
| 27 | html "<a href='$home$index_page'>Home</a>\n" |
| 28 | if {[anycap jor]} { |
| 29 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 30 | } |
| 31 | if {[hascap oh]} { |
| 32 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 33 | } |
| 34 | if {[hascap o]} { |
| 35 | html "<a href='$home/brlist'>Branches</a>\n" |
| 36 | html "<a href='$home/taglist'>Tags</a>\n" |
| 37 | } |
| 38 | if {[hascap r]} { |
| 39 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 40 | } |
| 41 | if {[hascap j]} { |
| 42 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 43 | } |
| 44 | if {[hascap s]} { |
| 45 | html "<a href='$home/setup'>Admin</a>\n" |
| 46 | } elseif {[hascap a]} { |
| 47 |
| --- skins/black_and_white/header.txt | |
| +++ skins/black_and_white/header.txt | |
| @@ -26,21 +26,21 @@ | |
| 26 | <th1> |
| 27 | html "<a href='$home$index_page'>Home</a>\n" |
| 28 | if {[anycap jor]} { |
| 29 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 30 | } |
| 31 | if {[anoncap oh]} { |
| 32 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 33 | } |
| 34 | if {[anoncap o]} { |
| 35 | html "<a href='$home/brlist'>Branches</a>\n" |
| 36 | html "<a href='$home/taglist'>Tags</a>\n" |
| 37 | } |
| 38 | if {[anoncap r]} { |
| 39 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 40 | } |
| 41 | if {[anoncap j]} { |
| 42 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 43 | } |
| 44 | if {[hascap s]} { |
| 45 | html "<a href='$home/setup'>Admin</a>\n" |
| 46 | } elseif {[hascap a]} { |
| 47 |
+4
-4
| --- skins/default/header.txt | ||
| +++ skins/default/header.txt | ||
| @@ -25,21 +25,21 @@ | ||
| 25 | 25 | <th1> |
| 26 | 26 | html "<a href='$home$index_page'>Home</a>\n" |
| 27 | 27 | if {[anycap jor]} { |
| 28 | 28 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 29 | 29 | } |
| 30 | -if {[hascap oh]} { | |
| 30 | +if {[anoncap oh]} { | |
| 31 | 31 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 32 | 32 | } |
| 33 | -if {[hascap o]} { | |
| 33 | +if {[anoncap o]} { | |
| 34 | 34 | html "<a href='$home/brlist'>Branches</a>\n" |
| 35 | 35 | html "<a href='$home/taglist'>Tags</a>\n" |
| 36 | 36 | } |
| 37 | -if {[hascap r]} { | |
| 37 | +if {[anoncap r]} { | |
| 38 | 38 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 39 | 39 | } |
| 40 | -if {[hascap j]} { | |
| 40 | +if {[anoncap j]} { | |
| 41 | 41 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 42 | 42 | } |
| 43 | 43 | if {[hascap s]} { |
| 44 | 44 | html "<a href='$home/setup'>Admin</a>\n" |
| 45 | 45 | } elseif {[hascap a]} { |
| 46 | 46 |
| --- skins/default/header.txt | |
| +++ skins/default/header.txt | |
| @@ -25,21 +25,21 @@ | |
| 25 | <th1> |
| 26 | html "<a href='$home$index_page'>Home</a>\n" |
| 27 | if {[anycap jor]} { |
| 28 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 29 | } |
| 30 | if {[hascap oh]} { |
| 31 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 32 | } |
| 33 | if {[hascap o]} { |
| 34 | html "<a href='$home/brlist'>Branches</a>\n" |
| 35 | html "<a href='$home/taglist'>Tags</a>\n" |
| 36 | } |
| 37 | if {[hascap r]} { |
| 38 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 39 | } |
| 40 | if {[hascap j]} { |
| 41 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 42 | } |
| 43 | if {[hascap s]} { |
| 44 | html "<a href='$home/setup'>Admin</a>\n" |
| 45 | } elseif {[hascap a]} { |
| 46 |
| --- skins/default/header.txt | |
| +++ skins/default/header.txt | |
| @@ -25,21 +25,21 @@ | |
| 25 | <th1> |
| 26 | html "<a href='$home$index_page'>Home</a>\n" |
| 27 | if {[anycap jor]} { |
| 28 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 29 | } |
| 30 | if {[anoncap oh]} { |
| 31 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 32 | } |
| 33 | if {[anoncap o]} { |
| 34 | html "<a href='$home/brlist'>Branches</a>\n" |
| 35 | html "<a href='$home/taglist'>Tags</a>\n" |
| 36 | } |
| 37 | if {[anoncap r]} { |
| 38 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 39 | } |
| 40 | if {[anoncap j]} { |
| 41 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 42 | } |
| 43 | if {[hascap s]} { |
| 44 | html "<a href='$home/setup'>Admin</a>\n" |
| 45 | } elseif {[hascap a]} { |
| 46 |
+4
-4
| --- skins/eagle/header.txt | ||
| +++ skins/eagle/header.txt | ||
| @@ -106,21 +106,21 @@ | ||
| 106 | 106 | html "<a href='$home$index_page'>Home</a>\n" |
| 107 | 107 | html "<a href='$home/help'>Help</a>\n" |
| 108 | 108 | if {[anycap jor]} { |
| 109 | 109 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 110 | 110 | } |
| 111 | -if {[hascap oh]} { | |
| 111 | +if {[anoncap oh]} { | |
| 112 | 112 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 113 | 113 | } |
| 114 | -if {[hascap o]} { | |
| 114 | +if {[anoncap o]} { | |
| 115 | 115 | html "<a href='$home/brlist'>Branches</a>\n" |
| 116 | 116 | html "<a href='$home/taglist'>Tags</a>\n" |
| 117 | 117 | } |
| 118 | -if {[hascap r]} { | |
| 118 | +if {[anoncap r]} { | |
| 119 | 119 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 120 | 120 | } |
| 121 | -if {[hascap j]} { | |
| 121 | +if {[anoncap j]} { | |
| 122 | 122 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 123 | 123 | } |
| 124 | 124 | if {[hascap s]} { |
| 125 | 125 | html "<a href='$home/setup'>Admin</a>\n" |
| 126 | 126 | } elseif {[hascap a]} { |
| 127 | 127 |
| --- skins/eagle/header.txt | |
| +++ skins/eagle/header.txt | |
| @@ -106,21 +106,21 @@ | |
| 106 | html "<a href='$home$index_page'>Home</a>\n" |
| 107 | html "<a href='$home/help'>Help</a>\n" |
| 108 | if {[anycap jor]} { |
| 109 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 110 | } |
| 111 | if {[hascap oh]} { |
| 112 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 113 | } |
| 114 | if {[hascap o]} { |
| 115 | html "<a href='$home/brlist'>Branches</a>\n" |
| 116 | html "<a href='$home/taglist'>Tags</a>\n" |
| 117 | } |
| 118 | if {[hascap r]} { |
| 119 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 120 | } |
| 121 | if {[hascap j]} { |
| 122 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 123 | } |
| 124 | if {[hascap s]} { |
| 125 | html "<a href='$home/setup'>Admin</a>\n" |
| 126 | } elseif {[hascap a]} { |
| 127 |
| --- skins/eagle/header.txt | |
| +++ skins/eagle/header.txt | |
| @@ -106,21 +106,21 @@ | |
| 106 | html "<a href='$home$index_page'>Home</a>\n" |
| 107 | html "<a href='$home/help'>Help</a>\n" |
| 108 | if {[anycap jor]} { |
| 109 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 110 | } |
| 111 | if {[anoncap oh]} { |
| 112 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 113 | } |
| 114 | if {[anoncap o]} { |
| 115 | html "<a href='$home/brlist'>Branches</a>\n" |
| 116 | html "<a href='$home/taglist'>Tags</a>\n" |
| 117 | } |
| 118 | if {[anoncap r]} { |
| 119 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 120 | } |
| 121 | if {[anoncap j]} { |
| 122 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 123 | } |
| 124 | if {[hascap s]} { |
| 125 | html "<a href='$home/setup'>Admin</a>\n" |
| 126 | } elseif {[hascap a]} { |
| 127 |
+4
-4
| --- skins/enhanced1/header.txt | ||
| +++ skins/enhanced1/header.txt | ||
| @@ -106,21 +106,21 @@ | ||
| 106 | 106 | html "<a href='$home$index_page'>Home</a>\n" |
| 107 | 107 | html "<a href='$home/help'>Help</a>\n" |
| 108 | 108 | if {[anycap jor]} { |
| 109 | 109 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 110 | 110 | } |
| 111 | -if {[hascap oh]} { | |
| 111 | +if {[anoncap oh]} { | |
| 112 | 112 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 113 | 113 | } |
| 114 | -if {[hascap o]} { | |
| 114 | +if {[anoncap o]} { | |
| 115 | 115 | html "<a href='$home/brlist'>Branches</a>\n" |
| 116 | 116 | html "<a href='$home/taglist'>Tags</a>\n" |
| 117 | 117 | } |
| 118 | -if {[hascap r]} { | |
| 118 | +if {[anoncap r]} { | |
| 119 | 119 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 120 | 120 | } |
| 121 | -if {[hascap j]} { | |
| 121 | +if {[anoncap j]} { | |
| 122 | 122 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 123 | 123 | } |
| 124 | 124 | if {[hascap s]} { |
| 125 | 125 | html "<a href='$home/setup'>Admin</a>\n" |
| 126 | 126 | } elseif {[hascap a]} { |
| 127 | 127 |
| --- skins/enhanced1/header.txt | |
| +++ skins/enhanced1/header.txt | |
| @@ -106,21 +106,21 @@ | |
| 106 | html "<a href='$home$index_page'>Home</a>\n" |
| 107 | html "<a href='$home/help'>Help</a>\n" |
| 108 | if {[anycap jor]} { |
| 109 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 110 | } |
| 111 | if {[hascap oh]} { |
| 112 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 113 | } |
| 114 | if {[hascap o]} { |
| 115 | html "<a href='$home/brlist'>Branches</a>\n" |
| 116 | html "<a href='$home/taglist'>Tags</a>\n" |
| 117 | } |
| 118 | if {[hascap r]} { |
| 119 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 120 | } |
| 121 | if {[hascap j]} { |
| 122 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 123 | } |
| 124 | if {[hascap s]} { |
| 125 | html "<a href='$home/setup'>Admin</a>\n" |
| 126 | } elseif {[hascap a]} { |
| 127 |
| --- skins/enhanced1/header.txt | |
| +++ skins/enhanced1/header.txt | |
| @@ -106,21 +106,21 @@ | |
| 106 | html "<a href='$home$index_page'>Home</a>\n" |
| 107 | html "<a href='$home/help'>Help</a>\n" |
| 108 | if {[anycap jor]} { |
| 109 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 110 | } |
| 111 | if {[anoncap oh]} { |
| 112 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 113 | } |
| 114 | if {[anoncap o]} { |
| 115 | html "<a href='$home/brlist'>Branches</a>\n" |
| 116 | html "<a href='$home/taglist'>Tags</a>\n" |
| 117 | } |
| 118 | if {[anoncap r]} { |
| 119 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 120 | } |
| 121 | if {[anoncap j]} { |
| 122 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 123 | } |
| 124 | if {[hascap s]} { |
| 125 | html "<a href='$home/setup'>Admin</a>\n" |
| 126 | } elseif {[hascap a]} { |
| 127 |
+4
-4
| --- skins/etienne1/header.txt | ||
| +++ skins/etienne1/header.txt | ||
| @@ -65,21 +65,21 @@ | ||
| 65 | 65 | menulink "home" $index_page Home |
| 66 | 66 | |
| 67 | 67 | if {[anycap jor]} { |
| 68 | 68 | menulink "timeline" "/timeline" Timeline |
| 69 | 69 | } |
| 70 | -if {[hascap oh]} { | |
| 70 | +if {[anoncap oh]} { | |
| 71 | 71 | menulink "dir" "/dir?ci=tip" Files |
| 72 | 72 | } |
| 73 | -if {[hascap o]} { | |
| 73 | +if {[anoncap o]} { | |
| 74 | 74 | menulink "brlist" "/brlist" Branches |
| 75 | 75 | menulink "taglist" "/taglist" Tags |
| 76 | 76 | } |
| 77 | -if {[hascap r]} { | |
| 77 | +if {[anoncap r]} { | |
| 78 | 78 | menulink "ticket" "/ticket" Tickets |
| 79 | 79 | } |
| 80 | -if {[hascap j]} { | |
| 80 | +if {[anoncap j]} { | |
| 81 | 81 | menulink "wiki" "/wiki" Wiki |
| 82 | 82 | } |
| 83 | 83 | if {[hascap s]} { |
| 84 | 84 | menulink "setup" "/setup" Admin |
| 85 | 85 | } elseif {[hascap a]} { |
| 86 | 86 |
| --- skins/etienne1/header.txt | |
| +++ skins/etienne1/header.txt | |
| @@ -65,21 +65,21 @@ | |
| 65 | menulink "home" $index_page Home |
| 66 | |
| 67 | if {[anycap jor]} { |
| 68 | menulink "timeline" "/timeline" Timeline |
| 69 | } |
| 70 | if {[hascap oh]} { |
| 71 | menulink "dir" "/dir?ci=tip" Files |
| 72 | } |
| 73 | if {[hascap o]} { |
| 74 | menulink "brlist" "/brlist" Branches |
| 75 | menulink "taglist" "/taglist" Tags |
| 76 | } |
| 77 | if {[hascap r]} { |
| 78 | menulink "ticket" "/ticket" Tickets |
| 79 | } |
| 80 | if {[hascap j]} { |
| 81 | menulink "wiki" "/wiki" Wiki |
| 82 | } |
| 83 | if {[hascap s]} { |
| 84 | menulink "setup" "/setup" Admin |
| 85 | } elseif {[hascap a]} { |
| 86 |
| --- skins/etienne1/header.txt | |
| +++ skins/etienne1/header.txt | |
| @@ -65,21 +65,21 @@ | |
| 65 | menulink "home" $index_page Home |
| 66 | |
| 67 | if {[anycap jor]} { |
| 68 | menulink "timeline" "/timeline" Timeline |
| 69 | } |
| 70 | if {[anoncap oh]} { |
| 71 | menulink "dir" "/dir?ci=tip" Files |
| 72 | } |
| 73 | if {[anoncap o]} { |
| 74 | menulink "brlist" "/brlist" Branches |
| 75 | menulink "taglist" "/taglist" Tags |
| 76 | } |
| 77 | if {[anoncap r]} { |
| 78 | menulink "ticket" "/ticket" Tickets |
| 79 | } |
| 80 | if {[anoncap j]} { |
| 81 | menulink "wiki" "/wiki" Wiki |
| 82 | } |
| 83 | if {[hascap s]} { |
| 84 | menulink "setup" "/setup" Admin |
| 85 | } elseif {[hascap a]} { |
| 86 |
+4
-4
| --- skins/khaki/header.txt | ||
| +++ skins/khaki/header.txt | ||
| @@ -24,21 +24,21 @@ | ||
| 24 | 24 | <th1> |
| 25 | 25 | html "<a href='$home$index_page'>Home</a>\n" |
| 26 | 26 | if {[anycap jor]} { |
| 27 | 27 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 28 | 28 | } |
| 29 | -if {[hascap oh]} { | |
| 29 | +if {[anoncap oh]} { | |
| 30 | 30 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 31 | 31 | } |
| 32 | -if {[hascap o]} { | |
| 32 | +if {[anoncap o]} { | |
| 33 | 33 | html "<a href='$home/brlist'>Branches</a>\n" |
| 34 | 34 | html "<a href='$home/taglist'>Tags</a>\n" |
| 35 | 35 | } |
| 36 | -if {[hascap r]} { | |
| 36 | +if {[anoncap r]} { | |
| 37 | 37 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 38 | 38 | } |
| 39 | -if {[hascap j]} { | |
| 39 | +if {[anoncap j]} { | |
| 40 | 40 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 41 | 41 | } |
| 42 | 42 | if {[hascap s]} { |
| 43 | 43 | html "<a href='$home/setup'>Admin</a>\n" |
| 44 | 44 | } elseif {[hascap a]} { |
| 45 | 45 |
| --- skins/khaki/header.txt | |
| +++ skins/khaki/header.txt | |
| @@ -24,21 +24,21 @@ | |
| 24 | <th1> |
| 25 | html "<a href='$home$index_page'>Home</a>\n" |
| 26 | if {[anycap jor]} { |
| 27 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 28 | } |
| 29 | if {[hascap oh]} { |
| 30 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 31 | } |
| 32 | if {[hascap o]} { |
| 33 | html "<a href='$home/brlist'>Branches</a>\n" |
| 34 | html "<a href='$home/taglist'>Tags</a>\n" |
| 35 | } |
| 36 | if {[hascap r]} { |
| 37 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 38 | } |
| 39 | if {[hascap j]} { |
| 40 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 41 | } |
| 42 | if {[hascap s]} { |
| 43 | html "<a href='$home/setup'>Admin</a>\n" |
| 44 | } elseif {[hascap a]} { |
| 45 |
| --- skins/khaki/header.txt | |
| +++ skins/khaki/header.txt | |
| @@ -24,21 +24,21 @@ | |
| 24 | <th1> |
| 25 | html "<a href='$home$index_page'>Home</a>\n" |
| 26 | if {[anycap jor]} { |
| 27 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 28 | } |
| 29 | if {[anoncap oh]} { |
| 30 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 31 | } |
| 32 | if {[anoncap o]} { |
| 33 | html "<a href='$home/brlist'>Branches</a>\n" |
| 34 | html "<a href='$home/taglist'>Tags</a>\n" |
| 35 | } |
| 36 | if {[anoncap r]} { |
| 37 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 38 | } |
| 39 | if {[anoncap j]} { |
| 40 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 41 | } |
| 42 | if {[hascap s]} { |
| 43 | html "<a href='$home/setup'>Admin</a>\n" |
| 44 | } elseif {[hascap a]} { |
| 45 |
+4
-4
| --- skins/plain_gray/header.txt | ||
| +++ skins/plain_gray/header.txt | ||
| @@ -22,21 +22,21 @@ | ||
| 22 | 22 | <th1> |
| 23 | 23 | html "<a href='$home$index_page'>Home</a>\n" |
| 24 | 24 | if {[anycap jor]} { |
| 25 | 25 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 26 | 26 | } |
| 27 | -if {[hascap oh]} { | |
| 27 | +if {[anoncap oh]} { | |
| 28 | 28 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 29 | 29 | } |
| 30 | -if {[hascap o]} { | |
| 30 | +if {[anoncap o]} { | |
| 31 | 31 | html "<a href='$home/brlist'>Branches</a>\n" |
| 32 | 32 | html "<a href='$home/taglist'>Tags</a>\n" |
| 33 | 33 | } |
| 34 | -if {[hascap r]} { | |
| 34 | +if {[anoncap r]} { | |
| 35 | 35 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 36 | 36 | } |
| 37 | -if {[hascap j]} { | |
| 37 | +if {[anoncap j]} { | |
| 38 | 38 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 39 | 39 | } |
| 40 | 40 | if {[hascap s]} { |
| 41 | 41 | html "<a href='$home/setup'>Admin</a>\n" |
| 42 | 42 | } elseif {[hascap a]} { |
| 43 | 43 |
| --- skins/plain_gray/header.txt | |
| +++ skins/plain_gray/header.txt | |
| @@ -22,21 +22,21 @@ | |
| 22 | <th1> |
| 23 | html "<a href='$home$index_page'>Home</a>\n" |
| 24 | if {[anycap jor]} { |
| 25 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 26 | } |
| 27 | if {[hascap oh]} { |
| 28 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 29 | } |
| 30 | if {[hascap o]} { |
| 31 | html "<a href='$home/brlist'>Branches</a>\n" |
| 32 | html "<a href='$home/taglist'>Tags</a>\n" |
| 33 | } |
| 34 | if {[hascap r]} { |
| 35 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 36 | } |
| 37 | if {[hascap j]} { |
| 38 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 39 | } |
| 40 | if {[hascap s]} { |
| 41 | html "<a href='$home/setup'>Admin</a>\n" |
| 42 | } elseif {[hascap a]} { |
| 43 |
| --- skins/plain_gray/header.txt | |
| +++ skins/plain_gray/header.txt | |
| @@ -22,21 +22,21 @@ | |
| 22 | <th1> |
| 23 | html "<a href='$home$index_page'>Home</a>\n" |
| 24 | if {[anycap jor]} { |
| 25 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 26 | } |
| 27 | if {[anoncap oh]} { |
| 28 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 29 | } |
| 30 | if {[anoncap o]} { |
| 31 | html "<a href='$home/brlist'>Branches</a>\n" |
| 32 | html "<a href='$home/taglist'>Tags</a>\n" |
| 33 | } |
| 34 | if {[anoncap r]} { |
| 35 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 36 | } |
| 37 | if {[anoncap j]} { |
| 38 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 39 | } |
| 40 | if {[hascap s]} { |
| 41 | html "<a href='$home/setup'>Admin</a>\n" |
| 42 | } elseif {[hascap a]} { |
| 43 |
+4
-4
| --- skins/rounded1/header.txt | ||
| +++ skins/rounded1/header.txt | ||
| @@ -26,21 +26,21 @@ | ||
| 26 | 26 | <th1> |
| 27 | 27 | html "<a href='$home$index_page'>Home</a>\n" |
| 28 | 28 | if {[anycap jor]} { |
| 29 | 29 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 30 | 30 | } |
| 31 | -if {[hascap oh]} { | |
| 31 | +if {[anoncap oh]} { | |
| 32 | 32 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 33 | 33 | } |
| 34 | -if {[hascap o]} { | |
| 34 | +if {[anoncap o]} { | |
| 35 | 35 | html "<a href='$home/brlist'>Branches</a>\n" |
| 36 | 36 | html "<a href='$home/taglist'>Tags</a>\n" |
| 37 | 37 | } |
| 38 | -if {[hascap r]} { | |
| 38 | +if {[anoncap r]} { | |
| 39 | 39 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 40 | 40 | } |
| 41 | -if {[hascap j]} { | |
| 41 | +if {[anoncap j]} { | |
| 42 | 42 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 43 | 43 | } |
| 44 | 44 | if {[hascap s]} { |
| 45 | 45 | html "<a href='$home/setup'>Admin</a>\n" |
| 46 | 46 | } elseif {[hascap a]} { |
| 47 | 47 |
| --- skins/rounded1/header.txt | |
| +++ skins/rounded1/header.txt | |
| @@ -26,21 +26,21 @@ | |
| 26 | <th1> |
| 27 | html "<a href='$home$index_page'>Home</a>\n" |
| 28 | if {[anycap jor]} { |
| 29 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 30 | } |
| 31 | if {[hascap oh]} { |
| 32 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 33 | } |
| 34 | if {[hascap o]} { |
| 35 | html "<a href='$home/brlist'>Branches</a>\n" |
| 36 | html "<a href='$home/taglist'>Tags</a>\n" |
| 37 | } |
| 38 | if {[hascap r]} { |
| 39 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 40 | } |
| 41 | if {[hascap j]} { |
| 42 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 43 | } |
| 44 | if {[hascap s]} { |
| 45 | html "<a href='$home/setup'>Admin</a>\n" |
| 46 | } elseif {[hascap a]} { |
| 47 |
| --- skins/rounded1/header.txt | |
| +++ skins/rounded1/header.txt | |
| @@ -26,21 +26,21 @@ | |
| 26 | <th1> |
| 27 | html "<a href='$home$index_page'>Home</a>\n" |
| 28 | if {[anycap jor]} { |
| 29 | html "<a href='$home/timeline'>Timeline</a>\n" |
| 30 | } |
| 31 | if {[anoncap oh]} { |
| 32 | html "<a href='$home/tree?ci=tip'>Files</a>\n" |
| 33 | } |
| 34 | if {[anoncap o]} { |
| 35 | html "<a href='$home/brlist'>Branches</a>\n" |
| 36 | html "<a href='$home/taglist'>Tags</a>\n" |
| 37 | } |
| 38 | if {[anoncap r]} { |
| 39 | html "<a href='$home/ticket'>Tickets</a>\n" |
| 40 | } |
| 41 | if {[anoncap j]} { |
| 42 | html "<a href='$home/wiki'>Wiki</a>\n" |
| 43 | } |
| 44 | if {[hascap s]} { |
| 45 | html "<a href='$home/setup'>Admin</a>\n" |
| 46 | } elseif {[hascap a]} { |
| 47 |
+22
-10
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -48,19 +48,22 @@ | ||
| 48 | 48 | " (SELECT uuid FROM blob WHERE rid=attachid), attachid" |
| 49 | 49 | " FROM attachment", |
| 50 | 50 | timeline_utc() |
| 51 | 51 | ); |
| 52 | 52 | if( zPage ){ |
| 53 | - if( g.perm.RdWiki==0 ) login_needed(); | |
| 53 | + if( g.perm.RdWiki==0 ){ login_needed(g.anon.RdWiki); return; } | |
| 54 | 54 | style_header("Attachments To %h", zPage); |
| 55 | 55 | blob_append_sql(&sql, " WHERE target=%Q", zPage); |
| 56 | 56 | }else if( zTkt ){ |
| 57 | - if( g.perm.RdTkt==0 ) login_needed(); | |
| 57 | + if( g.perm.RdTkt==0 ){ login_needed(g.anon.RdTkt); return; } | |
| 58 | 58 | style_header("Attachments To Ticket %S", zTkt); |
| 59 | 59 | blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt); |
| 60 | 60 | }else{ |
| 61 | - if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed(); | |
| 61 | + if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ){ | |
| 62 | + login_needed(g.anon.RdTkt || g.anon.RdWiki); | |
| 63 | + return; | |
| 64 | + } | |
| 62 | 65 | style_header("All Attachments"); |
| 63 | 66 | } |
| 64 | 67 | blob_append_sql(&sql, " ORDER BY mtime DESC"); |
| 65 | 68 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 66 | 69 | @ <ol> |
| @@ -150,14 +153,14 @@ | ||
| 150 | 153 | |
| 151 | 154 | if( zPage && zTkt ) zTkt = 0; |
| 152 | 155 | if( zFile==0 ) fossil_redirect_home(); |
| 153 | 156 | login_check_credentials(); |
| 154 | 157 | if( zPage ){ |
| 155 | - if( g.perm.RdWiki==0 ) login_needed(); | |
| 158 | + if( g.perm.RdWiki==0 ){ login_needed(g.anon.RdWiki); return; } | |
| 156 | 159 | zTarget = zPage; |
| 157 | 160 | }else if( zTkt ){ |
| 158 | - if( g.perm.RdTkt==0 ) login_needed(); | |
| 161 | + if( g.perm.RdTkt==0 ){ login_needed(g.anon.RdTkt); return; } | |
| 159 | 162 | zTarget = zTkt; |
| 160 | 163 | }else{ |
| 161 | 164 | fossil_redirect_home(); |
| 162 | 165 | } |
| 163 | 166 | if( attachid>0 ){ |
| @@ -243,19 +246,25 @@ | ||
| 243 | 246 | if( P("cancel") ) cgi_redirect(zFrom); |
| 244 | 247 | if( zPage && zTkt ) fossil_redirect_home(); |
| 245 | 248 | if( zPage==0 && zTkt==0 ) fossil_redirect_home(); |
| 246 | 249 | login_check_credentials(); |
| 247 | 250 | if( zPage ){ |
| 248 | - if( g.perm.ApndWiki==0 || g.perm.Attach==0 ) login_needed(); | |
| 251 | + if( g.perm.ApndWiki==0 || g.perm.Attach==0 ){ | |
| 252 | + login_needed(g.anon.ApndWiki && g.anon.Attach); | |
| 253 | + return; | |
| 254 | + } | |
| 249 | 255 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'", zPage) ){ |
| 250 | 256 | fossil_redirect_home(); |
| 251 | 257 | } |
| 252 | 258 | zTarget = zPage; |
| 253 | 259 | zTargetType = mprintf("Wiki Page <a href=\"%R/wiki?name=%h\">%h</a>", |
| 254 | 260 | zPage, zPage); |
| 255 | 261 | }else{ |
| 256 | - if( g.perm.ApndTkt==0 || g.perm.Attach==0 ) login_needed(); | |
| 262 | + if( g.perm.ApndTkt==0 || g.perm.Attach==0 ){ | |
| 263 | + login_needed(g.anon.ApndTkt && g.anon.Attach); | |
| 264 | + return; | |
| 265 | + } | |
| 257 | 266 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTkt) ){ |
| 258 | 267 | zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" |
| 259 | 268 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 260 | 269 | if( zTkt==0 ) fossil_redirect_home(); |
| 261 | 270 | } |
| @@ -369,11 +378,14 @@ | ||
| 369 | 378 | Blob attach; /* Content of the attachment */ |
| 370 | 379 | int fShowContent = 0; |
| 371 | 380 | const char *zLn = P("ln"); |
| 372 | 381 | |
| 373 | 382 | login_check_credentials(); |
| 374 | - if( !g.perm.RdTkt && !g.perm.RdWiki ){ login_needed(); return; } | |
| 383 | + if( !g.perm.RdTkt && !g.perm.RdWiki ){ | |
| 384 | + login_needed(g.anon.RdTkt || g.anon.RdWiki); | |
| 385 | + return; | |
| 386 | + } | |
| 375 | 387 | rid = name_to_rid_www("name"); |
| 376 | 388 | if( rid==0 ){ fossil_redirect_home(); } |
| 377 | 389 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 378 | 390 | #if 0 |
| 379 | 391 | /* Shunning here needs to get both the attachment control artifact and |
| @@ -399,17 +411,17 @@ | ||
| 399 | 411 | fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0; |
| 400 | 412 | if( validate16(zTarget, strlen(zTarget)) |
| 401 | 413 | && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget) |
| 402 | 414 | ){ |
| 403 | 415 | zTktUuid = zTarget; |
| 404 | - if( !g.perm.RdTkt ){ login_needed(); return; } | |
| 416 | + if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } | |
| 405 | 417 | if( g.perm.WrTkt ){ |
| 406 | 418 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 407 | 419 | } |
| 408 | 420 | }else if( db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'",zTarget) ){ |
| 409 | 421 | zWikiName = zTarget; |
| 410 | - if( !g.perm.RdWiki ){ login_needed(); return; } | |
| 422 | + if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } | |
| 411 | 423 | if( g.perm.WrWiki ){ |
| 412 | 424 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 413 | 425 | } |
| 414 | 426 | } |
| 415 | 427 | zDate = db_text(0, "SELECT datetime(%.12f)", pAttach->rDate); |
| 416 | 428 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -48,19 +48,22 @@ | |
| 48 | " (SELECT uuid FROM blob WHERE rid=attachid), attachid" |
| 49 | " FROM attachment", |
| 50 | timeline_utc() |
| 51 | ); |
| 52 | if( zPage ){ |
| 53 | if( g.perm.RdWiki==0 ) login_needed(); |
| 54 | style_header("Attachments To %h", zPage); |
| 55 | blob_append_sql(&sql, " WHERE target=%Q", zPage); |
| 56 | }else if( zTkt ){ |
| 57 | if( g.perm.RdTkt==0 ) login_needed(); |
| 58 | style_header("Attachments To Ticket %S", zTkt); |
| 59 | blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt); |
| 60 | }else{ |
| 61 | if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ) login_needed(); |
| 62 | style_header("All Attachments"); |
| 63 | } |
| 64 | blob_append_sql(&sql, " ORDER BY mtime DESC"); |
| 65 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 66 | @ <ol> |
| @@ -150,14 +153,14 @@ | |
| 150 | |
| 151 | if( zPage && zTkt ) zTkt = 0; |
| 152 | if( zFile==0 ) fossil_redirect_home(); |
| 153 | login_check_credentials(); |
| 154 | if( zPage ){ |
| 155 | if( g.perm.RdWiki==0 ) login_needed(); |
| 156 | zTarget = zPage; |
| 157 | }else if( zTkt ){ |
| 158 | if( g.perm.RdTkt==0 ) login_needed(); |
| 159 | zTarget = zTkt; |
| 160 | }else{ |
| 161 | fossil_redirect_home(); |
| 162 | } |
| 163 | if( attachid>0 ){ |
| @@ -243,19 +246,25 @@ | |
| 243 | if( P("cancel") ) cgi_redirect(zFrom); |
| 244 | if( zPage && zTkt ) fossil_redirect_home(); |
| 245 | if( zPage==0 && zTkt==0 ) fossil_redirect_home(); |
| 246 | login_check_credentials(); |
| 247 | if( zPage ){ |
| 248 | if( g.perm.ApndWiki==0 || g.perm.Attach==0 ) login_needed(); |
| 249 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'", zPage) ){ |
| 250 | fossil_redirect_home(); |
| 251 | } |
| 252 | zTarget = zPage; |
| 253 | zTargetType = mprintf("Wiki Page <a href=\"%R/wiki?name=%h\">%h</a>", |
| 254 | zPage, zPage); |
| 255 | }else{ |
| 256 | if( g.perm.ApndTkt==0 || g.perm.Attach==0 ) login_needed(); |
| 257 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTkt) ){ |
| 258 | zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" |
| 259 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 260 | if( zTkt==0 ) fossil_redirect_home(); |
| 261 | } |
| @@ -369,11 +378,14 @@ | |
| 369 | Blob attach; /* Content of the attachment */ |
| 370 | int fShowContent = 0; |
| 371 | const char *zLn = P("ln"); |
| 372 | |
| 373 | login_check_credentials(); |
| 374 | if( !g.perm.RdTkt && !g.perm.RdWiki ){ login_needed(); return; } |
| 375 | rid = name_to_rid_www("name"); |
| 376 | if( rid==0 ){ fossil_redirect_home(); } |
| 377 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 378 | #if 0 |
| 379 | /* Shunning here needs to get both the attachment control artifact and |
| @@ -399,17 +411,17 @@ | |
| 399 | fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0; |
| 400 | if( validate16(zTarget, strlen(zTarget)) |
| 401 | && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget) |
| 402 | ){ |
| 403 | zTktUuid = zTarget; |
| 404 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 405 | if( g.perm.WrTkt ){ |
| 406 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 407 | } |
| 408 | }else if( db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'",zTarget) ){ |
| 409 | zWikiName = zTarget; |
| 410 | if( !g.perm.RdWiki ){ login_needed(); return; } |
| 411 | if( g.perm.WrWiki ){ |
| 412 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 413 | } |
| 414 | } |
| 415 | zDate = db_text(0, "SELECT datetime(%.12f)", pAttach->rDate); |
| 416 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -48,19 +48,22 @@ | |
| 48 | " (SELECT uuid FROM blob WHERE rid=attachid), attachid" |
| 49 | " FROM attachment", |
| 50 | timeline_utc() |
| 51 | ); |
| 52 | if( zPage ){ |
| 53 | if( g.perm.RdWiki==0 ){ login_needed(g.anon.RdWiki); return; } |
| 54 | style_header("Attachments To %h", zPage); |
| 55 | blob_append_sql(&sql, " WHERE target=%Q", zPage); |
| 56 | }else if( zTkt ){ |
| 57 | if( g.perm.RdTkt==0 ){ login_needed(g.anon.RdTkt); return; } |
| 58 | style_header("Attachments To Ticket %S", zTkt); |
| 59 | blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt); |
| 60 | }else{ |
| 61 | if( g.perm.RdTkt==0 && g.perm.RdWiki==0 ){ |
| 62 | login_needed(g.anon.RdTkt || g.anon.RdWiki); |
| 63 | return; |
| 64 | } |
| 65 | style_header("All Attachments"); |
| 66 | } |
| 67 | blob_append_sql(&sql, " ORDER BY mtime DESC"); |
| 68 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 69 | @ <ol> |
| @@ -150,14 +153,14 @@ | |
| 153 | |
| 154 | if( zPage && zTkt ) zTkt = 0; |
| 155 | if( zFile==0 ) fossil_redirect_home(); |
| 156 | login_check_credentials(); |
| 157 | if( zPage ){ |
| 158 | if( g.perm.RdWiki==0 ){ login_needed(g.anon.RdWiki); return; } |
| 159 | zTarget = zPage; |
| 160 | }else if( zTkt ){ |
| 161 | if( g.perm.RdTkt==0 ){ login_needed(g.anon.RdTkt); return; } |
| 162 | zTarget = zTkt; |
| 163 | }else{ |
| 164 | fossil_redirect_home(); |
| 165 | } |
| 166 | if( attachid>0 ){ |
| @@ -243,19 +246,25 @@ | |
| 246 | if( P("cancel") ) cgi_redirect(zFrom); |
| 247 | if( zPage && zTkt ) fossil_redirect_home(); |
| 248 | if( zPage==0 && zTkt==0 ) fossil_redirect_home(); |
| 249 | login_check_credentials(); |
| 250 | if( zPage ){ |
| 251 | if( g.perm.ApndWiki==0 || g.perm.Attach==0 ){ |
| 252 | login_needed(g.anon.ApndWiki && g.anon.Attach); |
| 253 | return; |
| 254 | } |
| 255 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'", zPage) ){ |
| 256 | fossil_redirect_home(); |
| 257 | } |
| 258 | zTarget = zPage; |
| 259 | zTargetType = mprintf("Wiki Page <a href=\"%R/wiki?name=%h\">%h</a>", |
| 260 | zPage, zPage); |
| 261 | }else{ |
| 262 | if( g.perm.ApndTkt==0 || g.perm.Attach==0 ){ |
| 263 | login_needed(g.anon.ApndTkt && g.anon.Attach); |
| 264 | return; |
| 265 | } |
| 266 | if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTkt) ){ |
| 267 | zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag" |
| 268 | " WHERE tagname GLOB 'tkt-%q*'", zTkt); |
| 269 | if( zTkt==0 ) fossil_redirect_home(); |
| 270 | } |
| @@ -369,11 +378,14 @@ | |
| 378 | Blob attach; /* Content of the attachment */ |
| 379 | int fShowContent = 0; |
| 380 | const char *zLn = P("ln"); |
| 381 | |
| 382 | login_check_credentials(); |
| 383 | if( !g.perm.RdTkt && !g.perm.RdWiki ){ |
| 384 | login_needed(g.anon.RdTkt || g.anon.RdWiki); |
| 385 | return; |
| 386 | } |
| 387 | rid = name_to_rid_www("name"); |
| 388 | if( rid==0 ){ fossil_redirect_home(); } |
| 389 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 390 | #if 0 |
| 391 | /* Shunning here needs to get both the attachment control artifact and |
| @@ -399,17 +411,17 @@ | |
| 411 | fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0; |
| 412 | if( validate16(zTarget, strlen(zTarget)) |
| 413 | && db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget) |
| 414 | ){ |
| 415 | zTktUuid = zTarget; |
| 416 | if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } |
| 417 | if( g.perm.WrTkt ){ |
| 418 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 419 | } |
| 420 | }else if( db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'",zTarget) ){ |
| 421 | zWikiName = zTarget; |
| 422 | if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } |
| 423 | if( g.perm.WrWiki ){ |
| 424 | style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid); |
| 425 | } |
| 426 | } |
| 427 | zDate = db_text(0, "SELECT datetime(%.12f)", pAttach->rDate); |
| 428 |
+3
-3
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -339,11 +339,11 @@ | ||
| 339 | 339 | */ |
| 340 | 340 | static void new_brlist_page(void){ |
| 341 | 341 | Stmt q; |
| 342 | 342 | double rNow; |
| 343 | 343 | login_check_credentials(); |
| 344 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 344 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 345 | 345 | style_header("Branches"); |
| 346 | 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | 347 | login_anonymous_available(); |
| 348 | 348 | |
| 349 | 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| @@ -408,11 +408,11 @@ | ||
| 408 | 408 | if( showClosed==0 && showAll==0 && showOpen==0 && colorTest==0 ){ |
| 409 | 409 | new_brlist_page(); |
| 410 | 410 | return; |
| 411 | 411 | } |
| 412 | 412 | login_check_credentials(); |
| 413 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 413 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 414 | 414 | if( colorTest ){ |
| 415 | 415 | showClosed = 0; |
| 416 | 416 | showAll = 1; |
| 417 | 417 | } |
| 418 | 418 | if( showAll ) brFlags = BRL_BOTH; |
| @@ -515,11 +515,11 @@ | ||
| 515 | 515 | */ |
| 516 | 516 | void brtimeline_page(void){ |
| 517 | 517 | Stmt q; |
| 518 | 518 | |
| 519 | 519 | login_check_credentials(); |
| 520 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 520 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 521 | 521 | |
| 522 | 522 | style_header("Branches"); |
| 523 | 523 | style_submenu_element("List", "List", "brlist"); |
| 524 | 524 | login_anonymous_available(); |
| 525 | 525 | @ <h2>The initial check-in for each branch:</h2> |
| 526 | 526 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -339,11 +339,11 @@ | |
| 339 | */ |
| 340 | static void new_brlist_page(void){ |
| 341 | Stmt q; |
| 342 | double rNow; |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Read ){ login_needed(); return; } |
| 345 | style_header("Branches"); |
| 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | login_anonymous_available(); |
| 348 | |
| 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| @@ -408,11 +408,11 @@ | |
| 408 | if( showClosed==0 && showAll==0 && showOpen==0 && colorTest==0 ){ |
| 409 | new_brlist_page(); |
| 410 | return; |
| 411 | } |
| 412 | login_check_credentials(); |
| 413 | if( !g.perm.Read ){ login_needed(); return; } |
| 414 | if( colorTest ){ |
| 415 | showClosed = 0; |
| 416 | showAll = 1; |
| 417 | } |
| 418 | if( showAll ) brFlags = BRL_BOTH; |
| @@ -515,11 +515,11 @@ | |
| 515 | */ |
| 516 | void brtimeline_page(void){ |
| 517 | Stmt q; |
| 518 | |
| 519 | login_check_credentials(); |
| 520 | if( !g.perm.Read ){ login_needed(); return; } |
| 521 | |
| 522 | style_header("Branches"); |
| 523 | style_submenu_element("List", "List", "brlist"); |
| 524 | login_anonymous_available(); |
| 525 | @ <h2>The initial check-in for each branch:</h2> |
| 526 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -339,11 +339,11 @@ | |
| 339 | */ |
| 340 | static void new_brlist_page(void){ |
| 341 | Stmt q; |
| 342 | double rNow; |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 345 | style_header("Branches"); |
| 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | login_anonymous_available(); |
| 348 | |
| 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| @@ -408,11 +408,11 @@ | |
| 408 | if( showClosed==0 && showAll==0 && showOpen==0 && colorTest==0 ){ |
| 409 | new_brlist_page(); |
| 410 | return; |
| 411 | } |
| 412 | login_check_credentials(); |
| 413 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 414 | if( colorTest ){ |
| 415 | showClosed = 0; |
| 416 | showAll = 1; |
| 417 | } |
| 418 | if( showAll ) brFlags = BRL_BOTH; |
| @@ -515,11 +515,11 @@ | |
| 515 | */ |
| 516 | void brtimeline_page(void){ |
| 517 | Stmt q; |
| 518 | |
| 519 | login_check_credentials(); |
| 520 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 521 | |
| 522 | style_header("Branches"); |
| 523 | style_submenu_element("List", "List", "brlist"); |
| 524 | login_anonymous_available(); |
| 525 | @ <h2>The initial check-in for each branch:</h2> |
| 526 |
+3
-3
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -130,11 +130,11 @@ | ||
| 130 | 130 | int linkTip = 1; |
| 131 | 131 | HQuery sURI; |
| 132 | 132 | |
| 133 | 133 | if( strcmp(PD("type","flat"),"tree")==0 ){ page_tree(); return; } |
| 134 | 134 | login_check_credentials(); |
| 135 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 135 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 136 | 136 | while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; } |
| 137 | 137 | style_header("File List"); |
| 138 | 138 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 139 | 139 | sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0, |
| 140 | 140 | pathelementFunc, 0, 0); |
| @@ -542,11 +542,11 @@ | ||
| 542 | 542 | char *zProjectName = db_get("project-name", 0); |
| 543 | 543 | |
| 544 | 544 | if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; } |
| 545 | 545 | memset(&sTree, 0, sizeof(sTree)); |
| 546 | 546 | login_check_credentials(); |
| 547 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 547 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 548 | 548 | while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; } |
| 549 | 549 | sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0, |
| 550 | 550 | pathelementFunc, 0, 0); |
| 551 | 551 | url_initialize(&sURI, "tree"); |
| 552 | 552 | cgi_query_parameters_to_url(&sURI); |
| @@ -1002,11 +1002,11 @@ | ||
| 1002 | 1002 | const char *zNow; /* Time of checkin */ |
| 1003 | 1003 | int showId = PB("showid"); |
| 1004 | 1004 | Stmt q1, q2; |
| 1005 | 1005 | double baseTime; |
| 1006 | 1006 | login_check_credentials(); |
| 1007 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 1007 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 1008 | 1008 | zName = P("name"); |
| 1009 | 1009 | if( zName==0 ) zName = "tip"; |
| 1010 | 1010 | rid = symbolic_name_to_rid(zName, "ci"); |
| 1011 | 1011 | if( rid==0 ){ |
| 1012 | 1012 | fossil_fatal("not a valid check-in: %s", zName); |
| 1013 | 1013 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -130,11 +130,11 @@ | |
| 130 | int linkTip = 1; |
| 131 | HQuery sURI; |
| 132 | |
| 133 | if( strcmp(PD("type","flat"),"tree")==0 ){ page_tree(); return; } |
| 134 | login_check_credentials(); |
| 135 | if( !g.perm.Read ){ login_needed(); return; } |
| 136 | while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; } |
| 137 | style_header("File List"); |
| 138 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 139 | sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0, |
| 140 | pathelementFunc, 0, 0); |
| @@ -542,11 +542,11 @@ | |
| 542 | char *zProjectName = db_get("project-name", 0); |
| 543 | |
| 544 | if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; } |
| 545 | memset(&sTree, 0, sizeof(sTree)); |
| 546 | login_check_credentials(); |
| 547 | if( !g.perm.Read ){ login_needed(); return; } |
| 548 | while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; } |
| 549 | sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0, |
| 550 | pathelementFunc, 0, 0); |
| 551 | url_initialize(&sURI, "tree"); |
| 552 | cgi_query_parameters_to_url(&sURI); |
| @@ -1002,11 +1002,11 @@ | |
| 1002 | const char *zNow; /* Time of checkin */ |
| 1003 | int showId = PB("showid"); |
| 1004 | Stmt q1, q2; |
| 1005 | double baseTime; |
| 1006 | login_check_credentials(); |
| 1007 | if( !g.perm.Read ){ login_needed(); return; } |
| 1008 | zName = P("name"); |
| 1009 | if( zName==0 ) zName = "tip"; |
| 1010 | rid = symbolic_name_to_rid(zName, "ci"); |
| 1011 | if( rid==0 ){ |
| 1012 | fossil_fatal("not a valid check-in: %s", zName); |
| 1013 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -130,11 +130,11 @@ | |
| 130 | int linkTip = 1; |
| 131 | HQuery sURI; |
| 132 | |
| 133 | if( strcmp(PD("type","flat"),"tree")==0 ){ page_tree(); return; } |
| 134 | login_check_credentials(); |
| 135 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 136 | while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; } |
| 137 | style_header("File List"); |
| 138 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 139 | sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0, |
| 140 | pathelementFunc, 0, 0); |
| @@ -542,11 +542,11 @@ | |
| 542 | char *zProjectName = db_get("project-name", 0); |
| 543 | |
| 544 | if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; } |
| 545 | memset(&sTree, 0, sizeof(sTree)); |
| 546 | login_check_credentials(); |
| 547 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 548 | while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; } |
| 549 | sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0, |
| 550 | pathelementFunc, 0, 0); |
| 551 | url_initialize(&sURI, "tree"); |
| 552 | cgi_query_parameters_to_url(&sURI); |
| @@ -1002,11 +1002,11 @@ | |
| 1002 | const char *zNow; /* Time of checkin */ |
| 1003 | int showId = PB("showid"); |
| 1004 | Stmt q1, q2; |
| 1005 | double baseTime; |
| 1006 | login_check_credentials(); |
| 1007 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1008 | zName = P("name"); |
| 1009 | if( zName==0 ) zName = "tip"; |
| 1010 | rid = symbolic_name_to_rid(zName, "ci"); |
| 1011 | if( rid==0 ){ |
| 1012 | fossil_fatal("not a valid check-in: %s", zName); |
| 1013 |
+2
-2
| --- src/cache.c | ||
| +++ src/cache.c | ||
| @@ -330,11 +330,11 @@ | ||
| 330 | 330 | sqlite3 *db; |
| 331 | 331 | sqlite3_stmt *pStmt; |
| 332 | 332 | char zBuf[100]; |
| 333 | 333 | |
| 334 | 334 | login_check_credentials(); |
| 335 | - if( !g.perm.Setup ){ login_needed(); return; } | |
| 335 | + if( !g.perm.Setup ){ login_needed(0); return; } | |
| 336 | 336 | style_header("Web Cache Status"); |
| 337 | 337 | db = cacheOpen(0); |
| 338 | 338 | if( db==0 ){ |
| 339 | 339 | @ The web-page cache is disabled for this repository |
| 340 | 340 | }else{ |
| @@ -378,11 +378,11 @@ | ||
| 378 | 378 | void cache_getpage(void){ |
| 379 | 379 | const char *zKey; |
| 380 | 380 | Blob content; |
| 381 | 381 | |
| 382 | 382 | login_check_credentials(); |
| 383 | - if( !g.perm.Setup ){ login_needed(); return; } | |
| 383 | + if( !g.perm.Setup ){ login_needed(0); return; } | |
| 384 | 384 | zKey = PD("key",""); |
| 385 | 385 | blob_zero(&content); |
| 386 | 386 | if( cache_read(&content, zKey)==0 ){ |
| 387 | 387 | style_header("Cache Download Error"); |
| 388 | 388 | @ The cache does not contain any entry with this key: "%h(zKey)" |
| 389 | 389 |
| --- src/cache.c | |
| +++ src/cache.c | |
| @@ -330,11 +330,11 @@ | |
| 330 | sqlite3 *db; |
| 331 | sqlite3_stmt *pStmt; |
| 332 | char zBuf[100]; |
| 333 | |
| 334 | login_check_credentials(); |
| 335 | if( !g.perm.Setup ){ login_needed(); return; } |
| 336 | style_header("Web Cache Status"); |
| 337 | db = cacheOpen(0); |
| 338 | if( db==0 ){ |
| 339 | @ The web-page cache is disabled for this repository |
| 340 | }else{ |
| @@ -378,11 +378,11 @@ | |
| 378 | void cache_getpage(void){ |
| 379 | const char *zKey; |
| 380 | Blob content; |
| 381 | |
| 382 | login_check_credentials(); |
| 383 | if( !g.perm.Setup ){ login_needed(); return; } |
| 384 | zKey = PD("key",""); |
| 385 | blob_zero(&content); |
| 386 | if( cache_read(&content, zKey)==0 ){ |
| 387 | style_header("Cache Download Error"); |
| 388 | @ The cache does not contain any entry with this key: "%h(zKey)" |
| 389 |
| --- src/cache.c | |
| +++ src/cache.c | |
| @@ -330,11 +330,11 @@ | |
| 330 | sqlite3 *db; |
| 331 | sqlite3_stmt *pStmt; |
| 332 | char zBuf[100]; |
| 333 | |
| 334 | login_check_credentials(); |
| 335 | if( !g.perm.Setup ){ login_needed(0); return; } |
| 336 | style_header("Web Cache Status"); |
| 337 | db = cacheOpen(0); |
| 338 | if( db==0 ){ |
| 339 | @ The web-page cache is disabled for this repository |
| 340 | }else{ |
| @@ -378,11 +378,11 @@ | |
| 378 | void cache_getpage(void){ |
| 379 | const char *zKey; |
| 380 | Blob content; |
| 381 | |
| 382 | login_check_credentials(); |
| 383 | if( !g.perm.Setup ){ login_needed(0); return; } |
| 384 | zKey = PD("key",""); |
| 385 | blob_zero(&content); |
| 386 | if( cache_read(&content, zKey)==0 ){ |
| 387 | style_header("Cache Download Error"); |
| 388 | @ The cache does not contain any entry with this key: "%h(zKey)" |
| 389 |
+1
-1
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -439,11 +439,11 @@ | ||
| 439 | 439 | Stmt q; |
| 440 | 440 | int showAll = P("all")!=0; |
| 441 | 441 | int showClosed = P("closed")!=0; |
| 442 | 442 | |
| 443 | 443 | login_check_credentials(); |
| 444 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 444 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 445 | 445 | |
| 446 | 446 | if( !showAll ){ |
| 447 | 447 | style_submenu_element("All", "All", "leaves?all"); |
| 448 | 448 | } |
| 449 | 449 | if( !showClosed ){ |
| 450 | 450 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -439,11 +439,11 @@ | |
| 439 | Stmt q; |
| 440 | int showAll = P("all")!=0; |
| 441 | int showClosed = P("closed")!=0; |
| 442 | |
| 443 | login_check_credentials(); |
| 444 | if( !g.perm.Read ){ login_needed(); return; } |
| 445 | |
| 446 | if( !showAll ){ |
| 447 | style_submenu_element("All", "All", "leaves?all"); |
| 448 | } |
| 449 | if( !showClosed ){ |
| 450 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -439,11 +439,11 @@ | |
| 439 | Stmt q; |
| 440 | int showAll = P("all")!=0; |
| 441 | int showClosed = P("closed")!=0; |
| 442 | |
| 443 | login_check_credentials(); |
| 444 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 445 | |
| 446 | if( !showAll ){ |
| 447 | style_submenu_element("All", "All", "leaves?all"); |
| 448 | } |
| 449 | if( !showClosed ){ |
| 450 |
+1
-1
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -2234,11 +2234,11 @@ | ||
| 2234 | 2234 | int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */ |
| 2235 | 2235 | |
| 2236 | 2236 | /* Gather query parameters */ |
| 2237 | 2237 | showLog = atoi(PD("log","1")); |
| 2238 | 2238 | login_check_credentials(); |
| 2239 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 2239 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 2240 | 2240 | if( exclude_spiders("annotate") ) return; |
| 2241 | 2241 | load_control(); |
| 2242 | 2242 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2243 | 2243 | zFilename = P("filename"); |
| 2244 | 2244 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2245 | 2245 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -2234,11 +2234,11 @@ | |
| 2234 | int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */ |
| 2235 | |
| 2236 | /* Gather query parameters */ |
| 2237 | showLog = atoi(PD("log","1")); |
| 2238 | login_check_credentials(); |
| 2239 | if( !g.perm.Read ){ login_needed(); return; } |
| 2240 | if( exclude_spiders("annotate") ) return; |
| 2241 | load_control(); |
| 2242 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2243 | zFilename = P("filename"); |
| 2244 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2245 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -2234,11 +2234,11 @@ | |
| 2234 | int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */ |
| 2235 | |
| 2236 | /* Gather query parameters */ |
| 2237 | showLog = atoi(PD("log","1")); |
| 2238 | login_check_credentials(); |
| 2239 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 2240 | if( exclude_spiders("annotate") ) return; |
| 2241 | load_control(); |
| 2242 | mid = name_to_typed_rid(PD("checkin","0"),"ci"); |
| 2243 | zFilename = P("filename"); |
| 2244 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 2245 |
+1
-1
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -841,11 +841,11 @@ | ||
| 841 | 841 | */ |
| 842 | 842 | void vpatch_page(void){ |
| 843 | 843 | const char *zFrom = P("from"); |
| 844 | 844 | const char *zTo = P("to"); |
| 845 | 845 | login_check_credentials(); |
| 846 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 846 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 847 | 847 | if( zFrom==0 || zTo==0 ) fossil_redirect_home(); |
| 848 | 848 | |
| 849 | 849 | cgi_set_content_type("text/plain"); |
| 850 | 850 | diff_all_two_versions(zFrom, zTo, 0, 0, 0, DIFF_VERBOSE); |
| 851 | 851 | } |
| 852 | 852 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -841,11 +841,11 @@ | |
| 841 | */ |
| 842 | void vpatch_page(void){ |
| 843 | const char *zFrom = P("from"); |
| 844 | const char *zTo = P("to"); |
| 845 | login_check_credentials(); |
| 846 | if( !g.perm.Read ){ login_needed(); return; } |
| 847 | if( zFrom==0 || zTo==0 ) fossil_redirect_home(); |
| 848 | |
| 849 | cgi_set_content_type("text/plain"); |
| 850 | diff_all_two_versions(zFrom, zTo, 0, 0, 0, DIFF_VERBOSE); |
| 851 | } |
| 852 |
| --- src/diffcmd.c | |
| +++ src/diffcmd.c | |
| @@ -841,11 +841,11 @@ | |
| 841 | */ |
| 842 | void vpatch_page(void){ |
| 843 | const char *zFrom = P("from"); |
| 844 | const char *zTo = P("to"); |
| 845 | login_check_credentials(); |
| 846 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 847 | if( zFrom==0 || zTo==0 ) fossil_redirect_home(); |
| 848 | |
| 849 | cgi_set_content_type("text/plain"); |
| 850 | diff_all_two_versions(zFrom, zTo, 0, 0, 0, DIFF_VERBOSE); |
| 851 | } |
| 852 |
+1
-1
| --- src/doc.c | ||
| +++ src/doc.c | ||
| @@ -543,11 +543,11 @@ | ||
| 543 | 543 | static const char *const azSuffix[] = { |
| 544 | 544 | "index.html", "index.wiki", "index.md" |
| 545 | 545 | }; |
| 546 | 546 | |
| 547 | 547 | login_check_credentials(); |
| 548 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 548 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 549 | 549 | blob_init(&title, 0, 0); |
| 550 | 550 | db_begin_transaction(); |
| 551 | 551 | while( rid==0 && (++nMiss)<=ArraySize(azSuffix) ){ |
| 552 | 552 | zName = PD("name", "tip/index.wiki"); |
| 553 | 553 | for(i=0; zName[i] && zName[i]!='/'; i++){} |
| 554 | 554 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -543,11 +543,11 @@ | |
| 543 | static const char *const azSuffix[] = { |
| 544 | "index.html", "index.wiki", "index.md" |
| 545 | }; |
| 546 | |
| 547 | login_check_credentials(); |
| 548 | if( !g.perm.Read ){ login_needed(); return; } |
| 549 | blob_init(&title, 0, 0); |
| 550 | db_begin_transaction(); |
| 551 | while( rid==0 && (++nMiss)<=ArraySize(azSuffix) ){ |
| 552 | zName = PD("name", "tip/index.wiki"); |
| 553 | for(i=0; zName[i] && zName[i]!='/'; i++){} |
| 554 |
| --- src/doc.c | |
| +++ src/doc.c | |
| @@ -543,11 +543,11 @@ | |
| 543 | static const char *const azSuffix[] = { |
| 544 | "index.html", "index.wiki", "index.md" |
| 545 | }; |
| 546 | |
| 547 | login_check_credentials(); |
| 548 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 549 | blob_init(&title, 0, 0); |
| 550 | db_begin_transaction(); |
| 551 | while( rid==0 && (++nMiss)<=ArraySize(azSuffix) ){ |
| 552 | zName = PD("name", "tip/index.wiki"); |
| 553 | for(i=0; zName[i] && zName[i]!='/'; i++){} |
| 554 |
+2
-2
| --- src/event.c | ||
| +++ src/event.c | ||
| @@ -69,11 +69,11 @@ | ||
| 69 | 69 | |
| 70 | 70 | /* wiki-read privilege is needed in order to read events. |
| 71 | 71 | */ |
| 72 | 72 | login_check_credentials(); |
| 73 | 73 | if( !g.perm.RdWiki ){ |
| 74 | - login_needed(); | |
| 74 | + login_needed(g.anon.RdWiki); | |
| 75 | 75 | return; |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | 78 | zEventId = P("name"); |
| 79 | 79 | if( zEventId==0 ){ fossil_redirect_home(); return; } |
| @@ -233,11 +233,11 @@ | ||
| 233 | 233 | |
| 234 | 234 | /* Need both check-in and wiki-write or wiki-create privileges in order |
| 235 | 235 | ** to edit/create an event. |
| 236 | 236 | */ |
| 237 | 237 | if( !g.perm.Write || (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){ |
| 238 | - login_needed(); | |
| 238 | + login_needed(g.anon.Write && (rid ? g.anon.WrWiki : g.anon.NewWiki)); | |
| 239 | 239 | return; |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | 242 | /* Figure out the color */ |
| 243 | 243 | if( rid ){ |
| 244 | 244 |
| --- src/event.c | |
| +++ src/event.c | |
| @@ -69,11 +69,11 @@ | |
| 69 | |
| 70 | /* wiki-read privilege is needed in order to read events. |
| 71 | */ |
| 72 | login_check_credentials(); |
| 73 | if( !g.perm.RdWiki ){ |
| 74 | login_needed(); |
| 75 | return; |
| 76 | } |
| 77 | |
| 78 | zEventId = P("name"); |
| 79 | if( zEventId==0 ){ fossil_redirect_home(); return; } |
| @@ -233,11 +233,11 @@ | |
| 233 | |
| 234 | /* Need both check-in and wiki-write or wiki-create privileges in order |
| 235 | ** to edit/create an event. |
| 236 | */ |
| 237 | if( !g.perm.Write || (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){ |
| 238 | login_needed(); |
| 239 | return; |
| 240 | } |
| 241 | |
| 242 | /* Figure out the color */ |
| 243 | if( rid ){ |
| 244 |
| --- src/event.c | |
| +++ src/event.c | |
| @@ -69,11 +69,11 @@ | |
| 69 | |
| 70 | /* wiki-read privilege is needed in order to read events. |
| 71 | */ |
| 72 | login_check_credentials(); |
| 73 | if( !g.perm.RdWiki ){ |
| 74 | login_needed(g.anon.RdWiki); |
| 75 | return; |
| 76 | } |
| 77 | |
| 78 | zEventId = P("name"); |
| 79 | if( zEventId==0 ){ fossil_redirect_home(); return; } |
| @@ -233,11 +233,11 @@ | |
| 233 | |
| 234 | /* Need both check-in and wiki-write or wiki-create privileges in order |
| 235 | ** to edit/create an event. |
| 236 | */ |
| 237 | if( !g.perm.Write || (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){ |
| 238 | login_needed(g.anon.Write && (rid ? g.anon.WrWiki : g.anon.NewWiki)); |
| 239 | return; |
| 240 | } |
| 241 | |
| 242 | /* Figure out the color */ |
| 243 | if( rid ){ |
| 244 |
+1
-1
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -305,11 +305,11 @@ | ||
| 305 | 305 | int uBg = P("ubg")!=0; |
| 306 | 306 | int fDebug = atoi(PD("debug","0")); |
| 307 | 307 | int fShowId = P("showid")!=0; |
| 308 | 308 | |
| 309 | 309 | login_check_credentials(); |
| 310 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 310 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 311 | 311 | style_header("File History"); |
| 312 | 312 | login_anonymous_available(); |
| 313 | 313 | url_initialize(&url, "finfo"); |
| 314 | 314 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 315 | 315 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 316 | 316 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -305,11 +305,11 @@ | |
| 305 | int uBg = P("ubg")!=0; |
| 306 | int fDebug = atoi(PD("debug","0")); |
| 307 | int fShowId = P("showid")!=0; |
| 308 | |
| 309 | login_check_credentials(); |
| 310 | if( !g.perm.Read ){ login_needed(); return; } |
| 311 | style_header("File History"); |
| 312 | login_anonymous_available(); |
| 313 | url_initialize(&url, "finfo"); |
| 314 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 315 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 316 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -305,11 +305,11 @@ | |
| 305 | int uBg = P("ubg")!=0; |
| 306 | int fDebug = atoi(PD("debug","0")); |
| 307 | int fShowId = P("showid")!=0; |
| 308 | |
| 309 | login_check_credentials(); |
| 310 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 311 | style_header("File History"); |
| 312 | login_anonymous_available(); |
| 313 | url_initialize(&url, "finfo"); |
| 314 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 315 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 316 |
+13
-13
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -527,11 +527,11 @@ | ||
| 527 | 527 | const char *zW; /* URL param for ignoring whitespace */ |
| 528 | 528 | const char *zPage = "vinfo"; /* Page that shows diffs */ |
| 529 | 529 | const char *zPageHide = "ci"; /* Page that hides diffs */ |
| 530 | 530 | |
| 531 | 531 | login_check_credentials(); |
| 532 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 532 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 533 | 533 | zName = P("name"); |
| 534 | 534 | rid = name_to_rid_www("name"); |
| 535 | 535 | if( rid==0 ){ |
| 536 | 536 | style_header("Check-in Information Error"); |
| 537 | 537 | @ No such object: %h(g.argv[2]) |
| @@ -657,11 +657,11 @@ | ||
| 657 | 657 | } |
| 658 | 658 | db_finalize(&q2); |
| 659 | 659 | |
| 660 | 660 | |
| 661 | 661 | /* The Download: line */ |
| 662 | - if( g.perm.Zip ){ | |
| 662 | + if( g.anon.Zip ){ | |
| 663 | 663 | char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s", |
| 664 | 664 | zPJ, zUuid, zUuid); |
| 665 | 665 | @ </td></tr> |
| 666 | 666 | @ <tr><th>Downloads:</th><td> |
| 667 | 667 | @ %z(href("%s",zUrl))Tarball</a> |
| @@ -674,11 +674,11 @@ | ||
| 674 | 674 | @ <td> |
| 675 | 675 | @ %z(href("%R/tree?ci=%!S",zUuid))files</a> |
| 676 | 676 | @ | %z(href("%R/fileage?name=%!S",zUuid))file ages</a> |
| 677 | 677 | @ | %z(href("%R/tree?nofiles&type=tree&ci=%!S",zUuid))folders</a> |
| 678 | 678 | @ | %z(href("%R/artifact/%!S",zUuid))manifest</a> |
| 679 | - if( g.perm.Write ){ | |
| 679 | + if( g.anon.Write ){ | |
| 680 | 680 | @ | %z(href("%R/ci_edit?r=%!S",zUuid))edit</a> |
| 681 | 681 | } |
| 682 | 682 | @ </td> |
| 683 | 683 | @ </tr> |
| 684 | 684 | blob_reset(&projName); |
| @@ -773,11 +773,11 @@ | ||
| 773 | 773 | Blob wiki; |
| 774 | 774 | int modPending; |
| 775 | 775 | const char *zModAction; |
| 776 | 776 | |
| 777 | 777 | login_check_credentials(); |
| 778 | - if( !g.perm.RdWiki ){ login_needed(); return; } | |
| 778 | + if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } | |
| 779 | 779 | rid = name_to_rid_www("name"); |
| 780 | 780 | if( rid==0 || (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))==0 ){ |
| 781 | 781 | style_header("Wiki Page Information Error"); |
| 782 | 782 | @ No such object: %h(P("name")) |
| 783 | 783 | style_footer(); |
| @@ -991,11 +991,11 @@ | ||
| 991 | 991 | const char *zW; |
| 992 | 992 | const char *zVerbose; |
| 993 | 993 | const char *zGlob; |
| 994 | 994 | ReCompiled *pRe = 0; |
| 995 | 995 | login_check_credentials(); |
| 996 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 996 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 997 | 997 | login_anonymous_available(); |
| 998 | 998 | zRe = P("regex"); |
| 999 | 999 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1000 | 1000 | zBranch = P("branch"); |
| 1001 | 1001 | if( zBranch && zBranch[0] ){ |
| @@ -1363,17 +1363,17 @@ | ||
| 1363 | 1363 | }else{ |
| 1364 | 1364 | @ Attachment "%h(zFilename)" to |
| 1365 | 1365 | } |
| 1366 | 1366 | objType |= OBJTYPE_ATTACHMENT; |
| 1367 | 1367 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1368 | - if( g.perm.Hyperlink && g.perm.RdTkt ){ | |
| 1368 | + if( g.perm.Hyperlink && g.anon.RdTkt ){ | |
| 1369 | 1369 | @ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>] |
| 1370 | 1370 | }else{ |
| 1371 | 1371 | @ ticket [%S(zTarget)] |
| 1372 | 1372 | } |
| 1373 | 1373 | }else{ |
| 1374 | - if( g.perm.Hyperlink && g.perm.RdWiki ){ | |
| 1374 | + if( g.perm.Hyperlink && g.anon.RdWiki ){ | |
| 1375 | 1375 | @ wiki page [%z(href("%R/wiki?name=%t",zTarget))%h(zTarget)</a>] |
| 1376 | 1376 | }else{ |
| 1377 | 1377 | @ wiki page [%h(zTarget)] |
| 1378 | 1378 | } |
| 1379 | 1379 | } |
| @@ -1421,11 +1421,11 @@ | ||
| 1421 | 1421 | ReCompiled *pRe = 0; |
| 1422 | 1422 | u64 diffFlags; |
| 1423 | 1423 | u32 objdescFlags = 0; |
| 1424 | 1424 | |
| 1425 | 1425 | login_check_credentials(); |
| 1426 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 1426 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 1427 | 1427 | v1 = name_to_rid_www("v1"); |
| 1428 | 1428 | v2 = name_to_rid_www("v2"); |
| 1429 | 1429 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 1430 | 1430 | zRe = P("regex"); |
| 1431 | 1431 | if( zRe ) re_compile(&pRe, zRe, 0); |
| @@ -1506,11 +1506,11 @@ | ||
| 1506 | 1506 | const char *zMime; |
| 1507 | 1507 | Blob content; |
| 1508 | 1508 | |
| 1509 | 1509 | rid = name_to_rid_www("name"); |
| 1510 | 1510 | login_check_credentials(); |
| 1511 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 1511 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 1512 | 1512 | if( rid==0 ) fossil_redirect_home(); |
| 1513 | 1513 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1514 | 1514 | if( fossil_strcmp(P("name"), zUuid)==0 && login_is_nobody() ){ |
| 1515 | 1515 | g.isConst = 1; |
| 1516 | 1516 | } |
| @@ -1603,11 +1603,11 @@ | ||
| 1603 | 1603 | char *zUuid; |
| 1604 | 1604 | u32 objdescFlags = 0; |
| 1605 | 1605 | |
| 1606 | 1606 | rid = name_to_rid_www("name"); |
| 1607 | 1607 | login_check_credentials(); |
| 1608 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 1608 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 1609 | 1609 | if( rid==0 ) fossil_redirect_home(); |
| 1610 | 1610 | if( g.perm.Admin ){ |
| 1611 | 1611 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1612 | 1612 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1613 | 1613 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun", |
| @@ -1789,11 +1789,11 @@ | ||
| 1789 | 1789 | if( rid==0 ){ |
| 1790 | 1790 | rid = name_to_rid_www("name"); |
| 1791 | 1791 | } |
| 1792 | 1792 | |
| 1793 | 1793 | login_check_credentials(); |
| 1794 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 1794 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 1795 | 1795 | if( rid==0 ) fossil_redirect_home(); |
| 1796 | 1796 | if( g.perm.Admin ){ |
| 1797 | 1797 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1798 | 1798 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1799 | 1799 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| @@ -1904,11 +1904,11 @@ | ||
| 1904 | 1904 | Manifest *pTktChng; |
| 1905 | 1905 | int modPending; |
| 1906 | 1906 | const char *zModAction; |
| 1907 | 1907 | char *zTktTitle; |
| 1908 | 1908 | login_check_credentials(); |
| 1909 | - if( !g.perm.RdTkt ){ login_needed(); return; } | |
| 1909 | + if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } | |
| 1910 | 1910 | rid = name_to_rid_www("name"); |
| 1911 | 1911 | if( rid==0 ){ fossil_redirect_home(); } |
| 1912 | 1912 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1913 | 1913 | if( g.perm.Admin ){ |
| 1914 | 1914 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| @@ -2276,11 +2276,11 @@ | ||
| 2276 | 2276 | Blob comment; |
| 2277 | 2277 | char *zBranchName = 0; |
| 2278 | 2278 | Stmt q; |
| 2279 | 2279 | |
| 2280 | 2280 | login_check_credentials(); |
| 2281 | - if( !g.perm.Write ){ login_needed(); return; } | |
| 2281 | + if( !g.perm.Write ){ login_needed(g.anon.Write); return; } | |
| 2282 | 2282 | rid = name_to_typed_rid(P("r"), "ci"); |
| 2283 | 2283 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 2284 | 2284 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| 2285 | 2285 | " FROM event WHERE objid=%d", rid); |
| 2286 | 2286 | if( zComment==0 ) fossil_redirect_home(); |
| 2287 | 2287 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -527,11 +527,11 @@ | |
| 527 | const char *zW; /* URL param for ignoring whitespace */ |
| 528 | const char *zPage = "vinfo"; /* Page that shows diffs */ |
| 529 | const char *zPageHide = "ci"; /* Page that hides diffs */ |
| 530 | |
| 531 | login_check_credentials(); |
| 532 | if( !g.perm.Read ){ login_needed(); return; } |
| 533 | zName = P("name"); |
| 534 | rid = name_to_rid_www("name"); |
| 535 | if( rid==0 ){ |
| 536 | style_header("Check-in Information Error"); |
| 537 | @ No such object: %h(g.argv[2]) |
| @@ -657,11 +657,11 @@ | |
| 657 | } |
| 658 | db_finalize(&q2); |
| 659 | |
| 660 | |
| 661 | /* The Download: line */ |
| 662 | if( g.perm.Zip ){ |
| 663 | char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s", |
| 664 | zPJ, zUuid, zUuid); |
| 665 | @ </td></tr> |
| 666 | @ <tr><th>Downloads:</th><td> |
| 667 | @ %z(href("%s",zUrl))Tarball</a> |
| @@ -674,11 +674,11 @@ | |
| 674 | @ <td> |
| 675 | @ %z(href("%R/tree?ci=%!S",zUuid))files</a> |
| 676 | @ | %z(href("%R/fileage?name=%!S",zUuid))file ages</a> |
| 677 | @ | %z(href("%R/tree?nofiles&type=tree&ci=%!S",zUuid))folders</a> |
| 678 | @ | %z(href("%R/artifact/%!S",zUuid))manifest</a> |
| 679 | if( g.perm.Write ){ |
| 680 | @ | %z(href("%R/ci_edit?r=%!S",zUuid))edit</a> |
| 681 | } |
| 682 | @ </td> |
| 683 | @ </tr> |
| 684 | blob_reset(&projName); |
| @@ -773,11 +773,11 @@ | |
| 773 | Blob wiki; |
| 774 | int modPending; |
| 775 | const char *zModAction; |
| 776 | |
| 777 | login_check_credentials(); |
| 778 | if( !g.perm.RdWiki ){ login_needed(); return; } |
| 779 | rid = name_to_rid_www("name"); |
| 780 | if( rid==0 || (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))==0 ){ |
| 781 | style_header("Wiki Page Information Error"); |
| 782 | @ No such object: %h(P("name")) |
| 783 | style_footer(); |
| @@ -991,11 +991,11 @@ | |
| 991 | const char *zW; |
| 992 | const char *zVerbose; |
| 993 | const char *zGlob; |
| 994 | ReCompiled *pRe = 0; |
| 995 | login_check_credentials(); |
| 996 | if( !g.perm.Read ){ login_needed(); return; } |
| 997 | login_anonymous_available(); |
| 998 | zRe = P("regex"); |
| 999 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1000 | zBranch = P("branch"); |
| 1001 | if( zBranch && zBranch[0] ){ |
| @@ -1363,17 +1363,17 @@ | |
| 1363 | }else{ |
| 1364 | @ Attachment "%h(zFilename)" to |
| 1365 | } |
| 1366 | objType |= OBJTYPE_ATTACHMENT; |
| 1367 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1368 | if( g.perm.Hyperlink && g.perm.RdTkt ){ |
| 1369 | @ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>] |
| 1370 | }else{ |
| 1371 | @ ticket [%S(zTarget)] |
| 1372 | } |
| 1373 | }else{ |
| 1374 | if( g.perm.Hyperlink && g.perm.RdWiki ){ |
| 1375 | @ wiki page [%z(href("%R/wiki?name=%t",zTarget))%h(zTarget)</a>] |
| 1376 | }else{ |
| 1377 | @ wiki page [%h(zTarget)] |
| 1378 | } |
| 1379 | } |
| @@ -1421,11 +1421,11 @@ | |
| 1421 | ReCompiled *pRe = 0; |
| 1422 | u64 diffFlags; |
| 1423 | u32 objdescFlags = 0; |
| 1424 | |
| 1425 | login_check_credentials(); |
| 1426 | if( !g.perm.Read ){ login_needed(); return; } |
| 1427 | v1 = name_to_rid_www("v1"); |
| 1428 | v2 = name_to_rid_www("v2"); |
| 1429 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 1430 | zRe = P("regex"); |
| 1431 | if( zRe ) re_compile(&pRe, zRe, 0); |
| @@ -1506,11 +1506,11 @@ | |
| 1506 | const char *zMime; |
| 1507 | Blob content; |
| 1508 | |
| 1509 | rid = name_to_rid_www("name"); |
| 1510 | login_check_credentials(); |
| 1511 | if( !g.perm.Read ){ login_needed(); return; } |
| 1512 | if( rid==0 ) fossil_redirect_home(); |
| 1513 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1514 | if( fossil_strcmp(P("name"), zUuid)==0 && login_is_nobody() ){ |
| 1515 | g.isConst = 1; |
| 1516 | } |
| @@ -1603,11 +1603,11 @@ | |
| 1603 | char *zUuid; |
| 1604 | u32 objdescFlags = 0; |
| 1605 | |
| 1606 | rid = name_to_rid_www("name"); |
| 1607 | login_check_credentials(); |
| 1608 | if( !g.perm.Read ){ login_needed(); return; } |
| 1609 | if( rid==0 ) fossil_redirect_home(); |
| 1610 | if( g.perm.Admin ){ |
| 1611 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1612 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1613 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun", |
| @@ -1789,11 +1789,11 @@ | |
| 1789 | if( rid==0 ){ |
| 1790 | rid = name_to_rid_www("name"); |
| 1791 | } |
| 1792 | |
| 1793 | login_check_credentials(); |
| 1794 | if( !g.perm.Read ){ login_needed(); return; } |
| 1795 | if( rid==0 ) fossil_redirect_home(); |
| 1796 | if( g.perm.Admin ){ |
| 1797 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1798 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1799 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| @@ -1904,11 +1904,11 @@ | |
| 1904 | Manifest *pTktChng; |
| 1905 | int modPending; |
| 1906 | const char *zModAction; |
| 1907 | char *zTktTitle; |
| 1908 | login_check_credentials(); |
| 1909 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 1910 | rid = name_to_rid_www("name"); |
| 1911 | if( rid==0 ){ fossil_redirect_home(); } |
| 1912 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1913 | if( g.perm.Admin ){ |
| 1914 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| @@ -2276,11 +2276,11 @@ | |
| 2276 | Blob comment; |
| 2277 | char *zBranchName = 0; |
| 2278 | Stmt q; |
| 2279 | |
| 2280 | login_check_credentials(); |
| 2281 | if( !g.perm.Write ){ login_needed(); return; } |
| 2282 | rid = name_to_typed_rid(P("r"), "ci"); |
| 2283 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 2284 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| 2285 | " FROM event WHERE objid=%d", rid); |
| 2286 | if( zComment==0 ) fossil_redirect_home(); |
| 2287 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -527,11 +527,11 @@ | |
| 527 | const char *zW; /* URL param for ignoring whitespace */ |
| 528 | const char *zPage = "vinfo"; /* Page that shows diffs */ |
| 529 | const char *zPageHide = "ci"; /* Page that hides diffs */ |
| 530 | |
| 531 | login_check_credentials(); |
| 532 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 533 | zName = P("name"); |
| 534 | rid = name_to_rid_www("name"); |
| 535 | if( rid==0 ){ |
| 536 | style_header("Check-in Information Error"); |
| 537 | @ No such object: %h(g.argv[2]) |
| @@ -657,11 +657,11 @@ | |
| 657 | } |
| 658 | db_finalize(&q2); |
| 659 | |
| 660 | |
| 661 | /* The Download: line */ |
| 662 | if( g.anon.Zip ){ |
| 663 | char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s", |
| 664 | zPJ, zUuid, zUuid); |
| 665 | @ </td></tr> |
| 666 | @ <tr><th>Downloads:</th><td> |
| 667 | @ %z(href("%s",zUrl))Tarball</a> |
| @@ -674,11 +674,11 @@ | |
| 674 | @ <td> |
| 675 | @ %z(href("%R/tree?ci=%!S",zUuid))files</a> |
| 676 | @ | %z(href("%R/fileage?name=%!S",zUuid))file ages</a> |
| 677 | @ | %z(href("%R/tree?nofiles&type=tree&ci=%!S",zUuid))folders</a> |
| 678 | @ | %z(href("%R/artifact/%!S",zUuid))manifest</a> |
| 679 | if( g.anon.Write ){ |
| 680 | @ | %z(href("%R/ci_edit?r=%!S",zUuid))edit</a> |
| 681 | } |
| 682 | @ </td> |
| 683 | @ </tr> |
| 684 | blob_reset(&projName); |
| @@ -773,11 +773,11 @@ | |
| 773 | Blob wiki; |
| 774 | int modPending; |
| 775 | const char *zModAction; |
| 776 | |
| 777 | login_check_credentials(); |
| 778 | if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } |
| 779 | rid = name_to_rid_www("name"); |
| 780 | if( rid==0 || (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))==0 ){ |
| 781 | style_header("Wiki Page Information Error"); |
| 782 | @ No such object: %h(P("name")) |
| 783 | style_footer(); |
| @@ -991,11 +991,11 @@ | |
| 991 | const char *zW; |
| 992 | const char *zVerbose; |
| 993 | const char *zGlob; |
| 994 | ReCompiled *pRe = 0; |
| 995 | login_check_credentials(); |
| 996 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 997 | login_anonymous_available(); |
| 998 | zRe = P("regex"); |
| 999 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1000 | zBranch = P("branch"); |
| 1001 | if( zBranch && zBranch[0] ){ |
| @@ -1363,17 +1363,17 @@ | |
| 1363 | }else{ |
| 1364 | @ Attachment "%h(zFilename)" to |
| 1365 | } |
| 1366 | objType |= OBJTYPE_ATTACHMENT; |
| 1367 | if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){ |
| 1368 | if( g.perm.Hyperlink && g.anon.RdTkt ){ |
| 1369 | @ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>] |
| 1370 | }else{ |
| 1371 | @ ticket [%S(zTarget)] |
| 1372 | } |
| 1373 | }else{ |
| 1374 | if( g.perm.Hyperlink && g.anon.RdWiki ){ |
| 1375 | @ wiki page [%z(href("%R/wiki?name=%t",zTarget))%h(zTarget)</a>] |
| 1376 | }else{ |
| 1377 | @ wiki page [%h(zTarget)] |
| 1378 | } |
| 1379 | } |
| @@ -1421,11 +1421,11 @@ | |
| 1421 | ReCompiled *pRe = 0; |
| 1422 | u64 diffFlags; |
| 1423 | u32 objdescFlags = 0; |
| 1424 | |
| 1425 | login_check_credentials(); |
| 1426 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1427 | v1 = name_to_rid_www("v1"); |
| 1428 | v2 = name_to_rid_www("v2"); |
| 1429 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 1430 | zRe = P("regex"); |
| 1431 | if( zRe ) re_compile(&pRe, zRe, 0); |
| @@ -1506,11 +1506,11 @@ | |
| 1506 | const char *zMime; |
| 1507 | Blob content; |
| 1508 | |
| 1509 | rid = name_to_rid_www("name"); |
| 1510 | login_check_credentials(); |
| 1511 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1512 | if( rid==0 ) fossil_redirect_home(); |
| 1513 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1514 | if( fossil_strcmp(P("name"), zUuid)==0 && login_is_nobody() ){ |
| 1515 | g.isConst = 1; |
| 1516 | } |
| @@ -1603,11 +1603,11 @@ | |
| 1603 | char *zUuid; |
| 1604 | u32 objdescFlags = 0; |
| 1605 | |
| 1606 | rid = name_to_rid_www("name"); |
| 1607 | login_check_credentials(); |
| 1608 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1609 | if( rid==0 ) fossil_redirect_home(); |
| 1610 | if( g.perm.Admin ){ |
| 1611 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1612 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1613 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun", |
| @@ -1789,11 +1789,11 @@ | |
| 1789 | if( rid==0 ){ |
| 1790 | rid = name_to_rid_www("name"); |
| 1791 | } |
| 1792 | |
| 1793 | login_check_credentials(); |
| 1794 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1795 | if( rid==0 ) fossil_redirect_home(); |
| 1796 | if( g.perm.Admin ){ |
| 1797 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1798 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 1799 | style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun", |
| @@ -1904,11 +1904,11 @@ | |
| 1904 | Manifest *pTktChng; |
| 1905 | int modPending; |
| 1906 | const char *zModAction; |
| 1907 | char *zTktTitle; |
| 1908 | login_check_credentials(); |
| 1909 | if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } |
| 1910 | rid = name_to_rid_www("name"); |
| 1911 | if( rid==0 ){ fossil_redirect_home(); } |
| 1912 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1913 | if( g.perm.Admin ){ |
| 1914 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| @@ -2276,11 +2276,11 @@ | |
| 2276 | Blob comment; |
| 2277 | char *zBranchName = 0; |
| 2278 | Stmt q; |
| 2279 | |
| 2280 | login_check_credentials(); |
| 2281 | if( !g.perm.Write ){ login_needed(g.anon.Write); return; } |
| 2282 | rid = name_to_typed_rid(P("r"), "ci"); |
| 2283 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 2284 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| 2285 | " FROM event WHERE objid=%d", rid); |
| 2286 | if( zComment==0 ) fossil_redirect_home(); |
| 2287 |
+152
-106
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -352,16 +352,12 @@ | ||
| 352 | 352 | login_cookie_path(), -86400); |
| 353 | 353 | db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, " |
| 354 | 354 | " cexpire=0 WHERE uid=%d" |
| 355 | 355 | " AND login NOT IN ('anonymous','nobody'," |
| 356 | 356 | " 'developer','reader')", g.userUid); |
| 357 | - cgi_replace_parameter(cookie, NULL) | |
| 358 | - /* At the time of this writing, cgi_replace_parameter() was | |
| 359 | - ** "NULL-value-safe", and I'm hoping the NULL doesn't cause any | |
| 360 | - ** downstream problems here. We could alternately use "" here. | |
| 361 | - */ | |
| 362 | - ; | |
| 357 | + cgi_replace_parameter(cookie, NULL); | |
| 358 | + cgi_replace_parameter("anon", NULL); | |
| 363 | 359 | } |
| 364 | 360 | } |
| 365 | 361 | |
| 366 | 362 | /* |
| 367 | 363 | ** Return true if the prefix of zStr matches zPattern. Return false if |
| @@ -451,27 +447,46 @@ | ||
| 451 | 447 | } |
| 452 | 448 | sqlite3_result_int(context, rc); |
| 453 | 449 | } |
| 454 | 450 | |
| 455 | 451 | /* |
| 456 | -** WEBPAGE: login | |
| 457 | -** WEBPAGE: logout | |
| 458 | -** WEBPAGE: my | |
| 459 | -** | |
| 460 | -** Generate the login page. | |
| 461 | -** | |
| 452 | +** Return true if the current page was reached by a redirect from the /login | |
| 453 | +** page. | |
| 454 | +*/ | |
| 455 | +int referred_from_login(void){ | |
| 456 | + const char *zReferer = P("HTTP_REFERER"); | |
| 457 | + char *zPattern; | |
| 458 | + int rc; | |
| 459 | + if( zReferer==0 ) return 0; | |
| 460 | + zPattern = mprintf("%s/login*", g.zBaseURL); | |
| 461 | + rc = sqlite3_strglob(zPattern, zReferer)==0; | |
| 462 | + fossil_free(zPattern); | |
| 463 | + return rc; | |
| 464 | +} | |
| 465 | + | |
| 466 | +/* | |
| 462 | 467 | ** There used to be a page named "my" that was designed to show information |
| 463 | 468 | ** about a specific user. The "my" page was linked from the "Logged in as USER" |
| 464 | 469 | ** line on the title bar. The "my" page was never completed so it is now |
| 465 | 470 | ** removed. Use this page as a placeholder in older installations. |
| 471 | +** | |
| 472 | +** WEBPAGE: login | |
| 473 | +** WEBPAGE: logout | |
| 474 | +** WEBPAGE: my | |
| 475 | +** | |
| 476 | +** The login/logout page. Parameters: | |
| 477 | +** | |
| 478 | +** g=URL Jump back to this URL after login completes | |
| 479 | +** anon The g=URL is not accessible by "nobody" but is | |
| 480 | +** accessible by "anonymous" | |
| 466 | 481 | */ |
| 467 | 482 | void login_page(void){ |
| 468 | 483 | const char *zUsername, *zPasswd; |
| 469 | 484 | const char *zNew1, *zNew2; |
| 470 | 485 | const char *zAnonPw = 0; |
| 471 | 486 | const char *zGoto = P("g"); |
| 472 | - int anonFlag; | |
| 487 | + int anonFlag; /* Login as "anonymous" would be useful */ | |
| 473 | 488 | char *zErrMsg = ""; |
| 474 | 489 | int uid; /* User id logged in user */ |
| 475 | 490 | char *zSha1Pw; |
| 476 | 491 | const char *zIpAddr; /* IP address of requestor */ |
| 477 | 492 | const char *zReferer; |
| @@ -489,15 +504,20 @@ | ||
| 489 | 504 | } |
| 490 | 505 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 491 | 506 | constant_time_cmp_function, 0, 0); |
| 492 | 507 | zUsername = P("u"); |
| 493 | 508 | zPasswd = P("p"); |
| 494 | - anonFlag = P("anon")!=0; | |
| 495 | - if( P("out")!=0 ){ | |
| 509 | + anonFlag = g.zLogin==0 && PB("anon"); | |
| 510 | + | |
| 511 | + /* Handle log-out requests */ | |
| 512 | + if( P("out") ){ | |
| 496 | 513 | login_clear_login_data(); |
| 497 | 514 | redirect_to_g(); |
| 515 | + return; | |
| 498 | 516 | } |
| 517 | + | |
| 518 | + /* Deal with password-change requests */ | |
| 499 | 519 | if( g.perm.Password && zPasswd |
| 500 | 520 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 501 | 521 | ){ |
| 502 | 522 | /* The user requests a password change */ |
| 503 | 523 | zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0); |
| @@ -577,19 +597,40 @@ | ||
| 577 | 597 | } |
| 578 | 598 | } |
| 579 | 599 | style_header("Login/Logout"); |
| 580 | 600 | style_adunit_config(ADUNIT_OFF); |
| 581 | 601 | @ %s(zErrMsg) |
| 582 | - if( zGoto && P("anon")==0 ){ | |
| 583 | - @ <p>A login is required for <a href="%h(zGoto)">%h(zGoto)</a>.</p> | |
| 602 | + if( zGoto ){ | |
| 603 | + char *zAbbrev = fossil_strdup(zGoto); | |
| 604 | + int i; | |
| 605 | + for(i=0; zAbbrev[i] && zAbbrev[i]!='?'; i++){} | |
| 606 | + zAbbrev[i] = 0; | |
| 607 | + if( g.zLogin ){ | |
| 608 | + @ <p>Use a different login with greater privilege that <b>%h(g.zLogin)</b> | |
| 609 | + @ to access <b>%h(zAbbrev)</b>. | |
| 610 | + }else if( anonFlag ){ | |
| 611 | + @ <p>Login as <b>anonymous</b> or any named user | |
| 612 | + @ to access page <b>%h(zAbbrev)</b>. | |
| 613 | + }else{ | |
| 614 | + @ <p>Login as a named user to access page <b>%h(zAbbrev)</b>. | |
| 615 | + } | |
| 584 | 616 | } |
| 585 | 617 | form_begin(0, "%R/login"); |
| 586 | 618 | if( zGoto ){ |
| 587 | 619 | @ <input type="hidden" name="g" value="%h(zGoto)" /> |
| 588 | 620 | }else if( zReferer && strncmp(g.zBaseURL, zReferer, strlen(g.zBaseURL))==0 ){ |
| 589 | 621 | @ <input type="hidden" name="g" value="%h(zReferer)" /> |
| 590 | 622 | } |
| 623 | + if( anonFlag ){ | |
| 624 | + @ <input type="hidden" name="anon" value="1" /> | |
| 625 | + } | |
| 626 | + if( g.zLogin ){ | |
| 627 | + @ <p>Currently logged in as <b>%h(g.zLogin)</b>. | |
| 628 | + @ <input type="submit" name="out" value="Logout"></p> | |
| 629 | + @ <hr /> | |
| 630 | + @ <p>Change user: | |
| 631 | + } | |
| 591 | 632 | @ <table class="login_out"> |
| 592 | 633 | @ <tr> |
| 593 | 634 | @ <td class="login_out_label">User ID:</td> |
| 594 | 635 | if( anonFlag ){ |
| 595 | 636 | @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td> |
| @@ -599,11 +640,11 @@ | ||
| 599 | 640 | @ </tr> |
| 600 | 641 | @ <tr> |
| 601 | 642 | @ <td class="login_out_label">Password:</td> |
| 602 | 643 | @ <td><input type="password" id="p" name="p" value="" size="30" /></td> |
| 603 | 644 | @ </tr> |
| 604 | - if( g.zLogin==0 ){ | |
| 645 | + if( g.zLogin==0 && (anonFlag || zGoto==0) ){ | |
| 605 | 646 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 606 | 647 | " WHERE login='anonymous'" |
| 607 | 648 | " AND cap!=''"); |
| 608 | 649 | } |
| 609 | 650 | @ <tr> |
| @@ -624,20 +665,11 @@ | ||
| 624 | 665 | @ form.action = "%h(zSSL)/login"; |
| 625 | 666 | @ } |
| 626 | 667 | } |
| 627 | 668 | @ } |
| 628 | 669 | @ </script> |
| 629 | - if( g.zLogin==0 ){ | |
| 630 | - @ <p>Enter | |
| 631 | - }else{ | |
| 632 | - @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p> | |
| 633 | - @ <p>To change your login to a different user, enter | |
| 634 | - } | |
| 635 | - @ your user-id and password at the left and press the | |
| 636 | - @ "Login" button. Your user name will be stored in a browser cookie. | |
| 637 | - @ You must configure your web browser to accept cookies in order for | |
| 638 | - @ the login to take.</p> | |
| 670 | + @ <p>Pressing the Login button grants permission to store a cookie.</p> | |
| 639 | 671 | if( db_get_boolean("self-register", 0) ){ |
| 640 | 672 | @ <p>If you do not have an account, you can |
| 641 | 673 | @ <a href="%R/register?g=%T(P("G"))">create one</a>. |
| 642 | 674 | } |
| 643 | 675 | if( zAnonPw ){ |
| @@ -657,22 +689,14 @@ | ||
| 657 | 689 | @ onclick="gebi('u').value='anonymous'; gebi('p').value='%s(zDecoded)';" /> |
| 658 | 690 | } |
| 659 | 691 | @ </div> |
| 660 | 692 | free(zCaptcha); |
| 661 | 693 | } |
| 662 | - if( g.zLogin ){ | |
| 663 | - @ <hr /> | |
| 664 | - @ <p>To log off the system (and delete your login cookie) | |
| 665 | - @ press the following button:<br /> | |
| 666 | - @ <input type="submit" name="out" value="Logout" /></p> | |
| 667 | - } | |
| 668 | 694 | @ </form> |
| 669 | 695 | if( g.perm.Password ){ |
| 670 | 696 | @ <hr /> |
| 671 | - @ <p>To change your password, enter your old password and your | |
| 672 | - @ new password twice below then press the "Change Password" | |
| 673 | - @ button.</p> | |
| 697 | + @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p> | |
| 674 | 698 | form_begin(0, "%R/login"); |
| 675 | 699 | @ <table> |
| 676 | 700 | @ <tr><td class="login_out_label">Old Password:</td> |
| 677 | 701 | @ <td><input type="password" name="p" size="30" /></td></tr> |
| 678 | 702 | @ <tr><td class="login_out_label">New Password:</td> |
| @@ -811,10 +835,11 @@ | ||
| 811 | 835 | ** variables appropriately. |
| 812 | 836 | ** |
| 813 | 837 | ** g.userUid Database USER.UID value. Might be -1 for "nobody" |
| 814 | 838 | ** g.zLogin Database USER.LOGIN value. NULL for user "nobody" |
| 815 | 839 | ** g.perm Permissions granted to this user |
| 840 | +** g.anon Permissions that would be available to anonymous | |
| 816 | 841 | ** g.isHuman True if the user is human, not a spider or robot |
| 817 | 842 | ** |
| 818 | 843 | */ |
| 819 | 844 | void login_check_credentials(void){ |
| 820 | 845 | int uid = 0; /* User id */ |
| @@ -1002,23 +1027,32 @@ | ||
| 1002 | 1027 | ** Memory of settings |
| 1003 | 1028 | */ |
| 1004 | 1029 | static int login_anon_once = 1; |
| 1005 | 1030 | |
| 1006 | 1031 | /* |
| 1007 | -** Add the default privileges of users "nobody" and "anonymous" as appropriate | |
| 1008 | -** for the user g.zLogin. | |
| 1032 | +** Add to g.perm the default privileges of users "nobody" and/or "anonymous" | |
| 1033 | +** as appropriate for the user g.zLogin. | |
| 1034 | +** | |
| 1035 | +** This routine also sets up g.anon to be either a copy of g.perm for | |
| 1036 | +** all logged in uses, or the privileges that would be available to "anonymous" | |
| 1037 | +** if g.zLogin==0 (meaning that the user is "nobody"). | |
| 1009 | 1038 | */ |
| 1010 | 1039 | void login_set_anon_nobody_capabilities(void){ |
| 1011 | - if( g.zLogin && login_anon_once ){ | |
| 1040 | + if( login_anon_once ){ | |
| 1012 | 1041 | const char *zCap; |
| 1013 | - /* All logged-in users inherit privileges from "nobody" */ | |
| 1042 | + /* All users get privileges from "nobody" */ | |
| 1014 | 1043 | zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); |
| 1015 | 1044 | login_set_capabilities(zCap, 0); |
| 1016 | - if( fossil_strcmp(g.zLogin, "nobody")!=0 ){ | |
| 1045 | + zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); | |
| 1046 | + if( g.zLogin && fossil_strcmp(g.zLogin, "nobody")!=0 ){ | |
| 1017 | 1047 | /* All logged-in users inherit privileges from "anonymous" */ |
| 1018 | - zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); | |
| 1019 | 1048 | login_set_capabilities(zCap, 0); |
| 1049 | + g.anon = g.perm; | |
| 1050 | + }else{ | |
| 1051 | + /* Record the privileges of anonymous in g.anon */ | |
| 1052 | + g.anon = g.perm; | |
| 1053 | + login_set_capabilities(zCap, LOGIN_ANON); | |
| 1020 | 1054 | } |
| 1021 | 1055 | login_anon_once = 0; |
| 1022 | 1056 | } |
| 1023 | 1057 | } |
| 1024 | 1058 | |
| @@ -1025,55 +1059,57 @@ | ||
| 1025 | 1059 | /* |
| 1026 | 1060 | ** Flags passed into the 2nd argument of login_set/replace_capabilities(). |
| 1027 | 1061 | */ |
| 1028 | 1062 | #if INTERFACE |
| 1029 | 1063 | #define LOGIN_IGNORE_UV 0x01 /* Ignore "u" and "v" */ |
| 1064 | +#define LOGIN_ANON 0x02 /* Use g.anon instead of g.perm */ | |
| 1030 | 1065 | #endif |
| 1031 | 1066 | |
| 1032 | 1067 | /* |
| 1033 | -** Adds all capability flags in zCap to g.perm. | |
| 1068 | +** Adds all capability flags in zCap to g.perm or g.anon. | |
| 1034 | 1069 | */ |
| 1035 | 1070 | void login_set_capabilities(const char *zCap, unsigned flags){ |
| 1036 | 1071 | int i; |
| 1072 | + FossilUserPerms *p = (flags & LOGIN_ANON) ? &g.anon : &g.perm; | |
| 1037 | 1073 | if(NULL==zCap){ |
| 1038 | 1074 | return; |
| 1039 | 1075 | } |
| 1040 | 1076 | for(i=0; zCap[i]; i++){ |
| 1041 | 1077 | switch( zCap[i] ){ |
| 1042 | - case 's': g.perm.Setup = 1; /* Fall thru into Admin */ | |
| 1043 | - case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip = | |
| 1044 | - g.perm.RdWiki = g.perm.WrWiki = g.perm.NewWiki = | |
| 1045 | - g.perm.ApndWiki = g.perm.Hyperlink = g.perm.Clone = | |
| 1046 | - g.perm.NewTkt = g.perm.Password = g.perm.RdAddr = | |
| 1047 | - g.perm.TktFmt = g.perm.Attach = g.perm.ApndTkt = | |
| 1048 | - g.perm.ModWiki = g.perm.ModTkt = 1; | |
| 1078 | + case 's': p->Setup = 1; /* Fall thru into Admin */ | |
| 1079 | + case 'a': p->Admin = p->RdTkt = p->WrTkt = p->Zip = | |
| 1080 | + p->RdWiki = p->WrWiki = p->NewWiki = | |
| 1081 | + p->ApndWiki = p->Hyperlink = p->Clone = | |
| 1082 | + p->NewTkt = p->Password = p->RdAddr = | |
| 1083 | + p->TktFmt = p->Attach = p->ApndTkt = | |
| 1084 | + p->ModWiki = p->ModTkt = 1; | |
| 1049 | 1085 | /* Fall thru into Read/Write */ |
| 1050 | - case 'i': g.perm.Read = g.perm.Write = 1; break; | |
| 1051 | - case 'o': g.perm.Read = 1; break; | |
| 1052 | - case 'z': g.perm.Zip = 1; break; | |
| 1053 | - | |
| 1054 | - case 'd': g.perm.Delete = 1; break; | |
| 1055 | - case 'h': g.perm.Hyperlink = 1; break; | |
| 1056 | - case 'g': g.perm.Clone = 1; break; | |
| 1057 | - case 'p': g.perm.Password = 1; break; | |
| 1058 | - | |
| 1059 | - case 'j': g.perm.RdWiki = 1; break; | |
| 1060 | - case 'k': g.perm.WrWiki = g.perm.RdWiki = g.perm.ApndWiki =1; break; | |
| 1061 | - case 'm': g.perm.ApndWiki = 1; break; | |
| 1062 | - case 'f': g.perm.NewWiki = 1; break; | |
| 1063 | - case 'l': g.perm.ModWiki = 1; break; | |
| 1064 | - | |
| 1065 | - case 'e': g.perm.RdAddr = 1; break; | |
| 1066 | - case 'r': g.perm.RdTkt = 1; break; | |
| 1067 | - case 'n': g.perm.NewTkt = 1; break; | |
| 1068 | - case 'w': g.perm.WrTkt = g.perm.RdTkt = g.perm.NewTkt = | |
| 1069 | - g.perm.ApndTkt = 1; break; | |
| 1070 | - case 'c': g.perm.ApndTkt = 1; break; | |
| 1071 | - case 'q': g.perm.ModTkt = 1; break; | |
| 1072 | - case 't': g.perm.TktFmt = 1; break; | |
| 1073 | - case 'b': g.perm.Attach = 1; break; | |
| 1074 | - case 'x': g.perm.Private = 1; break; | |
| 1086 | + case 'i': p->Read = p->Write = 1; break; | |
| 1087 | + case 'o': p->Read = 1; break; | |
| 1088 | + case 'z': p->Zip = 1; break; | |
| 1089 | + | |
| 1090 | + case 'd': p->Delete = 1; break; | |
| 1091 | + case 'h': p->Hyperlink = 1; break; | |
| 1092 | + case 'g': p->Clone = 1; break; | |
| 1093 | + case 'p': p->Password = 1; break; | |
| 1094 | + | |
| 1095 | + case 'j': p->RdWiki = 1; break; | |
| 1096 | + case 'k': p->WrWiki = p->RdWiki = p->ApndWiki =1; break; | |
| 1097 | + case 'm': p->ApndWiki = 1; break; | |
| 1098 | + case 'f': p->NewWiki = 1; break; | |
| 1099 | + case 'l': p->ModWiki = 1; break; | |
| 1100 | + | |
| 1101 | + case 'e': p->RdAddr = 1; break; | |
| 1102 | + case 'r': p->RdTkt = 1; break; | |
| 1103 | + case 'n': p->NewTkt = 1; break; | |
| 1104 | + case 'w': p->WrTkt = p->RdTkt = p->NewTkt = | |
| 1105 | + p->ApndTkt = 1; break; | |
| 1106 | + case 'c': p->ApndTkt = 1; break; | |
| 1107 | + case 'q': p->ModTkt = 1; break; | |
| 1108 | + case 't': p->TktFmt = 1; break; | |
| 1109 | + case 'b': p->Attach = 1; break; | |
| 1110 | + case 'x': p->Private = 1; break; | |
| 1075 | 1111 | |
| 1076 | 1112 | /* The "u" privileges is a little different. It recursively |
| 1077 | 1113 | ** inherits all privileges of the user named "reader" */ |
| 1078 | 1114 | case 'u': { |
| 1079 | 1115 | if( (flags & LOGIN_IGNORE_UV)==0 ){ |
| @@ -1110,42 +1146,43 @@ | ||
| 1110 | 1146 | /* |
| 1111 | 1147 | ** If the current login lacks any of the capabilities listed in |
| 1112 | 1148 | ** the input, then return 0. If all capabilities are present, then |
| 1113 | 1149 | ** return 1. |
| 1114 | 1150 | */ |
| 1115 | -int login_has_capability(const char *zCap, int nCap){ | |
| 1151 | +int login_has_capability(const char *zCap, int nCap, u32 flgs){ | |
| 1116 | 1152 | int i; |
| 1117 | 1153 | int rc = 1; |
| 1154 | + FossilUserPerms *p = (flgs & LOGIN_ANON) ? &g.anon : &g.perm; | |
| 1118 | 1155 | if( nCap<0 ) nCap = strlen(zCap); |
| 1119 | 1156 | for(i=0; i<nCap && rc && zCap[i]; i++){ |
| 1120 | 1157 | switch( zCap[i] ){ |
| 1121 | - case 'a': rc = g.perm.Admin; break; | |
| 1122 | - case 'b': rc = g.perm.Attach; break; | |
| 1123 | - case 'c': rc = g.perm.ApndTkt; break; | |
| 1124 | - case 'd': rc = g.perm.Delete; break; | |
| 1125 | - case 'e': rc = g.perm.RdAddr; break; | |
| 1126 | - case 'f': rc = g.perm.NewWiki; break; | |
| 1127 | - case 'g': rc = g.perm.Clone; break; | |
| 1128 | - case 'h': rc = g.perm.Hyperlink; break; | |
| 1129 | - case 'i': rc = g.perm.Write; break; | |
| 1130 | - case 'j': rc = g.perm.RdWiki; break; | |
| 1131 | - case 'k': rc = g.perm.WrWiki; break; | |
| 1132 | - case 'l': rc = g.perm.ModWiki; break; | |
| 1133 | - case 'm': rc = g.perm.ApndWiki; break; | |
| 1134 | - case 'n': rc = g.perm.NewTkt; break; | |
| 1135 | - case 'o': rc = g.perm.Read; break; | |
| 1136 | - case 'p': rc = g.perm.Password; break; | |
| 1137 | - case 'q': rc = g.perm.ModTkt; break; | |
| 1138 | - case 'r': rc = g.perm.RdTkt; break; | |
| 1139 | - case 's': rc = g.perm.Setup; break; | |
| 1140 | - case 't': rc = g.perm.TktFmt; break; | |
| 1158 | + case 'a': rc = p->Admin; break; | |
| 1159 | + case 'b': rc = p->Attach; break; | |
| 1160 | + case 'c': rc = p->ApndTkt; break; | |
| 1161 | + case 'd': rc = p->Delete; break; | |
| 1162 | + case 'e': rc = p->RdAddr; break; | |
| 1163 | + case 'f': rc = p->NewWiki; break; | |
| 1164 | + case 'g': rc = p->Clone; break; | |
| 1165 | + case 'h': rc = p->Hyperlink; break; | |
| 1166 | + case 'i': rc = p->Write; break; | |
| 1167 | + case 'j': rc = p->RdWiki; break; | |
| 1168 | + case 'k': rc = p->WrWiki; break; | |
| 1169 | + case 'l': rc = p->ModWiki; break; | |
| 1170 | + case 'm': rc = p->ApndWiki; break; | |
| 1171 | + case 'n': rc = p->NewTkt; break; | |
| 1172 | + case 'o': rc = p->Read; break; | |
| 1173 | + case 'p': rc = p->Password; break; | |
| 1174 | + case 'q': rc = p->ModTkt; break; | |
| 1175 | + case 'r': rc = p->RdTkt; break; | |
| 1176 | + case 's': rc = p->Setup; break; | |
| 1177 | + case 't': rc = p->TktFmt; break; | |
| 1141 | 1178 | /* case 'u': READER */ |
| 1142 | 1179 | /* case 'v': DEVELOPER */ |
| 1143 | - case 'w': rc = g.perm.WrTkt; break; | |
| 1144 | - case 'x': rc = g.perm.Private; break; | |
| 1180 | + case 'w': rc = p->WrTkt; break; | |
| 1181 | + case 'x': rc = p->Private; break; | |
| 1145 | 1182 | /* case 'y': */ |
| 1146 | - case 'z': rc = g.perm.Zip; break; | |
| 1183 | + case 'z': rc = p->Zip; break; | |
| 1147 | 1184 | default: rc = 0; break; |
| 1148 | 1185 | } |
| 1149 | 1186 | } |
| 1150 | 1187 | return rc; |
| 1151 | 1188 | } |
| @@ -1195,11 +1232,11 @@ | ||
| 1195 | 1232 | |
| 1196 | 1233 | /* |
| 1197 | 1234 | ** Call this routine when the credential check fails. It causes |
| 1198 | 1235 | ** a redirect to the "login" page. |
| 1199 | 1236 | */ |
| 1200 | -void login_needed(void){ | |
| 1237 | +void login_needed(int anonOk){ | |
| 1201 | 1238 | #ifdef FOSSIL_ENABLE_JSON |
| 1202 | 1239 | if(g.json.isJsonMode){ |
| 1203 | 1240 | json_err( FSL_JSON_E_DENIED, NULL, 1 ); |
| 1204 | 1241 | fossil_exit(0); |
| 1205 | 1242 | /* NOTREACHED */ |
| @@ -1206,11 +1243,23 @@ | ||
| 1206 | 1243 | assert(0); |
| 1207 | 1244 | }else |
| 1208 | 1245 | #endif /* FOSSIL_ENABLE_JSON */ |
| 1209 | 1246 | { |
| 1210 | 1247 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1211 | - cgi_redirect(mprintf("login?g=%T", zUrl)); | |
| 1248 | + const char *zQS = P("QUERY_STRING"); | |
| 1249 | + Blob redir; | |
| 1250 | + blob_init(&redir, 0, 0); | |
| 1251 | + if( login_wants_https_redirect() ){ | |
| 1252 | + blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl); | |
| 1253 | + }else{ | |
| 1254 | + blob_appendf(&redir, "%R/login?g=%T", zUrl); | |
| 1255 | + } | |
| 1256 | + if( anonOk ) blob_append(&redir, "&anon", 5); | |
| 1257 | + if( zQS && zQS[0] ){ | |
| 1258 | + blob_appendf(&redir, "&%s", zQS); | |
| 1259 | + } | |
| 1260 | + cgi_redirect(blob_str(&redir)); | |
| 1212 | 1261 | /* NOTREACHED */ |
| 1213 | 1262 | assert(0); |
| 1214 | 1263 | } |
| 1215 | 1264 | } |
| 1216 | 1265 | |
| @@ -1219,14 +1268,11 @@ | ||
| 1219 | 1268 | ** the anonymous user has Hyperlink permission, then paint a mesage |
| 1220 | 1269 | ** to inform the user that much more information is available by |
| 1221 | 1270 | ** logging in as anonymous. |
| 1222 | 1271 | */ |
| 1223 | 1272 | void login_anonymous_available(void){ |
| 1224 | - if( !g.perm.Hyperlink && | |
| 1225 | - db_exists("SELECT 1 FROM user" | |
| 1226 | - " WHERE login='anonymous'" | |
| 1227 | - " AND cap LIKE '%%h%%'") ){ | |
| 1273 | + if( !g.perm.Hyperlink && g.anon.Hyperlink ){ | |
| 1228 | 1274 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1229 | 1275 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1230 | 1276 | @ Use <a href="%R/login?anon=1&g=%T(zUrl)">anonymous login</a> |
| 1231 | 1277 | @ to enable hyperlinks.</p> |
| 1232 | 1278 | } |
| 1233 | 1279 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -352,16 +352,12 @@ | |
| 352 | login_cookie_path(), -86400); |
| 353 | db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, " |
| 354 | " cexpire=0 WHERE uid=%d" |
| 355 | " AND login NOT IN ('anonymous','nobody'," |
| 356 | " 'developer','reader')", g.userUid); |
| 357 | cgi_replace_parameter(cookie, NULL) |
| 358 | /* At the time of this writing, cgi_replace_parameter() was |
| 359 | ** "NULL-value-safe", and I'm hoping the NULL doesn't cause any |
| 360 | ** downstream problems here. We could alternately use "" here. |
| 361 | */ |
| 362 | ; |
| 363 | } |
| 364 | } |
| 365 | |
| 366 | /* |
| 367 | ** Return true if the prefix of zStr matches zPattern. Return false if |
| @@ -451,27 +447,46 @@ | |
| 451 | } |
| 452 | sqlite3_result_int(context, rc); |
| 453 | } |
| 454 | |
| 455 | /* |
| 456 | ** WEBPAGE: login |
| 457 | ** WEBPAGE: logout |
| 458 | ** WEBPAGE: my |
| 459 | ** |
| 460 | ** Generate the login page. |
| 461 | ** |
| 462 | ** There used to be a page named "my" that was designed to show information |
| 463 | ** about a specific user. The "my" page was linked from the "Logged in as USER" |
| 464 | ** line on the title bar. The "my" page was never completed so it is now |
| 465 | ** removed. Use this page as a placeholder in older installations. |
| 466 | */ |
| 467 | void login_page(void){ |
| 468 | const char *zUsername, *zPasswd; |
| 469 | const char *zNew1, *zNew2; |
| 470 | const char *zAnonPw = 0; |
| 471 | const char *zGoto = P("g"); |
| 472 | int anonFlag; |
| 473 | char *zErrMsg = ""; |
| 474 | int uid; /* User id logged in user */ |
| 475 | char *zSha1Pw; |
| 476 | const char *zIpAddr; /* IP address of requestor */ |
| 477 | const char *zReferer; |
| @@ -489,15 +504,20 @@ | |
| 489 | } |
| 490 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 491 | constant_time_cmp_function, 0, 0); |
| 492 | zUsername = P("u"); |
| 493 | zPasswd = P("p"); |
| 494 | anonFlag = P("anon")!=0; |
| 495 | if( P("out")!=0 ){ |
| 496 | login_clear_login_data(); |
| 497 | redirect_to_g(); |
| 498 | } |
| 499 | if( g.perm.Password && zPasswd |
| 500 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 501 | ){ |
| 502 | /* The user requests a password change */ |
| 503 | zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0); |
| @@ -577,19 +597,40 @@ | |
| 577 | } |
| 578 | } |
| 579 | style_header("Login/Logout"); |
| 580 | style_adunit_config(ADUNIT_OFF); |
| 581 | @ %s(zErrMsg) |
| 582 | if( zGoto && P("anon")==0 ){ |
| 583 | @ <p>A login is required for <a href="%h(zGoto)">%h(zGoto)</a>.</p> |
| 584 | } |
| 585 | form_begin(0, "%R/login"); |
| 586 | if( zGoto ){ |
| 587 | @ <input type="hidden" name="g" value="%h(zGoto)" /> |
| 588 | }else if( zReferer && strncmp(g.zBaseURL, zReferer, strlen(g.zBaseURL))==0 ){ |
| 589 | @ <input type="hidden" name="g" value="%h(zReferer)" /> |
| 590 | } |
| 591 | @ <table class="login_out"> |
| 592 | @ <tr> |
| 593 | @ <td class="login_out_label">User ID:</td> |
| 594 | if( anonFlag ){ |
| 595 | @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td> |
| @@ -599,11 +640,11 @@ | |
| 599 | @ </tr> |
| 600 | @ <tr> |
| 601 | @ <td class="login_out_label">Password:</td> |
| 602 | @ <td><input type="password" id="p" name="p" value="" size="30" /></td> |
| 603 | @ </tr> |
| 604 | if( g.zLogin==0 ){ |
| 605 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 606 | " WHERE login='anonymous'" |
| 607 | " AND cap!=''"); |
| 608 | } |
| 609 | @ <tr> |
| @@ -624,20 +665,11 @@ | |
| 624 | @ form.action = "%h(zSSL)/login"; |
| 625 | @ } |
| 626 | } |
| 627 | @ } |
| 628 | @ </script> |
| 629 | if( g.zLogin==0 ){ |
| 630 | @ <p>Enter |
| 631 | }else{ |
| 632 | @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p> |
| 633 | @ <p>To change your login to a different user, enter |
| 634 | } |
| 635 | @ your user-id and password at the left and press the |
| 636 | @ "Login" button. Your user name will be stored in a browser cookie. |
| 637 | @ You must configure your web browser to accept cookies in order for |
| 638 | @ the login to take.</p> |
| 639 | if( db_get_boolean("self-register", 0) ){ |
| 640 | @ <p>If you do not have an account, you can |
| 641 | @ <a href="%R/register?g=%T(P("G"))">create one</a>. |
| 642 | } |
| 643 | if( zAnonPw ){ |
| @@ -657,22 +689,14 @@ | |
| 657 | @ onclick="gebi('u').value='anonymous'; gebi('p').value='%s(zDecoded)';" /> |
| 658 | } |
| 659 | @ </div> |
| 660 | free(zCaptcha); |
| 661 | } |
| 662 | if( g.zLogin ){ |
| 663 | @ <hr /> |
| 664 | @ <p>To log off the system (and delete your login cookie) |
| 665 | @ press the following button:<br /> |
| 666 | @ <input type="submit" name="out" value="Logout" /></p> |
| 667 | } |
| 668 | @ </form> |
| 669 | if( g.perm.Password ){ |
| 670 | @ <hr /> |
| 671 | @ <p>To change your password, enter your old password and your |
| 672 | @ new password twice below then press the "Change Password" |
| 673 | @ button.</p> |
| 674 | form_begin(0, "%R/login"); |
| 675 | @ <table> |
| 676 | @ <tr><td class="login_out_label">Old Password:</td> |
| 677 | @ <td><input type="password" name="p" size="30" /></td></tr> |
| 678 | @ <tr><td class="login_out_label">New Password:</td> |
| @@ -811,10 +835,11 @@ | |
| 811 | ** variables appropriately. |
| 812 | ** |
| 813 | ** g.userUid Database USER.UID value. Might be -1 for "nobody" |
| 814 | ** g.zLogin Database USER.LOGIN value. NULL for user "nobody" |
| 815 | ** g.perm Permissions granted to this user |
| 816 | ** g.isHuman True if the user is human, not a spider or robot |
| 817 | ** |
| 818 | */ |
| 819 | void login_check_credentials(void){ |
| 820 | int uid = 0; /* User id */ |
| @@ -1002,23 +1027,32 @@ | |
| 1002 | ** Memory of settings |
| 1003 | */ |
| 1004 | static int login_anon_once = 1; |
| 1005 | |
| 1006 | /* |
| 1007 | ** Add the default privileges of users "nobody" and "anonymous" as appropriate |
| 1008 | ** for the user g.zLogin. |
| 1009 | */ |
| 1010 | void login_set_anon_nobody_capabilities(void){ |
| 1011 | if( g.zLogin && login_anon_once ){ |
| 1012 | const char *zCap; |
| 1013 | /* All logged-in users inherit privileges from "nobody" */ |
| 1014 | zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); |
| 1015 | login_set_capabilities(zCap, 0); |
| 1016 | if( fossil_strcmp(g.zLogin, "nobody")!=0 ){ |
| 1017 | /* All logged-in users inherit privileges from "anonymous" */ |
| 1018 | zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); |
| 1019 | login_set_capabilities(zCap, 0); |
| 1020 | } |
| 1021 | login_anon_once = 0; |
| 1022 | } |
| 1023 | } |
| 1024 | |
| @@ -1025,55 +1059,57 @@ | |
| 1025 | /* |
| 1026 | ** Flags passed into the 2nd argument of login_set/replace_capabilities(). |
| 1027 | */ |
| 1028 | #if INTERFACE |
| 1029 | #define LOGIN_IGNORE_UV 0x01 /* Ignore "u" and "v" */ |
| 1030 | #endif |
| 1031 | |
| 1032 | /* |
| 1033 | ** Adds all capability flags in zCap to g.perm. |
| 1034 | */ |
| 1035 | void login_set_capabilities(const char *zCap, unsigned flags){ |
| 1036 | int i; |
| 1037 | if(NULL==zCap){ |
| 1038 | return; |
| 1039 | } |
| 1040 | for(i=0; zCap[i]; i++){ |
| 1041 | switch( zCap[i] ){ |
| 1042 | case 's': g.perm.Setup = 1; /* Fall thru into Admin */ |
| 1043 | case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip = |
| 1044 | g.perm.RdWiki = g.perm.WrWiki = g.perm.NewWiki = |
| 1045 | g.perm.ApndWiki = g.perm.Hyperlink = g.perm.Clone = |
| 1046 | g.perm.NewTkt = g.perm.Password = g.perm.RdAddr = |
| 1047 | g.perm.TktFmt = g.perm.Attach = g.perm.ApndTkt = |
| 1048 | g.perm.ModWiki = g.perm.ModTkt = 1; |
| 1049 | /* Fall thru into Read/Write */ |
| 1050 | case 'i': g.perm.Read = g.perm.Write = 1; break; |
| 1051 | case 'o': g.perm.Read = 1; break; |
| 1052 | case 'z': g.perm.Zip = 1; break; |
| 1053 | |
| 1054 | case 'd': g.perm.Delete = 1; break; |
| 1055 | case 'h': g.perm.Hyperlink = 1; break; |
| 1056 | case 'g': g.perm.Clone = 1; break; |
| 1057 | case 'p': g.perm.Password = 1; break; |
| 1058 | |
| 1059 | case 'j': g.perm.RdWiki = 1; break; |
| 1060 | case 'k': g.perm.WrWiki = g.perm.RdWiki = g.perm.ApndWiki =1; break; |
| 1061 | case 'm': g.perm.ApndWiki = 1; break; |
| 1062 | case 'f': g.perm.NewWiki = 1; break; |
| 1063 | case 'l': g.perm.ModWiki = 1; break; |
| 1064 | |
| 1065 | case 'e': g.perm.RdAddr = 1; break; |
| 1066 | case 'r': g.perm.RdTkt = 1; break; |
| 1067 | case 'n': g.perm.NewTkt = 1; break; |
| 1068 | case 'w': g.perm.WrTkt = g.perm.RdTkt = g.perm.NewTkt = |
| 1069 | g.perm.ApndTkt = 1; break; |
| 1070 | case 'c': g.perm.ApndTkt = 1; break; |
| 1071 | case 'q': g.perm.ModTkt = 1; break; |
| 1072 | case 't': g.perm.TktFmt = 1; break; |
| 1073 | case 'b': g.perm.Attach = 1; break; |
| 1074 | case 'x': g.perm.Private = 1; break; |
| 1075 | |
| 1076 | /* The "u" privileges is a little different. It recursively |
| 1077 | ** inherits all privileges of the user named "reader" */ |
| 1078 | case 'u': { |
| 1079 | if( (flags & LOGIN_IGNORE_UV)==0 ){ |
| @@ -1110,42 +1146,43 @@ | |
| 1110 | /* |
| 1111 | ** If the current login lacks any of the capabilities listed in |
| 1112 | ** the input, then return 0. If all capabilities are present, then |
| 1113 | ** return 1. |
| 1114 | */ |
| 1115 | int login_has_capability(const char *zCap, int nCap){ |
| 1116 | int i; |
| 1117 | int rc = 1; |
| 1118 | if( nCap<0 ) nCap = strlen(zCap); |
| 1119 | for(i=0; i<nCap && rc && zCap[i]; i++){ |
| 1120 | switch( zCap[i] ){ |
| 1121 | case 'a': rc = g.perm.Admin; break; |
| 1122 | case 'b': rc = g.perm.Attach; break; |
| 1123 | case 'c': rc = g.perm.ApndTkt; break; |
| 1124 | case 'd': rc = g.perm.Delete; break; |
| 1125 | case 'e': rc = g.perm.RdAddr; break; |
| 1126 | case 'f': rc = g.perm.NewWiki; break; |
| 1127 | case 'g': rc = g.perm.Clone; break; |
| 1128 | case 'h': rc = g.perm.Hyperlink; break; |
| 1129 | case 'i': rc = g.perm.Write; break; |
| 1130 | case 'j': rc = g.perm.RdWiki; break; |
| 1131 | case 'k': rc = g.perm.WrWiki; break; |
| 1132 | case 'l': rc = g.perm.ModWiki; break; |
| 1133 | case 'm': rc = g.perm.ApndWiki; break; |
| 1134 | case 'n': rc = g.perm.NewTkt; break; |
| 1135 | case 'o': rc = g.perm.Read; break; |
| 1136 | case 'p': rc = g.perm.Password; break; |
| 1137 | case 'q': rc = g.perm.ModTkt; break; |
| 1138 | case 'r': rc = g.perm.RdTkt; break; |
| 1139 | case 's': rc = g.perm.Setup; break; |
| 1140 | case 't': rc = g.perm.TktFmt; break; |
| 1141 | /* case 'u': READER */ |
| 1142 | /* case 'v': DEVELOPER */ |
| 1143 | case 'w': rc = g.perm.WrTkt; break; |
| 1144 | case 'x': rc = g.perm.Private; break; |
| 1145 | /* case 'y': */ |
| 1146 | case 'z': rc = g.perm.Zip; break; |
| 1147 | default: rc = 0; break; |
| 1148 | } |
| 1149 | } |
| 1150 | return rc; |
| 1151 | } |
| @@ -1195,11 +1232,11 @@ | |
| 1195 | |
| 1196 | /* |
| 1197 | ** Call this routine when the credential check fails. It causes |
| 1198 | ** a redirect to the "login" page. |
| 1199 | */ |
| 1200 | void login_needed(void){ |
| 1201 | #ifdef FOSSIL_ENABLE_JSON |
| 1202 | if(g.json.isJsonMode){ |
| 1203 | json_err( FSL_JSON_E_DENIED, NULL, 1 ); |
| 1204 | fossil_exit(0); |
| 1205 | /* NOTREACHED */ |
| @@ -1206,11 +1243,23 @@ | |
| 1206 | assert(0); |
| 1207 | }else |
| 1208 | #endif /* FOSSIL_ENABLE_JSON */ |
| 1209 | { |
| 1210 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1211 | cgi_redirect(mprintf("login?g=%T", zUrl)); |
| 1212 | /* NOTREACHED */ |
| 1213 | assert(0); |
| 1214 | } |
| 1215 | } |
| 1216 | |
| @@ -1219,14 +1268,11 @@ | |
| 1219 | ** the anonymous user has Hyperlink permission, then paint a mesage |
| 1220 | ** to inform the user that much more information is available by |
| 1221 | ** logging in as anonymous. |
| 1222 | */ |
| 1223 | void login_anonymous_available(void){ |
| 1224 | if( !g.perm.Hyperlink && |
| 1225 | db_exists("SELECT 1 FROM user" |
| 1226 | " WHERE login='anonymous'" |
| 1227 | " AND cap LIKE '%%h%%'") ){ |
| 1228 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1229 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1230 | @ Use <a href="%R/login?anon=1&g=%T(zUrl)">anonymous login</a> |
| 1231 | @ to enable hyperlinks.</p> |
| 1232 | } |
| 1233 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -352,16 +352,12 @@ | |
| 352 | login_cookie_path(), -86400); |
| 353 | db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, " |
| 354 | " cexpire=0 WHERE uid=%d" |
| 355 | " AND login NOT IN ('anonymous','nobody'," |
| 356 | " 'developer','reader')", g.userUid); |
| 357 | cgi_replace_parameter(cookie, NULL); |
| 358 | cgi_replace_parameter("anon", NULL); |
| 359 | } |
| 360 | } |
| 361 | |
| 362 | /* |
| 363 | ** Return true if the prefix of zStr matches zPattern. Return false if |
| @@ -451,27 +447,46 @@ | |
| 447 | } |
| 448 | sqlite3_result_int(context, rc); |
| 449 | } |
| 450 | |
| 451 | /* |
| 452 | ** Return true if the current page was reached by a redirect from the /login |
| 453 | ** page. |
| 454 | */ |
| 455 | int referred_from_login(void){ |
| 456 | const char *zReferer = P("HTTP_REFERER"); |
| 457 | char *zPattern; |
| 458 | int rc; |
| 459 | if( zReferer==0 ) return 0; |
| 460 | zPattern = mprintf("%s/login*", g.zBaseURL); |
| 461 | rc = sqlite3_strglob(zPattern, zReferer)==0; |
| 462 | fossil_free(zPattern); |
| 463 | return rc; |
| 464 | } |
| 465 | |
| 466 | /* |
| 467 | ** There used to be a page named "my" that was designed to show information |
| 468 | ** about a specific user. The "my" page was linked from the "Logged in as USER" |
| 469 | ** line on the title bar. The "my" page was never completed so it is now |
| 470 | ** removed. Use this page as a placeholder in older installations. |
| 471 | ** |
| 472 | ** WEBPAGE: login |
| 473 | ** WEBPAGE: logout |
| 474 | ** WEBPAGE: my |
| 475 | ** |
| 476 | ** The login/logout page. Parameters: |
| 477 | ** |
| 478 | ** g=URL Jump back to this URL after login completes |
| 479 | ** anon The g=URL is not accessible by "nobody" but is |
| 480 | ** accessible by "anonymous" |
| 481 | */ |
| 482 | void login_page(void){ |
| 483 | const char *zUsername, *zPasswd; |
| 484 | const char *zNew1, *zNew2; |
| 485 | const char *zAnonPw = 0; |
| 486 | const char *zGoto = P("g"); |
| 487 | int anonFlag; /* Login as "anonymous" would be useful */ |
| 488 | char *zErrMsg = ""; |
| 489 | int uid; /* User id logged in user */ |
| 490 | char *zSha1Pw; |
| 491 | const char *zIpAddr; /* IP address of requestor */ |
| 492 | const char *zReferer; |
| @@ -489,15 +504,20 @@ | |
| 504 | } |
| 505 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 506 | constant_time_cmp_function, 0, 0); |
| 507 | zUsername = P("u"); |
| 508 | zPasswd = P("p"); |
| 509 | anonFlag = g.zLogin==0 && PB("anon"); |
| 510 | |
| 511 | /* Handle log-out requests */ |
| 512 | if( P("out") ){ |
| 513 | login_clear_login_data(); |
| 514 | redirect_to_g(); |
| 515 | return; |
| 516 | } |
| 517 | |
| 518 | /* Deal with password-change requests */ |
| 519 | if( g.perm.Password && zPasswd |
| 520 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 521 | ){ |
| 522 | /* The user requests a password change */ |
| 523 | zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0); |
| @@ -577,19 +597,40 @@ | |
| 597 | } |
| 598 | } |
| 599 | style_header("Login/Logout"); |
| 600 | style_adunit_config(ADUNIT_OFF); |
| 601 | @ %s(zErrMsg) |
| 602 | if( zGoto ){ |
| 603 | char *zAbbrev = fossil_strdup(zGoto); |
| 604 | int i; |
| 605 | for(i=0; zAbbrev[i] && zAbbrev[i]!='?'; i++){} |
| 606 | zAbbrev[i] = 0; |
| 607 | if( g.zLogin ){ |
| 608 | @ <p>Use a different login with greater privilege that <b>%h(g.zLogin)</b> |
| 609 | @ to access <b>%h(zAbbrev)</b>. |
| 610 | }else if( anonFlag ){ |
| 611 | @ <p>Login as <b>anonymous</b> or any named user |
| 612 | @ to access page <b>%h(zAbbrev)</b>. |
| 613 | }else{ |
| 614 | @ <p>Login as a named user to access page <b>%h(zAbbrev)</b>. |
| 615 | } |
| 616 | } |
| 617 | form_begin(0, "%R/login"); |
| 618 | if( zGoto ){ |
| 619 | @ <input type="hidden" name="g" value="%h(zGoto)" /> |
| 620 | }else if( zReferer && strncmp(g.zBaseURL, zReferer, strlen(g.zBaseURL))==0 ){ |
| 621 | @ <input type="hidden" name="g" value="%h(zReferer)" /> |
| 622 | } |
| 623 | if( anonFlag ){ |
| 624 | @ <input type="hidden" name="anon" value="1" /> |
| 625 | } |
| 626 | if( g.zLogin ){ |
| 627 | @ <p>Currently logged in as <b>%h(g.zLogin)</b>. |
| 628 | @ <input type="submit" name="out" value="Logout"></p> |
| 629 | @ <hr /> |
| 630 | @ <p>Change user: |
| 631 | } |
| 632 | @ <table class="login_out"> |
| 633 | @ <tr> |
| 634 | @ <td class="login_out_label">User ID:</td> |
| 635 | if( anonFlag ){ |
| 636 | @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td> |
| @@ -599,11 +640,11 @@ | |
| 640 | @ </tr> |
| 641 | @ <tr> |
| 642 | @ <td class="login_out_label">Password:</td> |
| 643 | @ <td><input type="password" id="p" name="p" value="" size="30" /></td> |
| 644 | @ </tr> |
| 645 | if( g.zLogin==0 && (anonFlag || zGoto==0) ){ |
| 646 | zAnonPw = db_text(0, "SELECT pw FROM user" |
| 647 | " WHERE login='anonymous'" |
| 648 | " AND cap!=''"); |
| 649 | } |
| 650 | @ <tr> |
| @@ -624,20 +665,11 @@ | |
| 665 | @ form.action = "%h(zSSL)/login"; |
| 666 | @ } |
| 667 | } |
| 668 | @ } |
| 669 | @ </script> |
| 670 | @ <p>Pressing the Login button grants permission to store a cookie.</p> |
| 671 | if( db_get_boolean("self-register", 0) ){ |
| 672 | @ <p>If you do not have an account, you can |
| 673 | @ <a href="%R/register?g=%T(P("G"))">create one</a>. |
| 674 | } |
| 675 | if( zAnonPw ){ |
| @@ -657,22 +689,14 @@ | |
| 689 | @ onclick="gebi('u').value='anonymous'; gebi('p').value='%s(zDecoded)';" /> |
| 690 | } |
| 691 | @ </div> |
| 692 | free(zCaptcha); |
| 693 | } |
| 694 | @ </form> |
| 695 | if( g.perm.Password ){ |
| 696 | @ <hr /> |
| 697 | @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p> |
| 698 | form_begin(0, "%R/login"); |
| 699 | @ <table> |
| 700 | @ <tr><td class="login_out_label">Old Password:</td> |
| 701 | @ <td><input type="password" name="p" size="30" /></td></tr> |
| 702 | @ <tr><td class="login_out_label">New Password:</td> |
| @@ -811,10 +835,11 @@ | |
| 835 | ** variables appropriately. |
| 836 | ** |
| 837 | ** g.userUid Database USER.UID value. Might be -1 for "nobody" |
| 838 | ** g.zLogin Database USER.LOGIN value. NULL for user "nobody" |
| 839 | ** g.perm Permissions granted to this user |
| 840 | ** g.anon Permissions that would be available to anonymous |
| 841 | ** g.isHuman True if the user is human, not a spider or robot |
| 842 | ** |
| 843 | */ |
| 844 | void login_check_credentials(void){ |
| 845 | int uid = 0; /* User id */ |
| @@ -1002,23 +1027,32 @@ | |
| 1027 | ** Memory of settings |
| 1028 | */ |
| 1029 | static int login_anon_once = 1; |
| 1030 | |
| 1031 | /* |
| 1032 | ** Add to g.perm the default privileges of users "nobody" and/or "anonymous" |
| 1033 | ** as appropriate for the user g.zLogin. |
| 1034 | ** |
| 1035 | ** This routine also sets up g.anon to be either a copy of g.perm for |
| 1036 | ** all logged in uses, or the privileges that would be available to "anonymous" |
| 1037 | ** if g.zLogin==0 (meaning that the user is "nobody"). |
| 1038 | */ |
| 1039 | void login_set_anon_nobody_capabilities(void){ |
| 1040 | if( login_anon_once ){ |
| 1041 | const char *zCap; |
| 1042 | /* All users get privileges from "nobody" */ |
| 1043 | zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); |
| 1044 | login_set_capabilities(zCap, 0); |
| 1045 | zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); |
| 1046 | if( g.zLogin && fossil_strcmp(g.zLogin, "nobody")!=0 ){ |
| 1047 | /* All logged-in users inherit privileges from "anonymous" */ |
| 1048 | login_set_capabilities(zCap, 0); |
| 1049 | g.anon = g.perm; |
| 1050 | }else{ |
| 1051 | /* Record the privileges of anonymous in g.anon */ |
| 1052 | g.anon = g.perm; |
| 1053 | login_set_capabilities(zCap, LOGIN_ANON); |
| 1054 | } |
| 1055 | login_anon_once = 0; |
| 1056 | } |
| 1057 | } |
| 1058 | |
| @@ -1025,55 +1059,57 @@ | |
| 1059 | /* |
| 1060 | ** Flags passed into the 2nd argument of login_set/replace_capabilities(). |
| 1061 | */ |
| 1062 | #if INTERFACE |
| 1063 | #define LOGIN_IGNORE_UV 0x01 /* Ignore "u" and "v" */ |
| 1064 | #define LOGIN_ANON 0x02 /* Use g.anon instead of g.perm */ |
| 1065 | #endif |
| 1066 | |
| 1067 | /* |
| 1068 | ** Adds all capability flags in zCap to g.perm or g.anon. |
| 1069 | */ |
| 1070 | void login_set_capabilities(const char *zCap, unsigned flags){ |
| 1071 | int i; |
| 1072 | FossilUserPerms *p = (flags & LOGIN_ANON) ? &g.anon : &g.perm; |
| 1073 | if(NULL==zCap){ |
| 1074 | return; |
| 1075 | } |
| 1076 | for(i=0; zCap[i]; i++){ |
| 1077 | switch( zCap[i] ){ |
| 1078 | case 's': p->Setup = 1; /* Fall thru into Admin */ |
| 1079 | case 'a': p->Admin = p->RdTkt = p->WrTkt = p->Zip = |
| 1080 | p->RdWiki = p->WrWiki = p->NewWiki = |
| 1081 | p->ApndWiki = p->Hyperlink = p->Clone = |
| 1082 | p->NewTkt = p->Password = p->RdAddr = |
| 1083 | p->TktFmt = p->Attach = p->ApndTkt = |
| 1084 | p->ModWiki = p->ModTkt = 1; |
| 1085 | /* Fall thru into Read/Write */ |
| 1086 | case 'i': p->Read = p->Write = 1; break; |
| 1087 | case 'o': p->Read = 1; break; |
| 1088 | case 'z': p->Zip = 1; break; |
| 1089 | |
| 1090 | case 'd': p->Delete = 1; break; |
| 1091 | case 'h': p->Hyperlink = 1; break; |
| 1092 | case 'g': p->Clone = 1; break; |
| 1093 | case 'p': p->Password = 1; break; |
| 1094 | |
| 1095 | case 'j': p->RdWiki = 1; break; |
| 1096 | case 'k': p->WrWiki = p->RdWiki = p->ApndWiki =1; break; |
| 1097 | case 'm': p->ApndWiki = 1; break; |
| 1098 | case 'f': p->NewWiki = 1; break; |
| 1099 | case 'l': p->ModWiki = 1; break; |
| 1100 | |
| 1101 | case 'e': p->RdAddr = 1; break; |
| 1102 | case 'r': p->RdTkt = 1; break; |
| 1103 | case 'n': p->NewTkt = 1; break; |
| 1104 | case 'w': p->WrTkt = p->RdTkt = p->NewTkt = |
| 1105 | p->ApndTkt = 1; break; |
| 1106 | case 'c': p->ApndTkt = 1; break; |
| 1107 | case 'q': p->ModTkt = 1; break; |
| 1108 | case 't': p->TktFmt = 1; break; |
| 1109 | case 'b': p->Attach = 1; break; |
| 1110 | case 'x': p->Private = 1; break; |
| 1111 | |
| 1112 | /* The "u" privileges is a little different. It recursively |
| 1113 | ** inherits all privileges of the user named "reader" */ |
| 1114 | case 'u': { |
| 1115 | if( (flags & LOGIN_IGNORE_UV)==0 ){ |
| @@ -1110,42 +1146,43 @@ | |
| 1146 | /* |
| 1147 | ** If the current login lacks any of the capabilities listed in |
| 1148 | ** the input, then return 0. If all capabilities are present, then |
| 1149 | ** return 1. |
| 1150 | */ |
| 1151 | int login_has_capability(const char *zCap, int nCap, u32 flgs){ |
| 1152 | int i; |
| 1153 | int rc = 1; |
| 1154 | FossilUserPerms *p = (flgs & LOGIN_ANON) ? &g.anon : &g.perm; |
| 1155 | if( nCap<0 ) nCap = strlen(zCap); |
| 1156 | for(i=0; i<nCap && rc && zCap[i]; i++){ |
| 1157 | switch( zCap[i] ){ |
| 1158 | case 'a': rc = p->Admin; break; |
| 1159 | case 'b': rc = p->Attach; break; |
| 1160 | case 'c': rc = p->ApndTkt; break; |
| 1161 | case 'd': rc = p->Delete; break; |
| 1162 | case 'e': rc = p->RdAddr; break; |
| 1163 | case 'f': rc = p->NewWiki; break; |
| 1164 | case 'g': rc = p->Clone; break; |
| 1165 | case 'h': rc = p->Hyperlink; break; |
| 1166 | case 'i': rc = p->Write; break; |
| 1167 | case 'j': rc = p->RdWiki; break; |
| 1168 | case 'k': rc = p->WrWiki; break; |
| 1169 | case 'l': rc = p->ModWiki; break; |
| 1170 | case 'm': rc = p->ApndWiki; break; |
| 1171 | case 'n': rc = p->NewTkt; break; |
| 1172 | case 'o': rc = p->Read; break; |
| 1173 | case 'p': rc = p->Password; break; |
| 1174 | case 'q': rc = p->ModTkt; break; |
| 1175 | case 'r': rc = p->RdTkt; break; |
| 1176 | case 's': rc = p->Setup; break; |
| 1177 | case 't': rc = p->TktFmt; break; |
| 1178 | /* case 'u': READER */ |
| 1179 | /* case 'v': DEVELOPER */ |
| 1180 | case 'w': rc = p->WrTkt; break; |
| 1181 | case 'x': rc = p->Private; break; |
| 1182 | /* case 'y': */ |
| 1183 | case 'z': rc = p->Zip; break; |
| 1184 | default: rc = 0; break; |
| 1185 | } |
| 1186 | } |
| 1187 | return rc; |
| 1188 | } |
| @@ -1195,11 +1232,11 @@ | |
| 1232 | |
| 1233 | /* |
| 1234 | ** Call this routine when the credential check fails. It causes |
| 1235 | ** a redirect to the "login" page. |
| 1236 | */ |
| 1237 | void login_needed(int anonOk){ |
| 1238 | #ifdef FOSSIL_ENABLE_JSON |
| 1239 | if(g.json.isJsonMode){ |
| 1240 | json_err( FSL_JSON_E_DENIED, NULL, 1 ); |
| 1241 | fossil_exit(0); |
| 1242 | /* NOTREACHED */ |
| @@ -1206,11 +1243,23 @@ | |
| 1243 | assert(0); |
| 1244 | }else |
| 1245 | #endif /* FOSSIL_ENABLE_JSON */ |
| 1246 | { |
| 1247 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1248 | const char *zQS = P("QUERY_STRING"); |
| 1249 | Blob redir; |
| 1250 | blob_init(&redir, 0, 0); |
| 1251 | if( login_wants_https_redirect() ){ |
| 1252 | blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl); |
| 1253 | }else{ |
| 1254 | blob_appendf(&redir, "%R/login?g=%T", zUrl); |
| 1255 | } |
| 1256 | if( anonOk ) blob_append(&redir, "&anon", 5); |
| 1257 | if( zQS && zQS[0] ){ |
| 1258 | blob_appendf(&redir, "&%s", zQS); |
| 1259 | } |
| 1260 | cgi_redirect(blob_str(&redir)); |
| 1261 | /* NOTREACHED */ |
| 1262 | assert(0); |
| 1263 | } |
| 1264 | } |
| 1265 | |
| @@ -1219,14 +1268,11 @@ | |
| 1268 | ** the anonymous user has Hyperlink permission, then paint a mesage |
| 1269 | ** to inform the user that much more information is available by |
| 1270 | ** logging in as anonymous. |
| 1271 | */ |
| 1272 | void login_anonymous_available(void){ |
| 1273 | if( !g.perm.Hyperlink && g.anon.Hyperlink ){ |
| 1274 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1275 | @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br /> |
| 1276 | @ Use <a href="%R/login?anon=1&g=%T(zUrl)">anonymous login</a> |
| 1277 | @ to enable hyperlinks.</p> |
| 1278 | } |
| 1279 |
+6
-1
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -193,12 +193,17 @@ | ||
| 193 | 193 | /* Information used to populate the RCVFROM table */ |
| 194 | 194 | int rcvid; /* The rcvid. 0 if not yet defined. */ |
| 195 | 195 | char *zIpAddr; /* The remote IP address */ |
| 196 | 196 | char *zNonce; /* The nonce used for login */ |
| 197 | 197 | |
| 198 | - /* permissions used by the server */ | |
| 198 | + /* permissions available to current user */ | |
| 199 | 199 | struct FossilUserPerms perm; |
| 200 | + | |
| 201 | + /* permissions available to current user or to "anonymous". | |
| 202 | + ** This is the logical union of perm permissions above with | |
| 203 | + ** the value that perm would take if g.zLogin were "anonymous". */ | |
| 204 | + struct FossilUserPerms anon; | |
| 200 | 205 | |
| 201 | 206 | #ifdef FOSSIL_ENABLE_TCL |
| 202 | 207 | /* all Tcl related context necessary for integration */ |
| 203 | 208 | struct TclContext tcl; |
| 204 | 209 | #endif |
| 205 | 210 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -193,12 +193,17 @@ | |
| 193 | /* Information used to populate the RCVFROM table */ |
| 194 | int rcvid; /* The rcvid. 0 if not yet defined. */ |
| 195 | char *zIpAddr; /* The remote IP address */ |
| 196 | char *zNonce; /* The nonce used for login */ |
| 197 | |
| 198 | /* permissions used by the server */ |
| 199 | struct FossilUserPerms perm; |
| 200 | |
| 201 | #ifdef FOSSIL_ENABLE_TCL |
| 202 | /* all Tcl related context necessary for integration */ |
| 203 | struct TclContext tcl; |
| 204 | #endif |
| 205 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -193,12 +193,17 @@ | |
| 193 | /* Information used to populate the RCVFROM table */ |
| 194 | int rcvid; /* The rcvid. 0 if not yet defined. */ |
| 195 | char *zIpAddr; /* The remote IP address */ |
| 196 | char *zNonce; /* The nonce used for login */ |
| 197 | |
| 198 | /* permissions available to current user */ |
| 199 | struct FossilUserPerms perm; |
| 200 | |
| 201 | /* permissions available to current user or to "anonymous". |
| 202 | ** This is the logical union of perm permissions above with |
| 203 | ** the value that perm would take if g.zLogin were "anonymous". */ |
| 204 | struct FossilUserPerms anon; |
| 205 | |
| 206 | #ifdef FOSSIL_ENABLE_TCL |
| 207 | /* all Tcl related context necessary for integration */ |
| 208 | struct TclContext tcl; |
| 209 | #endif |
| 210 |
+4
-1
| --- src/moderate.c | ||
| +++ src/moderate.c | ||
| @@ -144,11 +144,14 @@ | ||
| 144 | 144 | void modreq_page(void){ |
| 145 | 145 | Blob sql; |
| 146 | 146 | Stmt q; |
| 147 | 147 | |
| 148 | 148 | login_check_credentials(); |
| 149 | - if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; } | |
| 149 | + if( !g.perm.RdWiki && !g.perm.RdTkt ){ | |
| 150 | + login_needed(g.anon.RdWiki && g.anon.RdTkt); | |
| 151 | + return; | |
| 152 | + } | |
| 150 | 153 | style_header("Pending Moderation Requests"); |
| 151 | 154 | @ <h2>All Pending Moderation Requests</h2> |
| 152 | 155 | if( moderation_table_exists() ){ |
| 153 | 156 | blob_init(&sql, timeline_query_for_www(), -1); |
| 154 | 157 | blob_append_sql(&sql, |
| 155 | 158 |
| --- src/moderate.c | |
| +++ src/moderate.c | |
| @@ -144,11 +144,14 @@ | |
| 144 | void modreq_page(void){ |
| 145 | Blob sql; |
| 146 | Stmt q; |
| 147 | |
| 148 | login_check_credentials(); |
| 149 | if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; } |
| 150 | style_header("Pending Moderation Requests"); |
| 151 | @ <h2>All Pending Moderation Requests</h2> |
| 152 | if( moderation_table_exists() ){ |
| 153 | blob_init(&sql, timeline_query_for_www(), -1); |
| 154 | blob_append_sql(&sql, |
| 155 |
| --- src/moderate.c | |
| +++ src/moderate.c | |
| @@ -144,11 +144,14 @@ | |
| 144 | void modreq_page(void){ |
| 145 | Blob sql; |
| 146 | Stmt q; |
| 147 | |
| 148 | login_check_credentials(); |
| 149 | if( !g.perm.RdWiki && !g.perm.RdTkt ){ |
| 150 | login_needed(g.anon.RdWiki && g.anon.RdTkt); |
| 151 | return; |
| 152 | } |
| 153 | style_header("Pending Moderation Requests"); |
| 154 | @ <h2>All Pending Moderation Requests</h2> |
| 155 | if( moderation_table_exists() ){ |
| 156 | blob_init(&sql, timeline_query_for_www(), -1); |
| 157 | blob_append_sql(&sql, |
| 158 |
+2
-2
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -987,11 +987,11 @@ | ||
| 987 | 987 | int n = atoi(PD("n","5000")); |
| 988 | 988 | int mx = db_int(0, "SELECT max(rid) FROM blob"); |
| 989 | 989 | char *zRange; |
| 990 | 990 | |
| 991 | 991 | login_check_credentials(); |
| 992 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 992 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 993 | 993 | style_header("List Of Artifacts"); |
| 994 | 994 | if( mx>n && P("s")==0 ){ |
| 995 | 995 | int i; |
| 996 | 996 | @ <p>Select a range of artifacts to view:</p> |
| 997 | 997 | @ <ul> |
| @@ -1083,11 +1083,11 @@ | ||
| 1083 | 1083 | int cnt; |
| 1084 | 1084 | char *azHit[MAX_COLLIDE]; |
| 1085 | 1085 | char z[UUID_SIZE+1]; |
| 1086 | 1086 | } aCollide[UUID_SIZE+1]; |
| 1087 | 1087 | login_check_credentials(); |
| 1088 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 1088 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 1089 | 1089 | memset(aCollide, 0, sizeof(aCollide)); |
| 1090 | 1090 | memset(zPrev, 0, sizeof(zPrev)); |
| 1091 | 1091 | db_prepare(&q,"SELECT uuid FROM blob ORDER BY 1"); |
| 1092 | 1092 | while( db_step(&q)==SQLITE_ROW ){ |
| 1093 | 1093 | const char *zUuid = db_column_text(&q,0); |
| 1094 | 1094 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -987,11 +987,11 @@ | |
| 987 | int n = atoi(PD("n","5000")); |
| 988 | int mx = db_int(0, "SELECT max(rid) FROM blob"); |
| 989 | char *zRange; |
| 990 | |
| 991 | login_check_credentials(); |
| 992 | if( !g.perm.Read ){ login_needed(); return; } |
| 993 | style_header("List Of Artifacts"); |
| 994 | if( mx>n && P("s")==0 ){ |
| 995 | int i; |
| 996 | @ <p>Select a range of artifacts to view:</p> |
| 997 | @ <ul> |
| @@ -1083,11 +1083,11 @@ | |
| 1083 | int cnt; |
| 1084 | char *azHit[MAX_COLLIDE]; |
| 1085 | char z[UUID_SIZE+1]; |
| 1086 | } aCollide[UUID_SIZE+1]; |
| 1087 | login_check_credentials(); |
| 1088 | if( !g.perm.Read ){ login_needed(); return; } |
| 1089 | memset(aCollide, 0, sizeof(aCollide)); |
| 1090 | memset(zPrev, 0, sizeof(zPrev)); |
| 1091 | db_prepare(&q,"SELECT uuid FROM blob ORDER BY 1"); |
| 1092 | while( db_step(&q)==SQLITE_ROW ){ |
| 1093 | const char *zUuid = db_column_text(&q,0); |
| 1094 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -987,11 +987,11 @@ | |
| 987 | int n = atoi(PD("n","5000")); |
| 988 | int mx = db_int(0, "SELECT max(rid) FROM blob"); |
| 989 | char *zRange; |
| 990 | |
| 991 | login_check_credentials(); |
| 992 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 993 | style_header("List Of Artifacts"); |
| 994 | if( mx>n && P("s")==0 ){ |
| 995 | int i; |
| 996 | @ <p>Select a range of artifacts to view:</p> |
| 997 | @ <ul> |
| @@ -1083,11 +1083,11 @@ | |
| 1083 | int cnt; |
| 1084 | char *azHit[MAX_COLLIDE]; |
| 1085 | char z[UUID_SIZE+1]; |
| 1086 | } aCollide[UUID_SIZE+1]; |
| 1087 | login_check_credentials(); |
| 1088 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1089 | memset(aCollide, 0, sizeof(aCollide)); |
| 1090 | memset(zPrev, 0, sizeof(zPrev)); |
| 1091 | db_prepare(&q,"SELECT uuid FROM blob ORDER BY 1"); |
| 1092 | while( db_step(&q)==SQLITE_ROW ){ |
| 1093 | const char *zUuid = db_column_text(&q,0); |
| 1094 |
+1
-1
| --- src/path.c | ||
| +++ src/path.c | ||
| @@ -543,11 +543,11 @@ | ||
| 543 | 543 | */ |
| 544 | 544 | void test_rename_list_page(void){ |
| 545 | 545 | Stmt q; |
| 546 | 546 | |
| 547 | 547 | login_check_credentials(); |
| 548 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 548 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 549 | 549 | style_header("List Of File Name Changes"); |
| 550 | 550 | @ <h3>NB: Experimental Page</h3> |
| 551 | 551 | @ <table border="1" width="100%%"> |
| 552 | 552 | @ <tr><th>Date & Time</th> |
| 553 | 553 | @ <th>Old Name</th> |
| 554 | 554 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -543,11 +543,11 @@ | |
| 543 | */ |
| 544 | void test_rename_list_page(void){ |
| 545 | Stmt q; |
| 546 | |
| 547 | login_check_credentials(); |
| 548 | if( !g.perm.Read ){ login_needed(); return; } |
| 549 | style_header("List Of File Name Changes"); |
| 550 | @ <h3>NB: Experimental Page</h3> |
| 551 | @ <table border="1" width="100%%"> |
| 552 | @ <tr><th>Date & Time</th> |
| 553 | @ <th>Old Name</th> |
| 554 |
| --- src/path.c | |
| +++ src/path.c | |
| @@ -543,11 +543,11 @@ | |
| 543 | */ |
| 544 | void test_rename_list_page(void){ |
| 545 | Stmt q; |
| 546 | |
| 547 | login_check_credentials(); |
| 548 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 549 | style_header("List Of File Name Changes"); |
| 550 | @ <h3>NB: Experimental Page</h3> |
| 551 | @ <table border="1" width="100%%"> |
| 552 | @ <tr><th>Date & Time</th> |
| 553 | @ <th>Old Name</th> |
| 554 |
+7
-4
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -40,11 +40,14 @@ | ||
| 40 | 40 | Stmt q; |
| 41 | 41 | int rn = 0; |
| 42 | 42 | int cnt = 0; |
| 43 | 43 | |
| 44 | 44 | login_check_credentials(); |
| 45 | - if( !g.perm.RdTkt && !g.perm.NewTkt ){ login_needed(); return; } | |
| 45 | + if( !g.perm.RdTkt && !g.perm.NewTkt ){ | |
| 46 | + login_needed(g.anon.RdTkt || g.anon.NewTkt); | |
| 47 | + return; | |
| 48 | + } | |
| 46 | 49 | style_header("Ticket Main Menu"); |
| 47 | 50 | ticket_standard_submenu(T_ALL_BUT(T_REPLIST)); |
| 48 | 51 | if( g.thTrace ) Th_Trace("BEGIN_REPORTLIST<br />\n", -1); |
| 49 | 52 | zScript = ticket_reportlist_code(); |
| 50 | 53 | if( g.thTrace ) Th_Trace("BEGIN_REPORTLIST_SCRIPT<br />\n", -1); |
| @@ -293,11 +296,11 @@ | ||
| 293 | 296 | const char *zClrKey; |
| 294 | 297 | Stmt q; |
| 295 | 298 | |
| 296 | 299 | login_check_credentials(); |
| 297 | 300 | if( !g.perm.TktFmt ){ |
| 298 | - login_needed(); | |
| 301 | + login_needed(g.anon.TktFmt); | |
| 299 | 302 | return; |
| 300 | 303 | } |
| 301 | 304 | rn = atoi(PD("rn","0")); |
| 302 | 305 | db_prepare(&q, "SELECT title, sqlcode, owner, cols " |
| 303 | 306 | "FROM reportfmt WHERE rn=%d",rn); |
| @@ -343,11 +346,11 @@ | ||
| 343 | 346 | char *zSQL; |
| 344 | 347 | char *zErr = 0; |
| 345 | 348 | |
| 346 | 349 | login_check_credentials(); |
| 347 | 350 | if( !g.perm.TktFmt ){ |
| 348 | - login_needed(); | |
| 351 | + login_needed(g.anon.TktFmt); | |
| 349 | 352 | return; |
| 350 | 353 | } |
| 351 | 354 | /*view_add_functions(0);*/ |
| 352 | 355 | rn = atoi(PD("rn","0")); |
| 353 | 356 | zTitle = P("t"); |
| @@ -1078,11 +1081,11 @@ | ||
| 1078 | 1081 | Stmt q; |
| 1079 | 1082 | char *zErr1 = 0; |
| 1080 | 1083 | char *zErr2 = 0; |
| 1081 | 1084 | |
| 1082 | 1085 | login_check_credentials(); |
| 1083 | - if( !g.perm.RdTkt ){ login_needed(); return; } | |
| 1086 | + if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } | |
| 1084 | 1087 | rn = atoi(PD("rn","0")); |
| 1085 | 1088 | if( rn==0 ){ |
| 1086 | 1089 | cgi_redirect("reportlist"); |
| 1087 | 1090 | return; |
| 1088 | 1091 | } |
| 1089 | 1092 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -40,11 +40,14 @@ | |
| 40 | Stmt q; |
| 41 | int rn = 0; |
| 42 | int cnt = 0; |
| 43 | |
| 44 | login_check_credentials(); |
| 45 | if( !g.perm.RdTkt && !g.perm.NewTkt ){ login_needed(); return; } |
| 46 | style_header("Ticket Main Menu"); |
| 47 | ticket_standard_submenu(T_ALL_BUT(T_REPLIST)); |
| 48 | if( g.thTrace ) Th_Trace("BEGIN_REPORTLIST<br />\n", -1); |
| 49 | zScript = ticket_reportlist_code(); |
| 50 | if( g.thTrace ) Th_Trace("BEGIN_REPORTLIST_SCRIPT<br />\n", -1); |
| @@ -293,11 +296,11 @@ | |
| 293 | const char *zClrKey; |
| 294 | Stmt q; |
| 295 | |
| 296 | login_check_credentials(); |
| 297 | if( !g.perm.TktFmt ){ |
| 298 | login_needed(); |
| 299 | return; |
| 300 | } |
| 301 | rn = atoi(PD("rn","0")); |
| 302 | db_prepare(&q, "SELECT title, sqlcode, owner, cols " |
| 303 | "FROM reportfmt WHERE rn=%d",rn); |
| @@ -343,11 +346,11 @@ | |
| 343 | char *zSQL; |
| 344 | char *zErr = 0; |
| 345 | |
| 346 | login_check_credentials(); |
| 347 | if( !g.perm.TktFmt ){ |
| 348 | login_needed(); |
| 349 | return; |
| 350 | } |
| 351 | /*view_add_functions(0);*/ |
| 352 | rn = atoi(PD("rn","0")); |
| 353 | zTitle = P("t"); |
| @@ -1078,11 +1081,11 @@ | |
| 1078 | Stmt q; |
| 1079 | char *zErr1 = 0; |
| 1080 | char *zErr2 = 0; |
| 1081 | |
| 1082 | login_check_credentials(); |
| 1083 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 1084 | rn = atoi(PD("rn","0")); |
| 1085 | if( rn==0 ){ |
| 1086 | cgi_redirect("reportlist"); |
| 1087 | return; |
| 1088 | } |
| 1089 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -40,11 +40,14 @@ | |
| 40 | Stmt q; |
| 41 | int rn = 0; |
| 42 | int cnt = 0; |
| 43 | |
| 44 | login_check_credentials(); |
| 45 | if( !g.perm.RdTkt && !g.perm.NewTkt ){ |
| 46 | login_needed(g.anon.RdTkt || g.anon.NewTkt); |
| 47 | return; |
| 48 | } |
| 49 | style_header("Ticket Main Menu"); |
| 50 | ticket_standard_submenu(T_ALL_BUT(T_REPLIST)); |
| 51 | if( g.thTrace ) Th_Trace("BEGIN_REPORTLIST<br />\n", -1); |
| 52 | zScript = ticket_reportlist_code(); |
| 53 | if( g.thTrace ) Th_Trace("BEGIN_REPORTLIST_SCRIPT<br />\n", -1); |
| @@ -293,11 +296,11 @@ | |
| 296 | const char *zClrKey; |
| 297 | Stmt q; |
| 298 | |
| 299 | login_check_credentials(); |
| 300 | if( !g.perm.TktFmt ){ |
| 301 | login_needed(g.anon.TktFmt); |
| 302 | return; |
| 303 | } |
| 304 | rn = atoi(PD("rn","0")); |
| 305 | db_prepare(&q, "SELECT title, sqlcode, owner, cols " |
| 306 | "FROM reportfmt WHERE rn=%d",rn); |
| @@ -343,11 +346,11 @@ | |
| 346 | char *zSQL; |
| 347 | char *zErr = 0; |
| 348 | |
| 349 | login_check_credentials(); |
| 350 | if( !g.perm.TktFmt ){ |
| 351 | login_needed(g.anon.TktFmt); |
| 352 | return; |
| 353 | } |
| 354 | /*view_add_functions(0);*/ |
| 355 | rn = atoi(PD("rn","0")); |
| 356 | zTitle = P("t"); |
| @@ -1078,11 +1081,11 @@ | |
| 1081 | Stmt q; |
| 1082 | char *zErr1 = 0; |
| 1083 | char *zErr2 = 0; |
| 1084 | |
| 1085 | login_check_credentials(); |
| 1086 | if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } |
| 1087 | rn = atoi(PD("rn","0")); |
| 1088 | if( rn==0 ){ |
| 1089 | cgi_redirect("reportlist"); |
| 1090 | return; |
| 1091 | } |
| 1092 |
+33
-18
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -59,11 +59,11 @@ | ||
| 59 | 59 | ** WEBPAGE: /setup |
| 60 | 60 | */ |
| 61 | 61 | void setup_page(void){ |
| 62 | 62 | login_check_credentials(); |
| 63 | 63 | if( !g.perm.Setup ){ |
| 64 | - login_needed(); | |
| 64 | + login_needed(0); | |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | 67 | style_header("Server Administration"); |
| 68 | 68 | |
| 69 | 69 | /* Make sure the header contains <base href="...">. Issue a warning |
| @@ -152,11 +152,11 @@ | ||
| 152 | 152 | Stmt s; |
| 153 | 153 | int prevLevel = 0; |
| 154 | 154 | |
| 155 | 155 | login_check_credentials(); |
| 156 | 156 | if( !g.perm.Admin ){ |
| 157 | - login_needed(); | |
| 157 | + login_needed(0); | |
| 158 | 158 | return; |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | 161 | style_submenu_element("Add", "Add User", "setup_uedit"); |
| 162 | 162 | style_header("User List"); |
| @@ -336,11 +336,11 @@ | ||
| 336 | 336 | const char *oa[128]; |
| 337 | 337 | |
| 338 | 338 | /* Must have ADMIN privileges to access this page |
| 339 | 339 | */ |
| 340 | 340 | login_check_credentials(); |
| 341 | - if( !g.perm.Admin ){ login_needed(); return; } | |
| 341 | + if( !g.perm.Admin ){ login_needed(0); return; } | |
| 342 | 342 | |
| 343 | 343 | /* Check to see if an ADMIN user is trying to edit a SETUP account. |
| 344 | 344 | ** Don't allow that. |
| 345 | 345 | */ |
| 346 | 346 | zId = PD("id", "0"); |
| @@ -998,11 +998,12 @@ | ||
| 998 | 998 | ** WEBPAGE: setup_access |
| 999 | 999 | */ |
| 1000 | 1000 | void setup_access(void){ |
| 1001 | 1001 | login_check_credentials(); |
| 1002 | 1002 | if( !g.perm.Setup ){ |
| 1003 | - login_needed(); | |
| 1003 | + login_needed(0); | |
| 1004 | + return; | |
| 1004 | 1005 | } |
| 1005 | 1006 | |
| 1006 | 1007 | style_header("Access Control Settings"); |
| 1007 | 1008 | db_begin_transaction(); |
| 1008 | 1009 | @ <form action="%s(g.zTop)/setup_access" method="post"><div> |
| @@ -1203,11 +1204,12 @@ | ||
| 1203 | 1204 | const char *zPw = PD("pw", ""); |
| 1204 | 1205 | const char *zNewName = PD("newname", "New Login Group"); |
| 1205 | 1206 | |
| 1206 | 1207 | login_check_credentials(); |
| 1207 | 1208 | if( !g.perm.Setup ){ |
| 1208 | - login_needed(); | |
| 1209 | + login_needed(0); | |
| 1210 | + return; | |
| 1209 | 1211 | } |
| 1210 | 1212 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1211 | 1213 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 1212 | 1214 | blob_reset(&fullName); |
| 1213 | 1215 | if( P("join")!=0 ){ |
| @@ -1315,11 +1317,12 @@ | ||
| 1315 | 1317 | "3", "YYMMDD HH:MM", |
| 1316 | 1318 | "4", "(off)" |
| 1317 | 1319 | }; |
| 1318 | 1320 | login_check_credentials(); |
| 1319 | 1321 | if( !g.perm.Setup ){ |
| 1320 | - login_needed(); | |
| 1322 | + login_needed(0); | |
| 1323 | + return; | |
| 1321 | 1324 | } |
| 1322 | 1325 | |
| 1323 | 1326 | style_header("Timeline Display Preferences"); |
| 1324 | 1327 | db_begin_transaction(); |
| 1325 | 1328 | @ <form action="%s(g.zTop)/setup_timeline" method="post"><div> |
| @@ -1393,11 +1396,12 @@ | ||
| 1393 | 1396 | void setup_settings(void){ |
| 1394 | 1397 | Setting const *pSet; |
| 1395 | 1398 | |
| 1396 | 1399 | login_check_credentials(); |
| 1397 | 1400 | if( !g.perm.Setup ){ |
| 1398 | - login_needed(); | |
| 1401 | + login_needed(0); | |
| 1402 | + return; | |
| 1399 | 1403 | } |
| 1400 | 1404 | |
| 1401 | 1405 | (void) aCmdHelp; /* NOTE: Silence compiler warning. */ |
| 1402 | 1406 | style_header("Settings"); |
| 1403 | 1407 | if(!g.repositoryOpen){ |
| @@ -1473,11 +1477,12 @@ | ||
| 1473 | 1477 | ** WEBPAGE: setup_config |
| 1474 | 1478 | */ |
| 1475 | 1479 | void setup_config(void){ |
| 1476 | 1480 | login_check_credentials(); |
| 1477 | 1481 | if( !g.perm.Setup ){ |
| 1478 | - login_needed(); | |
| 1482 | + login_needed(0); | |
| 1483 | + return; | |
| 1479 | 1484 | } |
| 1480 | 1485 | |
| 1481 | 1486 | style_header("WWW Configuration"); |
| 1482 | 1487 | db_begin_transaction(); |
| 1483 | 1488 | @ <form action="%s(g.zTop)/setup_config" method="post"><div> |
| @@ -1551,11 +1556,12 @@ | ||
| 1551 | 1556 | ** WEBPAGE: setup_editcss |
| 1552 | 1557 | */ |
| 1553 | 1558 | void setup_editcss(void){ |
| 1554 | 1559 | login_check_credentials(); |
| 1555 | 1560 | if( !g.perm.Setup ){ |
| 1556 | - login_needed(); | |
| 1561 | + login_needed(0); | |
| 1562 | + return; | |
| 1557 | 1563 | } |
| 1558 | 1564 | db_begin_transaction(); |
| 1559 | 1565 | if( P("clear")!=0 ){ |
| 1560 | 1566 | db_multi_exec("DELETE FROM config WHERE name='css'"); |
| 1561 | 1567 | cgi_replace_parameter("css", builtin_text("skins/default/css.txt")); |
| @@ -1596,11 +1602,12 @@ | ||
| 1596 | 1602 | ** WEBPAGE: setup_header |
| 1597 | 1603 | */ |
| 1598 | 1604 | void setup_header(void){ |
| 1599 | 1605 | login_check_credentials(); |
| 1600 | 1606 | if( !g.perm.Setup ){ |
| 1601 | - login_needed(); | |
| 1607 | + login_needed(0); | |
| 1608 | + return; | |
| 1602 | 1609 | } |
| 1603 | 1610 | db_begin_transaction(); |
| 1604 | 1611 | if( P("clear")!=0 ){ |
| 1605 | 1612 | db_multi_exec("DELETE FROM config WHERE name='header'"); |
| 1606 | 1613 | cgi_replace_parameter("header", builtin_text("skins/default/header.txt")); |
| @@ -1660,11 +1667,12 @@ | ||
| 1660 | 1667 | ** WEBPAGE: setup_footer |
| 1661 | 1668 | */ |
| 1662 | 1669 | void setup_footer(void){ |
| 1663 | 1670 | login_check_credentials(); |
| 1664 | 1671 | if( !g.perm.Setup ){ |
| 1665 | - login_needed(); | |
| 1672 | + login_needed(0); | |
| 1673 | + return; | |
| 1666 | 1674 | } |
| 1667 | 1675 | db_begin_transaction(); |
| 1668 | 1676 | if( P("clear")!=0 ){ |
| 1669 | 1677 | db_multi_exec("DELETE FROM config WHERE name='footer'"); |
| 1670 | 1678 | cgi_replace_parameter("footer", builtin_text("skins/default/footer.txt")); |
| @@ -1697,11 +1705,12 @@ | ||
| 1697 | 1705 | ** WEBPAGE: setup_modreq |
| 1698 | 1706 | */ |
| 1699 | 1707 | void setup_modreq(void){ |
| 1700 | 1708 | login_check_credentials(); |
| 1701 | 1709 | if( !g.perm.Setup ){ |
| 1702 | - login_needed(); | |
| 1710 | + login_needed(0); | |
| 1711 | + return; | |
| 1703 | 1712 | } |
| 1704 | 1713 | |
| 1705 | 1714 | style_header("Moderator For Wiki And Tickets"); |
| 1706 | 1715 | db_begin_transaction(); |
| 1707 | 1716 | @ <form action="%R/setup_modreq" method="post"><div> |
| @@ -1741,11 +1750,12 @@ | ||
| 1741 | 1750 | ** WEBPAGE: setup_adunit |
| 1742 | 1751 | */ |
| 1743 | 1752 | void setup_adunit(void){ |
| 1744 | 1753 | login_check_credentials(); |
| 1745 | 1754 | if( !g.perm.Setup ){ |
| 1746 | - login_needed(); | |
| 1755 | + login_needed(0); | |
| 1756 | + return; | |
| 1747 | 1757 | } |
| 1748 | 1758 | db_begin_transaction(); |
| 1749 | 1759 | if( P("clear")!=0 ){ |
| 1750 | 1760 | db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'"); |
| 1751 | 1761 | cgi_replace_parameter("adunit",""); |
| @@ -1822,11 +1832,12 @@ | ||
| 1822 | 1832 | if( szBgImg>0 ){ |
| 1823 | 1833 | zBgMime = PD("bgim:mimetype","image/gif"); |
| 1824 | 1834 | } |
| 1825 | 1835 | login_check_credentials(); |
| 1826 | 1836 | if( !g.perm.Setup ){ |
| 1827 | - login_needed(); | |
| 1837 | + login_needed(0); | |
| 1838 | + return; | |
| 1828 | 1839 | } |
| 1829 | 1840 | db_begin_transaction(); |
| 1830 | 1841 | if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){ |
| 1831 | 1842 | Blob img; |
| 1832 | 1843 | Stmt ins; |
| @@ -1961,11 +1972,12 @@ | ||
| 1961 | 1972 | void sql_page(void){ |
| 1962 | 1973 | const char *zQ = P("q"); |
| 1963 | 1974 | int go = P("go")!=0; |
| 1964 | 1975 | login_check_credentials(); |
| 1965 | 1976 | if( !g.perm.Setup ){ |
| 1966 | - login_needed(); | |
| 1977 | + login_needed(0); | |
| 1978 | + return; | |
| 1967 | 1979 | } |
| 1968 | 1980 | db_begin_transaction(); |
| 1969 | 1981 | style_header("Raw SQL Commands"); |
| 1970 | 1982 | @ <p><b>Caution:</b> There are no restrictions on the SQL that can be |
| 1971 | 1983 | @ run by this page. You can do serious and irrepairable damage to the |
| @@ -2082,11 +2094,12 @@ | ||
| 2082 | 2094 | void th1_page(void){ |
| 2083 | 2095 | const char *zQ = P("q"); |
| 2084 | 2096 | int go = P("go")!=0; |
| 2085 | 2097 | login_check_credentials(); |
| 2086 | 2098 | if( !g.perm.Setup ){ |
| 2087 | - login_needed(); | |
| 2099 | + login_needed(0); | |
| 2100 | + return; | |
| 2088 | 2101 | } |
| 2089 | 2102 | db_begin_transaction(); |
| 2090 | 2103 | style_header("Raw TH1 Commands"); |
| 2091 | 2104 | @ <p><b>Caution:</b> There are no restrictions on the TH1 that can be |
| 2092 | 2105 | @ run by this page. If Tcl integration was enabled at compile-time and |
| @@ -2142,11 +2155,12 @@ | ||
| 2142 | 2155 | int limit; |
| 2143 | 2156 | int fLogEnabled; |
| 2144 | 2157 | int counter = 0; |
| 2145 | 2158 | login_check_credentials(); |
| 2146 | 2159 | if( !g.perm.Setup && !g.perm.Admin ){ |
| 2147 | - login_needed(); | |
| 2160 | + login_needed(0); | |
| 2161 | + return; | |
| 2148 | 2162 | } |
| 2149 | 2163 | style_header("Admin Log"); |
| 2150 | 2164 | create_admin_log_table(); |
| 2151 | 2165 | limit = atoi(PD("n","20")); |
| 2152 | 2166 | fLogEnabled = db_get_boolean("admin-log", 0); |
| @@ -2199,11 +2213,12 @@ | ||
| 2199 | 2213 | ** Configure the search engine. |
| 2200 | 2214 | */ |
| 2201 | 2215 | void page_srchsetup(){ |
| 2202 | 2216 | login_check_credentials(); |
| 2203 | 2217 | if( !g.perm.Setup && !g.perm.Admin ){ |
| 2204 | - login_needed(); | |
| 2218 | + login_needed(0); | |
| 2219 | + return; | |
| 2205 | 2220 | } |
| 2206 | 2221 | style_header("Search Configuration"); |
| 2207 | 2222 | @ <form action="%s(g.zTop)/srchsetup" method="post"><div> |
| 2208 | 2223 | login_insert_csrf_secret(); |
| 2209 | 2224 | @ <div style="text-align:center;font-weight:bold;"> |
| 2210 | 2225 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -59,11 +59,11 @@ | |
| 59 | ** WEBPAGE: /setup |
| 60 | */ |
| 61 | void setup_page(void){ |
| 62 | login_check_credentials(); |
| 63 | if( !g.perm.Setup ){ |
| 64 | login_needed(); |
| 65 | } |
| 66 | |
| 67 | style_header("Server Administration"); |
| 68 | |
| 69 | /* Make sure the header contains <base href="...">. Issue a warning |
| @@ -152,11 +152,11 @@ | |
| 152 | Stmt s; |
| 153 | int prevLevel = 0; |
| 154 | |
| 155 | login_check_credentials(); |
| 156 | if( !g.perm.Admin ){ |
| 157 | login_needed(); |
| 158 | return; |
| 159 | } |
| 160 | |
| 161 | style_submenu_element("Add", "Add User", "setup_uedit"); |
| 162 | style_header("User List"); |
| @@ -336,11 +336,11 @@ | |
| 336 | const char *oa[128]; |
| 337 | |
| 338 | /* Must have ADMIN privileges to access this page |
| 339 | */ |
| 340 | login_check_credentials(); |
| 341 | if( !g.perm.Admin ){ login_needed(); return; } |
| 342 | |
| 343 | /* Check to see if an ADMIN user is trying to edit a SETUP account. |
| 344 | ** Don't allow that. |
| 345 | */ |
| 346 | zId = PD("id", "0"); |
| @@ -998,11 +998,12 @@ | |
| 998 | ** WEBPAGE: setup_access |
| 999 | */ |
| 1000 | void setup_access(void){ |
| 1001 | login_check_credentials(); |
| 1002 | if( !g.perm.Setup ){ |
| 1003 | login_needed(); |
| 1004 | } |
| 1005 | |
| 1006 | style_header("Access Control Settings"); |
| 1007 | db_begin_transaction(); |
| 1008 | @ <form action="%s(g.zTop)/setup_access" method="post"><div> |
| @@ -1203,11 +1204,12 @@ | |
| 1203 | const char *zPw = PD("pw", ""); |
| 1204 | const char *zNewName = PD("newname", "New Login Group"); |
| 1205 | |
| 1206 | login_check_credentials(); |
| 1207 | if( !g.perm.Setup ){ |
| 1208 | login_needed(); |
| 1209 | } |
| 1210 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1211 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 1212 | blob_reset(&fullName); |
| 1213 | if( P("join")!=0 ){ |
| @@ -1315,11 +1317,12 @@ | |
| 1315 | "3", "YYMMDD HH:MM", |
| 1316 | "4", "(off)" |
| 1317 | }; |
| 1318 | login_check_credentials(); |
| 1319 | if( !g.perm.Setup ){ |
| 1320 | login_needed(); |
| 1321 | } |
| 1322 | |
| 1323 | style_header("Timeline Display Preferences"); |
| 1324 | db_begin_transaction(); |
| 1325 | @ <form action="%s(g.zTop)/setup_timeline" method="post"><div> |
| @@ -1393,11 +1396,12 @@ | |
| 1393 | void setup_settings(void){ |
| 1394 | Setting const *pSet; |
| 1395 | |
| 1396 | login_check_credentials(); |
| 1397 | if( !g.perm.Setup ){ |
| 1398 | login_needed(); |
| 1399 | } |
| 1400 | |
| 1401 | (void) aCmdHelp; /* NOTE: Silence compiler warning. */ |
| 1402 | style_header("Settings"); |
| 1403 | if(!g.repositoryOpen){ |
| @@ -1473,11 +1477,12 @@ | |
| 1473 | ** WEBPAGE: setup_config |
| 1474 | */ |
| 1475 | void setup_config(void){ |
| 1476 | login_check_credentials(); |
| 1477 | if( !g.perm.Setup ){ |
| 1478 | login_needed(); |
| 1479 | } |
| 1480 | |
| 1481 | style_header("WWW Configuration"); |
| 1482 | db_begin_transaction(); |
| 1483 | @ <form action="%s(g.zTop)/setup_config" method="post"><div> |
| @@ -1551,11 +1556,12 @@ | |
| 1551 | ** WEBPAGE: setup_editcss |
| 1552 | */ |
| 1553 | void setup_editcss(void){ |
| 1554 | login_check_credentials(); |
| 1555 | if( !g.perm.Setup ){ |
| 1556 | login_needed(); |
| 1557 | } |
| 1558 | db_begin_transaction(); |
| 1559 | if( P("clear")!=0 ){ |
| 1560 | db_multi_exec("DELETE FROM config WHERE name='css'"); |
| 1561 | cgi_replace_parameter("css", builtin_text("skins/default/css.txt")); |
| @@ -1596,11 +1602,12 @@ | |
| 1596 | ** WEBPAGE: setup_header |
| 1597 | */ |
| 1598 | void setup_header(void){ |
| 1599 | login_check_credentials(); |
| 1600 | if( !g.perm.Setup ){ |
| 1601 | login_needed(); |
| 1602 | } |
| 1603 | db_begin_transaction(); |
| 1604 | if( P("clear")!=0 ){ |
| 1605 | db_multi_exec("DELETE FROM config WHERE name='header'"); |
| 1606 | cgi_replace_parameter("header", builtin_text("skins/default/header.txt")); |
| @@ -1660,11 +1667,12 @@ | |
| 1660 | ** WEBPAGE: setup_footer |
| 1661 | */ |
| 1662 | void setup_footer(void){ |
| 1663 | login_check_credentials(); |
| 1664 | if( !g.perm.Setup ){ |
| 1665 | login_needed(); |
| 1666 | } |
| 1667 | db_begin_transaction(); |
| 1668 | if( P("clear")!=0 ){ |
| 1669 | db_multi_exec("DELETE FROM config WHERE name='footer'"); |
| 1670 | cgi_replace_parameter("footer", builtin_text("skins/default/footer.txt")); |
| @@ -1697,11 +1705,12 @@ | |
| 1697 | ** WEBPAGE: setup_modreq |
| 1698 | */ |
| 1699 | void setup_modreq(void){ |
| 1700 | login_check_credentials(); |
| 1701 | if( !g.perm.Setup ){ |
| 1702 | login_needed(); |
| 1703 | } |
| 1704 | |
| 1705 | style_header("Moderator For Wiki And Tickets"); |
| 1706 | db_begin_transaction(); |
| 1707 | @ <form action="%R/setup_modreq" method="post"><div> |
| @@ -1741,11 +1750,12 @@ | |
| 1741 | ** WEBPAGE: setup_adunit |
| 1742 | */ |
| 1743 | void setup_adunit(void){ |
| 1744 | login_check_credentials(); |
| 1745 | if( !g.perm.Setup ){ |
| 1746 | login_needed(); |
| 1747 | } |
| 1748 | db_begin_transaction(); |
| 1749 | if( P("clear")!=0 ){ |
| 1750 | db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'"); |
| 1751 | cgi_replace_parameter("adunit",""); |
| @@ -1822,11 +1832,12 @@ | |
| 1822 | if( szBgImg>0 ){ |
| 1823 | zBgMime = PD("bgim:mimetype","image/gif"); |
| 1824 | } |
| 1825 | login_check_credentials(); |
| 1826 | if( !g.perm.Setup ){ |
| 1827 | login_needed(); |
| 1828 | } |
| 1829 | db_begin_transaction(); |
| 1830 | if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){ |
| 1831 | Blob img; |
| 1832 | Stmt ins; |
| @@ -1961,11 +1972,12 @@ | |
| 1961 | void sql_page(void){ |
| 1962 | const char *zQ = P("q"); |
| 1963 | int go = P("go")!=0; |
| 1964 | login_check_credentials(); |
| 1965 | if( !g.perm.Setup ){ |
| 1966 | login_needed(); |
| 1967 | } |
| 1968 | db_begin_transaction(); |
| 1969 | style_header("Raw SQL Commands"); |
| 1970 | @ <p><b>Caution:</b> There are no restrictions on the SQL that can be |
| 1971 | @ run by this page. You can do serious and irrepairable damage to the |
| @@ -2082,11 +2094,12 @@ | |
| 2082 | void th1_page(void){ |
| 2083 | const char *zQ = P("q"); |
| 2084 | int go = P("go")!=0; |
| 2085 | login_check_credentials(); |
| 2086 | if( !g.perm.Setup ){ |
| 2087 | login_needed(); |
| 2088 | } |
| 2089 | db_begin_transaction(); |
| 2090 | style_header("Raw TH1 Commands"); |
| 2091 | @ <p><b>Caution:</b> There are no restrictions on the TH1 that can be |
| 2092 | @ run by this page. If Tcl integration was enabled at compile-time and |
| @@ -2142,11 +2155,12 @@ | |
| 2142 | int limit; |
| 2143 | int fLogEnabled; |
| 2144 | int counter = 0; |
| 2145 | login_check_credentials(); |
| 2146 | if( !g.perm.Setup && !g.perm.Admin ){ |
| 2147 | login_needed(); |
| 2148 | } |
| 2149 | style_header("Admin Log"); |
| 2150 | create_admin_log_table(); |
| 2151 | limit = atoi(PD("n","20")); |
| 2152 | fLogEnabled = db_get_boolean("admin-log", 0); |
| @@ -2199,11 +2213,12 @@ | |
| 2199 | ** Configure the search engine. |
| 2200 | */ |
| 2201 | void page_srchsetup(){ |
| 2202 | login_check_credentials(); |
| 2203 | if( !g.perm.Setup && !g.perm.Admin ){ |
| 2204 | login_needed(); |
| 2205 | } |
| 2206 | style_header("Search Configuration"); |
| 2207 | @ <form action="%s(g.zTop)/srchsetup" method="post"><div> |
| 2208 | login_insert_csrf_secret(); |
| 2209 | @ <div style="text-align:center;font-weight:bold;"> |
| 2210 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -59,11 +59,11 @@ | |
| 59 | ** WEBPAGE: /setup |
| 60 | */ |
| 61 | void setup_page(void){ |
| 62 | login_check_credentials(); |
| 63 | if( !g.perm.Setup ){ |
| 64 | login_needed(0); |
| 65 | } |
| 66 | |
| 67 | style_header("Server Administration"); |
| 68 | |
| 69 | /* Make sure the header contains <base href="...">. Issue a warning |
| @@ -152,11 +152,11 @@ | |
| 152 | Stmt s; |
| 153 | int prevLevel = 0; |
| 154 | |
| 155 | login_check_credentials(); |
| 156 | if( !g.perm.Admin ){ |
| 157 | login_needed(0); |
| 158 | return; |
| 159 | } |
| 160 | |
| 161 | style_submenu_element("Add", "Add User", "setup_uedit"); |
| 162 | style_header("User List"); |
| @@ -336,11 +336,11 @@ | |
| 336 | const char *oa[128]; |
| 337 | |
| 338 | /* Must have ADMIN privileges to access this page |
| 339 | */ |
| 340 | login_check_credentials(); |
| 341 | if( !g.perm.Admin ){ login_needed(0); return; } |
| 342 | |
| 343 | /* Check to see if an ADMIN user is trying to edit a SETUP account. |
| 344 | ** Don't allow that. |
| 345 | */ |
| 346 | zId = PD("id", "0"); |
| @@ -998,11 +998,12 @@ | |
| 998 | ** WEBPAGE: setup_access |
| 999 | */ |
| 1000 | void setup_access(void){ |
| 1001 | login_check_credentials(); |
| 1002 | if( !g.perm.Setup ){ |
| 1003 | login_needed(0); |
| 1004 | return; |
| 1005 | } |
| 1006 | |
| 1007 | style_header("Access Control Settings"); |
| 1008 | db_begin_transaction(); |
| 1009 | @ <form action="%s(g.zTop)/setup_access" method="post"><div> |
| @@ -1203,11 +1204,12 @@ | |
| 1204 | const char *zPw = PD("pw", ""); |
| 1205 | const char *zNewName = PD("newname", "New Login Group"); |
| 1206 | |
| 1207 | login_check_credentials(); |
| 1208 | if( !g.perm.Setup ){ |
| 1209 | login_needed(0); |
| 1210 | return; |
| 1211 | } |
| 1212 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 1213 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 1214 | blob_reset(&fullName); |
| 1215 | if( P("join")!=0 ){ |
| @@ -1315,11 +1317,12 @@ | |
| 1317 | "3", "YYMMDD HH:MM", |
| 1318 | "4", "(off)" |
| 1319 | }; |
| 1320 | login_check_credentials(); |
| 1321 | if( !g.perm.Setup ){ |
| 1322 | login_needed(0); |
| 1323 | return; |
| 1324 | } |
| 1325 | |
| 1326 | style_header("Timeline Display Preferences"); |
| 1327 | db_begin_transaction(); |
| 1328 | @ <form action="%s(g.zTop)/setup_timeline" method="post"><div> |
| @@ -1393,11 +1396,12 @@ | |
| 1396 | void setup_settings(void){ |
| 1397 | Setting const *pSet; |
| 1398 | |
| 1399 | login_check_credentials(); |
| 1400 | if( !g.perm.Setup ){ |
| 1401 | login_needed(0); |
| 1402 | return; |
| 1403 | } |
| 1404 | |
| 1405 | (void) aCmdHelp; /* NOTE: Silence compiler warning. */ |
| 1406 | style_header("Settings"); |
| 1407 | if(!g.repositoryOpen){ |
| @@ -1473,11 +1477,12 @@ | |
| 1477 | ** WEBPAGE: setup_config |
| 1478 | */ |
| 1479 | void setup_config(void){ |
| 1480 | login_check_credentials(); |
| 1481 | if( !g.perm.Setup ){ |
| 1482 | login_needed(0); |
| 1483 | return; |
| 1484 | } |
| 1485 | |
| 1486 | style_header("WWW Configuration"); |
| 1487 | db_begin_transaction(); |
| 1488 | @ <form action="%s(g.zTop)/setup_config" method="post"><div> |
| @@ -1551,11 +1556,12 @@ | |
| 1556 | ** WEBPAGE: setup_editcss |
| 1557 | */ |
| 1558 | void setup_editcss(void){ |
| 1559 | login_check_credentials(); |
| 1560 | if( !g.perm.Setup ){ |
| 1561 | login_needed(0); |
| 1562 | return; |
| 1563 | } |
| 1564 | db_begin_transaction(); |
| 1565 | if( P("clear")!=0 ){ |
| 1566 | db_multi_exec("DELETE FROM config WHERE name='css'"); |
| 1567 | cgi_replace_parameter("css", builtin_text("skins/default/css.txt")); |
| @@ -1596,11 +1602,12 @@ | |
| 1602 | ** WEBPAGE: setup_header |
| 1603 | */ |
| 1604 | void setup_header(void){ |
| 1605 | login_check_credentials(); |
| 1606 | if( !g.perm.Setup ){ |
| 1607 | login_needed(0); |
| 1608 | return; |
| 1609 | } |
| 1610 | db_begin_transaction(); |
| 1611 | if( P("clear")!=0 ){ |
| 1612 | db_multi_exec("DELETE FROM config WHERE name='header'"); |
| 1613 | cgi_replace_parameter("header", builtin_text("skins/default/header.txt")); |
| @@ -1660,11 +1667,12 @@ | |
| 1667 | ** WEBPAGE: setup_footer |
| 1668 | */ |
| 1669 | void setup_footer(void){ |
| 1670 | login_check_credentials(); |
| 1671 | if( !g.perm.Setup ){ |
| 1672 | login_needed(0); |
| 1673 | return; |
| 1674 | } |
| 1675 | db_begin_transaction(); |
| 1676 | if( P("clear")!=0 ){ |
| 1677 | db_multi_exec("DELETE FROM config WHERE name='footer'"); |
| 1678 | cgi_replace_parameter("footer", builtin_text("skins/default/footer.txt")); |
| @@ -1697,11 +1705,12 @@ | |
| 1705 | ** WEBPAGE: setup_modreq |
| 1706 | */ |
| 1707 | void setup_modreq(void){ |
| 1708 | login_check_credentials(); |
| 1709 | if( !g.perm.Setup ){ |
| 1710 | login_needed(0); |
| 1711 | return; |
| 1712 | } |
| 1713 | |
| 1714 | style_header("Moderator For Wiki And Tickets"); |
| 1715 | db_begin_transaction(); |
| 1716 | @ <form action="%R/setup_modreq" method="post"><div> |
| @@ -1741,11 +1750,12 @@ | |
| 1750 | ** WEBPAGE: setup_adunit |
| 1751 | */ |
| 1752 | void setup_adunit(void){ |
| 1753 | login_check_credentials(); |
| 1754 | if( !g.perm.Setup ){ |
| 1755 | login_needed(0); |
| 1756 | return; |
| 1757 | } |
| 1758 | db_begin_transaction(); |
| 1759 | if( P("clear")!=0 ){ |
| 1760 | db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'"); |
| 1761 | cgi_replace_parameter("adunit",""); |
| @@ -1822,11 +1832,12 @@ | |
| 1832 | if( szBgImg>0 ){ |
| 1833 | zBgMime = PD("bgim:mimetype","image/gif"); |
| 1834 | } |
| 1835 | login_check_credentials(); |
| 1836 | if( !g.perm.Setup ){ |
| 1837 | login_needed(0); |
| 1838 | return; |
| 1839 | } |
| 1840 | db_begin_transaction(); |
| 1841 | if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){ |
| 1842 | Blob img; |
| 1843 | Stmt ins; |
| @@ -1961,11 +1972,12 @@ | |
| 1972 | void sql_page(void){ |
| 1973 | const char *zQ = P("q"); |
| 1974 | int go = P("go")!=0; |
| 1975 | login_check_credentials(); |
| 1976 | if( !g.perm.Setup ){ |
| 1977 | login_needed(0); |
| 1978 | return; |
| 1979 | } |
| 1980 | db_begin_transaction(); |
| 1981 | style_header("Raw SQL Commands"); |
| 1982 | @ <p><b>Caution:</b> There are no restrictions on the SQL that can be |
| 1983 | @ run by this page. You can do serious and irrepairable damage to the |
| @@ -2082,11 +2094,12 @@ | |
| 2094 | void th1_page(void){ |
| 2095 | const char *zQ = P("q"); |
| 2096 | int go = P("go")!=0; |
| 2097 | login_check_credentials(); |
| 2098 | if( !g.perm.Setup ){ |
| 2099 | login_needed(0); |
| 2100 | return; |
| 2101 | } |
| 2102 | db_begin_transaction(); |
| 2103 | style_header("Raw TH1 Commands"); |
| 2104 | @ <p><b>Caution:</b> There are no restrictions on the TH1 that can be |
| 2105 | @ run by this page. If Tcl integration was enabled at compile-time and |
| @@ -2142,11 +2155,12 @@ | |
| 2155 | int limit; |
| 2156 | int fLogEnabled; |
| 2157 | int counter = 0; |
| 2158 | login_check_credentials(); |
| 2159 | if( !g.perm.Setup && !g.perm.Admin ){ |
| 2160 | login_needed(0); |
| 2161 | return; |
| 2162 | } |
| 2163 | style_header("Admin Log"); |
| 2164 | create_admin_log_table(); |
| 2165 | limit = atoi(PD("n","20")); |
| 2166 | fLogEnabled = db_get_boolean("admin-log", 0); |
| @@ -2199,11 +2213,12 @@ | |
| 2213 | ** Configure the search engine. |
| 2214 | */ |
| 2215 | void page_srchsetup(){ |
| 2216 | login_check_credentials(); |
| 2217 | if( !g.perm.Setup && !g.perm.Admin ){ |
| 2218 | login_needed(0); |
| 2219 | return; |
| 2220 | } |
| 2221 | style_header("Search Configuration"); |
| 2222 | @ <form action="%s(g.zTop)/srchsetup" method="post"><div> |
| 2223 | login_insert_csrf_secret(); |
| 2224 | @ <div style="text-align:center;font-weight:bold;"> |
| 2225 |
+6
-3
| --- src/shun.c | ||
| +++ src/shun.c | ||
| @@ -49,11 +49,12 @@ | ||
| 49 | 49 | int numRows = 3; |
| 50 | 50 | char *zCanonical = 0; |
| 51 | 51 | |
| 52 | 52 | login_check_credentials(); |
| 53 | 53 | if( !g.perm.Admin ){ |
| 54 | - login_needed(); | |
| 54 | + login_needed(0); | |
| 55 | + return; | |
| 55 | 56 | } |
| 56 | 57 | if( P("rebuild") ){ |
| 57 | 58 | db_close(1); |
| 58 | 59 | db_open_repository(g.zRepositoryName); |
| 59 | 60 | db_begin_transaction(); |
| @@ -301,11 +302,12 @@ | ||
| 301 | 302 | int cnt; |
| 302 | 303 | Stmt q; |
| 303 | 304 | |
| 304 | 305 | login_check_credentials(); |
| 305 | 306 | if( !g.perm.Admin ){ |
| 306 | - login_needed(); | |
| 307 | + login_needed(0); | |
| 308 | + return; | |
| 307 | 309 | } |
| 308 | 310 | style_header("Artifact Receipts"); |
| 309 | 311 | if( showAll ){ |
| 310 | 312 | ofst = 0; |
| 311 | 313 | }else{ |
| @@ -381,11 +383,12 @@ | ||
| 381 | 383 | int rcvid = atoi(PD("rcvid","0")); |
| 382 | 384 | Stmt q; |
| 383 | 385 | |
| 384 | 386 | login_check_credentials(); |
| 385 | 387 | if( !g.perm.Admin ){ |
| 386 | - login_needed(); | |
| 388 | + login_needed(0); | |
| 389 | + return; | |
| 387 | 390 | } |
| 388 | 391 | style_header("Artifact Receipt %d", rcvid); |
| 389 | 392 | if( db_exists( |
| 390 | 393 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 391 | 394 | " NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 392 | 395 |
| --- src/shun.c | |
| +++ src/shun.c | |
| @@ -49,11 +49,12 @@ | |
| 49 | int numRows = 3; |
| 50 | char *zCanonical = 0; |
| 51 | |
| 52 | login_check_credentials(); |
| 53 | if( !g.perm.Admin ){ |
| 54 | login_needed(); |
| 55 | } |
| 56 | if( P("rebuild") ){ |
| 57 | db_close(1); |
| 58 | db_open_repository(g.zRepositoryName); |
| 59 | db_begin_transaction(); |
| @@ -301,11 +302,12 @@ | |
| 301 | int cnt; |
| 302 | Stmt q; |
| 303 | |
| 304 | login_check_credentials(); |
| 305 | if( !g.perm.Admin ){ |
| 306 | login_needed(); |
| 307 | } |
| 308 | style_header("Artifact Receipts"); |
| 309 | if( showAll ){ |
| 310 | ofst = 0; |
| 311 | }else{ |
| @@ -381,11 +383,12 @@ | |
| 381 | int rcvid = atoi(PD("rcvid","0")); |
| 382 | Stmt q; |
| 383 | |
| 384 | login_check_credentials(); |
| 385 | if( !g.perm.Admin ){ |
| 386 | login_needed(); |
| 387 | } |
| 388 | style_header("Artifact Receipt %d", rcvid); |
| 389 | if( db_exists( |
| 390 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 391 | " NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 392 |
| --- src/shun.c | |
| +++ src/shun.c | |
| @@ -49,11 +49,12 @@ | |
| 49 | int numRows = 3; |
| 50 | char *zCanonical = 0; |
| 51 | |
| 52 | login_check_credentials(); |
| 53 | if( !g.perm.Admin ){ |
| 54 | login_needed(0); |
| 55 | return; |
| 56 | } |
| 57 | if( P("rebuild") ){ |
| 58 | db_close(1); |
| 59 | db_open_repository(g.zRepositoryName); |
| 60 | db_begin_transaction(); |
| @@ -301,11 +302,12 @@ | |
| 302 | int cnt; |
| 303 | Stmt q; |
| 304 | |
| 305 | login_check_credentials(); |
| 306 | if( !g.perm.Admin ){ |
| 307 | login_needed(0); |
| 308 | return; |
| 309 | } |
| 310 | style_header("Artifact Receipts"); |
| 311 | if( showAll ){ |
| 312 | ofst = 0; |
| 313 | }else{ |
| @@ -381,11 +383,12 @@ | |
| 383 | int rcvid = atoi(PD("rcvid","0")); |
| 384 | Stmt q; |
| 385 | |
| 386 | login_check_credentials(); |
| 387 | if( !g.perm.Admin ){ |
| 388 | login_needed(0); |
| 389 | return; |
| 390 | } |
| 391 | style_header("Artifact Receipt %d", rcvid); |
| 392 | if( db_exists( |
| 393 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 394 | " NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 395 |
+2
-1
| --- src/skins.c | ||
| +++ src/skins.c | ||
| @@ -289,11 +289,12 @@ | ||
| 289 | 289 | Stmt q; |
| 290 | 290 | int seenCurrent = 0; |
| 291 | 291 | |
| 292 | 292 | login_check_credentials(); |
| 293 | 293 | if( !g.perm.Setup ){ |
| 294 | - login_needed(); | |
| 294 | + login_needed(0); | |
| 295 | + return; | |
| 295 | 296 | } |
| 296 | 297 | db_begin_transaction(); |
| 297 | 298 | zCurrent = getSkin(0); |
| 298 | 299 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 299 | 300 | aBuiltinSkin[i].zSQL = getSkin(aBuiltinSkin[i].zLabel); |
| 300 | 301 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -289,11 +289,12 @@ | |
| 289 | Stmt q; |
| 290 | int seenCurrent = 0; |
| 291 | |
| 292 | login_check_credentials(); |
| 293 | if( !g.perm.Setup ){ |
| 294 | login_needed(); |
| 295 | } |
| 296 | db_begin_transaction(); |
| 297 | zCurrent = getSkin(0); |
| 298 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 299 | aBuiltinSkin[i].zSQL = getSkin(aBuiltinSkin[i].zLabel); |
| 300 |
| --- src/skins.c | |
| +++ src/skins.c | |
| @@ -289,11 +289,12 @@ | |
| 289 | Stmt q; |
| 290 | int seenCurrent = 0; |
| 291 | |
| 292 | login_check_credentials(); |
| 293 | if( !g.perm.Setup ){ |
| 294 | login_needed(0); |
| 295 | return; |
| 296 | } |
| 297 | db_begin_transaction(); |
| 298 | zCurrent = getSkin(0); |
| 299 | for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ |
| 300 | aBuiltinSkin[i].zSQL = getSkin(aBuiltinSkin[i].zLabel); |
| 301 |
+3
-3
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -52,11 +52,11 @@ | ||
| 52 | 52 | int brief; |
| 53 | 53 | char zBuf[100]; |
| 54 | 54 | const char *p; |
| 55 | 55 | |
| 56 | 56 | login_check_credentials(); |
| 57 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 57 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 58 | 58 | brief = P("brief")!=0; |
| 59 | 59 | style_header("Repository Statistics"); |
| 60 | 60 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 61 | 61 | if( g.perm.Admin ){ |
| 62 | 62 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| @@ -292,11 +292,11 @@ | ||
| 292 | 292 | */ |
| 293 | 293 | void urllist_page(void){ |
| 294 | 294 | Stmt q; |
| 295 | 295 | int cnt; |
| 296 | 296 | login_check_credentials(); |
| 297 | - if( !g.perm.Admin ){ login_needed(); return; } | |
| 297 | + if( !g.perm.Admin ){ login_needed(0); return; } | |
| 298 | 298 | |
| 299 | 299 | style_header("URLs and Checkouts"); |
| 300 | 300 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 301 | 301 | style_submenu_element("Stat", "Repository Stats", "stat"); |
| 302 | 302 | style_submenu_element("Schema", "Repository Schema", "repo_schema"); |
| @@ -339,11 +339,11 @@ | ||
| 339 | 339 | ** Show the repository schema |
| 340 | 340 | */ |
| 341 | 341 | void repo_schema_page(void){ |
| 342 | 342 | Stmt q; |
| 343 | 343 | login_check_credentials(); |
| 344 | - if( !g.perm.Admin ){ login_needed(); return; } | |
| 344 | + if( !g.perm.Admin ){ login_needed(0); return; } | |
| 345 | 345 | |
| 346 | 346 | style_header("Repository Schema"); |
| 347 | 347 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 348 | 348 | style_submenu_element("Stat", "Repository Stats", "stat"); |
| 349 | 349 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| 350 | 350 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -52,11 +52,11 @@ | |
| 52 | int brief; |
| 53 | char zBuf[100]; |
| 54 | const char *p; |
| 55 | |
| 56 | login_check_credentials(); |
| 57 | if( !g.perm.Read ){ login_needed(); return; } |
| 58 | brief = P("brief")!=0; |
| 59 | style_header("Repository Statistics"); |
| 60 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 61 | if( g.perm.Admin ){ |
| 62 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| @@ -292,11 +292,11 @@ | |
| 292 | */ |
| 293 | void urllist_page(void){ |
| 294 | Stmt q; |
| 295 | int cnt; |
| 296 | login_check_credentials(); |
| 297 | if( !g.perm.Admin ){ login_needed(); return; } |
| 298 | |
| 299 | style_header("URLs and Checkouts"); |
| 300 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 301 | style_submenu_element("Stat", "Repository Stats", "stat"); |
| 302 | style_submenu_element("Schema", "Repository Schema", "repo_schema"); |
| @@ -339,11 +339,11 @@ | |
| 339 | ** Show the repository schema |
| 340 | */ |
| 341 | void repo_schema_page(void){ |
| 342 | Stmt q; |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Admin ){ login_needed(); return; } |
| 345 | |
| 346 | style_header("Repository Schema"); |
| 347 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 348 | style_submenu_element("Stat", "Repository Stats", "stat"); |
| 349 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| 350 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -52,11 +52,11 @@ | |
| 52 | int brief; |
| 53 | char zBuf[100]; |
| 54 | const char *p; |
| 55 | |
| 56 | login_check_credentials(); |
| 57 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 58 | brief = P("brief")!=0; |
| 59 | style_header("Repository Statistics"); |
| 60 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 61 | if( g.perm.Admin ){ |
| 62 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| @@ -292,11 +292,11 @@ | |
| 292 | */ |
| 293 | void urllist_page(void){ |
| 294 | Stmt q; |
| 295 | int cnt; |
| 296 | login_check_credentials(); |
| 297 | if( !g.perm.Admin ){ login_needed(0); return; } |
| 298 | |
| 299 | style_header("URLs and Checkouts"); |
| 300 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 301 | style_submenu_element("Stat", "Repository Stats", "stat"); |
| 302 | style_submenu_element("Schema", "Repository Schema", "repo_schema"); |
| @@ -339,11 +339,11 @@ | |
| 339 | ** Show the repository schema |
| 340 | */ |
| 341 | void repo_schema_page(void){ |
| 342 | Stmt q; |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Admin ){ login_needed(0); return; } |
| 345 | |
| 346 | style_header("Repository Schema"); |
| 347 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 348 | style_submenu_element("Stat", "Repository Stats", "stat"); |
| 349 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| 350 |
+1
-1
| --- src/statrep.c | ||
| +++ src/statrep.c | ||
| @@ -728,11 +728,11 @@ | ||
| 728 | 728 | HQuery url; /* URL for various branch links */ |
| 729 | 729 | const char *zView = P("view"); /* Which view/report to show. */ |
| 730 | 730 | const char *zUserName = P("user"); |
| 731 | 731 | |
| 732 | 732 | login_check_credentials(); |
| 733 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 733 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 734 | 734 | if(!zUserName) zUserName = P("u"); |
| 735 | 735 | url_initialize(&url, "reports"); |
| 736 | 736 | if(zUserName && *zUserName){ |
| 737 | 737 | url_add_parameter(&url,"user", zUserName); |
| 738 | 738 | statrep_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 739 | 739 |
| --- src/statrep.c | |
| +++ src/statrep.c | |
| @@ -728,11 +728,11 @@ | |
| 728 | HQuery url; /* URL for various branch links */ |
| 729 | const char *zView = P("view"); /* Which view/report to show. */ |
| 730 | const char *zUserName = P("user"); |
| 731 | |
| 732 | login_check_credentials(); |
| 733 | if( !g.perm.Read ){ login_needed(); return; } |
| 734 | if(!zUserName) zUserName = P("u"); |
| 735 | url_initialize(&url, "reports"); |
| 736 | if(zUserName && *zUserName){ |
| 737 | url_add_parameter(&url,"user", zUserName); |
| 738 | statrep_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 739 |
| --- src/statrep.c | |
| +++ src/statrep.c | |
| @@ -728,11 +728,11 @@ | |
| 728 | HQuery url; /* URL for various branch links */ |
| 729 | const char *zView = P("view"); /* Which view/report to show. */ |
| 730 | const char *zUserName = P("user"); |
| 731 | |
| 732 | login_check_credentials(); |
| 733 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 734 | if(!zUserName) zUserName = P("u"); |
| 735 | url_initialize(&url, "reports"); |
| 736 | if(zUserName && *zUserName){ |
| 737 | url_add_parameter(&url,"user", zUserName); |
| 738 | statrep_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 739 |
+10
-2
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -1411,11 +1411,11 @@ | ||
| 1411 | 1411 | "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL", |
| 1412 | 1412 | }; |
| 1413 | 1413 | |
| 1414 | 1414 | login_check_credentials(); |
| 1415 | 1415 | if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){ |
| 1416 | - login_needed(); | |
| 1416 | + login_needed(0); | |
| 1417 | 1417 | return; |
| 1418 | 1418 | } |
| 1419 | 1419 | for(i=0; i<count(azCgiVars); i++) (void)P(azCgiVars[i]); |
| 1420 | 1420 | style_header("Environment Test"); |
| 1421 | 1421 | showAll = atoi(PD("showall","0")); |
| @@ -1430,17 +1430,25 @@ | ||
| 1430 | 1430 | @ g.zBaseURL = %h(g.zBaseURL)<br /> |
| 1431 | 1431 | @ g.zHttpsURL = %h(g.zHttpsURL)<br /> |
| 1432 | 1432 | @ g.zTop = %h(g.zTop)<br /> |
| 1433 | 1433 | @ g.zPath = %h(g.zPath)<br /> |
| 1434 | 1434 | for(i=0, c='a'; c<='z'; c++){ |
| 1435 | - if( login_has_capability(&c, 1) ) zCap[i++] = c; | |
| 1435 | + if( login_has_capability(&c, 1, 0) ) zCap[i++] = c; | |
| 1436 | 1436 | } |
| 1437 | 1437 | zCap[i] = 0; |
| 1438 | 1438 | @ g.userUid = %d(g.userUid)<br /> |
| 1439 | 1439 | @ g.zLogin = %h(g.zLogin)<br /> |
| 1440 | 1440 | @ g.isHuman = %d(g.isHuman)<br /> |
| 1441 | 1441 | @ capabilities = %s(zCap)<br /> |
| 1442 | + for(i=0, c='a'; c<='z'; c++){ | |
| 1443 | + if( login_has_capability(&c, 1, LOGIN_ANON) | |
| 1444 | + && !login_has_capability(&c, 1, 0) ) zCap[i++] = c; | |
| 1445 | + } | |
| 1446 | + zCap[i] = 0; | |
| 1447 | + if( i>0 ){ | |
| 1448 | + @ anonymous-adds = %s(zCap)<br /> | |
| 1449 | + } | |
| 1442 | 1450 | @ g.zRepositoryName = %h(g.zRepositoryName)<br /> |
| 1443 | 1451 | @ load_average() = %f(load_average())<br /> |
| 1444 | 1452 | @ <hr> |
| 1445 | 1453 | P("HTTP_USER_AGENT"); |
| 1446 | 1454 | cgi_print_all(showAll); |
| 1447 | 1455 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1411,11 +1411,11 @@ | |
| 1411 | "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL", |
| 1412 | }; |
| 1413 | |
| 1414 | login_check_credentials(); |
| 1415 | if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){ |
| 1416 | login_needed(); |
| 1417 | return; |
| 1418 | } |
| 1419 | for(i=0; i<count(azCgiVars); i++) (void)P(azCgiVars[i]); |
| 1420 | style_header("Environment Test"); |
| 1421 | showAll = atoi(PD("showall","0")); |
| @@ -1430,17 +1430,25 @@ | |
| 1430 | @ g.zBaseURL = %h(g.zBaseURL)<br /> |
| 1431 | @ g.zHttpsURL = %h(g.zHttpsURL)<br /> |
| 1432 | @ g.zTop = %h(g.zTop)<br /> |
| 1433 | @ g.zPath = %h(g.zPath)<br /> |
| 1434 | for(i=0, c='a'; c<='z'; c++){ |
| 1435 | if( login_has_capability(&c, 1) ) zCap[i++] = c; |
| 1436 | } |
| 1437 | zCap[i] = 0; |
| 1438 | @ g.userUid = %d(g.userUid)<br /> |
| 1439 | @ g.zLogin = %h(g.zLogin)<br /> |
| 1440 | @ g.isHuman = %d(g.isHuman)<br /> |
| 1441 | @ capabilities = %s(zCap)<br /> |
| 1442 | @ g.zRepositoryName = %h(g.zRepositoryName)<br /> |
| 1443 | @ load_average() = %f(load_average())<br /> |
| 1444 | @ <hr> |
| 1445 | P("HTTP_USER_AGENT"); |
| 1446 | cgi_print_all(showAll); |
| 1447 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1411,11 +1411,11 @@ | |
| 1411 | "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL", |
| 1412 | }; |
| 1413 | |
| 1414 | login_check_credentials(); |
| 1415 | if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){ |
| 1416 | login_needed(0); |
| 1417 | return; |
| 1418 | } |
| 1419 | for(i=0; i<count(azCgiVars); i++) (void)P(azCgiVars[i]); |
| 1420 | style_header("Environment Test"); |
| 1421 | showAll = atoi(PD("showall","0")); |
| @@ -1430,17 +1430,25 @@ | |
| 1430 | @ g.zBaseURL = %h(g.zBaseURL)<br /> |
| 1431 | @ g.zHttpsURL = %h(g.zHttpsURL)<br /> |
| 1432 | @ g.zTop = %h(g.zTop)<br /> |
| 1433 | @ g.zPath = %h(g.zPath)<br /> |
| 1434 | for(i=0, c='a'; c<='z'; c++){ |
| 1435 | if( login_has_capability(&c, 1, 0) ) zCap[i++] = c; |
| 1436 | } |
| 1437 | zCap[i] = 0; |
| 1438 | @ g.userUid = %d(g.userUid)<br /> |
| 1439 | @ g.zLogin = %h(g.zLogin)<br /> |
| 1440 | @ g.isHuman = %d(g.isHuman)<br /> |
| 1441 | @ capabilities = %s(zCap)<br /> |
| 1442 | for(i=0, c='a'; c<='z'; c++){ |
| 1443 | if( login_has_capability(&c, 1, LOGIN_ANON) |
| 1444 | && !login_has_capability(&c, 1, 0) ) zCap[i++] = c; |
| 1445 | } |
| 1446 | zCap[i] = 0; |
| 1447 | if( i>0 ){ |
| 1448 | @ anonymous-adds = %s(zCap)<br /> |
| 1449 | } |
| 1450 | @ g.zRepositoryName = %h(g.zRepositoryName)<br /> |
| 1451 | @ load_average() = %f(load_average())<br /> |
| 1452 | @ <hr> |
| 1453 | P("HTTP_USER_AGENT"); |
| 1454 | cgi_print_all(showAll); |
| 1455 |
+2
-2
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -542,11 +542,11 @@ | ||
| 542 | 542 | void taglist_page(void){ |
| 543 | 543 | Stmt q; |
| 544 | 544 | |
| 545 | 545 | login_check_credentials(); |
| 546 | 546 | if( !g.perm.Read ){ |
| 547 | - login_needed(); | |
| 547 | + login_needed(g.anon.Read); | |
| 548 | 548 | } |
| 549 | 549 | login_anonymous_available(); |
| 550 | 550 | style_header("Tags"); |
| 551 | 551 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 552 | 552 | style_submenu_element("Timeline", "Timeline", "tagtimeline"); |
| @@ -580,11 +580,11 @@ | ||
| 580 | 580 | */ |
| 581 | 581 | void tagtimeline_page(void){ |
| 582 | 582 | Stmt q; |
| 583 | 583 | |
| 584 | 584 | login_check_credentials(); |
| 585 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 585 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 586 | 586 | |
| 587 | 587 | style_header("Tagged Check-ins"); |
| 588 | 588 | style_submenu_element("List", "List", "taglist"); |
| 589 | 589 | login_anonymous_available(); |
| 590 | 590 | @ <h2>Check-ins with non-propagating tags:</h2> |
| 591 | 591 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -542,11 +542,11 @@ | |
| 542 | void taglist_page(void){ |
| 543 | Stmt q; |
| 544 | |
| 545 | login_check_credentials(); |
| 546 | if( !g.perm.Read ){ |
| 547 | login_needed(); |
| 548 | } |
| 549 | login_anonymous_available(); |
| 550 | style_header("Tags"); |
| 551 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 552 | style_submenu_element("Timeline", "Timeline", "tagtimeline"); |
| @@ -580,11 +580,11 @@ | |
| 580 | */ |
| 581 | void tagtimeline_page(void){ |
| 582 | Stmt q; |
| 583 | |
| 584 | login_check_credentials(); |
| 585 | if( !g.perm.Read ){ login_needed(); return; } |
| 586 | |
| 587 | style_header("Tagged Check-ins"); |
| 588 | style_submenu_element("List", "List", "taglist"); |
| 589 | login_anonymous_available(); |
| 590 | @ <h2>Check-ins with non-propagating tags:</h2> |
| 591 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -542,11 +542,11 @@ | |
| 542 | void taglist_page(void){ |
| 543 | Stmt q; |
| 544 | |
| 545 | login_check_credentials(); |
| 546 | if( !g.perm.Read ){ |
| 547 | login_needed(g.anon.Read); |
| 548 | } |
| 549 | login_anonymous_available(); |
| 550 | style_header("Tags"); |
| 551 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 552 | style_submenu_element("Timeline", "Timeline", "tagtimeline"); |
| @@ -580,11 +580,11 @@ | |
| 580 | */ |
| 581 | void tagtimeline_page(void){ |
| 582 | Stmt q; |
| 583 | |
| 584 | login_check_credentials(); |
| 585 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 586 | |
| 587 | style_header("Tagged Check-ins"); |
| 588 | style_submenu_element("List", "List", "taglist"); |
| 589 | login_anonymous_available(); |
| 590 | @ <h2>Check-ins with non-propagating tags:</h2> |
| 591 |
+12
-1
| --- src/tar.c | ||
| +++ src/tar.c | ||
| @@ -603,11 +603,11 @@ | ||
| 603 | 603 | char *zName, *zRid, *zKey; |
| 604 | 604 | int nName, nRid; |
| 605 | 605 | Blob tarball; |
| 606 | 606 | |
| 607 | 607 | login_check_credentials(); |
| 608 | - if( !g.perm.Zip ){ login_needed(); return; } | |
| 608 | + if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; } | |
| 609 | 609 | load_control(); |
| 610 | 610 | zName = mprintf("%s", PD("name","")); |
| 611 | 611 | nName = strlen(zName); |
| 612 | 612 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 613 | 613 | nRid = strlen(zRid); |
| @@ -638,10 +638,21 @@ | ||
| 638 | 638 | @ zName = "%h(zName)"<br> |
| 639 | 639 | @ rid = %d(rid)<br> |
| 640 | 640 | @ zKey = "%h(zKey)" |
| 641 | 641 | style_footer(); |
| 642 | 642 | return; |
| 643 | + } | |
| 644 | + if( referred_from_login() ){ | |
| 645 | + style_header("Tarball Download"); | |
| 646 | + @ <form action='%R/tarball'> | |
| 647 | + cgi_query_parameters_to_hidden(); | |
| 648 | + @ <p>Tarball named <b>%h(zName).tar.gz</b> holding the content | |
| 649 | + @ of check-in <b>%h(zRid)</b>: | |
| 650 | + @ <input type="submit" value="Download" /> | |
| 651 | + @ </form> | |
| 652 | + style_footer(); | |
| 653 | + return; | |
| 643 | 654 | } |
| 644 | 655 | blob_zero(&tarball); |
| 645 | 656 | if( cache_read(&tarball, zKey)==0 ){ |
| 646 | 657 | tarball_of_checkin(rid, &tarball, zName); |
| 647 | 658 | cache_write(&tarball, zKey); |
| 648 | 659 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -603,11 +603,11 @@ | |
| 603 | char *zName, *zRid, *zKey; |
| 604 | int nName, nRid; |
| 605 | Blob tarball; |
| 606 | |
| 607 | login_check_credentials(); |
| 608 | if( !g.perm.Zip ){ login_needed(); return; } |
| 609 | load_control(); |
| 610 | zName = mprintf("%s", PD("name","")); |
| 611 | nName = strlen(zName); |
| 612 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 613 | nRid = strlen(zRid); |
| @@ -638,10 +638,21 @@ | |
| 638 | @ zName = "%h(zName)"<br> |
| 639 | @ rid = %d(rid)<br> |
| 640 | @ zKey = "%h(zKey)" |
| 641 | style_footer(); |
| 642 | return; |
| 643 | } |
| 644 | blob_zero(&tarball); |
| 645 | if( cache_read(&tarball, zKey)==0 ){ |
| 646 | tarball_of_checkin(rid, &tarball, zName); |
| 647 | cache_write(&tarball, zKey); |
| 648 |
| --- src/tar.c | |
| +++ src/tar.c | |
| @@ -603,11 +603,11 @@ | |
| 603 | char *zName, *zRid, *zKey; |
| 604 | int nName, nRid; |
| 605 | Blob tarball; |
| 606 | |
| 607 | login_check_credentials(); |
| 608 | if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; } |
| 609 | load_control(); |
| 610 | zName = mprintf("%s", PD("name","")); |
| 611 | nName = strlen(zName); |
| 612 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 613 | nRid = strlen(zRid); |
| @@ -638,10 +638,21 @@ | |
| 638 | @ zName = "%h(zName)"<br> |
| 639 | @ rid = %d(rid)<br> |
| 640 | @ zKey = "%h(zKey)" |
| 641 | style_footer(); |
| 642 | return; |
| 643 | } |
| 644 | if( referred_from_login() ){ |
| 645 | style_header("Tarball Download"); |
| 646 | @ <form action='%R/tarball'> |
| 647 | cgi_query_parameters_to_hidden(); |
| 648 | @ <p>Tarball named <b>%h(zName).tar.gz</b> holding the content |
| 649 | @ of check-in <b>%h(zRid)</b>: |
| 650 | @ <input type="submit" value="Download" /> |
| 651 | @ </form> |
| 652 | style_footer(); |
| 653 | return; |
| 654 | } |
| 655 | blob_zero(&tarball); |
| 656 | if( cache_read(&tarball, zKey)==0 ){ |
| 657 | tarball_of_checkin(rid, &tarball, zName); |
| 658 | cache_write(&tarball, zKey); |
| 659 |
+11
-5
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -342,12 +342,14 @@ | ||
| 342 | 342 | return TH_OK; |
| 343 | 343 | } |
| 344 | 344 | |
| 345 | 345 | /* |
| 346 | 346 | ** TH1 command: hascap STRING... |
| 347 | +** TH1 command: anoncap STRING... | |
| 347 | 348 | ** |
| 348 | -** Return true if the user has all of the capabilities listed in STRING. | |
| 349 | +** Return true if the current user (hascap) or if the anonymous user | |
| 350 | +** (anoncap) has all of the capabilities listed in STRING. | |
| 349 | 351 | */ |
| 350 | 352 | static int hascapCmd( |
| 351 | 353 | Th_Interp *interp, |
| 352 | 354 | void *p, |
| 353 | 355 | int argc, |
| @@ -357,11 +359,11 @@ | ||
| 357 | 359 | int rc = 0, i; |
| 358 | 360 | if( argc<2 ){ |
| 359 | 361 | return Th_WrongNumArgs(interp, "hascap STRING ..."); |
| 360 | 362 | } |
| 361 | 363 | for(i=1; i<argc && rc==0; i++){ |
| 362 | - rc = login_has_capability((char*)argv[i],argl[i]); | |
| 364 | + rc = login_has_capability((char*)argv[i],argl[i],*(int*)p); | |
| 363 | 365 | } |
| 364 | 366 | if( g.thTrace ){ |
| 365 | 367 | Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); |
| 366 | 368 | } |
| 367 | 369 | Th_SetResultInt(interp, rc); |
| @@ -543,11 +545,12 @@ | ||
| 543 | 545 | |
| 544 | 546 | |
| 545 | 547 | /* |
| 546 | 548 | ** TH1 command: anycap STRING |
| 547 | 549 | ** |
| 548 | -** Return true if the user has any one of the capabilities listed in STRING. | |
| 550 | +** Return true if the current user user | |
| 551 | +** has any one of the capabilities listed in STRING. | |
| 549 | 552 | */ |
| 550 | 553 | static int anycapCmd( |
| 551 | 554 | Th_Interp *interp, |
| 552 | 555 | void *p, |
| 553 | 556 | int argc, |
| @@ -558,11 +561,11 @@ | ||
| 558 | 561 | int i; |
| 559 | 562 | if( argc!=2 ){ |
| 560 | 563 | return Th_WrongNumArgs(interp, "anycap STRING"); |
| 561 | 564 | } |
| 562 | 565 | for(i=0; rc==0 && i<argl[1]; i++){ |
| 563 | - rc = login_has_capability((char*)&argv[1][i],1); | |
| 566 | + rc = login_has_capability((char*)&argv[1][i],1,0); | |
| 564 | 567 | } |
| 565 | 568 | if( g.thTrace ){ |
| 566 | 569 | Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); |
| 567 | 570 | } |
| 568 | 571 | Th_SetResultInt(interp, rc); |
| @@ -1450,15 +1453,18 @@ | ||
| 1450 | 1453 | int needConfig = flags & TH_INIT_NEED_CONFIG; |
| 1451 | 1454 | int forceReset = flags & TH_INIT_FORCE_RESET; |
| 1452 | 1455 | int forceTcl = flags & TH_INIT_FORCE_TCL; |
| 1453 | 1456 | int forceSetup = flags & TH_INIT_FORCE_SETUP; |
| 1454 | 1457 | static unsigned int aFlags[] = { 0, 1, WIKI_LINKSONLY }; |
| 1458 | + static int anonFlag = LOGIN_ANON; | |
| 1459 | + static int zeroInt = 0; | |
| 1455 | 1460 | static struct _Command { |
| 1456 | 1461 | const char *zName; |
| 1457 | 1462 | Th_CommandProc xProc; |
| 1458 | 1463 | void *pContext; |
| 1459 | 1464 | } aCommand[] = { |
| 1465 | + {"anoncap", hascapCmd, (void*)&anonFlag}, | |
| 1460 | 1466 | {"anycap", anycapCmd, 0}, |
| 1461 | 1467 | {"artifact", artifactCmd, 0}, |
| 1462 | 1468 | {"checkout", checkoutCmd, 0}, |
| 1463 | 1469 | {"combobox", comboboxCmd, 0}, |
| 1464 | 1470 | {"date", dateCmd, 0}, |
| @@ -1465,11 +1471,11 @@ | ||
| 1465 | 1471 | {"decorate", wikiCmd, (void*)&aFlags[2]}, |
| 1466 | 1472 | {"enable_output", enableOutputCmd, 0}, |
| 1467 | 1473 | {"getParameter", getParameterCmd, 0}, |
| 1468 | 1474 | {"globalState", globalStateCmd, 0}, |
| 1469 | 1475 | {"httpize", httpizeCmd, 0}, |
| 1470 | - {"hascap", hascapCmd, 0}, | |
| 1476 | + {"hascap", hascapCmd, (void*)&zeroInt}, | |
| 1471 | 1477 | {"hasfeature", hasfeatureCmd, 0}, |
| 1472 | 1478 | {"html", putsCmd, (void*)&aFlags[0]}, |
| 1473 | 1479 | {"htmlize", htmlizeCmd, 0}, |
| 1474 | 1480 | {"http", httpCmd, 0}, |
| 1475 | 1481 | {"linecount", linecntCmd, 0}, |
| 1476 | 1482 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -342,12 +342,14 @@ | |
| 342 | return TH_OK; |
| 343 | } |
| 344 | |
| 345 | /* |
| 346 | ** TH1 command: hascap STRING... |
| 347 | ** |
| 348 | ** Return true if the user has all of the capabilities listed in STRING. |
| 349 | */ |
| 350 | static int hascapCmd( |
| 351 | Th_Interp *interp, |
| 352 | void *p, |
| 353 | int argc, |
| @@ -357,11 +359,11 @@ | |
| 357 | int rc = 0, i; |
| 358 | if( argc<2 ){ |
| 359 | return Th_WrongNumArgs(interp, "hascap STRING ..."); |
| 360 | } |
| 361 | for(i=1; i<argc && rc==0; i++){ |
| 362 | rc = login_has_capability((char*)argv[i],argl[i]); |
| 363 | } |
| 364 | if( g.thTrace ){ |
| 365 | Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); |
| 366 | } |
| 367 | Th_SetResultInt(interp, rc); |
| @@ -543,11 +545,12 @@ | |
| 543 | |
| 544 | |
| 545 | /* |
| 546 | ** TH1 command: anycap STRING |
| 547 | ** |
| 548 | ** Return true if the user has any one of the capabilities listed in STRING. |
| 549 | */ |
| 550 | static int anycapCmd( |
| 551 | Th_Interp *interp, |
| 552 | void *p, |
| 553 | int argc, |
| @@ -558,11 +561,11 @@ | |
| 558 | int i; |
| 559 | if( argc!=2 ){ |
| 560 | return Th_WrongNumArgs(interp, "anycap STRING"); |
| 561 | } |
| 562 | for(i=0; rc==0 && i<argl[1]; i++){ |
| 563 | rc = login_has_capability((char*)&argv[1][i],1); |
| 564 | } |
| 565 | if( g.thTrace ){ |
| 566 | Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); |
| 567 | } |
| 568 | Th_SetResultInt(interp, rc); |
| @@ -1450,15 +1453,18 @@ | |
| 1450 | int needConfig = flags & TH_INIT_NEED_CONFIG; |
| 1451 | int forceReset = flags & TH_INIT_FORCE_RESET; |
| 1452 | int forceTcl = flags & TH_INIT_FORCE_TCL; |
| 1453 | int forceSetup = flags & TH_INIT_FORCE_SETUP; |
| 1454 | static unsigned int aFlags[] = { 0, 1, WIKI_LINKSONLY }; |
| 1455 | static struct _Command { |
| 1456 | const char *zName; |
| 1457 | Th_CommandProc xProc; |
| 1458 | void *pContext; |
| 1459 | } aCommand[] = { |
| 1460 | {"anycap", anycapCmd, 0}, |
| 1461 | {"artifact", artifactCmd, 0}, |
| 1462 | {"checkout", checkoutCmd, 0}, |
| 1463 | {"combobox", comboboxCmd, 0}, |
| 1464 | {"date", dateCmd, 0}, |
| @@ -1465,11 +1471,11 @@ | |
| 1465 | {"decorate", wikiCmd, (void*)&aFlags[2]}, |
| 1466 | {"enable_output", enableOutputCmd, 0}, |
| 1467 | {"getParameter", getParameterCmd, 0}, |
| 1468 | {"globalState", globalStateCmd, 0}, |
| 1469 | {"httpize", httpizeCmd, 0}, |
| 1470 | {"hascap", hascapCmd, 0}, |
| 1471 | {"hasfeature", hasfeatureCmd, 0}, |
| 1472 | {"html", putsCmd, (void*)&aFlags[0]}, |
| 1473 | {"htmlize", htmlizeCmd, 0}, |
| 1474 | {"http", httpCmd, 0}, |
| 1475 | {"linecount", linecntCmd, 0}, |
| 1476 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -342,12 +342,14 @@ | |
| 342 | return TH_OK; |
| 343 | } |
| 344 | |
| 345 | /* |
| 346 | ** TH1 command: hascap STRING... |
| 347 | ** TH1 command: anoncap STRING... |
| 348 | ** |
| 349 | ** Return true if the current user (hascap) or if the anonymous user |
| 350 | ** (anoncap) has all of the capabilities listed in STRING. |
| 351 | */ |
| 352 | static int hascapCmd( |
| 353 | Th_Interp *interp, |
| 354 | void *p, |
| 355 | int argc, |
| @@ -357,11 +359,11 @@ | |
| 359 | int rc = 0, i; |
| 360 | if( argc<2 ){ |
| 361 | return Th_WrongNumArgs(interp, "hascap STRING ..."); |
| 362 | } |
| 363 | for(i=1; i<argc && rc==0; i++){ |
| 364 | rc = login_has_capability((char*)argv[i],argl[i],*(int*)p); |
| 365 | } |
| 366 | if( g.thTrace ){ |
| 367 | Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); |
| 368 | } |
| 369 | Th_SetResultInt(interp, rc); |
| @@ -543,11 +545,12 @@ | |
| 545 | |
| 546 | |
| 547 | /* |
| 548 | ** TH1 command: anycap STRING |
| 549 | ** |
| 550 | ** Return true if the current user user |
| 551 | ** has any one of the capabilities listed in STRING. |
| 552 | */ |
| 553 | static int anycapCmd( |
| 554 | Th_Interp *interp, |
| 555 | void *p, |
| 556 | int argc, |
| @@ -558,11 +561,11 @@ | |
| 561 | int i; |
| 562 | if( argc!=2 ){ |
| 563 | return Th_WrongNumArgs(interp, "anycap STRING"); |
| 564 | } |
| 565 | for(i=0; rc==0 && i<argl[1]; i++){ |
| 566 | rc = login_has_capability((char*)&argv[1][i],1,0); |
| 567 | } |
| 568 | if( g.thTrace ){ |
| 569 | Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); |
| 570 | } |
| 571 | Th_SetResultInt(interp, rc); |
| @@ -1450,15 +1453,18 @@ | |
| 1453 | int needConfig = flags & TH_INIT_NEED_CONFIG; |
| 1454 | int forceReset = flags & TH_INIT_FORCE_RESET; |
| 1455 | int forceTcl = flags & TH_INIT_FORCE_TCL; |
| 1456 | int forceSetup = flags & TH_INIT_FORCE_SETUP; |
| 1457 | static unsigned int aFlags[] = { 0, 1, WIKI_LINKSONLY }; |
| 1458 | static int anonFlag = LOGIN_ANON; |
| 1459 | static int zeroInt = 0; |
| 1460 | static struct _Command { |
| 1461 | const char *zName; |
| 1462 | Th_CommandProc xProc; |
| 1463 | void *pContext; |
| 1464 | } aCommand[] = { |
| 1465 | {"anoncap", hascapCmd, (void*)&anonFlag}, |
| 1466 | {"anycap", anycapCmd, 0}, |
| 1467 | {"artifact", artifactCmd, 0}, |
| 1468 | {"checkout", checkoutCmd, 0}, |
| 1469 | {"combobox", comboboxCmd, 0}, |
| 1470 | {"date", dateCmd, 0}, |
| @@ -1465,11 +1471,11 @@ | |
| 1471 | {"decorate", wikiCmd, (void*)&aFlags[2]}, |
| 1472 | {"enable_output", enableOutputCmd, 0}, |
| 1473 | {"getParameter", getParameterCmd, 0}, |
| 1474 | {"globalState", globalStateCmd, 0}, |
| 1475 | {"httpize", httpizeCmd, 0}, |
| 1476 | {"hascap", hascapCmd, (void*)&zeroInt}, |
| 1477 | {"hasfeature", hasfeatureCmd, 0}, |
| 1478 | {"html", putsCmd, (void*)&aFlags[0]}, |
| 1479 | {"htmlize", htmlizeCmd, 0}, |
| 1480 | {"http", httpCmd, 0}, |
| 1481 | {"linecount", linecntCmd, 0}, |
| 1482 |
+6
-3
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -163,11 +163,11 @@ | ||
| 163 | 163 | void test_hash_color_page(void){ |
| 164 | 164 | const char *zBr; |
| 165 | 165 | char zNm[10]; |
| 166 | 166 | int i, cnt; |
| 167 | 167 | login_check_credentials(); |
| 168 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 168 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 169 | 169 | |
| 170 | 170 | style_header("Hash Color Test"); |
| 171 | 171 | for(i=cnt=0; i<10; i++){ |
| 172 | 172 | sqlite3_snprintf(sizeof(zNm),zNm,"b%d",i); |
| 173 | 173 | zBr = P(zNm); |
| @@ -1175,11 +1175,11 @@ | ||
| 1175 | 1175 | if( pd_rid ){ |
| 1176 | 1176 | p_rid = d_rid = pd_rid; |
| 1177 | 1177 | } |
| 1178 | 1178 | login_check_credentials(); |
| 1179 | 1179 | if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ |
| 1180 | - login_needed(); | |
| 1180 | + login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki); | |
| 1181 | 1181 | return; |
| 1182 | 1182 | } |
| 1183 | 1183 | url_initialize(&url, "timeline"); |
| 1184 | 1184 | cgi_query_parameters_to_url(&url); |
| 1185 | 1185 | if( zTagName && g.perm.Read ){ |
| @@ -2068,11 +2068,14 @@ | ||
| 2068 | 2068 | */ |
| 2069 | 2069 | void test_timewarp_page(void){ |
| 2070 | 2070 | Stmt q; |
| 2071 | 2071 | |
| 2072 | 2072 | login_check_credentials(); |
| 2073 | - if( !g.perm.Read || !g.perm.Hyperlink ){ login_needed(); return; } | |
| 2073 | + if( !g.perm.Read || !g.perm.Hyperlink ){ | |
| 2074 | + login_needed(g.anon.Read && g.anon.Hyperlink); | |
| 2075 | + return; | |
| 2076 | + } | |
| 2074 | 2077 | style_header("Instances of timewarp"); |
| 2075 | 2078 | @ <ul> |
| 2076 | 2079 | db_prepare(&q, |
| 2077 | 2080 | "SELECT blob.uuid " |
| 2078 | 2081 | " FROM plink p, plink c, blob" |
| 2079 | 2082 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -163,11 +163,11 @@ | |
| 163 | void test_hash_color_page(void){ |
| 164 | const char *zBr; |
| 165 | char zNm[10]; |
| 166 | int i, cnt; |
| 167 | login_check_credentials(); |
| 168 | if( !g.perm.Read ){ login_needed(); return; } |
| 169 | |
| 170 | style_header("Hash Color Test"); |
| 171 | for(i=cnt=0; i<10; i++){ |
| 172 | sqlite3_snprintf(sizeof(zNm),zNm,"b%d",i); |
| 173 | zBr = P(zNm); |
| @@ -1175,11 +1175,11 @@ | |
| 1175 | if( pd_rid ){ |
| 1176 | p_rid = d_rid = pd_rid; |
| 1177 | } |
| 1178 | login_check_credentials(); |
| 1179 | if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ |
| 1180 | login_needed(); |
| 1181 | return; |
| 1182 | } |
| 1183 | url_initialize(&url, "timeline"); |
| 1184 | cgi_query_parameters_to_url(&url); |
| 1185 | if( zTagName && g.perm.Read ){ |
| @@ -2068,11 +2068,14 @@ | |
| 2068 | */ |
| 2069 | void test_timewarp_page(void){ |
| 2070 | Stmt q; |
| 2071 | |
| 2072 | login_check_credentials(); |
| 2073 | if( !g.perm.Read || !g.perm.Hyperlink ){ login_needed(); return; } |
| 2074 | style_header("Instances of timewarp"); |
| 2075 | @ <ul> |
| 2076 | db_prepare(&q, |
| 2077 | "SELECT blob.uuid " |
| 2078 | " FROM plink p, plink c, blob" |
| 2079 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -163,11 +163,11 @@ | |
| 163 | void test_hash_color_page(void){ |
| 164 | const char *zBr; |
| 165 | char zNm[10]; |
| 166 | int i, cnt; |
| 167 | login_check_credentials(); |
| 168 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 169 | |
| 170 | style_header("Hash Color Test"); |
| 171 | for(i=cnt=0; i<10; i++){ |
| 172 | sqlite3_snprintf(sizeof(zNm),zNm,"b%d",i); |
| 173 | zBr = P(zNm); |
| @@ -1175,11 +1175,11 @@ | |
| 1175 | if( pd_rid ){ |
| 1176 | p_rid = d_rid = pd_rid; |
| 1177 | } |
| 1178 | login_check_credentials(); |
| 1179 | if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ |
| 1180 | login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki); |
| 1181 | return; |
| 1182 | } |
| 1183 | url_initialize(&url, "timeline"); |
| 1184 | cgi_query_parameters_to_url(&url); |
| 1185 | if( zTagName && g.perm.Read ){ |
| @@ -2068,11 +2068,14 @@ | |
| 2068 | */ |
| 2069 | void test_timewarp_page(void){ |
| 2070 | Stmt q; |
| 2071 | |
| 2072 | login_check_credentials(); |
| 2073 | if( !g.perm.Read || !g.perm.Hyperlink ){ |
| 2074 | login_needed(g.anon.Read && g.anon.Hyperlink); |
| 2075 | return; |
| 2076 | } |
| 2077 | style_header("Instances of timewarp"); |
| 2078 | @ <ul> |
| 2079 | db_prepare(&q, |
| 2080 | "SELECT blob.uuid " |
| 2081 | " FROM plink p, plink c, blob" |
| 2082 |
+18
-9
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -449,12 +449,12 @@ | ||
| 449 | 449 | const char *zScript; |
| 450 | 450 | char *zFullName; |
| 451 | 451 | const char *zUuid = PD("name",""); |
| 452 | 452 | |
| 453 | 453 | login_check_credentials(); |
| 454 | - if( !g.perm.RdTkt ){ login_needed(); return; } | |
| 455 | - if( g.perm.WrTkt || g.perm.ApndTkt ){ | |
| 454 | + if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } | |
| 455 | + if( g.anon.WrTkt || g.anon.ApndTkt ){ | |
| 456 | 456 | style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T", |
| 457 | 457 | g.zTop, PD("name","")); |
| 458 | 458 | } |
| 459 | 459 | if( g.perm.Hyperlink ){ |
| 460 | 460 | style_submenu_element("History", "History Of This Ticket", |
| @@ -462,15 +462,15 @@ | ||
| 462 | 462 | style_submenu_element("Timeline", "Timeline Of This Ticket", |
| 463 | 463 | "%s/tkttimeline/%T", g.zTop, zUuid); |
| 464 | 464 | style_submenu_element("Check-ins", "Check-ins Of This Ticket", |
| 465 | 465 | "%s/tkttimeline/%T?y=ci", g.zTop, zUuid); |
| 466 | 466 | } |
| 467 | - if( g.perm.NewTkt ){ | |
| 467 | + if( g.anon.NewTkt ){ | |
| 468 | 468 | style_submenu_element("New Ticket", "Create a new ticket", |
| 469 | 469 | "%s/tktnew", g.zTop); |
| 470 | 470 | } |
| 471 | - if( g.perm.ApndTkt && g.perm.Attach ){ | |
| 471 | + if( g.anon.ApndTkt && g.anon.Attach ){ | |
| 472 | 472 | style_submenu_element("Attach", "Add An Attachment", |
| 473 | 473 | "%s/attachadd?tkt=%T&from=%s/tktview/%t", |
| 474 | 474 | g.zTop, zUuid, g.zTop, zUuid); |
| 475 | 475 | } |
| 476 | 476 | if( P("plaintext") ){ |
| @@ -687,11 +687,11 @@ | ||
| 687 | 687 | void tktnew_page(void){ |
| 688 | 688 | const char *zScript; |
| 689 | 689 | char *zNewUuid = 0; |
| 690 | 690 | |
| 691 | 691 | login_check_credentials(); |
| 692 | - if( !g.perm.NewTkt ){ login_needed(); return; } | |
| 692 | + if( !g.perm.NewTkt ){ login_needed(g.anon.NewTkt); return; } | |
| 693 | 693 | if( P("cancel") ){ |
| 694 | 694 | cgi_redirect("home"); |
| 695 | 695 | } |
| 696 | 696 | style_header("New Ticket"); |
| 697 | 697 | ticket_standard_submenu(T_ALL_BUT(T_NEW)); |
| @@ -738,11 +738,14 @@ | ||
| 738 | 738 | int nName; |
| 739 | 739 | const char *zName; |
| 740 | 740 | int nRec; |
| 741 | 741 | |
| 742 | 742 | login_check_credentials(); |
| 743 | - if( !g.perm.ApndTkt && !g.perm.WrTkt ){ login_needed(); return; } | |
| 743 | + if( !g.perm.ApndTkt && !g.perm.WrTkt ){ | |
| 744 | + login_needed(g.anon.ApndTkt || g.anon.WrTkt); | |
| 745 | + return; | |
| 746 | + } | |
| 744 | 747 | zName = P("name"); |
| 745 | 748 | if( P("cancel") ){ |
| 746 | 749 | cgi_redirectf("tktview?name=%T", zName); |
| 747 | 750 | } |
| 748 | 751 | style_header("Edit Ticket"); |
| @@ -839,11 +842,14 @@ | ||
| 839 | 842 | int tagid; |
| 840 | 843 | char zGlobPattern[50]; |
| 841 | 844 | const char *zType; |
| 842 | 845 | |
| 843 | 846 | login_check_credentials(); |
| 844 | - if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; } | |
| 847 | + if( !g.perm.Hyperlink || !g.perm.RdTkt ){ | |
| 848 | + login_needed(g.anon.Hyperlink && g.anon.RdTkt); | |
| 849 | + return; | |
| 850 | + } | |
| 845 | 851 | zUuid = PD("name",""); |
| 846 | 852 | zType = PD("y","a"); |
| 847 | 853 | if( zType[0]!='c' ){ |
| 848 | 854 | style_submenu_element("Check-ins", "Check-ins", |
| 849 | 855 | "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); |
| @@ -912,11 +918,14 @@ | ||
| 912 | 918 | const char *zUuid; |
| 913 | 919 | int tagid; |
| 914 | 920 | int nChng = 0; |
| 915 | 921 | |
| 916 | 922 | login_check_credentials(); |
| 917 | - if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; } | |
| 923 | + if( !g.perm.Hyperlink || !g.perm.RdTkt ){ | |
| 924 | + login_needed(g.anon.Hyperlink && g.anon.RdTkt); | |
| 925 | + return; | |
| 926 | + } | |
| 918 | 927 | zUuid = PD("name",""); |
| 919 | 928 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 920 | 929 | style_submenu_element("Status", "Status", |
| 921 | 930 | "%s/info/%s", g.zTop, zUuid); |
| 922 | 931 | style_submenu_element("Check-ins", "Check-ins", |
| @@ -1403,11 +1412,11 @@ | ||
| 1403 | 1412 | style_submenu_element("Search","Search","%R/tktsrch"); |
| 1404 | 1413 | } |
| 1405 | 1414 | if( (ok & T_REPLIST)!=0 ){ |
| 1406 | 1415 | style_submenu_element("Reports","Reports","%R/reportlist"); |
| 1407 | 1416 | } |
| 1408 | - if( (ok & T_NEW)!=0 && g.perm.NewTkt ){ | |
| 1417 | + if( (ok & T_NEW)!=0 && g.anon.NewTkt ){ | |
| 1409 | 1418 | style_submenu_element("New","New","%R/tktnew"); |
| 1410 | 1419 | } |
| 1411 | 1420 | } |
| 1412 | 1421 | |
| 1413 | 1422 | /* |
| 1414 | 1423 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -449,12 +449,12 @@ | |
| 449 | const char *zScript; |
| 450 | char *zFullName; |
| 451 | const char *zUuid = PD("name",""); |
| 452 | |
| 453 | login_check_credentials(); |
| 454 | if( !g.perm.RdTkt ){ login_needed(); return; } |
| 455 | if( g.perm.WrTkt || g.perm.ApndTkt ){ |
| 456 | style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T", |
| 457 | g.zTop, PD("name","")); |
| 458 | } |
| 459 | if( g.perm.Hyperlink ){ |
| 460 | style_submenu_element("History", "History Of This Ticket", |
| @@ -462,15 +462,15 @@ | |
| 462 | style_submenu_element("Timeline", "Timeline Of This Ticket", |
| 463 | "%s/tkttimeline/%T", g.zTop, zUuid); |
| 464 | style_submenu_element("Check-ins", "Check-ins Of This Ticket", |
| 465 | "%s/tkttimeline/%T?y=ci", g.zTop, zUuid); |
| 466 | } |
| 467 | if( g.perm.NewTkt ){ |
| 468 | style_submenu_element("New Ticket", "Create a new ticket", |
| 469 | "%s/tktnew", g.zTop); |
| 470 | } |
| 471 | if( g.perm.ApndTkt && g.perm.Attach ){ |
| 472 | style_submenu_element("Attach", "Add An Attachment", |
| 473 | "%s/attachadd?tkt=%T&from=%s/tktview/%t", |
| 474 | g.zTop, zUuid, g.zTop, zUuid); |
| 475 | } |
| 476 | if( P("plaintext") ){ |
| @@ -687,11 +687,11 @@ | |
| 687 | void tktnew_page(void){ |
| 688 | const char *zScript; |
| 689 | char *zNewUuid = 0; |
| 690 | |
| 691 | login_check_credentials(); |
| 692 | if( !g.perm.NewTkt ){ login_needed(); return; } |
| 693 | if( P("cancel") ){ |
| 694 | cgi_redirect("home"); |
| 695 | } |
| 696 | style_header("New Ticket"); |
| 697 | ticket_standard_submenu(T_ALL_BUT(T_NEW)); |
| @@ -738,11 +738,14 @@ | |
| 738 | int nName; |
| 739 | const char *zName; |
| 740 | int nRec; |
| 741 | |
| 742 | login_check_credentials(); |
| 743 | if( !g.perm.ApndTkt && !g.perm.WrTkt ){ login_needed(); return; } |
| 744 | zName = P("name"); |
| 745 | if( P("cancel") ){ |
| 746 | cgi_redirectf("tktview?name=%T", zName); |
| 747 | } |
| 748 | style_header("Edit Ticket"); |
| @@ -839,11 +842,14 @@ | |
| 839 | int tagid; |
| 840 | char zGlobPattern[50]; |
| 841 | const char *zType; |
| 842 | |
| 843 | login_check_credentials(); |
| 844 | if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; } |
| 845 | zUuid = PD("name",""); |
| 846 | zType = PD("y","a"); |
| 847 | if( zType[0]!='c' ){ |
| 848 | style_submenu_element("Check-ins", "Check-ins", |
| 849 | "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); |
| @@ -912,11 +918,14 @@ | |
| 912 | const char *zUuid; |
| 913 | int tagid; |
| 914 | int nChng = 0; |
| 915 | |
| 916 | login_check_credentials(); |
| 917 | if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; } |
| 918 | zUuid = PD("name",""); |
| 919 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 920 | style_submenu_element("Status", "Status", |
| 921 | "%s/info/%s", g.zTop, zUuid); |
| 922 | style_submenu_element("Check-ins", "Check-ins", |
| @@ -1403,11 +1412,11 @@ | |
| 1403 | style_submenu_element("Search","Search","%R/tktsrch"); |
| 1404 | } |
| 1405 | if( (ok & T_REPLIST)!=0 ){ |
| 1406 | style_submenu_element("Reports","Reports","%R/reportlist"); |
| 1407 | } |
| 1408 | if( (ok & T_NEW)!=0 && g.perm.NewTkt ){ |
| 1409 | style_submenu_element("New","New","%R/tktnew"); |
| 1410 | } |
| 1411 | } |
| 1412 | |
| 1413 | /* |
| 1414 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -449,12 +449,12 @@ | |
| 449 | const char *zScript; |
| 450 | char *zFullName; |
| 451 | const char *zUuid = PD("name",""); |
| 452 | |
| 453 | login_check_credentials(); |
| 454 | if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } |
| 455 | if( g.anon.WrTkt || g.anon.ApndTkt ){ |
| 456 | style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T", |
| 457 | g.zTop, PD("name","")); |
| 458 | } |
| 459 | if( g.perm.Hyperlink ){ |
| 460 | style_submenu_element("History", "History Of This Ticket", |
| @@ -462,15 +462,15 @@ | |
| 462 | style_submenu_element("Timeline", "Timeline Of This Ticket", |
| 463 | "%s/tkttimeline/%T", g.zTop, zUuid); |
| 464 | style_submenu_element("Check-ins", "Check-ins Of This Ticket", |
| 465 | "%s/tkttimeline/%T?y=ci", g.zTop, zUuid); |
| 466 | } |
| 467 | if( g.anon.NewTkt ){ |
| 468 | style_submenu_element("New Ticket", "Create a new ticket", |
| 469 | "%s/tktnew", g.zTop); |
| 470 | } |
| 471 | if( g.anon.ApndTkt && g.anon.Attach ){ |
| 472 | style_submenu_element("Attach", "Add An Attachment", |
| 473 | "%s/attachadd?tkt=%T&from=%s/tktview/%t", |
| 474 | g.zTop, zUuid, g.zTop, zUuid); |
| 475 | } |
| 476 | if( P("plaintext") ){ |
| @@ -687,11 +687,11 @@ | |
| 687 | void tktnew_page(void){ |
| 688 | const char *zScript; |
| 689 | char *zNewUuid = 0; |
| 690 | |
| 691 | login_check_credentials(); |
| 692 | if( !g.perm.NewTkt ){ login_needed(g.anon.NewTkt); return; } |
| 693 | if( P("cancel") ){ |
| 694 | cgi_redirect("home"); |
| 695 | } |
| 696 | style_header("New Ticket"); |
| 697 | ticket_standard_submenu(T_ALL_BUT(T_NEW)); |
| @@ -738,11 +738,14 @@ | |
| 738 | int nName; |
| 739 | const char *zName; |
| 740 | int nRec; |
| 741 | |
| 742 | login_check_credentials(); |
| 743 | if( !g.perm.ApndTkt && !g.perm.WrTkt ){ |
| 744 | login_needed(g.anon.ApndTkt || g.anon.WrTkt); |
| 745 | return; |
| 746 | } |
| 747 | zName = P("name"); |
| 748 | if( P("cancel") ){ |
| 749 | cgi_redirectf("tktview?name=%T", zName); |
| 750 | } |
| 751 | style_header("Edit Ticket"); |
| @@ -839,11 +842,14 @@ | |
| 842 | int tagid; |
| 843 | char zGlobPattern[50]; |
| 844 | const char *zType; |
| 845 | |
| 846 | login_check_credentials(); |
| 847 | if( !g.perm.Hyperlink || !g.perm.RdTkt ){ |
| 848 | login_needed(g.anon.Hyperlink && g.anon.RdTkt); |
| 849 | return; |
| 850 | } |
| 851 | zUuid = PD("name",""); |
| 852 | zType = PD("y","a"); |
| 853 | if( zType[0]!='c' ){ |
| 854 | style_submenu_element("Check-ins", "Check-ins", |
| 855 | "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid); |
| @@ -912,11 +918,14 @@ | |
| 918 | const char *zUuid; |
| 919 | int tagid; |
| 920 | int nChng = 0; |
| 921 | |
| 922 | login_check_credentials(); |
| 923 | if( !g.perm.Hyperlink || !g.perm.RdTkt ){ |
| 924 | login_needed(g.anon.Hyperlink && g.anon.RdTkt); |
| 925 | return; |
| 926 | } |
| 927 | zUuid = PD("name",""); |
| 928 | zTitle = mprintf("History Of Ticket %h", zUuid); |
| 929 | style_submenu_element("Status", "Status", |
| 930 | "%s/info/%s", g.zTop, zUuid); |
| 931 | style_submenu_element("Check-ins", "Check-ins", |
| @@ -1403,11 +1412,11 @@ | |
| 1412 | style_submenu_element("Search","Search","%R/tktsrch"); |
| 1413 | } |
| 1414 | if( (ok & T_REPLIST)!=0 ){ |
| 1415 | style_submenu_element("Reports","Reports","%R/reportlist"); |
| 1416 | } |
| 1417 | if( (ok & T_NEW)!=0 && g.anon.NewTkt ){ |
| 1418 | style_submenu_element("New","New","%R/tktnew"); |
| 1419 | } |
| 1420 | } |
| 1421 | |
| 1422 | /* |
| 1423 |
+11
-8
| --- src/tktsetup.c | ||
| +++ src/tktsetup.c | ||
| @@ -27,11 +27,12 @@ | ||
| 27 | 27 | ** WEBPAGE: tktsetup |
| 28 | 28 | */ |
| 29 | 29 | void tktsetup_page(void){ |
| 30 | 30 | login_check_credentials(); |
| 31 | 31 | if( !g.perm.Setup ){ |
| 32 | - login_needed(); | |
| 32 | + login_needed(0); | |
| 33 | + return; | |
| 33 | 34 | } |
| 34 | 35 | |
| 35 | 36 | style_header("Ticket Setup"); |
| 36 | 37 | @ <table border="0" cellspacing="20"> |
| 37 | 38 | setup_menu_entry("Table", "tktsetup_tab", |
| @@ -118,13 +119,14 @@ | ||
| 118 | 119 | const char *z; |
| 119 | 120 | int isSubmit; |
| 120 | 121 | |
| 121 | 122 | login_check_credentials(); |
| 122 | 123 | if( !g.perm.Setup ){ |
| 123 | - login_needed(); | |
| 124 | + login_needed(0); | |
| 125 | + return; | |
| 124 | 126 | } |
| 125 | - if( P("setup") ){ | |
| 127 | + if( PB("setup") ){ | |
| 126 | 128 | cgi_redirect("tktsetup"); |
| 127 | 129 | } |
| 128 | 130 | isSubmit = P("submit")!=0; |
| 129 | 131 | z = P("x"); |
| 130 | 132 | if( z==0 ){ |
| @@ -713,11 +715,11 @@ | ||
| 713 | 715 | /* |
| 714 | 716 | ** The default report list page |
| 715 | 717 | */ |
| 716 | 718 | static const char zDefaultReportList[] = |
| 717 | 719 | @ <th1> |
| 718 | -@ if {[hascap n]} { | |
| 720 | +@ if {[anoncap n]} { | |
| 719 | 721 | @ html "<p>Enter a new ticket:</p>" |
| 720 | 722 | @ html "<ul><li><a href='tktnew'>New ticket</a></li></ul>" |
| 721 | 723 | @ } |
| 722 | 724 | @ </th1> |
| 723 | 725 | @ |
| @@ -725,16 +727,16 @@ | ||
| 725 | 727 | @ <ol> |
| 726 | 728 | @ <th1>html $report_items</th1> |
| 727 | 729 | @ </ol> |
| 728 | 730 | @ |
| 729 | 731 | @ <th1> |
| 730 | -@ if {[hascap t q]} { | |
| 732 | +@ if {[anoncap t q]} { | |
| 731 | 733 | @ html "<p>Other options:</p>\n<ul>\n" |
| 732 | -@ if {[hascap t]} { | |
| 734 | +@ if {[anoncap t]} { | |
| 733 | 735 | @ html "<li><a href='rptnew'>New report format</a></li>\n" |
| 734 | 736 | @ } |
| 735 | -@ if {[hascap q]} { | |
| 737 | +@ if {[anoncap q]} { | |
| 736 | 738 | @ html "<li><a href='modreq'>Tend to pending moderation requests</a></li>\n" |
| 737 | 739 | @ } |
| 738 | 740 | @ } |
| 739 | 741 | @ </th1> |
| 740 | 742 | ; |
| @@ -858,11 +860,12 @@ | ||
| 858 | 860 | ** WEBPAGE: tktsetup_timeline |
| 859 | 861 | */ |
| 860 | 862 | void tktsetup_timeline_page(void){ |
| 861 | 863 | login_check_credentials(); |
| 862 | 864 | if( !g.perm.Setup ){ |
| 863 | - login_needed(); | |
| 865 | + login_needed(0); | |
| 866 | + return; | |
| 864 | 867 | } |
| 865 | 868 | |
| 866 | 869 | if( P("setup") ){ |
| 867 | 870 | cgi_redirect("tktsetup"); |
| 868 | 871 | } |
| 869 | 872 |
| --- src/tktsetup.c | |
| +++ src/tktsetup.c | |
| @@ -27,11 +27,12 @@ | |
| 27 | ** WEBPAGE: tktsetup |
| 28 | */ |
| 29 | void tktsetup_page(void){ |
| 30 | login_check_credentials(); |
| 31 | if( !g.perm.Setup ){ |
| 32 | login_needed(); |
| 33 | } |
| 34 | |
| 35 | style_header("Ticket Setup"); |
| 36 | @ <table border="0" cellspacing="20"> |
| 37 | setup_menu_entry("Table", "tktsetup_tab", |
| @@ -118,13 +119,14 @@ | |
| 118 | const char *z; |
| 119 | int isSubmit; |
| 120 | |
| 121 | login_check_credentials(); |
| 122 | if( !g.perm.Setup ){ |
| 123 | login_needed(); |
| 124 | } |
| 125 | if( P("setup") ){ |
| 126 | cgi_redirect("tktsetup"); |
| 127 | } |
| 128 | isSubmit = P("submit")!=0; |
| 129 | z = P("x"); |
| 130 | if( z==0 ){ |
| @@ -713,11 +715,11 @@ | |
| 713 | /* |
| 714 | ** The default report list page |
| 715 | */ |
| 716 | static const char zDefaultReportList[] = |
| 717 | @ <th1> |
| 718 | @ if {[hascap n]} { |
| 719 | @ html "<p>Enter a new ticket:</p>" |
| 720 | @ html "<ul><li><a href='tktnew'>New ticket</a></li></ul>" |
| 721 | @ } |
| 722 | @ </th1> |
| 723 | @ |
| @@ -725,16 +727,16 @@ | |
| 725 | @ <ol> |
| 726 | @ <th1>html $report_items</th1> |
| 727 | @ </ol> |
| 728 | @ |
| 729 | @ <th1> |
| 730 | @ if {[hascap t q]} { |
| 731 | @ html "<p>Other options:</p>\n<ul>\n" |
| 732 | @ if {[hascap t]} { |
| 733 | @ html "<li><a href='rptnew'>New report format</a></li>\n" |
| 734 | @ } |
| 735 | @ if {[hascap q]} { |
| 736 | @ html "<li><a href='modreq'>Tend to pending moderation requests</a></li>\n" |
| 737 | @ } |
| 738 | @ } |
| 739 | @ </th1> |
| 740 | ; |
| @@ -858,11 +860,12 @@ | |
| 858 | ** WEBPAGE: tktsetup_timeline |
| 859 | */ |
| 860 | void tktsetup_timeline_page(void){ |
| 861 | login_check_credentials(); |
| 862 | if( !g.perm.Setup ){ |
| 863 | login_needed(); |
| 864 | } |
| 865 | |
| 866 | if( P("setup") ){ |
| 867 | cgi_redirect("tktsetup"); |
| 868 | } |
| 869 |
| --- src/tktsetup.c | |
| +++ src/tktsetup.c | |
| @@ -27,11 +27,12 @@ | |
| 27 | ** WEBPAGE: tktsetup |
| 28 | */ |
| 29 | void tktsetup_page(void){ |
| 30 | login_check_credentials(); |
| 31 | if( !g.perm.Setup ){ |
| 32 | login_needed(0); |
| 33 | return; |
| 34 | } |
| 35 | |
| 36 | style_header("Ticket Setup"); |
| 37 | @ <table border="0" cellspacing="20"> |
| 38 | setup_menu_entry("Table", "tktsetup_tab", |
| @@ -118,13 +119,14 @@ | |
| 119 | const char *z; |
| 120 | int isSubmit; |
| 121 | |
| 122 | login_check_credentials(); |
| 123 | if( !g.perm.Setup ){ |
| 124 | login_needed(0); |
| 125 | return; |
| 126 | } |
| 127 | if( PB("setup") ){ |
| 128 | cgi_redirect("tktsetup"); |
| 129 | } |
| 130 | isSubmit = P("submit")!=0; |
| 131 | z = P("x"); |
| 132 | if( z==0 ){ |
| @@ -713,11 +715,11 @@ | |
| 715 | /* |
| 716 | ** The default report list page |
| 717 | */ |
| 718 | static const char zDefaultReportList[] = |
| 719 | @ <th1> |
| 720 | @ if {[anoncap n]} { |
| 721 | @ html "<p>Enter a new ticket:</p>" |
| 722 | @ html "<ul><li><a href='tktnew'>New ticket</a></li></ul>" |
| 723 | @ } |
| 724 | @ </th1> |
| 725 | @ |
| @@ -725,16 +727,16 @@ | |
| 727 | @ <ol> |
| 728 | @ <th1>html $report_items</th1> |
| 729 | @ </ol> |
| 730 | @ |
| 731 | @ <th1> |
| 732 | @ if {[anoncap t q]} { |
| 733 | @ html "<p>Other options:</p>\n<ul>\n" |
| 734 | @ if {[anoncap t]} { |
| 735 | @ html "<li><a href='rptnew'>New report format</a></li>\n" |
| 736 | @ } |
| 737 | @ if {[anoncap q]} { |
| 738 | @ html "<li><a href='modreq'>Tend to pending moderation requests</a></li>\n" |
| 739 | @ } |
| 740 | @ } |
| 741 | @ </th1> |
| 742 | ; |
| @@ -858,11 +860,12 @@ | |
| 860 | ** WEBPAGE: tktsetup_timeline |
| 861 | */ |
| 862 | void tktsetup_timeline_page(void){ |
| 863 | login_check_credentials(); |
| 864 | if( !g.perm.Setup ){ |
| 865 | login_needed(0); |
| 866 | return; |
| 867 | } |
| 868 | |
| 869 | if( P("setup") ){ |
| 870 | cgi_redirect("tktsetup"); |
| 871 | } |
| 872 |
+1
-1
| --- src/user.c | ||
| +++ src/user.c | ||
| @@ -424,11 +424,11 @@ | ||
| 424 | 424 | Stmt q; |
| 425 | 425 | int cnt = 0; |
| 426 | 426 | int rc; |
| 427 | 427 | |
| 428 | 428 | login_check_credentials(); |
| 429 | - if( !g.perm.Admin ){ login_needed(); return; } | |
| 429 | + if( !g.perm.Admin ){ login_needed(0); return; } | |
| 430 | 430 | create_accesslog_table(); |
| 431 | 431 | |
| 432 | 432 | if( P("delall") && P("delallbtn") ){ |
| 433 | 433 | db_multi_exec("DELETE FROM accesslog"); |
| 434 | 434 | cgi_redirectf("%s/access_log?y=%d&n=%d&o=%o", g.zTop, y, n, skip); |
| 435 | 435 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -424,11 +424,11 @@ | |
| 424 | Stmt q; |
| 425 | int cnt = 0; |
| 426 | int rc; |
| 427 | |
| 428 | login_check_credentials(); |
| 429 | if( !g.perm.Admin ){ login_needed(); return; } |
| 430 | create_accesslog_table(); |
| 431 | |
| 432 | if( P("delall") && P("delallbtn") ){ |
| 433 | db_multi_exec("DELETE FROM accesslog"); |
| 434 | cgi_redirectf("%s/access_log?y=%d&n=%d&o=%o", g.zTop, y, n, skip); |
| 435 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -424,11 +424,11 @@ | |
| 424 | Stmt q; |
| 425 | int cnt = 0; |
| 426 | int rc; |
| 427 | |
| 428 | login_check_credentials(); |
| 429 | if( !g.perm.Admin ){ login_needed(0); return; } |
| 430 | create_accesslog_table(); |
| 431 | |
| 432 | if( P("delall") && P("delallbtn") ){ |
| 433 | db_multi_exec("DELETE FROM accesslog"); |
| 434 | cgi_redirectf("%s/access_log?y=%d&n=%d&o=%o", g.zTop, y, n, skip); |
| 435 |
+18
-18
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -222,11 +222,11 @@ | ||
| 222 | 222 | style_submenu_element("List","List","%R/wcontent"); |
| 223 | 223 | } |
| 224 | 224 | if( (ok & W_HELP)!=0 ){ |
| 225 | 225 | style_submenu_element("Help","Help","%R/wikihelp"); |
| 226 | 226 | } |
| 227 | - if( (ok & W_NEW)!=0 && g.perm.NewWiki ){ | |
| 227 | + if( (ok & W_NEW)!=0 && g.anon.NewWiki ){ | |
| 228 | 228 | style_submenu_element("New","New","%R/wikinew"); |
| 229 | 229 | } |
| 230 | 230 | #if 0 |
| 231 | 231 | if( (ok & W_BLOG)!=0 |
| 232 | 232 | #endif |
| @@ -239,11 +239,11 @@ | ||
| 239 | 239 | ** WEBPAGE: wikihelp |
| 240 | 240 | ** A generic landing page for wiki. |
| 241 | 241 | */ |
| 242 | 242 | void wiki_helppage(void){ |
| 243 | 243 | login_check_credentials(); |
| 244 | - if( !g.perm.RdWiki ){ login_needed(); return; } | |
| 244 | + if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } | |
| 245 | 245 | style_header("Wiki Help"); |
| 246 | 246 | wiki_standard_submenu(W_ALL_BUT(W_HELP)); |
| 247 | 247 | @ <h2>Wiki Links</h2> |
| 248 | 248 | @ <ul> |
| 249 | 249 | { char *zWikiHomePageName = db_get("index-page",0); |
| @@ -261,19 +261,19 @@ | ||
| 261 | 261 | @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li> |
| 262 | 262 | @ <li> Formatting rules for %z(href("%R/wiki_rules"))Fossil Wiki</a> and for |
| 263 | 263 | @ %z(href("%R/md_rules"))Markdown Wiki</a>.</li> |
| 264 | 264 | @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a> |
| 265 | 265 | @ to experiment.</li> |
| 266 | - if( g.perm.NewWiki ){ | |
| 266 | + if( g.anon.NewWiki ){ | |
| 267 | 267 | @ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li> |
| 268 | - if( g.perm.Write ){ | |
| 269 | - @ <li> Create a %z(href("%R/eventedit"))new blog entry</a>.</li> | |
| 268 | + if( g.anon.Write ){ | |
| 269 | + @ <li> Create a %z(href("%R/eventedit"))new tech-note</a>.</li> | |
| 270 | 270 | } |
| 271 | 271 | } |
| 272 | 272 | @ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a> |
| 273 | 273 | @ available on this server.</li> |
| 274 | - if( g.perm.ModWiki ){ | |
| 274 | + if( g.anon.ModWiki ){ | |
| 275 | 275 | @ <li> %z(href("%R/modreq"))Tend to pending moderation requests</a></li> |
| 276 | 276 | } |
| 277 | 277 | if( search_restrict(SRCH_WIKI)!=0 ){ |
| 278 | 278 | @ <li> %z(href("%R/wikisrch"))Search</a> for wiki pages containing key |
| 279 | 279 | @ words</li> |
| @@ -312,11 +312,11 @@ | ||
| 312 | 312 | const char *zPageName; |
| 313 | 313 | const char *zMimetype = 0; |
| 314 | 314 | char *zBody = mprintf("%s","<i>Empty Page</i>"); |
| 315 | 315 | |
| 316 | 316 | login_check_credentials(); |
| 317 | - if( !g.perm.RdWiki ){ login_needed(); return; } | |
| 317 | + if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } | |
| 318 | 318 | zPageName = P("name"); |
| 319 | 319 | if( zPageName==0 ){ |
| 320 | 320 | if( search_restrict(SRCH_WIKI)!=0 ){ |
| 321 | 321 | wiki_srchpage(); |
| 322 | 322 | }else{ |
| @@ -355,11 +355,11 @@ | ||
| 355 | 355 | "%R/wdiff?name=%T&a=%d", zPageName, rid); |
| 356 | 356 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 357 | 357 | style_submenu_element("Details", "Details", |
| 358 | 358 | "%R/info/%s", zUuid); |
| 359 | 359 | } |
| 360 | - if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){ | |
| 360 | + if( (rid && g.anon.WrWiki) || (!rid && g.anon.NewWiki) ){ | |
| 361 | 361 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 362 | 362 | style_submenu_element("Edit", "Edit Wiki Page", |
| 363 | 363 | "%s/wikiedit?name=%T&wysiwyg=1", |
| 364 | 364 | g.zTop, zPageName); |
| 365 | 365 | }else{ |
| @@ -366,16 +366,16 @@ | ||
| 366 | 366 | style_submenu_element("Edit", "Edit Wiki Page", |
| 367 | 367 | "%s/wikiedit?name=%T", |
| 368 | 368 | g.zTop, zPageName); |
| 369 | 369 | } |
| 370 | 370 | } |
| 371 | - if( rid && g.perm.ApndWiki && g.perm.Attach ){ | |
| 371 | + if( rid && g.anon.ApndWiki && g.anon.Attach ){ | |
| 372 | 372 | style_submenu_element("Attach", "Add An Attachment", |
| 373 | 373 | "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T", |
| 374 | 374 | g.zTop, zPageName, g.zTop, zPageName); |
| 375 | 375 | } |
| 376 | - if( rid && g.perm.ApndWiki ){ | |
| 376 | + if( rid && g.anon.ApndWiki ){ | |
| 377 | 377 | style_submenu_element("Append", "Add A Comment", |
| 378 | 378 | "%s/wikiappend?name=%T&mimetype=%s", |
| 379 | 379 | g.zTop, zPageName, zMimetype); |
| 380 | 380 | } |
| 381 | 381 | if( g.perm.Hyperlink ){ |
| @@ -485,11 +485,11 @@ | ||
| 485 | 485 | zPageName = PD("name",""); |
| 486 | 486 | if( check_name(zPageName) ) return; |
| 487 | 487 | isSandbox = is_sandbox(zPageName); |
| 488 | 488 | if( isSandbox ){ |
| 489 | 489 | if( !g.perm.WrWiki ){ |
| 490 | - login_needed(); | |
| 490 | + login_needed(g.anon.WrWiki); | |
| 491 | 491 | return; |
| 492 | 492 | } |
| 493 | 493 | if( zBody==0 ){ |
| 494 | 494 | zBody = db_get("sandbox",""); |
| 495 | 495 | zMimetype = db_get("sandbox-mimetype","text/x-fossil-wiki"); |
| @@ -501,11 +501,11 @@ | ||
| 501 | 501 | " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" |
| 502 | 502 | " ORDER BY mtime DESC", zTag |
| 503 | 503 | ); |
| 504 | 504 | free(zTag); |
| 505 | 505 | if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){ |
| 506 | - login_needed(); | |
| 506 | + login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki); | |
| 507 | 507 | return; |
| 508 | 508 | } |
| 509 | 509 | if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){ |
| 510 | 510 | zBody = pWiki->zWiki; |
| 511 | 511 | zMimetype = pWiki->zMimetype; |
| @@ -625,11 +625,11 @@ | ||
| 625 | 625 | void wikinew_page(void){ |
| 626 | 626 | const char *zName; |
| 627 | 627 | const char *zMimetype; |
| 628 | 628 | login_check_credentials(); |
| 629 | 629 | if( !g.perm.NewWiki ){ |
| 630 | - login_needed(); | |
| 630 | + login_needed(g.anon.NewWiki); | |
| 631 | 631 | return; |
| 632 | 632 | } |
| 633 | 633 | zName = PD("name",""); |
| 634 | 634 | zMimetype = wiki_filter_mimetypes(P("mimetype")); |
| 635 | 635 | if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){ |
| @@ -727,11 +727,11 @@ | ||
| 727 | 727 | fossil_redirect_home(); |
| 728 | 728 | return; |
| 729 | 729 | } |
| 730 | 730 | } |
| 731 | 731 | if( !g.perm.ApndWiki ){ |
| 732 | - login_needed(); | |
| 732 | + login_needed(g.anon.ApndWiki); | |
| 733 | 733 | return; |
| 734 | 734 | } |
| 735 | 735 | if( P("submit")!=0 && P("r")!=0 && P("u")!=0 |
| 736 | 736 | && (goodCaptcha = captcha_is_correct()) |
| 737 | 737 | ){ |
| @@ -840,11 +840,11 @@ | ||
| 840 | 840 | */ |
| 841 | 841 | void whistory_page(void){ |
| 842 | 842 | Stmt q; |
| 843 | 843 | const char *zPageName; |
| 844 | 844 | login_check_credentials(); |
| 845 | - if( !g.perm.Hyperlink ){ login_needed(); return; } | |
| 845 | + if( !g.perm.Hyperlink ){ login_needed(g.anon.Hyperlink); return; } | |
| 846 | 846 | zPageName = PD("name",""); |
| 847 | 847 | style_header("History Of %s", zPageName); |
| 848 | 848 | |
| 849 | 849 | db_prepare(&q, "%s AND event.objid IN " |
| 850 | 850 | " (SELECT rid FROM tagxref WHERE tagid=" |
| @@ -872,11 +872,11 @@ | ||
| 872 | 872 | Blob w1, w2, d; |
| 873 | 873 | u64 diffFlags; |
| 874 | 874 | |
| 875 | 875 | login_check_credentials(); |
| 876 | 876 | rid1 = atoi(PD("a","0")); |
| 877 | - if( !g.perm.Hyperlink ){ login_needed(); return; } | |
| 877 | + if( !g.perm.Hyperlink ){ login_needed(g.anon.Hyperlink); return; } | |
| 878 | 878 | if( rid1==0 ) fossil_redirect_home(); |
| 879 | 879 | rid2 = atoi(PD("b","0")); |
| 880 | 880 | zPageName = PD("name",""); |
| 881 | 881 | style_header("Changes To %s", zPageName); |
| 882 | 882 | |
| @@ -935,11 +935,11 @@ | ||
| 935 | 935 | void wcontent_page(void){ |
| 936 | 936 | Stmt q; |
| 937 | 937 | int showAll = P("all")!=0; |
| 938 | 938 | |
| 939 | 939 | login_check_credentials(); |
| 940 | - if( !g.perm.RdWiki ){ login_needed(); return; } | |
| 940 | + if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } | |
| 941 | 941 | style_header("Available Wiki Pages"); |
| 942 | 942 | if( showAll ){ |
| 943 | 943 | style_submenu_element("Active", "Only Active Pages", "%s/wcontent", g.zTop); |
| 944 | 944 | }else{ |
| 945 | 945 | style_submenu_element("All", "All", "%s/wcontent?all=1", g.zTop); |
| @@ -969,11 +969,11 @@ | ||
| 969 | 969 | */ |
| 970 | 970 | void wfind_page(void){ |
| 971 | 971 | Stmt q; |
| 972 | 972 | const char *zTitle; |
| 973 | 973 | login_check_credentials(); |
| 974 | - if( !g.perm.RdWiki ){ login_needed(); return; } | |
| 974 | + if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } | |
| 975 | 975 | zTitle = PD("title","*"); |
| 976 | 976 | style_header("Wiki Pages Found"); |
| 977 | 977 | @ <ul> |
| 978 | 978 | db_prepare(&q, |
| 979 | 979 | "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'" |
| 980 | 980 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | style_submenu_element("List","List","%R/wcontent"); |
| 223 | } |
| 224 | if( (ok & W_HELP)!=0 ){ |
| 225 | style_submenu_element("Help","Help","%R/wikihelp"); |
| 226 | } |
| 227 | if( (ok & W_NEW)!=0 && g.perm.NewWiki ){ |
| 228 | style_submenu_element("New","New","%R/wikinew"); |
| 229 | } |
| 230 | #if 0 |
| 231 | if( (ok & W_BLOG)!=0 |
| 232 | #endif |
| @@ -239,11 +239,11 @@ | |
| 239 | ** WEBPAGE: wikihelp |
| 240 | ** A generic landing page for wiki. |
| 241 | */ |
| 242 | void wiki_helppage(void){ |
| 243 | login_check_credentials(); |
| 244 | if( !g.perm.RdWiki ){ login_needed(); return; } |
| 245 | style_header("Wiki Help"); |
| 246 | wiki_standard_submenu(W_ALL_BUT(W_HELP)); |
| 247 | @ <h2>Wiki Links</h2> |
| 248 | @ <ul> |
| 249 | { char *zWikiHomePageName = db_get("index-page",0); |
| @@ -261,19 +261,19 @@ | |
| 261 | @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li> |
| 262 | @ <li> Formatting rules for %z(href("%R/wiki_rules"))Fossil Wiki</a> and for |
| 263 | @ %z(href("%R/md_rules"))Markdown Wiki</a>.</li> |
| 264 | @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a> |
| 265 | @ to experiment.</li> |
| 266 | if( g.perm.NewWiki ){ |
| 267 | @ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li> |
| 268 | if( g.perm.Write ){ |
| 269 | @ <li> Create a %z(href("%R/eventedit"))new blog entry</a>.</li> |
| 270 | } |
| 271 | } |
| 272 | @ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a> |
| 273 | @ available on this server.</li> |
| 274 | if( g.perm.ModWiki ){ |
| 275 | @ <li> %z(href("%R/modreq"))Tend to pending moderation requests</a></li> |
| 276 | } |
| 277 | if( search_restrict(SRCH_WIKI)!=0 ){ |
| 278 | @ <li> %z(href("%R/wikisrch"))Search</a> for wiki pages containing key |
| 279 | @ words</li> |
| @@ -312,11 +312,11 @@ | |
| 312 | const char *zPageName; |
| 313 | const char *zMimetype = 0; |
| 314 | char *zBody = mprintf("%s","<i>Empty Page</i>"); |
| 315 | |
| 316 | login_check_credentials(); |
| 317 | if( !g.perm.RdWiki ){ login_needed(); return; } |
| 318 | zPageName = P("name"); |
| 319 | if( zPageName==0 ){ |
| 320 | if( search_restrict(SRCH_WIKI)!=0 ){ |
| 321 | wiki_srchpage(); |
| 322 | }else{ |
| @@ -355,11 +355,11 @@ | |
| 355 | "%R/wdiff?name=%T&a=%d", zPageName, rid); |
| 356 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 357 | style_submenu_element("Details", "Details", |
| 358 | "%R/info/%s", zUuid); |
| 359 | } |
| 360 | if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){ |
| 361 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 362 | style_submenu_element("Edit", "Edit Wiki Page", |
| 363 | "%s/wikiedit?name=%T&wysiwyg=1", |
| 364 | g.zTop, zPageName); |
| 365 | }else{ |
| @@ -366,16 +366,16 @@ | |
| 366 | style_submenu_element("Edit", "Edit Wiki Page", |
| 367 | "%s/wikiedit?name=%T", |
| 368 | g.zTop, zPageName); |
| 369 | } |
| 370 | } |
| 371 | if( rid && g.perm.ApndWiki && g.perm.Attach ){ |
| 372 | style_submenu_element("Attach", "Add An Attachment", |
| 373 | "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T", |
| 374 | g.zTop, zPageName, g.zTop, zPageName); |
| 375 | } |
| 376 | if( rid && g.perm.ApndWiki ){ |
| 377 | style_submenu_element("Append", "Add A Comment", |
| 378 | "%s/wikiappend?name=%T&mimetype=%s", |
| 379 | g.zTop, zPageName, zMimetype); |
| 380 | } |
| 381 | if( g.perm.Hyperlink ){ |
| @@ -485,11 +485,11 @@ | |
| 485 | zPageName = PD("name",""); |
| 486 | if( check_name(zPageName) ) return; |
| 487 | isSandbox = is_sandbox(zPageName); |
| 488 | if( isSandbox ){ |
| 489 | if( !g.perm.WrWiki ){ |
| 490 | login_needed(); |
| 491 | return; |
| 492 | } |
| 493 | if( zBody==0 ){ |
| 494 | zBody = db_get("sandbox",""); |
| 495 | zMimetype = db_get("sandbox-mimetype","text/x-fossil-wiki"); |
| @@ -501,11 +501,11 @@ | |
| 501 | " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" |
| 502 | " ORDER BY mtime DESC", zTag |
| 503 | ); |
| 504 | free(zTag); |
| 505 | if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){ |
| 506 | login_needed(); |
| 507 | return; |
| 508 | } |
| 509 | if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){ |
| 510 | zBody = pWiki->zWiki; |
| 511 | zMimetype = pWiki->zMimetype; |
| @@ -625,11 +625,11 @@ | |
| 625 | void wikinew_page(void){ |
| 626 | const char *zName; |
| 627 | const char *zMimetype; |
| 628 | login_check_credentials(); |
| 629 | if( !g.perm.NewWiki ){ |
| 630 | login_needed(); |
| 631 | return; |
| 632 | } |
| 633 | zName = PD("name",""); |
| 634 | zMimetype = wiki_filter_mimetypes(P("mimetype")); |
| 635 | if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){ |
| @@ -727,11 +727,11 @@ | |
| 727 | fossil_redirect_home(); |
| 728 | return; |
| 729 | } |
| 730 | } |
| 731 | if( !g.perm.ApndWiki ){ |
| 732 | login_needed(); |
| 733 | return; |
| 734 | } |
| 735 | if( P("submit")!=0 && P("r")!=0 && P("u")!=0 |
| 736 | && (goodCaptcha = captcha_is_correct()) |
| 737 | ){ |
| @@ -840,11 +840,11 @@ | |
| 840 | */ |
| 841 | void whistory_page(void){ |
| 842 | Stmt q; |
| 843 | const char *zPageName; |
| 844 | login_check_credentials(); |
| 845 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 846 | zPageName = PD("name",""); |
| 847 | style_header("History Of %s", zPageName); |
| 848 | |
| 849 | db_prepare(&q, "%s AND event.objid IN " |
| 850 | " (SELECT rid FROM tagxref WHERE tagid=" |
| @@ -872,11 +872,11 @@ | |
| 872 | Blob w1, w2, d; |
| 873 | u64 diffFlags; |
| 874 | |
| 875 | login_check_credentials(); |
| 876 | rid1 = atoi(PD("a","0")); |
| 877 | if( !g.perm.Hyperlink ){ login_needed(); return; } |
| 878 | if( rid1==0 ) fossil_redirect_home(); |
| 879 | rid2 = atoi(PD("b","0")); |
| 880 | zPageName = PD("name",""); |
| 881 | style_header("Changes To %s", zPageName); |
| 882 | |
| @@ -935,11 +935,11 @@ | |
| 935 | void wcontent_page(void){ |
| 936 | Stmt q; |
| 937 | int showAll = P("all")!=0; |
| 938 | |
| 939 | login_check_credentials(); |
| 940 | if( !g.perm.RdWiki ){ login_needed(); return; } |
| 941 | style_header("Available Wiki Pages"); |
| 942 | if( showAll ){ |
| 943 | style_submenu_element("Active", "Only Active Pages", "%s/wcontent", g.zTop); |
| 944 | }else{ |
| 945 | style_submenu_element("All", "All", "%s/wcontent?all=1", g.zTop); |
| @@ -969,11 +969,11 @@ | |
| 969 | */ |
| 970 | void wfind_page(void){ |
| 971 | Stmt q; |
| 972 | const char *zTitle; |
| 973 | login_check_credentials(); |
| 974 | if( !g.perm.RdWiki ){ login_needed(); return; } |
| 975 | zTitle = PD("title","*"); |
| 976 | style_header("Wiki Pages Found"); |
| 977 | @ <ul> |
| 978 | db_prepare(&q, |
| 979 | "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'" |
| 980 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -222,11 +222,11 @@ | |
| 222 | style_submenu_element("List","List","%R/wcontent"); |
| 223 | } |
| 224 | if( (ok & W_HELP)!=0 ){ |
| 225 | style_submenu_element("Help","Help","%R/wikihelp"); |
| 226 | } |
| 227 | if( (ok & W_NEW)!=0 && g.anon.NewWiki ){ |
| 228 | style_submenu_element("New","New","%R/wikinew"); |
| 229 | } |
| 230 | #if 0 |
| 231 | if( (ok & W_BLOG)!=0 |
| 232 | #endif |
| @@ -239,11 +239,11 @@ | |
| 239 | ** WEBPAGE: wikihelp |
| 240 | ** A generic landing page for wiki. |
| 241 | */ |
| 242 | void wiki_helppage(void){ |
| 243 | login_check_credentials(); |
| 244 | if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } |
| 245 | style_header("Wiki Help"); |
| 246 | wiki_standard_submenu(W_ALL_BUT(W_HELP)); |
| 247 | @ <h2>Wiki Links</h2> |
| 248 | @ <ul> |
| 249 | { char *zWikiHomePageName = db_get("index-page",0); |
| @@ -261,19 +261,19 @@ | |
| 261 | @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li> |
| 262 | @ <li> Formatting rules for %z(href("%R/wiki_rules"))Fossil Wiki</a> and for |
| 263 | @ %z(href("%R/md_rules"))Markdown Wiki</a>.</li> |
| 264 | @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a> |
| 265 | @ to experiment.</li> |
| 266 | if( g.anon.NewWiki ){ |
| 267 | @ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li> |
| 268 | if( g.anon.Write ){ |
| 269 | @ <li> Create a %z(href("%R/eventedit"))new tech-note</a>.</li> |
| 270 | } |
| 271 | } |
| 272 | @ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a> |
| 273 | @ available on this server.</li> |
| 274 | if( g.anon.ModWiki ){ |
| 275 | @ <li> %z(href("%R/modreq"))Tend to pending moderation requests</a></li> |
| 276 | } |
| 277 | if( search_restrict(SRCH_WIKI)!=0 ){ |
| 278 | @ <li> %z(href("%R/wikisrch"))Search</a> for wiki pages containing key |
| 279 | @ words</li> |
| @@ -312,11 +312,11 @@ | |
| 312 | const char *zPageName; |
| 313 | const char *zMimetype = 0; |
| 314 | char *zBody = mprintf("%s","<i>Empty Page</i>"); |
| 315 | |
| 316 | login_check_credentials(); |
| 317 | if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } |
| 318 | zPageName = P("name"); |
| 319 | if( zPageName==0 ){ |
| 320 | if( search_restrict(SRCH_WIKI)!=0 ){ |
| 321 | wiki_srchpage(); |
| 322 | }else{ |
| @@ -355,11 +355,11 @@ | |
| 355 | "%R/wdiff?name=%T&a=%d", zPageName, rid); |
| 356 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 357 | style_submenu_element("Details", "Details", |
| 358 | "%R/info/%s", zUuid); |
| 359 | } |
| 360 | if( (rid && g.anon.WrWiki) || (!rid && g.anon.NewWiki) ){ |
| 361 | if( db_get_boolean("wysiwyg-wiki", 0) ){ |
| 362 | style_submenu_element("Edit", "Edit Wiki Page", |
| 363 | "%s/wikiedit?name=%T&wysiwyg=1", |
| 364 | g.zTop, zPageName); |
| 365 | }else{ |
| @@ -366,16 +366,16 @@ | |
| 366 | style_submenu_element("Edit", "Edit Wiki Page", |
| 367 | "%s/wikiedit?name=%T", |
| 368 | g.zTop, zPageName); |
| 369 | } |
| 370 | } |
| 371 | if( rid && g.anon.ApndWiki && g.anon.Attach ){ |
| 372 | style_submenu_element("Attach", "Add An Attachment", |
| 373 | "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T", |
| 374 | g.zTop, zPageName, g.zTop, zPageName); |
| 375 | } |
| 376 | if( rid && g.anon.ApndWiki ){ |
| 377 | style_submenu_element("Append", "Add A Comment", |
| 378 | "%s/wikiappend?name=%T&mimetype=%s", |
| 379 | g.zTop, zPageName, zMimetype); |
| 380 | } |
| 381 | if( g.perm.Hyperlink ){ |
| @@ -485,11 +485,11 @@ | |
| 485 | zPageName = PD("name",""); |
| 486 | if( check_name(zPageName) ) return; |
| 487 | isSandbox = is_sandbox(zPageName); |
| 488 | if( isSandbox ){ |
| 489 | if( !g.perm.WrWiki ){ |
| 490 | login_needed(g.anon.WrWiki); |
| 491 | return; |
| 492 | } |
| 493 | if( zBody==0 ){ |
| 494 | zBody = db_get("sandbox",""); |
| 495 | zMimetype = db_get("sandbox-mimetype","text/x-fossil-wiki"); |
| @@ -501,11 +501,11 @@ | |
| 501 | " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" |
| 502 | " ORDER BY mtime DESC", zTag |
| 503 | ); |
| 504 | free(zTag); |
| 505 | if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){ |
| 506 | login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki); |
| 507 | return; |
| 508 | } |
| 509 | if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){ |
| 510 | zBody = pWiki->zWiki; |
| 511 | zMimetype = pWiki->zMimetype; |
| @@ -625,11 +625,11 @@ | |
| 625 | void wikinew_page(void){ |
| 626 | const char *zName; |
| 627 | const char *zMimetype; |
| 628 | login_check_credentials(); |
| 629 | if( !g.perm.NewWiki ){ |
| 630 | login_needed(g.anon.NewWiki); |
| 631 | return; |
| 632 | } |
| 633 | zName = PD("name",""); |
| 634 | zMimetype = wiki_filter_mimetypes(P("mimetype")); |
| 635 | if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){ |
| @@ -727,11 +727,11 @@ | |
| 727 | fossil_redirect_home(); |
| 728 | return; |
| 729 | } |
| 730 | } |
| 731 | if( !g.perm.ApndWiki ){ |
| 732 | login_needed(g.anon.ApndWiki); |
| 733 | return; |
| 734 | } |
| 735 | if( P("submit")!=0 && P("r")!=0 && P("u")!=0 |
| 736 | && (goodCaptcha = captcha_is_correct()) |
| 737 | ){ |
| @@ -840,11 +840,11 @@ | |
| 840 | */ |
| 841 | void whistory_page(void){ |
| 842 | Stmt q; |
| 843 | const char *zPageName; |
| 844 | login_check_credentials(); |
| 845 | if( !g.perm.Hyperlink ){ login_needed(g.anon.Hyperlink); return; } |
| 846 | zPageName = PD("name",""); |
| 847 | style_header("History Of %s", zPageName); |
| 848 | |
| 849 | db_prepare(&q, "%s AND event.objid IN " |
| 850 | " (SELECT rid FROM tagxref WHERE tagid=" |
| @@ -872,11 +872,11 @@ | |
| 872 | Blob w1, w2, d; |
| 873 | u64 diffFlags; |
| 874 | |
| 875 | login_check_credentials(); |
| 876 | rid1 = atoi(PD("a","0")); |
| 877 | if( !g.perm.Hyperlink ){ login_needed(g.anon.Hyperlink); return; } |
| 878 | if( rid1==0 ) fossil_redirect_home(); |
| 879 | rid2 = atoi(PD("b","0")); |
| 880 | zPageName = PD("name",""); |
| 881 | style_header("Changes To %s", zPageName); |
| 882 | |
| @@ -935,11 +935,11 @@ | |
| 935 | void wcontent_page(void){ |
| 936 | Stmt q; |
| 937 | int showAll = P("all")!=0; |
| 938 | |
| 939 | login_check_credentials(); |
| 940 | if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } |
| 941 | style_header("Available Wiki Pages"); |
| 942 | if( showAll ){ |
| 943 | style_submenu_element("Active", "Only Active Pages", "%s/wcontent", g.zTop); |
| 944 | }else{ |
| 945 | style_submenu_element("All", "All", "%s/wcontent?all=1", g.zTop); |
| @@ -969,11 +969,11 @@ | |
| 969 | */ |
| 970 | void wfind_page(void){ |
| 971 | Stmt q; |
| 972 | const char *zTitle; |
| 973 | login_check_credentials(); |
| 974 | if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } |
| 975 | zTitle = PD("title","*"); |
| 976 | style_header("Wiki Pages Found"); |
| 977 | @ <ul> |
| 978 | db_prepare(&q, |
| 979 | "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'" |
| 980 |
+4
-2
| --- src/xfersetup.c | ||
| +++ src/xfersetup.c | ||
| @@ -27,11 +27,12 @@ | ||
| 27 | 27 | ** WEBPAGE: xfersetup |
| 28 | 28 | */ |
| 29 | 29 | void xfersetup_page(void){ |
| 30 | 30 | login_check_credentials(); |
| 31 | 31 | if( !g.perm.Setup ){ |
| 32 | - login_needed(); | |
| 32 | + login_needed(0); | |
| 33 | + return; | |
| 33 | 34 | } |
| 34 | 35 | |
| 35 | 36 | style_header("Transfer Setup"); |
| 36 | 37 | |
| 37 | 38 | @ <table border="0" cellspacing="20"> |
| @@ -104,11 +105,12 @@ | ||
| 104 | 105 | const char *z; |
| 105 | 106 | int isSubmit; |
| 106 | 107 | |
| 107 | 108 | login_check_credentials(); |
| 108 | 109 | if( !g.perm.Setup ){ |
| 109 | - login_needed(); | |
| 110 | + login_needed(0); | |
| 111 | + return; | |
| 110 | 112 | } |
| 111 | 113 | if( P("setup") ){ |
| 112 | 114 | cgi_redirect("xfersetup"); |
| 113 | 115 | } |
| 114 | 116 | isSubmit = P("submit")!=0; |
| 115 | 117 |
| --- src/xfersetup.c | |
| +++ src/xfersetup.c | |
| @@ -27,11 +27,12 @@ | |
| 27 | ** WEBPAGE: xfersetup |
| 28 | */ |
| 29 | void xfersetup_page(void){ |
| 30 | login_check_credentials(); |
| 31 | if( !g.perm.Setup ){ |
| 32 | login_needed(); |
| 33 | } |
| 34 | |
| 35 | style_header("Transfer Setup"); |
| 36 | |
| 37 | @ <table border="0" cellspacing="20"> |
| @@ -104,11 +105,12 @@ | |
| 104 | const char *z; |
| 105 | int isSubmit; |
| 106 | |
| 107 | login_check_credentials(); |
| 108 | if( !g.perm.Setup ){ |
| 109 | login_needed(); |
| 110 | } |
| 111 | if( P("setup") ){ |
| 112 | cgi_redirect("xfersetup"); |
| 113 | } |
| 114 | isSubmit = P("submit")!=0; |
| 115 |
| --- src/xfersetup.c | |
| +++ src/xfersetup.c | |
| @@ -27,11 +27,12 @@ | |
| 27 | ** WEBPAGE: xfersetup |
| 28 | */ |
| 29 | void xfersetup_page(void){ |
| 30 | login_check_credentials(); |
| 31 | if( !g.perm.Setup ){ |
| 32 | login_needed(0); |
| 33 | return; |
| 34 | } |
| 35 | |
| 36 | style_header("Transfer Setup"); |
| 37 | |
| 38 | @ <table border="0" cellspacing="20"> |
| @@ -104,11 +105,12 @@ | |
| 105 | const char *z; |
| 106 | int isSubmit; |
| 107 | |
| 108 | login_check_credentials(); |
| 109 | if( !g.perm.Setup ){ |
| 110 | login_needed(0); |
| 111 | return; |
| 112 | } |
| 113 | if( P("setup") ){ |
| 114 | cgi_redirect("xfersetup"); |
| 115 | } |
| 116 | isSubmit = P("submit")!=0; |
| 117 |
+12
-1
| --- src/zip.c | ||
| +++ src/zip.c | ||
| @@ -448,11 +448,11 @@ | ||
| 448 | 448 | int nName, nRid; |
| 449 | 449 | Blob zip; |
| 450 | 450 | char *zKey; |
| 451 | 451 | |
| 452 | 452 | login_check_credentials(); |
| 453 | - if( !g.perm.Zip ){ login_needed(); return; } | |
| 453 | + if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; } | |
| 454 | 454 | load_control(); |
| 455 | 455 | zName = mprintf("%s", PD("name","")); |
| 456 | 456 | nName = strlen(zName); |
| 457 | 457 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 458 | 458 | nRid = strlen(zRid); |
| @@ -472,10 +472,21 @@ | ||
| 472 | 472 | } |
| 473 | 473 | rid = name_to_typed_rid(nRid?zRid:zName,"ci"); |
| 474 | 474 | if( rid==0 ){ |
| 475 | 475 | @ Not found |
| 476 | 476 | return; |
| 477 | + } | |
| 478 | + if( referred_from_login() ){ | |
| 479 | + style_header("ZIP Archive Download"); | |
| 480 | + @ <form action='%R/zip'> | |
| 481 | + cgi_query_parameters_to_hidden(); | |
| 482 | + @ <p>ZIP Archive named <b>%h(zName).zip</b> holding the content | |
| 483 | + @ of check-in <b>%h(zRid)</b>: | |
| 484 | + @ <input type="submit" value="Download" /> | |
| 485 | + @ </form> | |
| 486 | + style_footer(); | |
| 487 | + return; | |
| 477 | 488 | } |
| 478 | 489 | if( nRid==0 && nName>10 ) zName[10] = 0; |
| 479 | 490 | zKey = db_text(0, "SELECT '/zip/'||uuid||'/%q' FROM blob WHERE rid=%d",zName,rid); |
| 480 | 491 | blob_zero(&zip); |
| 481 | 492 | if( cache_read(&zip, zKey)==0 ){ |
| 482 | 493 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -448,11 +448,11 @@ | |
| 448 | int nName, nRid; |
| 449 | Blob zip; |
| 450 | char *zKey; |
| 451 | |
| 452 | login_check_credentials(); |
| 453 | if( !g.perm.Zip ){ login_needed(); return; } |
| 454 | load_control(); |
| 455 | zName = mprintf("%s", PD("name","")); |
| 456 | nName = strlen(zName); |
| 457 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 458 | nRid = strlen(zRid); |
| @@ -472,10 +472,21 @@ | |
| 472 | } |
| 473 | rid = name_to_typed_rid(nRid?zRid:zName,"ci"); |
| 474 | if( rid==0 ){ |
| 475 | @ Not found |
| 476 | return; |
| 477 | } |
| 478 | if( nRid==0 && nName>10 ) zName[10] = 0; |
| 479 | zKey = db_text(0, "SELECT '/zip/'||uuid||'/%q' FROM blob WHERE rid=%d",zName,rid); |
| 480 | blob_zero(&zip); |
| 481 | if( cache_read(&zip, zKey)==0 ){ |
| 482 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -448,11 +448,11 @@ | |
| 448 | int nName, nRid; |
| 449 | Blob zip; |
| 450 | char *zKey; |
| 451 | |
| 452 | login_check_credentials(); |
| 453 | if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; } |
| 454 | load_control(); |
| 455 | zName = mprintf("%s", PD("name","")); |
| 456 | nName = strlen(zName); |
| 457 | zRid = mprintf("%s", PD("uuid","trunk")); |
| 458 | nRid = strlen(zRid); |
| @@ -472,10 +472,21 @@ | |
| 472 | } |
| 473 | rid = name_to_typed_rid(nRid?zRid:zName,"ci"); |
| 474 | if( rid==0 ){ |
| 475 | @ Not found |
| 476 | return; |
| 477 | } |
| 478 | if( referred_from_login() ){ |
| 479 | style_header("ZIP Archive Download"); |
| 480 | @ <form action='%R/zip'> |
| 481 | cgi_query_parameters_to_hidden(); |
| 482 | @ <p>ZIP Archive named <b>%h(zName).zip</b> holding the content |
| 483 | @ of check-in <b>%h(zRid)</b>: |
| 484 | @ <input type="submit" value="Download" /> |
| 485 | @ </form> |
| 486 | style_footer(); |
| 487 | return; |
| 488 | } |
| 489 | if( nRid==0 && nName>10 ) zName[10] = 0; |
| 490 | zKey = db_text(0, "SELECT '/zip/'||uuid||'/%q' FROM blob WHERE rid=%d",zName,rid); |
| 491 | blob_zero(&zip); |
| 492 | if( cache_read(&zip, zKey)==0 ){ |
| 493 |