Fossil SCM

When the user is "nobody", make the g.anon permission vector for "anonymous" available in addition to g.perm. Hyperlinks to pages that would be available to anonymous are shown rather than suppressed. When permission is denied and control jumps to login_needed() a new flag shows whether or not logging in as "anonymous" would help. Work in progress.

drh 2015-02-14 12:24 trunk
Commit 2f50d427a9482d4ccac4a1e42385905115b70338
+22 -10
--- src/attach.c
+++ src/attach.c
@@ -48,19 +48,22 @@
4848
" (SELECT uuid FROM blob WHERE rid=attachid), attachid"
4949
" FROM attachment",
5050
timeline_utc()
5151
);
5252
if( zPage ){
53
- if( g.perm.RdWiki==0 ) login_needed();
53
+ if( g.perm.RdWiki==0 ){ login_needed(g.anon.RdWiki); return; }
5454
style_header("Attachments To %h", zPage);
5555
blob_append_sql(&sql, " WHERE target=%Q", zPage);
5656
}else if( zTkt ){
57
- if( g.perm.RdTkt==0 ) login_needed();
57
+ if( g.perm.RdTkt==0 ){ login_needed(g.anon.RdTkt); return; }
5858
style_header("Attachments To Ticket %S", zTkt);
5959
blob_append_sql(&sql, " WHERE target GLOB '%q*'", zTkt);
6060
}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
+ }
6265
style_header("All Attachments");
6366
}
6467
blob_append_sql(&sql, " ORDER BY mtime DESC");
6568
db_prepare(&q, "%s", blob_sql_text(&sql));
6669
@ <ol>
@@ -150,14 +153,14 @@
150153
151154
if( zPage && zTkt ) zTkt = 0;
152155
if( zFile==0 ) fossil_redirect_home();
153156
login_check_credentials();
154157
if( zPage ){
155
- if( g.perm.RdWiki==0 ) login_needed();
158
+ if( g.perm.RdWiki==0 ){ login_needed(g.anon.RdWiki); return; }
156159
zTarget = zPage;
157160
}else if( zTkt ){
158
- if( g.perm.RdTkt==0 ) login_needed();
161
+ if( g.perm.RdTkt==0 ){ login_needed(g.anon.RdTkt); return; }
159162
zTarget = zTkt;
160163
}else{
161164
fossil_redirect_home();
162165
}
163166
if( attachid>0 ){
@@ -243,19 +246,25 @@
243246
if( P("cancel") ) cgi_redirect(zFrom);
244247
if( zPage && zTkt ) fossil_redirect_home();
245248
if( zPage==0 && zTkt==0 ) fossil_redirect_home();
246249
login_check_credentials();
247250
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
+ }
249255
if( !db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'", zPage) ){
250256
fossil_redirect_home();
251257
}
252258
zTarget = zPage;
253259
zTargetType = mprintf("Wiki Page <a href=\"%R/wiki?name=%h\">%h</a>",
254260
zPage, zPage);
255261
}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
+ }
257266
if( !db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'", zTkt) ){
258267
zTkt = db_text(0, "SELECT substr(tagname,5) FROM tag"
259268
" WHERE tagname GLOB 'tkt-%q*'", zTkt);
260269
if( zTkt==0 ) fossil_redirect_home();
261270
}
@@ -369,11 +378,14 @@
369378
Blob attach; /* Content of the attachment */
370379
int fShowContent = 0;
371380
const char *zLn = P("ln");
372381
373382
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
+ }
375387
rid = name_to_rid_www("name");
376388
if( rid==0 ){ fossil_redirect_home(); }
377389
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
378390
#if 0
379391
/* Shunning here needs to get both the attachment control artifact and
@@ -399,17 +411,17 @@
399411
fShowContent = zMime ? strncmp(zMime,"text/", 5)==0 : 0;
400412
if( validate16(zTarget, strlen(zTarget))
401413
&& db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%q'", zTarget)
402414
){
403415
zTktUuid = zTarget;
404
- if( !g.perm.RdTkt ){ login_needed(); return; }
416
+ if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
405417
if( g.perm.WrTkt ){
406418
style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
407419
}
408420
}else if( db_exists("SELECT 1 FROM tag WHERE tagname='wiki-%q'",zTarget) ){
409421
zWikiName = zTarget;
410
- if( !g.perm.RdWiki ){ login_needed(); return; }
422
+ if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
411423
if( g.perm.WrWiki ){
412424
style_submenu_element("Delete","Delete","%R/ainfo/%s?del", zUuid);
413425
}
414426
}
415427
zDate = db_text(0, "SELECT datetime(%.12f)", pAttach->rDate);
416428
--- 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 @@
339339
*/
340340
static void new_brlist_page(void){
341341
Stmt q;
342342
double rNow;
343343
login_check_credentials();
344
- if( !g.perm.Read ){ login_needed(); return; }
344
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
345345
style_header("Branches");
346346
style_adunit_config(ADUNIT_RIGHT_OK);
347347
login_anonymous_available();
348348
349349
db_prepare(&q, brlistQuery/*works-like:""*/);
@@ -408,11 +408,11 @@
408408
if( showClosed==0 && showAll==0 && showOpen==0 && colorTest==0 ){
409409
new_brlist_page();
410410
return;
411411
}
412412
login_check_credentials();
413
- if( !g.perm.Read ){ login_needed(); return; }
413
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
414414
if( colorTest ){
415415
showClosed = 0;
416416
showAll = 1;
417417
}
418418
if( showAll ) brFlags = BRL_BOTH;
@@ -515,11 +515,11 @@
515515
*/
516516
void brtimeline_page(void){
517517
Stmt q;
518518
519519
login_check_credentials();
520
- if( !g.perm.Read ){ login_needed(); return; }
520
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
521521
522522
style_header("Branches");
523523
style_submenu_element("List", "List", "brlist");
524524
login_anonymous_available();
525525
@ <h2>The initial check-in for each branch:</h2>
526526
--- 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 @@
130130
int linkTip = 1;
131131
HQuery sURI;
132132
133133
if( strcmp(PD("type","flat"),"tree")==0 ){ page_tree(); return; }
134134
login_check_credentials();
135
- if( !g.perm.Read ){ login_needed(); return; }
135
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
136136
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
137137
style_header("File List");
138138
style_adunit_config(ADUNIT_RIGHT_OK);
139139
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
140140
pathelementFunc, 0, 0);
@@ -542,11 +542,11 @@
542542
char *zProjectName = db_get("project-name", 0);
543543
544544
if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; }
545545
memset(&sTree, 0, sizeof(sTree));
546546
login_check_credentials();
547
- if( !g.perm.Read ){ login_needed(); return; }
547
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
548548
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
549549
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
550550
pathelementFunc, 0, 0);
551551
url_initialize(&sURI, "tree");
552552
cgi_query_parameters_to_url(&sURI);
@@ -1002,11 +1002,11 @@
10021002
const char *zNow; /* Time of checkin */
10031003
int showId = PB("showid");
10041004
Stmt q1, q2;
10051005
double baseTime;
10061006
login_check_credentials();
1007
- if( !g.perm.Read ){ login_needed(); return; }
1007
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
10081008
zName = P("name");
10091009
if( zName==0 ) zName = "tip";
10101010
rid = symbolic_name_to_rid(zName, "ci");
10111011
if( rid==0 ){
10121012
fossil_fatal("not a valid check-in: %s", zName);
10131013
--- 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 @@
330330
sqlite3 *db;
331331
sqlite3_stmt *pStmt;
332332
char zBuf[100];
333333
334334
login_check_credentials();
335
- if( !g.perm.Setup ){ login_needed(); return; }
335
+ if( !g.perm.Setup ){ login_needed(0); return; }
336336
style_header("Web Cache Status");
337337
db = cacheOpen(0);
338338
if( db==0 ){
339339
@ The web-page cache is disabled for this repository
340340
}else{
@@ -378,11 +378,11 @@
378378
void cache_getpage(void){
379379
const char *zKey;
380380
Blob content;
381381
382382
login_check_credentials();
383
- if( !g.perm.Setup ){ login_needed(); return; }
383
+ if( !g.perm.Setup ){ login_needed(0); return; }
384384
zKey = PD("key","");
385385
blob_zero(&content);
386386
if( cache_read(&content, zKey)==0 ){
387387
style_header("Cache Download Error");
388388
@ The cache does not contain any entry with this key: "%h(zKey)"
389389
--- 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
--- src/descendants.c
+++ src/descendants.c
@@ -439,11 +439,11 @@
439439
Stmt q;
440440
int showAll = P("all")!=0;
441441
int showClosed = P("closed")!=0;
442442
443443
login_check_credentials();
444
- if( !g.perm.Read ){ login_needed(); return; }
444
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
445445
446446
if( !showAll ){
447447
style_submenu_element("All", "All", "leaves?all");
448448
}
449449
if( !showClosed ){
450450
--- 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 @@
22342234
int bBlame = g.zPath[0]!='a';/* True for BLAME output. False for ANNOTATE. */
22352235
22362236
/* Gather query parameters */
22372237
showLog = atoi(PD("log","1"));
22382238
login_check_credentials();
2239
- if( !g.perm.Read ){ login_needed(); return; }
2239
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
22402240
if( exclude_spiders("annotate") ) return;
22412241
load_control();
22422242
mid = name_to_typed_rid(PD("checkin","0"),"ci");
22432243
zFilename = P("filename");
22442244
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
22452245
--- 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 @@
841841
*/
842842
void vpatch_page(void){
843843
const char *zFrom = P("from");
844844
const char *zTo = P("to");
845845
login_check_credentials();
846
- if( !g.perm.Read ){ login_needed(); return; }
846
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
847847
if( zFrom==0 || zTo==0 ) fossil_redirect_home();
848848
849849
cgi_set_content_type("text/plain");
850850
diff_all_two_versions(zFrom, zTo, 0, 0, 0, DIFF_VERBOSE);
851851
}
852852
--- 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 @@
543543
static const char *const azSuffix[] = {
544544
"index.html", "index.wiki", "index.md"
545545
};
546546
547547
login_check_credentials();
548
- if( !g.perm.Read ){ login_needed(); return; }
548
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
549549
blob_init(&title, 0, 0);
550550
db_begin_transaction();
551551
while( rid==0 && (++nMiss)<=ArraySize(azSuffix) ){
552552
zName = PD("name", "tip/index.wiki");
553553
for(i=0; zName[i] && zName[i]!='/'; i++){}
554554
--- 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 @@
6969
7070
/* wiki-read privilege is needed in order to read events.
7171
*/
7272
login_check_credentials();
7373
if( !g.perm.RdWiki ){
74
- login_needed();
74
+ login_needed(g.anon.RdWiki);
7575
return;
7676
}
7777
7878
zEventId = P("name");
7979
if( zEventId==0 ){ fossil_redirect_home(); return; }
@@ -233,11 +233,11 @@
233233
234234
/* Need both check-in and wiki-write or wiki-create privileges in order
235235
** to edit/create an event.
236236
*/
237237
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));
239239
return;
240240
}
241241
242242
/* Figure out the color */
243243
if( rid ){
244244
--- 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 @@
305305
int uBg = P("ubg")!=0;
306306
int fDebug = atoi(PD("debug","0"));
307307
int fShowId = P("showid")!=0;
308308
309309
login_check_credentials();
310
- if( !g.perm.Read ){ login_needed(); return; }
310
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
311311
style_header("File History");
312312
login_anonymous_available();
313313
url_initialize(&url, "finfo");
314314
if( brBg ) url_add_parameter(&url, "brbg", 0);
315315
if( uBg ) url_add_parameter(&url, "ubg", 0);
316316
--- 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 @@
527527
const char *zW; /* URL param for ignoring whitespace */
528528
const char *zPage = "vinfo"; /* Page that shows diffs */
529529
const char *zPageHide = "ci"; /* Page that hides diffs */
530530
531531
login_check_credentials();
532
- if( !g.perm.Read ){ login_needed(); return; }
532
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
533533
zName = P("name");
534534
rid = name_to_rid_www("name");
535535
if( rid==0 ){
536536
style_header("Check-in Information Error");
537537
@ No such object: %h(g.argv[2])
@@ -657,11 +657,11 @@
657657
}
658658
db_finalize(&q2);
659659
660660
661661
/* The Download: line */
662
- if( g.perm.Zip ){
662
+ if( g.perm.Zip || g.anon.Zip ){
663663
char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s",
664664
zPJ, zUuid, zUuid);
665665
@ </td></tr>
666666
@ <tr><th>Downloads:</th><td>
667667
@ %z(href("%s",zUrl))Tarball</a>
@@ -674,11 +674,11 @@
674674
@ <td>
675675
@ %z(href("%R/tree?ci=%!S",zUuid))files</a>
676676
@ | %z(href("%R/fileage?name=%!S",zUuid))file ages</a>
677677
@ | %z(href("%R/tree?nofiles&type=tree&ci=%!S",zUuid))folders</a>
678678
@ | %z(href("%R/artifact/%!S",zUuid))manifest</a>
679
- if( g.perm.Write ){
679
+ if( g.perm.Write || g.anon.Write ){
680680
@ | %z(href("%R/ci_edit?r=%!S",zUuid))edit</a>
681681
}
682682
@ </td>
683683
@ </tr>
684684
blob_reset(&projName);
@@ -773,11 +773,11 @@
773773
Blob wiki;
774774
int modPending;
775775
const char *zModAction;
776776
777777
login_check_credentials();
778
- if( !g.perm.RdWiki ){ login_needed(); return; }
778
+ if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
779779
rid = name_to_rid_www("name");
780780
if( rid==0 || (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))==0 ){
781781
style_header("Wiki Page Information Error");
782782
@ No such object: %h(P("name"))
783783
style_footer();
@@ -991,11 +991,11 @@
991991
const char *zW;
992992
const char *zVerbose;
993993
const char *zGlob;
994994
ReCompiled *pRe = 0;
995995
login_check_credentials();
996
- if( !g.perm.Read ){ login_needed(); return; }
996
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
997997
login_anonymous_available();
998998
zRe = P("regex");
999999
if( zRe ) re_compile(&pRe, zRe, 0);
10001000
zBranch = P("branch");
10011001
if( zBranch && zBranch[0] ){
@@ -1363,17 +1363,17 @@
13631363
}else{
13641364
@ Attachment "%h(zFilename)" to
13651365
}
13661366
objType |= OBJTYPE_ATTACHMENT;
13671367
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
1368
- if( g.perm.Hyperlink && g.perm.RdTkt ){
1368
+ if( g.perm.Hyperlink && (g.perm.RdTkt || g.anon.RdTkt) ){
13691369
@ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>]
13701370
}else{
13711371
@ ticket [%S(zTarget)]
13721372
}
13731373
}else{
1374
- if( g.perm.Hyperlink && g.perm.RdWiki ){
1374
+ if( g.perm.Hyperlink && (g.perm.RdWiki || g.anon.RdWiki) ){
13751375
@ wiki page [%z(href("%R/wiki?name=%t",zTarget))%h(zTarget)</a>]
13761376
}else{
13771377
@ wiki page [%h(zTarget)]
13781378
}
13791379
}
@@ -1421,11 +1421,11 @@
14211421
ReCompiled *pRe = 0;
14221422
u64 diffFlags;
14231423
u32 objdescFlags = 0;
14241424
14251425
login_check_credentials();
1426
- if( !g.perm.Read ){ login_needed(); return; }
1426
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
14271427
v1 = name_to_rid_www("v1");
14281428
v2 = name_to_rid_www("v2");
14291429
if( v1==0 || v2==0 ) fossil_redirect_home();
14301430
zRe = P("regex");
14311431
if( zRe ) re_compile(&pRe, zRe, 0);
@@ -1506,11 +1506,11 @@
15061506
const char *zMime;
15071507
Blob content;
15081508
15091509
rid = name_to_rid_www("name");
15101510
login_check_credentials();
1511
- if( !g.perm.Read ){ login_needed(); return; }
1511
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
15121512
if( rid==0 ) fossil_redirect_home();
15131513
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
15141514
if( fossil_strcmp(P("name"), zUuid)==0 && login_is_nobody() ){
15151515
g.isConst = 1;
15161516
}
@@ -1603,11 +1603,11 @@
16031603
char *zUuid;
16041604
u32 objdescFlags = 0;
16051605
16061606
rid = name_to_rid_www("name");
16071607
login_check_credentials();
1608
- if( !g.perm.Read ){ login_needed(); return; }
1608
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
16091609
if( rid==0 ) fossil_redirect_home();
16101610
if( g.perm.Admin ){
16111611
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
16121612
if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
16131613
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
@@ -1789,11 +1789,11 @@
17891789
if( rid==0 ){
17901790
rid = name_to_rid_www("name");
17911791
}
17921792
17931793
login_check_credentials();
1794
- if( !g.perm.Read ){ login_needed(); return; }
1794
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
17951795
if( rid==0 ) fossil_redirect_home();
17961796
if( g.perm.Admin ){
17971797
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
17981798
if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
17991799
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
@@ -1904,11 +1904,11 @@
19041904
Manifest *pTktChng;
19051905
int modPending;
19061906
const char *zModAction;
19071907
char *zTktTitle;
19081908
login_check_credentials();
1909
- if( !g.perm.RdTkt ){ login_needed(); return; }
1909
+ if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
19101910
rid = name_to_rid_www("name");
19111911
if( rid==0 ){ fossil_redirect_home(); }
19121912
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
19131913
if( g.perm.Admin ){
19141914
if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
@@ -2276,11 +2276,11 @@
22762276
Blob comment;
22772277
char *zBranchName = 0;
22782278
Stmt q;
22792279
22802280
login_check_credentials();
2281
- if( !g.perm.Write ){ login_needed(); return; }
2281
+ if( !g.perm.Write ){ login_needed(g.anon.Write); return; }
22822282
rid = name_to_typed_rid(P("r"), "ci");
22832283
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
22842284
zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
22852285
" FROM event WHERE objid=%d", rid);
22862286
if( zComment==0 ) fossil_redirect_home();
22872287
--- 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.perm.Zip || 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.perm.Write || 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.perm.RdTkt || 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.perm.RdWiki || 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
+105 -86
--- src/login.c
+++ src/login.c
@@ -352,16 +352,12 @@
352352
login_cookie_path(), -86400);
353353
db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, "
354354
" cexpire=0 WHERE uid=%d"
355355
" AND login NOT IN ('anonymous','nobody',"
356356
" '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);
363359
}
364360
}
365361
366362
/*
367363
** Return true if the prefix of zStr matches zPattern. Return false if
@@ -467,11 +463,11 @@
467463
void login_page(void){
468464
const char *zUsername, *zPasswd;
469465
const char *zNew1, *zNew2;
470466
const char *zAnonPw = 0;
471467
const char *zGoto = P("g");
472
- int anonFlag;
468
+ int anonFlag = PB("anon");
473469
char *zErrMsg = "";
474470
int uid; /* User id logged in user */
475471
char *zSha1Pw;
476472
const char *zIpAddr; /* IP address of requestor */
477473
const char *zReferer;
@@ -489,14 +485,14 @@
489485
}
490486
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
491487
constant_time_cmp_function, 0, 0);
492488
zUsername = P("u");
493489
zPasswd = P("p");
494
- anonFlag = P("anon")!=0;
495
- if( P("out")!=0 ){
490
+ if( P("out") ){
496491
login_clear_login_data();
497492
redirect_to_g();
493
+ return;
498494
}
499495
if( g.perm.Password && zPasswd
500496
&& (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0
501497
){
502498
/* The user requests a password change */
@@ -577,12 +573,24 @@
577573
}
578574
}
579575
style_header("Login/Logout");
580576
style_adunit_config(ADUNIT_OFF);
581577
@ %s(zErrMsg)
582
- if( zGoto && P("anon")==0 ){
583
- @ <p>A login is required for <a href="%h(zGoto)">%h(zGoto)</a>.</p>
578
+ if( zGoto ){
579
+ char *zAbbrev = fossil_strdup(zGoto);
580
+ int i;
581
+ for(i=0; zAbbrev[i] && zAbbrev[i]!='?'; i++){}
582
+ zAbbrev[i] = 0;
583
+ if( g.zLogin ){
584
+ @ <p>Use a different login with greater privilege that <b>%h(g.zLogin)</b>
585
+ @ to access <b>%h(zAbbrev)</b>.
586
+ }else if( anonFlag ){
587
+ @ <p>Login as <b>anonymous</b> or any named user
588
+ @ to access page <b>%h(zAbbrev)</b>.
589
+ }else{
590
+ @ <p>Login as a named user to access page <b>%h(zAbbrev)</b>.
591
+ }
584592
}
585593
form_begin(0, "%R/login");
586594
if( zGoto ){
587595
@ <input type="hidden" name="g" value="%h(zGoto)" />
588596
}else if( zReferer && strncmp(g.zBaseURL, zReferer, strlen(g.zBaseURL))==0 ){
@@ -624,20 +632,15 @@
624632
@ form.action = "%h(zSSL)/login";
625633
@ }
626634
}
627635
@ }
628636
@ </script>
629
- if( g.zLogin==0 ){
630
- @ <p>Enter
631
- }else{
637
+ if( g.zLogin ){
632638
@ <p>You are currently logged in as <b>%h(g.zLogin)</b></p>
633
- @ <p>To change your login to a different user, enter
634639
}
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>
640
+ @ <p>By pressing the Login button, you grant permission to store an
641
+ @ access token for this site in a cookie.</p>
639642
if( db_get_boolean("self-register", 0) ){
640643
@ <p>If you do not have an account, you can
641644
@ <a href="%R/register?g=%T(P("G"))">create one</a>.
642645
}
643646
if( zAnonPw ){
@@ -811,10 +814,11 @@
811814
** variables appropriately.
812815
**
813816
** g.userUid Database USER.UID value. Might be -1 for "nobody"
814817
** g.zLogin Database USER.LOGIN value. NULL for user "nobody"
815818
** g.perm Permissions granted to this user
819
+** g.anon Permissions that would be available to anonymous
816820
** g.isHuman True if the user is human, not a spider or robot
817821
**
818822
*/
819823
void login_check_credentials(void){
820824
int uid = 0; /* User id */
@@ -1006,19 +1010,22 @@
10061010
/*
10071011
** Add the default privileges of users "nobody" and "anonymous" as appropriate
10081012
** for the user g.zLogin.
10091013
*/
10101014
void login_set_anon_nobody_capabilities(void){
1011
- if( g.zLogin && login_anon_once ){
1015
+ if( login_anon_once ){
10121016
const char *zCap;
1013
- /* All logged-in users inherit privileges from "nobody" */
1017
+ /* All users get privileges from "nobody" */
10141018
zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'");
10151019
login_set_capabilities(zCap, 0);
1016
- if( fossil_strcmp(g.zLogin, "nobody")!=0 ){
1020
+ zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'");
1021
+ if( g.zLogin && fossil_strcmp(g.zLogin, "nobody")!=0 ){
10171022
/* All logged-in users inherit privileges from "anonymous" */
1018
- zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'");
10191023
login_set_capabilities(zCap, 0);
1024
+ }else{
1025
+ /* Record the privileges of anonymous in g.anon */
1026
+ login_set_capabilities(zCap, LOGIN_ANON);
10201027
}
10211028
login_anon_once = 0;
10221029
}
10231030
}
10241031
@@ -1025,55 +1032,57 @@
10251032
/*
10261033
** Flags passed into the 2nd argument of login_set/replace_capabilities().
10271034
*/
10281035
#if INTERFACE
10291036
#define LOGIN_IGNORE_UV 0x01 /* Ignore "u" and "v" */
1037
+#define LOGIN_ANON 0x02 /* Use g.anon instead of g.perm */
10301038
#endif
10311039
10321040
/*
1033
-** Adds all capability flags in zCap to g.perm.
1041
+** Adds all capability flags in zCap to g.perm or g.anon.
10341042
*/
10351043
void login_set_capabilities(const char *zCap, unsigned flags){
10361044
int i;
1045
+ FossilUserPerms *p = (flags & LOGIN_ANON) ? &g.anon : &g.perm;
10371046
if(NULL==zCap){
10381047
return;
10391048
}
10401049
for(i=0; zCap[i]; i++){
10411050
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;
1051
+ case 's': p->Setup = 1; /* Fall thru into Admin */
1052
+ case 'a': p->Admin = p->RdTkt = p->WrTkt = p->Zip =
1053
+ p->RdWiki = p->WrWiki = p->NewWiki =
1054
+ p->ApndWiki = p->Hyperlink = p->Clone =
1055
+ p->NewTkt = p->Password = p->RdAddr =
1056
+ p->TktFmt = p->Attach = p->ApndTkt =
1057
+ p->ModWiki = p->ModTkt = 1;
10491058
/* 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;
1059
+ case 'i': p->Read = p->Write = 1; break;
1060
+ case 'o': p->Read = 1; break;
1061
+ case 'z': p->Zip = 1; break;
1062
+
1063
+ case 'd': p->Delete = 1; break;
1064
+ case 'h': p->Hyperlink = 1; break;
1065
+ case 'g': p->Clone = 1; break;
1066
+ case 'p': p->Password = 1; break;
1067
+
1068
+ case 'j': p->RdWiki = 1; break;
1069
+ case 'k': p->WrWiki = p->RdWiki = p->ApndWiki =1; break;
1070
+ case 'm': p->ApndWiki = 1; break;
1071
+ case 'f': p->NewWiki = 1; break;
1072
+ case 'l': p->ModWiki = 1; break;
1073
+
1074
+ case 'e': p->RdAddr = 1; break;
1075
+ case 'r': p->RdTkt = 1; break;
1076
+ case 'n': p->NewTkt = 1; break;
1077
+ case 'w': p->WrTkt = p->RdTkt = p->NewTkt =
1078
+ p->ApndTkt = 1; break;
1079
+ case 'c': p->ApndTkt = 1; break;
1080
+ case 'q': p->ModTkt = 1; break;
1081
+ case 't': p->TktFmt = 1; break;
1082
+ case 'b': p->Attach = 1; break;
1083
+ case 'x': p->Private = 1; break;
10751084
10761085
/* The "u" privileges is a little different. It recursively
10771086
** inherits all privileges of the user named "reader" */
10781087
case 'u': {
10791088
if( (flags & LOGIN_IGNORE_UV)==0 ){
@@ -1110,42 +1119,43 @@
11101119
/*
11111120
** If the current login lacks any of the capabilities listed in
11121121
** the input, then return 0. If all capabilities are present, then
11131122
** return 1.
11141123
*/
1115
-int login_has_capability(const char *zCap, int nCap){
1124
+int login_has_capability(const char *zCap, int nCap, u32 flgs){
11161125
int i;
11171126
int rc = 1;
1127
+ FossilUserPerms *p = (flgs & LOGIN_ANON) ? &g.anon : &g.perm;
11181128
if( nCap<0 ) nCap = strlen(zCap);
11191129
for(i=0; i<nCap && rc && zCap[i]; i++){
11201130
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;
1131
+ case 'a': rc = p->Admin; break;
1132
+ case 'b': rc = p->Attach; break;
1133
+ case 'c': rc = p->ApndTkt; break;
1134
+ case 'd': rc = p->Delete; break;
1135
+ case 'e': rc = p->RdAddr; break;
1136
+ case 'f': rc = p->NewWiki; break;
1137
+ case 'g': rc = p->Clone; break;
1138
+ case 'h': rc = p->Hyperlink; break;
1139
+ case 'i': rc = p->Write; break;
1140
+ case 'j': rc = p->RdWiki; break;
1141
+ case 'k': rc = p->WrWiki; break;
1142
+ case 'l': rc = p->ModWiki; break;
1143
+ case 'm': rc = p->ApndWiki; break;
1144
+ case 'n': rc = p->NewTkt; break;
1145
+ case 'o': rc = p->Read; break;
1146
+ case 'p': rc = p->Password; break;
1147
+ case 'q': rc = p->ModTkt; break;
1148
+ case 'r': rc = p->RdTkt; break;
1149
+ case 's': rc = p->Setup; break;
1150
+ case 't': rc = p->TktFmt; break;
11411151
/* case 'u': READER */
11421152
/* case 'v': DEVELOPER */
1143
- case 'w': rc = g.perm.WrTkt; break;
1144
- case 'x': rc = g.perm.Private; break;
1153
+ case 'w': rc = p->WrTkt; break;
1154
+ case 'x': rc = p->Private; break;
11451155
/* case 'y': */
1146
- case 'z': rc = g.perm.Zip; break;
1156
+ case 'z': rc = p->Zip; break;
11471157
default: rc = 0; break;
11481158
}
11491159
}
11501160
return rc;
11511161
}
@@ -1195,11 +1205,11 @@
11951205
11961206
/*
11971207
** Call this routine when the credential check fails. It causes
11981208
** a redirect to the "login" page.
11991209
*/
1200
-void login_needed(void){
1210
+void login_needed(int anonOk){
12011211
#ifdef FOSSIL_ENABLE_JSON
12021212
if(g.json.isJsonMode){
12031213
json_err( FSL_JSON_E_DENIED, NULL, 1 );
12041214
fossil_exit(0);
12051215
/* NOTREACHED */
@@ -1206,11 +1216,23 @@
12061216
assert(0);
12071217
}else
12081218
#endif /* FOSSIL_ENABLE_JSON */
12091219
{
12101220
const char *zUrl = PD("REQUEST_URI", "index");
1211
- cgi_redirect(mprintf("login?g=%T", zUrl));
1221
+ const char *zQS = P("QUERY_STRING");
1222
+ Blob redir;
1223
+ blob_init(&redir, 0, 0);
1224
+ if( login_wants_https_redirect() ){
1225
+ blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl);
1226
+ }else{
1227
+ blob_appendf(&redir, "%R/login?g=%T", zUrl);
1228
+ }
1229
+ if( anonOk ) blob_append(&redir, "&anon", 5);
1230
+ if( zQS ){
1231
+ blob_appendf(&redir, "&%s", zQS);
1232
+ }
1233
+ cgi_redirect(blob_str(&redir));
12121234
/* NOTREACHED */
12131235
assert(0);
12141236
}
12151237
}
12161238
@@ -1219,14 +1241,11 @@
12191241
** the anonymous user has Hyperlink permission, then paint a mesage
12201242
** to inform the user that much more information is available by
12211243
** logging in as anonymous.
12221244
*/
12231245
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%%'") ){
1246
+ if( !g.perm.Hyperlink && g.anon.Hyperlink ){
12281247
const char *zUrl = PD("REQUEST_URI", "index");
12291248
@ <p>Many <span class="disabled">hyperlinks are disabled.</span><br />
12301249
@ Use <a href="%R/login?anon=1&amp;g=%T(zUrl)">anonymous login</a>
12311250
@ to enable hyperlinks.</p>
12321251
}
12331252
--- 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
@@ -467,11 +463,11 @@
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,14 +485,14 @@
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 */
@@ -577,12 +573,24 @@
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 ){
@@ -624,20 +632,15 @@
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 ){
@@ -811,10 +814,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 */
@@ -1006,19 +1010,22 @@
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 +1032,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 +1119,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 +1205,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 +1216,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 +1241,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&amp;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
@@ -467,11 +463,11 @@
463 void login_page(void){
464 const char *zUsername, *zPasswd;
465 const char *zNew1, *zNew2;
466 const char *zAnonPw = 0;
467 const char *zGoto = P("g");
468 int anonFlag = PB("anon");
469 char *zErrMsg = "";
470 int uid; /* User id logged in user */
471 char *zSha1Pw;
472 const char *zIpAddr; /* IP address of requestor */
473 const char *zReferer;
@@ -489,14 +485,14 @@
485 }
486 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
487 constant_time_cmp_function, 0, 0);
488 zUsername = P("u");
489 zPasswd = P("p");
490 if( P("out") ){
 
491 login_clear_login_data();
492 redirect_to_g();
493 return;
494 }
495 if( g.perm.Password && zPasswd
496 && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0
497 ){
498 /* The user requests a password change */
@@ -577,12 +573,24 @@
573 }
574 }
575 style_header("Login/Logout");
576 style_adunit_config(ADUNIT_OFF);
577 @ %s(zErrMsg)
578 if( zGoto ){
579 char *zAbbrev = fossil_strdup(zGoto);
580 int i;
581 for(i=0; zAbbrev[i] && zAbbrev[i]!='?'; i++){}
582 zAbbrev[i] = 0;
583 if( g.zLogin ){
584 @ <p>Use a different login with greater privilege that <b>%h(g.zLogin)</b>
585 @ to access <b>%h(zAbbrev)</b>.
586 }else if( anonFlag ){
587 @ <p>Login as <b>anonymous</b> or any named user
588 @ to access page <b>%h(zAbbrev)</b>.
589 }else{
590 @ <p>Login as a named user to access page <b>%h(zAbbrev)</b>.
591 }
592 }
593 form_begin(0, "%R/login");
594 if( zGoto ){
595 @ <input type="hidden" name="g" value="%h(zGoto)" />
596 }else if( zReferer && strncmp(g.zBaseURL, zReferer, strlen(g.zBaseURL))==0 ){
@@ -624,20 +632,15 @@
632 @ form.action = "%h(zSSL)/login";
633 @ }
634 }
635 @ }
636 @ </script>
637 if( g.zLogin ){
 
 
638 @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p>
 
639 }
640 @ <p>By pressing the Login button, you grant permission to store an
641 @ access token for this site in a cookie.</p>
 
 
642 if( db_get_boolean("self-register", 0) ){
643 @ <p>If you do not have an account, you can
644 @ <a href="%R/register?g=%T(P("G"))">create one</a>.
645 }
646 if( zAnonPw ){
@@ -811,10 +814,11 @@
814 ** variables appropriately.
815 **
816 ** g.userUid Database USER.UID value. Might be -1 for "nobody"
817 ** g.zLogin Database USER.LOGIN value. NULL for user "nobody"
818 ** g.perm Permissions granted to this user
819 ** g.anon Permissions that would be available to anonymous
820 ** g.isHuman True if the user is human, not a spider or robot
821 **
822 */
823 void login_check_credentials(void){
824 int uid = 0; /* User id */
@@ -1006,19 +1010,22 @@
1010 /*
1011 ** Add the default privileges of users "nobody" and "anonymous" as appropriate
1012 ** for the user g.zLogin.
1013 */
1014 void login_set_anon_nobody_capabilities(void){
1015 if( login_anon_once ){
1016 const char *zCap;
1017 /* All users get privileges from "nobody" */
1018 zCap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'");
1019 login_set_capabilities(zCap, 0);
1020 zCap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'");
1021 if( g.zLogin && fossil_strcmp(g.zLogin, "nobody")!=0 ){
1022 /* All logged-in users inherit privileges from "anonymous" */
 
1023 login_set_capabilities(zCap, 0);
1024 }else{
1025 /* Record the privileges of anonymous in g.anon */
1026 login_set_capabilities(zCap, LOGIN_ANON);
1027 }
1028 login_anon_once = 0;
1029 }
1030 }
1031
@@ -1025,55 +1032,57 @@
1032 /*
1033 ** Flags passed into the 2nd argument of login_set/replace_capabilities().
1034 */
1035 #if INTERFACE
1036 #define LOGIN_IGNORE_UV 0x01 /* Ignore "u" and "v" */
1037 #define LOGIN_ANON 0x02 /* Use g.anon instead of g.perm */
1038 #endif
1039
1040 /*
1041 ** Adds all capability flags in zCap to g.perm or g.anon.
1042 */
1043 void login_set_capabilities(const char *zCap, unsigned flags){
1044 int i;
1045 FossilUserPerms *p = (flags & LOGIN_ANON) ? &g.anon : &g.perm;
1046 if(NULL==zCap){
1047 return;
1048 }
1049 for(i=0; zCap[i]; i++){
1050 switch( zCap[i] ){
1051 case 's': p->Setup = 1; /* Fall thru into Admin */
1052 case 'a': p->Admin = p->RdTkt = p->WrTkt = p->Zip =
1053 p->RdWiki = p->WrWiki = p->NewWiki =
1054 p->ApndWiki = p->Hyperlink = p->Clone =
1055 p->NewTkt = p->Password = p->RdAddr =
1056 p->TktFmt = p->Attach = p->ApndTkt =
1057 p->ModWiki = p->ModTkt = 1;
1058 /* Fall thru into Read/Write */
1059 case 'i': p->Read = p->Write = 1; break;
1060 case 'o': p->Read = 1; break;
1061 case 'z': p->Zip = 1; break;
1062
1063 case 'd': p->Delete = 1; break;
1064 case 'h': p->Hyperlink = 1; break;
1065 case 'g': p->Clone = 1; break;
1066 case 'p': p->Password = 1; break;
1067
1068 case 'j': p->RdWiki = 1; break;
1069 case 'k': p->WrWiki = p->RdWiki = p->ApndWiki =1; break;
1070 case 'm': p->ApndWiki = 1; break;
1071 case 'f': p->NewWiki = 1; break;
1072 case 'l': p->ModWiki = 1; break;
1073
1074 case 'e': p->RdAddr = 1; break;
1075 case 'r': p->RdTkt = 1; break;
1076 case 'n': p->NewTkt = 1; break;
1077 case 'w': p->WrTkt = p->RdTkt = p->NewTkt =
1078 p->ApndTkt = 1; break;
1079 case 'c': p->ApndTkt = 1; break;
1080 case 'q': p->ModTkt = 1; break;
1081 case 't': p->TktFmt = 1; break;
1082 case 'b': p->Attach = 1; break;
1083 case 'x': p->Private = 1; break;
1084
1085 /* The "u" privileges is a little different. It recursively
1086 ** inherits all privileges of the user named "reader" */
1087 case 'u': {
1088 if( (flags & LOGIN_IGNORE_UV)==0 ){
@@ -1110,42 +1119,43 @@
1119 /*
1120 ** If the current login lacks any of the capabilities listed in
1121 ** the input, then return 0. If all capabilities are present, then
1122 ** return 1.
1123 */
1124 int login_has_capability(const char *zCap, int nCap, u32 flgs){
1125 int i;
1126 int rc = 1;
1127 FossilUserPerms *p = (flgs & LOGIN_ANON) ? &g.anon : &g.perm;
1128 if( nCap<0 ) nCap = strlen(zCap);
1129 for(i=0; i<nCap && rc && zCap[i]; i++){
1130 switch( zCap[i] ){
1131 case 'a': rc = p->Admin; break;
1132 case 'b': rc = p->Attach; break;
1133 case 'c': rc = p->ApndTkt; break;
1134 case 'd': rc = p->Delete; break;
1135 case 'e': rc = p->RdAddr; break;
1136 case 'f': rc = p->NewWiki; break;
1137 case 'g': rc = p->Clone; break;
1138 case 'h': rc = p->Hyperlink; break;
1139 case 'i': rc = p->Write; break;
1140 case 'j': rc = p->RdWiki; break;
1141 case 'k': rc = p->WrWiki; break;
1142 case 'l': rc = p->ModWiki; break;
1143 case 'm': rc = p->ApndWiki; break;
1144 case 'n': rc = p->NewTkt; break;
1145 case 'o': rc = p->Read; break;
1146 case 'p': rc = p->Password; break;
1147 case 'q': rc = p->ModTkt; break;
1148 case 'r': rc = p->RdTkt; break;
1149 case 's': rc = p->Setup; break;
1150 case 't': rc = p->TktFmt; break;
1151 /* case 'u': READER */
1152 /* case 'v': DEVELOPER */
1153 case 'w': rc = p->WrTkt; break;
1154 case 'x': rc = p->Private; break;
1155 /* case 'y': */
1156 case 'z': rc = p->Zip; break;
1157 default: rc = 0; break;
1158 }
1159 }
1160 return rc;
1161 }
@@ -1195,11 +1205,11 @@
1205
1206 /*
1207 ** Call this routine when the credential check fails. It causes
1208 ** a redirect to the "login" page.
1209 */
1210 void login_needed(int anonOk){
1211 #ifdef FOSSIL_ENABLE_JSON
1212 if(g.json.isJsonMode){
1213 json_err( FSL_JSON_E_DENIED, NULL, 1 );
1214 fossil_exit(0);
1215 /* NOTREACHED */
@@ -1206,11 +1216,23 @@
1216 assert(0);
1217 }else
1218 #endif /* FOSSIL_ENABLE_JSON */
1219 {
1220 const char *zUrl = PD("REQUEST_URI", "index");
1221 const char *zQS = P("QUERY_STRING");
1222 Blob redir;
1223 blob_init(&redir, 0, 0);
1224 if( login_wants_https_redirect() ){
1225 blob_appendf(&redir, "%s/login?g=%T", g.zHttpsURL, zUrl);
1226 }else{
1227 blob_appendf(&redir, "%R/login?g=%T", zUrl);
1228 }
1229 if( anonOk ) blob_append(&redir, "&anon", 5);
1230 if( zQS ){
1231 blob_appendf(&redir, "&%s", zQS);
1232 }
1233 cgi_redirect(blob_str(&redir));
1234 /* NOTREACHED */
1235 assert(0);
1236 }
1237 }
1238
@@ -1219,14 +1241,11 @@
1241 ** the anonymous user has Hyperlink permission, then paint a mesage
1242 ** to inform the user that much more information is available by
1243 ** logging in as anonymous.
1244 */
1245 void login_anonymous_available(void){
1246 if( !g.perm.Hyperlink && g.anon.Hyperlink ){
 
 
 
1247 const char *zUrl = PD("REQUEST_URI", "index");
1248 @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br />
1249 @ Use <a href="%R/login?anon=1&amp;g=%T(zUrl)">anonymous login</a>
1250 @ to enable hyperlinks.</p>
1251 }
1252
+4 -1
--- src/main.c
+++ src/main.c
@@ -193,12 +193,15 @@
193193
/* Information used to populate the RCVFROM table */
194194
int rcvid; /* The rcvid. 0 if not yet defined. */
195195
char *zIpAddr; /* The remote IP address */
196196
char *zNonce; /* The nonce used for login */
197197
198
- /* permissions used by the server */
198
+ /* permissions available to current user */
199199
struct FossilUserPerms perm;
200
+
201
+ /* permissions available to user "anonymous" */
202
+ struct FossilUserPerms anon;
200203
201204
#ifdef FOSSIL_ENABLE_TCL
202205
/* all Tcl related context necessary for integration */
203206
struct TclContext tcl;
204207
#endif
205208
--- src/main.c
+++ src/main.c
@@ -193,12 +193,15 @@
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,15 @@
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 user "anonymous" */
202 struct FossilUserPerms anon;
203
204 #ifdef FOSSIL_ENABLE_TCL
205 /* all Tcl related context necessary for integration */
206 struct TclContext tcl;
207 #endif
208
+4 -1
--- src/moderate.c
+++ src/moderate.c
@@ -144,11 +144,14 @@
144144
void modreq_page(void){
145145
Blob sql;
146146
Stmt q;
147147
148148
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
+ }
150153
style_header("Pending Moderation Requests");
151154
@ <h2>All Pending Moderation Requests</h2>
152155
if( moderation_table_exists() ){
153156
blob_init(&sql, timeline_query_for_www(), -1);
154157
blob_append_sql(&sql,
155158
--- 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 @@
987987
int n = atoi(PD("n","5000"));
988988
int mx = db_int(0, "SELECT max(rid) FROM blob");
989989
char *zRange;
990990
991991
login_check_credentials();
992
- if( !g.perm.Read ){ login_needed(); return; }
992
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
993993
style_header("List Of Artifacts");
994994
if( mx>n && P("s")==0 ){
995995
int i;
996996
@ <p>Select a range of artifacts to view:</p>
997997
@ <ul>
@@ -1083,11 +1083,11 @@
10831083
int cnt;
10841084
char *azHit[MAX_COLLIDE];
10851085
char z[UUID_SIZE+1];
10861086
} aCollide[UUID_SIZE+1];
10871087
login_check_credentials();
1088
- if( !g.perm.Read ){ login_needed(); return; }
1088
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
10891089
memset(aCollide, 0, sizeof(aCollide));
10901090
memset(zPrev, 0, sizeof(zPrev));
10911091
db_prepare(&q,"SELECT uuid FROM blob ORDER BY 1");
10921092
while( db_step(&q)==SQLITE_ROW ){
10931093
const char *zUuid = db_column_text(&q,0);
10941094
--- 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 @@
543543
*/
544544
void test_rename_list_page(void){
545545
Stmt q;
546546
547547
login_check_credentials();
548
- if( !g.perm.Read ){ login_needed(); return; }
548
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
549549
style_header("List Of File Name Changes");
550550
@ <h3>NB: Experimental Page</h3>
551551
@ <table border="1" width="100%%">
552552
@ <tr><th>Date &amp; Time</th>
553553
@ <th>Old Name</th>
554554
--- 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 &amp; 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 &amp; Time</th>
553 @ <th>Old Name</th>
554
+7 -4
--- src/report.c
+++ src/report.c
@@ -40,11 +40,14 @@
4040
Stmt q;
4141
int rn = 0;
4242
int cnt = 0;
4343
4444
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
+ }
4649
style_header("Ticket Main Menu");
4750
ticket_standard_submenu(T_ALL_BUT(T_REPLIST));
4851
if( g.thTrace ) Th_Trace("BEGIN_REPORTLIST<br />\n", -1);
4952
zScript = ticket_reportlist_code();
5053
if( g.thTrace ) Th_Trace("BEGIN_REPORTLIST_SCRIPT<br />\n", -1);
@@ -293,11 +296,11 @@
293296
const char *zClrKey;
294297
Stmt q;
295298
296299
login_check_credentials();
297300
if( !g.perm.TktFmt ){
298
- login_needed();
301
+ login_needed(g.anon.TktFmt);
299302
return;
300303
}
301304
rn = atoi(PD("rn","0"));
302305
db_prepare(&q, "SELECT title, sqlcode, owner, cols "
303306
"FROM reportfmt WHERE rn=%d",rn);
@@ -343,11 +346,11 @@
343346
char *zSQL;
344347
char *zErr = 0;
345348
346349
login_check_credentials();
347350
if( !g.perm.TktFmt ){
348
- login_needed();
351
+ login_needed(g.anon.TktFmt);
349352
return;
350353
}
351354
/*view_add_functions(0);*/
352355
rn = atoi(PD("rn","0"));
353356
zTitle = P("t");
@@ -1078,11 +1081,11 @@
10781081
Stmt q;
10791082
char *zErr1 = 0;
10801083
char *zErr2 = 0;
10811084
10821085
login_check_credentials();
1083
- if( !g.perm.RdTkt ){ login_needed(); return; }
1086
+ if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
10841087
rn = atoi(PD("rn","0"));
10851088
if( rn==0 ){
10861089
cgi_redirect("reportlist");
10871090
return;
10881091
}
10891092
--- 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 @@
5959
** WEBPAGE: /setup
6060
*/
6161
void setup_page(void){
6262
login_check_credentials();
6363
if( !g.perm.Setup ){
64
- login_needed();
64
+ login_needed(0);
6565
}
6666
6767
style_header("Server Administration");
6868
6969
/* Make sure the header contains <base href="...">. Issue a warning
@@ -152,11 +152,11 @@
152152
Stmt s;
153153
int prevLevel = 0;
154154
155155
login_check_credentials();
156156
if( !g.perm.Admin ){
157
- login_needed();
157
+ login_needed(0);
158158
return;
159159
}
160160
161161
style_submenu_element("Add", "Add User", "setup_uedit");
162162
style_header("User List");
@@ -336,11 +336,11 @@
336336
const char *oa[128];
337337
338338
/* Must have ADMIN privileges to access this page
339339
*/
340340
login_check_credentials();
341
- if( !g.perm.Admin ){ login_needed(); return; }
341
+ if( !g.perm.Admin ){ login_needed(0); return; }
342342
343343
/* Check to see if an ADMIN user is trying to edit a SETUP account.
344344
** Don't allow that.
345345
*/
346346
zId = PD("id", "0");
@@ -998,11 +998,12 @@
998998
** WEBPAGE: setup_access
999999
*/
10001000
void setup_access(void){
10011001
login_check_credentials();
10021002
if( !g.perm.Setup ){
1003
- login_needed();
1003
+ login_needed(0);
1004
+ return;
10041005
}
10051006
10061007
style_header("Access Control Settings");
10071008
db_begin_transaction();
10081009
@ <form action="%s(g.zTop)/setup_access" method="post"><div>
@@ -1203,11 +1204,12 @@
12031204
const char *zPw = PD("pw", "");
12041205
const char *zNewName = PD("newname", "New Login Group");
12051206
12061207
login_check_credentials();
12071208
if( !g.perm.Setup ){
1208
- login_needed();
1209
+ login_needed(0);
1210
+ return;
12091211
}
12101212
file_canonical_name(g.zRepositoryName, &fullName, 0);
12111213
zSelfRepo = fossil_strdup(blob_str(&fullName));
12121214
blob_reset(&fullName);
12131215
if( P("join")!=0 ){
@@ -1315,11 +1317,12 @@
13151317
"3", "YYMMDD HH:MM",
13161318
"4", "(off)"
13171319
};
13181320
login_check_credentials();
13191321
if( !g.perm.Setup ){
1320
- login_needed();
1322
+ login_needed(0);
1323
+ return;
13211324
}
13221325
13231326
style_header("Timeline Display Preferences");
13241327
db_begin_transaction();
13251328
@ <form action="%s(g.zTop)/setup_timeline" method="post"><div>
@@ -1393,11 +1396,12 @@
13931396
void setup_settings(void){
13941397
Setting const *pSet;
13951398
13961399
login_check_credentials();
13971400
if( !g.perm.Setup ){
1398
- login_needed();
1401
+ login_needed(0);
1402
+ return;
13991403
}
14001404
14011405
(void) aCmdHelp; /* NOTE: Silence compiler warning. */
14021406
style_header("Settings");
14031407
if(!g.repositoryOpen){
@@ -1473,11 +1477,12 @@
14731477
** WEBPAGE: setup_config
14741478
*/
14751479
void setup_config(void){
14761480
login_check_credentials();
14771481
if( !g.perm.Setup ){
1478
- login_needed();
1482
+ login_needed(0);
1483
+ return;
14791484
}
14801485
14811486
style_header("WWW Configuration");
14821487
db_begin_transaction();
14831488
@ <form action="%s(g.zTop)/setup_config" method="post"><div>
@@ -1551,11 +1556,12 @@
15511556
** WEBPAGE: setup_editcss
15521557
*/
15531558
void setup_editcss(void){
15541559
login_check_credentials();
15551560
if( !g.perm.Setup ){
1556
- login_needed();
1561
+ login_needed(0);
1562
+ return;
15571563
}
15581564
db_begin_transaction();
15591565
if( P("clear")!=0 ){
15601566
db_multi_exec("DELETE FROM config WHERE name='css'");
15611567
cgi_replace_parameter("css", builtin_text("skins/default/css.txt"));
@@ -1596,11 +1602,12 @@
15961602
** WEBPAGE: setup_header
15971603
*/
15981604
void setup_header(void){
15991605
login_check_credentials();
16001606
if( !g.perm.Setup ){
1601
- login_needed();
1607
+ login_needed(0);
1608
+ return;
16021609
}
16031610
db_begin_transaction();
16041611
if( P("clear")!=0 ){
16051612
db_multi_exec("DELETE FROM config WHERE name='header'");
16061613
cgi_replace_parameter("header", builtin_text("skins/default/header.txt"));
@@ -1660,11 +1667,12 @@
16601667
** WEBPAGE: setup_footer
16611668
*/
16621669
void setup_footer(void){
16631670
login_check_credentials();
16641671
if( !g.perm.Setup ){
1665
- login_needed();
1672
+ login_needed(0);
1673
+ return;
16661674
}
16671675
db_begin_transaction();
16681676
if( P("clear")!=0 ){
16691677
db_multi_exec("DELETE FROM config WHERE name='footer'");
16701678
cgi_replace_parameter("footer", builtin_text("skins/default/footer.txt"));
@@ -1697,11 +1705,12 @@
16971705
** WEBPAGE: setup_modreq
16981706
*/
16991707
void setup_modreq(void){
17001708
login_check_credentials();
17011709
if( !g.perm.Setup ){
1702
- login_needed();
1710
+ login_needed(0);
1711
+ return;
17031712
}
17041713
17051714
style_header("Moderator For Wiki And Tickets");
17061715
db_begin_transaction();
17071716
@ <form action="%R/setup_modreq" method="post"><div>
@@ -1741,11 +1750,12 @@
17411750
** WEBPAGE: setup_adunit
17421751
*/
17431752
void setup_adunit(void){
17441753
login_check_credentials();
17451754
if( !g.perm.Setup ){
1746
- login_needed();
1755
+ login_needed(0);
1756
+ return;
17471757
}
17481758
db_begin_transaction();
17491759
if( P("clear")!=0 ){
17501760
db_multi_exec("DELETE FROM config WHERE name GLOB 'adunit*'");
17511761
cgi_replace_parameter("adunit","");
@@ -1822,11 +1832,12 @@
18221832
if( szBgImg>0 ){
18231833
zBgMime = PD("bgim:mimetype","image/gif");
18241834
}
18251835
login_check_credentials();
18261836
if( !g.perm.Setup ){
1827
- login_needed();
1837
+ login_needed(0);
1838
+ return;
18281839
}
18291840
db_begin_transaction();
18301841
if( P("setlogo")!=0 && zLogoMime && zLogoMime[0] && szLogoImg>0 ){
18311842
Blob img;
18321843
Stmt ins;
@@ -1961,11 +1972,12 @@
19611972
void sql_page(void){
19621973
const char *zQ = P("q");
19631974
int go = P("go")!=0;
19641975
login_check_credentials();
19651976
if( !g.perm.Setup ){
1966
- login_needed();
1977
+ login_needed(0);
1978
+ return;
19671979
}
19681980
db_begin_transaction();
19691981
style_header("Raw SQL Commands");
19701982
@ <p><b>Caution:</b> There are no restrictions on the SQL that can be
19711983
@ run by this page. You can do serious and irrepairable damage to the
@@ -2082,11 +2094,12 @@
20822094
void th1_page(void){
20832095
const char *zQ = P("q");
20842096
int go = P("go")!=0;
20852097
login_check_credentials();
20862098
if( !g.perm.Setup ){
2087
- login_needed();
2099
+ login_needed(0);
2100
+ return;
20882101
}
20892102
db_begin_transaction();
20902103
style_header("Raw TH1 Commands");
20912104
@ <p><b>Caution:</b> There are no restrictions on the TH1 that can be
20922105
@ run by this page. If Tcl integration was enabled at compile-time and
@@ -2142,11 +2155,12 @@
21422155
int limit;
21432156
int fLogEnabled;
21442157
int counter = 0;
21452158
login_check_credentials();
21462159
if( !g.perm.Setup && !g.perm.Admin ){
2147
- login_needed();
2160
+ login_needed(0);
2161
+ return;
21482162
}
21492163
style_header("Admin Log");
21502164
create_admin_log_table();
21512165
limit = atoi(PD("n","20"));
21522166
fLogEnabled = db_get_boolean("admin-log", 0);
@@ -2199,11 +2213,12 @@
21992213
** Configure the search engine.
22002214
*/
22012215
void page_srchsetup(){
22022216
login_check_credentials();
22032217
if( !g.perm.Setup && !g.perm.Admin ){
2204
- login_needed();
2218
+ login_needed(0);
2219
+ return;
22052220
}
22062221
style_header("Search Configuration");
22072222
@ <form action="%s(g.zTop)/srchsetup" method="post"><div>
22082223
login_insert_csrf_secret();
22092224
@ <div style="text-align:center;font-weight:bold;">
22102225
--- 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 @@
4949
int numRows = 3;
5050
char *zCanonical = 0;
5151
5252
login_check_credentials();
5353
if( !g.perm.Admin ){
54
- login_needed();
54
+ login_needed(0);
55
+ return;
5556
}
5657
if( P("rebuild") ){
5758
db_close(1);
5859
db_open_repository(g.zRepositoryName);
5960
db_begin_transaction();
@@ -301,11 +302,12 @@
301302
int cnt;
302303
Stmt q;
303304
304305
login_check_credentials();
305306
if( !g.perm.Admin ){
306
- login_needed();
307
+ login_needed(0);
308
+ return;
307309
}
308310
style_header("Artifact Receipts");
309311
if( showAll ){
310312
ofst = 0;
311313
}else{
@@ -381,11 +383,12 @@
381383
int rcvid = atoi(PD("rcvid","0"));
382384
Stmt q;
383385
384386
login_check_credentials();
385387
if( !g.perm.Admin ){
386
- login_needed();
388
+ login_needed(0);
389
+ return;
387390
}
388391
style_header("Artifact Receipt %d", rcvid);
389392
if( db_exists(
390393
"SELECT 1 FROM blob WHERE rcvid=%d AND"
391394
" NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid)
392395
--- 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 @@
289289
Stmt q;
290290
int seenCurrent = 0;
291291
292292
login_check_credentials();
293293
if( !g.perm.Setup ){
294
- login_needed();
294
+ login_needed(0);
295
+ return;
295296
}
296297
db_begin_transaction();
297298
zCurrent = getSkin(0);
298299
for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
299300
aBuiltinSkin[i].zSQL = getSkin(aBuiltinSkin[i].zLabel);
300301
--- 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 @@
5252
int brief;
5353
char zBuf[100];
5454
const char *p;
5555
5656
login_check_credentials();
57
- if( !g.perm.Read ){ login_needed(); return; }
57
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
5858
brief = P("brief")!=0;
5959
style_header("Repository Statistics");
6060
style_adunit_config(ADUNIT_RIGHT_OK);
6161
if( g.perm.Admin ){
6262
style_submenu_element("URLs", "URLs and Checkouts", "urllist");
@@ -292,11 +292,11 @@
292292
*/
293293
void urllist_page(void){
294294
Stmt q;
295295
int cnt;
296296
login_check_credentials();
297
- if( !g.perm.Admin ){ login_needed(); return; }
297
+ if( !g.perm.Admin ){ login_needed(0); return; }
298298
299299
style_header("URLs and Checkouts");
300300
style_adunit_config(ADUNIT_RIGHT_OK);
301301
style_submenu_element("Stat", "Repository Stats", "stat");
302302
style_submenu_element("Schema", "Repository Schema", "repo_schema");
@@ -339,11 +339,11 @@
339339
** Show the repository schema
340340
*/
341341
void repo_schema_page(void){
342342
Stmt q;
343343
login_check_credentials();
344
- if( !g.perm.Admin ){ login_needed(); return; }
344
+ if( !g.perm.Admin ){ login_needed(0); return; }
345345
346346
style_header("Repository Schema");
347347
style_adunit_config(ADUNIT_RIGHT_OK);
348348
style_submenu_element("Stat", "Repository Stats", "stat");
349349
style_submenu_element("URLs", "URLs and Checkouts", "urllist");
350350
--- 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 @@
728728
HQuery url; /* URL for various branch links */
729729
const char *zView = P("view"); /* Which view/report to show. */
730730
const char *zUserName = P("user");
731731
732732
login_check_credentials();
733
- if( !g.perm.Read ){ login_needed(); return; }
733
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
734734
if(!zUserName) zUserName = P("u");
735735
url_initialize(&url, "reports");
736736
if(zUserName && *zUserName){
737737
url_add_parameter(&url,"user", zUserName);
738738
statrep_submenu(&url, "(Remove User Flag)", "view", zView, "user");
739739
--- 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 @@
14111411
"REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL",
14121412
};
14131413
14141414
login_check_credentials();
14151415
if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){
1416
- login_needed();
1416
+ login_needed(0);
14171417
return;
14181418
}
14191419
for(i=0; i<count(azCgiVars); i++) (void)P(azCgiVars[i]);
14201420
style_header("Environment Test");
14211421
showAll = atoi(PD("showall","0"));
@@ -1430,17 +1430,25 @@
14301430
@ g.zBaseURL = %h(g.zBaseURL)<br />
14311431
@ g.zHttpsURL = %h(g.zHttpsURL)<br />
14321432
@ g.zTop = %h(g.zTop)<br />
14331433
@ g.zPath = %h(g.zPath)<br />
14341434
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;
14361436
}
14371437
zCap[i] = 0;
14381438
@ g.userUid = %d(g.userUid)<br />
14391439
@ g.zLogin = %h(g.zLogin)<br />
14401440
@ g.isHuman = %d(g.isHuman)<br />
14411441
@ 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
+ }
14421450
@ g.zRepositoryName = %h(g.zRepositoryName)<br />
14431451
@ load_average() = %f(load_average())<br />
14441452
@ <hr>
14451453
P("HTTP_USER_AGENT");
14461454
cgi_print_all(showAll);
14471455
--- 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 @@
542542
void taglist_page(void){
543543
Stmt q;
544544
545545
login_check_credentials();
546546
if( !g.perm.Read ){
547
- login_needed();
547
+ login_needed(g.anon.Read);
548548
}
549549
login_anonymous_available();
550550
style_header("Tags");
551551
style_adunit_config(ADUNIT_RIGHT_OK);
552552
style_submenu_element("Timeline", "Timeline", "tagtimeline");
@@ -580,11 +580,11 @@
580580
*/
581581
void tagtimeline_page(void){
582582
Stmt q;
583583
584584
login_check_credentials();
585
- if( !g.perm.Read ){ login_needed(); return; }
585
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
586586
587587
style_header("Tagged Check-ins");
588588
style_submenu_element("List", "List", "taglist");
589589
login_anonymous_available();
590590
@ <h2>Check-ins with non-propagating tags:</h2>
591591
--- 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
+1 -1
--- src/tar.c
+++ src/tar.c
@@ -603,11 +603,11 @@
603603
char *zName, *zRid, *zKey;
604604
int nName, nRid;
605605
Blob tarball;
606606
607607
login_check_credentials();
608
- if( !g.perm.Zip ){ login_needed(); return; }
608
+ if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
609609
load_control();
610610
zName = mprintf("%s", PD("name",""));
611611
nName = strlen(zName);
612612
zRid = mprintf("%s", PD("uuid","trunk"));
613613
nRid = strlen(zRid);
614614
--- 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);
614
--- 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);
614
+11 -5
--- src/th_main.c
+++ src/th_main.c
@@ -342,12 +342,14 @@
342342
return TH_OK;
343343
}
344344
345345
/*
346346
** TH1 command: hascap STRING...
347
+** TH1 command: anoncap STRING...
347348
**
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.
349351
*/
350352
static int hascapCmd(
351353
Th_Interp *interp,
352354
void *p,
353355
int argc,
@@ -357,11 +359,11 @@
357359
int rc = 0, i;
358360
if( argc<2 ){
359361
return Th_WrongNumArgs(interp, "hascap STRING ...");
360362
}
361363
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);
363365
}
364366
if( g.thTrace ){
365367
Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc);
366368
}
367369
Th_SetResultInt(interp, rc);
@@ -543,11 +545,12 @@
543545
544546
545547
/*
546548
** TH1 command: anycap STRING
547549
**
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.
549552
*/
550553
static int anycapCmd(
551554
Th_Interp *interp,
552555
void *p,
553556
int argc,
@@ -558,11 +561,11 @@
558561
int i;
559562
if( argc!=2 ){
560563
return Th_WrongNumArgs(interp, "anycap STRING");
561564
}
562565
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);
564567
}
565568
if( g.thTrace ){
566569
Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc);
567570
}
568571
Th_SetResultInt(interp, rc);
@@ -1450,15 +1453,18 @@
14501453
int needConfig = flags & TH_INIT_NEED_CONFIG;
14511454
int forceReset = flags & TH_INIT_FORCE_RESET;
14521455
int forceTcl = flags & TH_INIT_FORCE_TCL;
14531456
int forceSetup = flags & TH_INIT_FORCE_SETUP;
14541457
static unsigned int aFlags[] = { 0, 1, WIKI_LINKSONLY };
1458
+ static int anonFlag = LOGIN_ANON;
1459
+ static int zeroInt = 0;
14551460
static struct _Command {
14561461
const char *zName;
14571462
Th_CommandProc xProc;
14581463
void *pContext;
14591464
} aCommand[] = {
1465
+ {"anoncap", hascapCmd, (void*)&anonFlag},
14601466
{"anycap", anycapCmd, 0},
14611467
{"artifact", artifactCmd, 0},
14621468
{"checkout", checkoutCmd, 0},
14631469
{"combobox", comboboxCmd, 0},
14641470
{"date", dateCmd, 0},
@@ -1465,11 +1471,11 @@
14651471
{"decorate", wikiCmd, (void*)&aFlags[2]},
14661472
{"enable_output", enableOutputCmd, 0},
14671473
{"getParameter", getParameterCmd, 0},
14681474
{"globalState", globalStateCmd, 0},
14691475
{"httpize", httpizeCmd, 0},
1470
- {"hascap", hascapCmd, 0},
1476
+ {"hascap", hascapCmd, (void*)&zeroInt},
14711477
{"hasfeature", hasfeatureCmd, 0},
14721478
{"html", putsCmd, (void*)&aFlags[0]},
14731479
{"htmlize", htmlizeCmd, 0},
14741480
{"http", httpCmd, 0},
14751481
{"linecount", linecntCmd, 0},
14761482
--- 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 @@
163163
void test_hash_color_page(void){
164164
const char *zBr;
165165
char zNm[10];
166166
int i, cnt;
167167
login_check_credentials();
168
- if( !g.perm.Read ){ login_needed(); return; }
168
+ if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
169169
170170
style_header("Hash Color Test");
171171
for(i=cnt=0; i<10; i++){
172172
sqlite3_snprintf(sizeof(zNm),zNm,"b%d",i);
173173
zBr = P(zNm);
@@ -1175,11 +1175,11 @@
11751175
if( pd_rid ){
11761176
p_rid = d_rid = pd_rid;
11771177
}
11781178
login_check_credentials();
11791179
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);
11811181
return;
11821182
}
11831183
url_initialize(&url, "timeline");
11841184
cgi_query_parameters_to_url(&url);
11851185
if( zTagName && g.perm.Read ){
@@ -2068,11 +2068,14 @@
20682068
*/
20692069
void test_timewarp_page(void){
20702070
Stmt q;
20712071
20722072
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
+ }
20742077
style_header("Instances of timewarp");
20752078
@ <ul>
20762079
db_prepare(&q,
20772080
"SELECT blob.uuid "
20782081
" FROM plink p, plink c, blob"
20792082
--- 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
+14 -5
--- src/tkt.c
+++ src/tkt.c
@@ -449,11 +449,11 @@
449449
const char *zScript;
450450
char *zFullName;
451451
const char *zUuid = PD("name","");
452452
453453
login_check_credentials();
454
- if( !g.perm.RdTkt ){ login_needed(); return; }
454
+ if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
455455
if( g.perm.WrTkt || g.perm.ApndTkt ){
456456
style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T",
457457
g.zTop, PD("name",""));
458458
}
459459
if( g.perm.Hyperlink ){
@@ -687,11 +687,11 @@
687687
void tktnew_page(void){
688688
const char *zScript;
689689
char *zNewUuid = 0;
690690
691691
login_check_credentials();
692
- if( !g.perm.NewTkt ){ login_needed(); return; }
692
+ if( !g.perm.NewTkt ){ login_needed(g.anon.NewTkt); return; }
693693
if( P("cancel") ){
694694
cgi_redirect("home");
695695
}
696696
style_header("New Ticket");
697697
ticket_standard_submenu(T_ALL_BUT(T_NEW));
@@ -738,11 +738,14 @@
738738
int nName;
739739
const char *zName;
740740
int nRec;
741741
742742
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
+ }
744747
zName = P("name");
745748
if( P("cancel") ){
746749
cgi_redirectf("tktview?name=%T", zName);
747750
}
748751
style_header("Edit Ticket");
@@ -839,11 +842,14 @@
839842
int tagid;
840843
char zGlobPattern[50];
841844
const char *zType;
842845
843846
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
+ }
845851
zUuid = PD("name","");
846852
zType = PD("y","a");
847853
if( zType[0]!='c' ){
848854
style_submenu_element("Check-ins", "Check-ins",
849855
"%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid);
@@ -912,11 +918,14 @@
912918
const char *zUuid;
913919
int tagid;
914920
int nChng = 0;
915921
916922
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
+ }
918927
zUuid = PD("name","");
919928
zTitle = mprintf("History Of Ticket %h", zUuid);
920929
style_submenu_element("Status", "Status",
921930
"%s/info/%s", g.zTop, zUuid);
922931
style_submenu_element("Check-ins", "Check-ins",
923932
--- src/tkt.c
+++ src/tkt.c
@@ -449,11 +449,11 @@
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 ){
@@ -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",
923
--- src/tkt.c
+++ src/tkt.c
@@ -449,11 +449,11 @@
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.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 ){
@@ -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",
932
+7 -4
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -27,11 +27,12 @@
2727
** WEBPAGE: tktsetup
2828
*/
2929
void tktsetup_page(void){
3030
login_check_credentials();
3131
if( !g.perm.Setup ){
32
- login_needed();
32
+ login_needed(0);
33
+ return;
3334
}
3435
3536
style_header("Ticket Setup");
3637
@ <table border="0" cellspacing="20">
3738
setup_menu_entry("Table", "tktsetup_tab",
@@ -118,13 +119,14 @@
118119
const char *z;
119120
int isSubmit;
120121
121122
login_check_credentials();
122123
if( !g.perm.Setup ){
123
- login_needed();
124
+ login_needed(0);
125
+ return;
124126
}
125
- if( P("setup") ){
127
+ if( PB("setup") ){
126128
cgi_redirect("tktsetup");
127129
}
128130
isSubmit = P("submit")!=0;
129131
z = P("x");
130132
if( z==0 ){
@@ -858,11 +860,12 @@
858860
** WEBPAGE: tktsetup_timeline
859861
*/
860862
void tktsetup_timeline_page(void){
861863
login_check_credentials();
862864
if( !g.perm.Setup ){
863
- login_needed();
865
+ login_needed(0);
866
+ return;
864867
}
865868
866869
if( P("setup") ){
867870
cgi_redirect("tktsetup");
868871
}
869872
--- 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 ){
@@ -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 ){
@@ -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 @@
424424
Stmt q;
425425
int cnt = 0;
426426
int rc;
427427
428428
login_check_credentials();
429
- if( !g.perm.Admin ){ login_needed(); return; }
429
+ if( !g.perm.Admin ){ login_needed(0); return; }
430430
create_accesslog_table();
431431
432432
if( P("delall") && P("delallbtn") ){
433433
db_multi_exec("DELETE FROM accesslog");
434434
cgi_redirectf("%s/access_log?y=%d&n=%d&o=%o", g.zTop, y, n, skip);
435435
--- 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
+10 -10
--- src/wiki.c
+++ src/wiki.c
@@ -239,11 +239,11 @@
239239
** WEBPAGE: wikihelp
240240
** A generic landing page for wiki.
241241
*/
242242
void wiki_helppage(void){
243243
login_check_credentials();
244
- if( !g.perm.RdWiki ){ login_needed(); return; }
244
+ if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
245245
style_header("Wiki Help");
246246
wiki_standard_submenu(W_ALL_BUT(W_HELP));
247247
@ <h2>Wiki Links</h2>
248248
@ <ul>
249249
{ char *zWikiHomePageName = db_get("index-page",0);
@@ -312,11 +312,11 @@
312312
const char *zPageName;
313313
const char *zMimetype = 0;
314314
char *zBody = mprintf("%s","<i>Empty Page</i>");
315315
316316
login_check_credentials();
317
- if( !g.perm.RdWiki ){ login_needed(); return; }
317
+ if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
318318
zPageName = P("name");
319319
if( zPageName==0 ){
320320
if( search_restrict(SRCH_WIKI)!=0 ){
321321
wiki_srchpage();
322322
}else{
@@ -485,11 +485,11 @@
485485
zPageName = PD("name","");
486486
if( check_name(zPageName) ) return;
487487
isSandbox = is_sandbox(zPageName);
488488
if( isSandbox ){
489489
if( !g.perm.WrWiki ){
490
- login_needed();
490
+ login_needed(g.anon.WrWiki);
491491
return;
492492
}
493493
if( zBody==0 ){
494494
zBody = db_get("sandbox","");
495495
zMimetype = db_get("sandbox-mimetype","text/x-fossil-wiki");
@@ -501,11 +501,11 @@
501501
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
502502
" ORDER BY mtime DESC", zTag
503503
);
504504
free(zTag);
505505
if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){
506
- login_needed();
506
+ login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki);
507507
return;
508508
}
509509
if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
510510
zBody = pWiki->zWiki;
511511
zMimetype = pWiki->zMimetype;
@@ -625,11 +625,11 @@
625625
void wikinew_page(void){
626626
const char *zName;
627627
const char *zMimetype;
628628
login_check_credentials();
629629
if( !g.perm.NewWiki ){
630
- login_needed();
630
+ login_needed(g.anon.NewWiki);
631631
return;
632632
}
633633
zName = PD("name","");
634634
zMimetype = wiki_filter_mimetypes(P("mimetype"));
635635
if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){
@@ -727,11 +727,11 @@
727727
fossil_redirect_home();
728728
return;
729729
}
730730
}
731731
if( !g.perm.ApndWiki ){
732
- login_needed();
732
+ login_needed(g.anon.ApndWiki);
733733
return;
734734
}
735735
if( P("submit")!=0 && P("r")!=0 && P("u")!=0
736736
&& (goodCaptcha = captcha_is_correct())
737737
){
@@ -840,11 +840,11 @@
840840
*/
841841
void whistory_page(void){
842842
Stmt q;
843843
const char *zPageName;
844844
login_check_credentials();
845
- if( !g.perm.Hyperlink ){ login_needed(); return; }
845
+ if( !g.perm.Hyperlink ){ login_needed(g.anon.Hyperlink); return; }
846846
zPageName = PD("name","");
847847
style_header("History Of %s", zPageName);
848848
849849
db_prepare(&q, "%s AND event.objid IN "
850850
" (SELECT rid FROM tagxref WHERE tagid="
@@ -872,11 +872,11 @@
872872
Blob w1, w2, d;
873873
u64 diffFlags;
874874
875875
login_check_credentials();
876876
rid1 = atoi(PD("a","0"));
877
- if( !g.perm.Hyperlink ){ login_needed(); return; }
877
+ if( !g.perm.Hyperlink ){ login_needed(g.anon.Hyperlink); return; }
878878
if( rid1==0 ) fossil_redirect_home();
879879
rid2 = atoi(PD("b","0"));
880880
zPageName = PD("name","");
881881
style_header("Changes To %s", zPageName);
882882
@@ -935,11 +935,11 @@
935935
void wcontent_page(void){
936936
Stmt q;
937937
int showAll = P("all")!=0;
938938
939939
login_check_credentials();
940
- if( !g.perm.RdWiki ){ login_needed(); return; }
940
+ if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
941941
style_header("Available Wiki Pages");
942942
if( showAll ){
943943
style_submenu_element("Active", "Only Active Pages", "%s/wcontent", g.zTop);
944944
}else{
945945
style_submenu_element("All", "All", "%s/wcontent?all=1", g.zTop);
@@ -969,11 +969,11 @@
969969
*/
970970
void wfind_page(void){
971971
Stmt q;
972972
const char *zTitle;
973973
login_check_credentials();
974
- if( !g.perm.RdWiki ){ login_needed(); return; }
974
+ if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
975975
zTitle = PD("title","*");
976976
style_header("Wiki Pages Found");
977977
@ <ul>
978978
db_prepare(&q,
979979
"SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
980980
--- src/wiki.c
+++ src/wiki.c
@@ -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);
@@ -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{
@@ -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
@@ -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);
@@ -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{
@@ -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 @@
2727
** WEBPAGE: xfersetup
2828
*/
2929
void xfersetup_page(void){
3030
login_check_credentials();
3131
if( !g.perm.Setup ){
32
- login_needed();
32
+ login_needed(0);
33
+ return;
3334
}
3435
3536
style_header("Transfer Setup");
3637
3738
@ <table border="0" cellspacing="20">
@@ -104,11 +105,12 @@
104105
const char *z;
105106
int isSubmit;
106107
107108
login_check_credentials();
108109
if( !g.perm.Setup ){
109
- login_needed();
110
+ login_needed(0);
111
+ return;
110112
}
111113
if( P("setup") ){
112114
cgi_redirect("xfersetup");
113115
}
114116
isSubmit = P("submit")!=0;
115117
--- 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
+1 -1
--- src/zip.c
+++ src/zip.c
@@ -448,11 +448,11 @@
448448
int nName, nRid;
449449
Blob zip;
450450
char *zKey;
451451
452452
login_check_credentials();
453
- if( !g.perm.Zip ){ login_needed(); return; }
453
+ if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
454454
load_control();
455455
zName = mprintf("%s", PD("name",""));
456456
nName = strlen(zName);
457457
zRid = mprintf("%s", PD("uuid","trunk"));
458458
nRid = strlen(zRid);
459459
--- 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);
459
--- 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);
459

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button