Fossil SCM

Do not allow edits to wiki pages associated with branches, checkins, or tags for users who do not also have checkin privileges.

drh 2018-12-31 14:33 describe-objects-using-wiki
Commit 60e8a08f2200140bd5d94fedbc195bcfc59d595da4a28c4089eb0463683236c8
2 files changed +26 -8 +31 -1
+26 -8
--- src/info.c
+++ src/info.c
@@ -691,10 +691,11 @@
691691
const char *zOrigUser;
692692
const char *zComment;
693693
const char *zDate;
694694
const char *zOrigDate;
695695
const char *zBrName;
696
+ int okWiki = 0;
696697
Blob wiki_links = BLOB_INITIALIZER;
697698
698699
style_header("Check-in [%S]", zUuid);
699700
login_anonymous_available();
700701
zEUser = db_text(0,
@@ -761,16 +762,20 @@
761762
" AND +tag.tagname GLOB 'sym-*'", rid);
762763
while( db_step(&q2)==SQLITE_ROW ){
763764
const char *zTagName = db_column_text(&q2, 0);
764765
if( fossil_strcmp(zTagName,zBrName)==0 ){
765766
@ | %z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
766
- blob_appendf(&wiki_links, " | %z%h</a>",
767
- href("%R/wiki?name=branch/%h",zTagName), zTagName);
767
+ if( g.perm.Write || wiki_tagid2("branch",zTagName)!=0 ){
768
+ blob_appendf(&wiki_links, " | %z%h</a>",
769
+ href("%R/wiki?name=branch/%h",zTagName), zTagName);
770
+ }
768771
}else{
769772
@ | %z(href("%R/timeline?t=%T&unhide",zTagName))%h(zTagName)</a>
770
- blob_appendf(&wiki_links, " | %z%h</a>",
771
- href("%R/wiki?name=tag/%h",zTagName), zTagName);
773
+ if( g.perm.Write || wiki_tagid2("tag",zTagName)!=0 ){
774
+ blob_appendf(&wiki_links, " | %z%h</a>",
775
+ href("%R/wiki?name=tag/%h",zTagName), zTagName);
776
+ }
772777
}
773778
}
774779
db_finalize(&q2);
775780
@ </td></tr>
776781
@@ -816,15 +821,28 @@
816821
@ <tr><th>Received&nbsp;From:</th>
817822
@ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
818823
}
819824
db_finalize(&q2);
820825
}
821
- if( g.perm.RdWiki && db_get_boolean("wiki-about",1) ){
822
- @ <tr><th>Wiki:</th>
823
- @ <td>%z(href("%R/wiki?name=checkin/%s",zUuid))this checkin</a>
824
- @ %b(&wiki_links)</td>
826
+
827
+ /* Only show links to wiki pages if the users can read wiki,
828
+ ** and only if the wiki pages already exist or the user has the
829
+ ** ability to create new ones. */
830
+ if( g.perm.RdWiki
831
+ && (g.perm.Write || blob_size(&wiki_links)>0
832
+ || (okWiki = wiki_tagid2("checkin",zUuid))!=0)
833
+ && db_get_boolean("wiki-about",1)
834
+ ){
835
+ const char *zLinks = blob_str(&wiki_links);
836
+ if( zLinks[0] ) zLinks += 3;
837
+ @ <tr><th>Wiki:</th><td>\
838
+ if( g.perm.Write || okWiki ){
839
+ @ %z(href("%R/wiki?name=checkin/%s",zUuid))this checkin</a> | \
840
+ }
841
+ @ %s(zLinks)</td></tr>
825842
}
843
+
826844
if( g.perm.Hyperlink ){
827845
@ <tr><th>Other&nbsp;Links:</th>
828846
@ <td>
829847
@ %z(href("%R/artifact/%!S",zUuid))manifest</a>
830848
@ | %z(href("%R/ci_tags/%!S",zUuid))tags</a>
831849
--- src/info.c
+++ src/info.c
@@ -691,10 +691,11 @@
691 const char *zOrigUser;
692 const char *zComment;
693 const char *zDate;
694 const char *zOrigDate;
695 const char *zBrName;
 
696 Blob wiki_links = BLOB_INITIALIZER;
697
698 style_header("Check-in [%S]", zUuid);
699 login_anonymous_available();
700 zEUser = db_text(0,
@@ -761,16 +762,20 @@
761 " AND +tag.tagname GLOB 'sym-*'", rid);
762 while( db_step(&q2)==SQLITE_ROW ){
763 const char *zTagName = db_column_text(&q2, 0);
764 if( fossil_strcmp(zTagName,zBrName)==0 ){
765 @ | %z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
766 blob_appendf(&wiki_links, " | %z%h</a>",
767 href("%R/wiki?name=branch/%h",zTagName), zTagName);
 
 
768 }else{
769 @ | %z(href("%R/timeline?t=%T&unhide",zTagName))%h(zTagName)</a>
770 blob_appendf(&wiki_links, " | %z%h</a>",
771 href("%R/wiki?name=tag/%h",zTagName), zTagName);
 
 
772 }
773 }
774 db_finalize(&q2);
775 @ </td></tr>
776
@@ -816,15 +821,28 @@
816 @ <tr><th>Received&nbsp;From:</th>
817 @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
818 }
819 db_finalize(&q2);
820 }
821 if( g.perm.RdWiki && db_get_boolean("wiki-about",1) ){
822 @ <tr><th>Wiki:</th>
823 @ <td>%z(href("%R/wiki?name=checkin/%s",zUuid))this checkin</a>
824 @ %b(&wiki_links)</td>
 
 
 
 
 
 
 
 
 
 
 
 
825 }
 
826 if( g.perm.Hyperlink ){
827 @ <tr><th>Other&nbsp;Links:</th>
828 @ <td>
829 @ %z(href("%R/artifact/%!S",zUuid))manifest</a>
830 @ | %z(href("%R/ci_tags/%!S",zUuid))tags</a>
831
--- src/info.c
+++ src/info.c
@@ -691,10 +691,11 @@
691 const char *zOrigUser;
692 const char *zComment;
693 const char *zDate;
694 const char *zOrigDate;
695 const char *zBrName;
696 int okWiki = 0;
697 Blob wiki_links = BLOB_INITIALIZER;
698
699 style_header("Check-in [%S]", zUuid);
700 login_anonymous_available();
701 zEUser = db_text(0,
@@ -761,16 +762,20 @@
762 " AND +tag.tagname GLOB 'sym-*'", rid);
763 while( db_step(&q2)==SQLITE_ROW ){
764 const char *zTagName = db_column_text(&q2, 0);
765 if( fossil_strcmp(zTagName,zBrName)==0 ){
766 @ | %z(href("%R/timeline?r=%T&unhide",zTagName))%h(zTagName)</a>
767 if( g.perm.Write || wiki_tagid2("branch",zTagName)!=0 ){
768 blob_appendf(&wiki_links, " | %z%h</a>",
769 href("%R/wiki?name=branch/%h",zTagName), zTagName);
770 }
771 }else{
772 @ | %z(href("%R/timeline?t=%T&unhide",zTagName))%h(zTagName)</a>
773 if( g.perm.Write || wiki_tagid2("tag",zTagName)!=0 ){
774 blob_appendf(&wiki_links, " | %z%h</a>",
775 href("%R/wiki?name=tag/%h",zTagName), zTagName);
776 }
777 }
778 }
779 db_finalize(&q2);
780 @ </td></tr>
781
@@ -816,15 +821,28 @@
821 @ <tr><th>Received&nbsp;From:</th>
822 @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
823 }
824 db_finalize(&q2);
825 }
826
827 /* Only show links to wiki pages if the users can read wiki,
828 ** and only if the wiki pages already exist or the user has the
829 ** ability to create new ones. */
830 if( g.perm.RdWiki
831 && (g.perm.Write || blob_size(&wiki_links)>0
832 || (okWiki = wiki_tagid2("checkin",zUuid))!=0)
833 && db_get_boolean("wiki-about",1)
834 ){
835 const char *zLinks = blob_str(&wiki_links);
836 if( zLinks[0] ) zLinks += 3;
837 @ <tr><th>Wiki:</th><td>\
838 if( g.perm.Write || okWiki ){
839 @ %z(href("%R/wiki?name=checkin/%s",zUuid))this checkin</a> | \
840 }
841 @ %s(zLinks)</td></tr>
842 }
843
844 if( g.perm.Hyperlink ){
845 @ <tr><th>Other&nbsp;Links:</th>
846 @ <td>
847 @ %z(href("%R/artifact/%!S",zUuid))manifest</a>
848 @ | %z(href("%R/ci_tags/%!S",zUuid))tags</a>
849
+31 -1
--- src/wiki.c
+++ src/wiki.c
@@ -78,10 +78,14 @@
7878
** Return the tagid associated with a particular wiki page.
7979
*/
8080
int wiki_tagid(const char *zPageName){
8181
return db_int(0, "SELECT tagid FROM tag WHERE tagname='wiki-%q'",zPageName);
8282
}
83
+int wiki_tagid2(const char *zPrefix, const char *zPageName){
84
+ return db_int(0, "SELECT tagid FROM tag WHERE tagname='wiki-%q/%q'",
85
+ zPrefix, zPageName);
86
+}
8387
8488
/*
8589
** Return the RID of the next or previous version of a wiki page.
8690
** Return 0 if rid is the last/first version.
8791
*/
@@ -371,10 +375,30 @@
371375
}
372376
else{
373377
style_header("%s%s", zExtra, zPageName);
374378
}
375379
}
380
+
381
+/*
382
+** Wiki pages with special names "branch/...", "checkin/...", and "tag/..."
383
+** requires perm.Write privilege in addition to perm.WrWiki in order
384
+** to write. This function determines whether the extra perm.Write
385
+** is required and available. Return true if writing to the wiki page
386
+** may proceed, and return false if permission is lacking.
387
+*/
388
+static int wiki_special_permission(const char *zPageName){
389
+ if( strncmp(zPageName,"branch/",7)!=0
390
+ && strncmp(zPageName,"checkin/",8)!=0
391
+ && strncmp(zPageName,"tag/",4)!=0
392
+ ){
393
+ return 1;
394
+ }
395
+ if( db_get_boolean("wiki-about",1)==0 ){
396
+ return 1;
397
+ }
398
+ return g.perm.Write;
399
+}
376400
377401
/*
378402
** WEBPAGE: wiki
379403
** URL: /wiki?name=PAGENAME
380404
*/
@@ -424,11 +448,13 @@
424448
zMimetype = pWiki->zMimetype;
425449
}
426450
}
427451
zMimetype = wiki_filter_mimetypes(zMimetype);
428452
if( !g.isHome ){
429
- if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
453
+ if( ((rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki))
454
+ && wiki_special_permission(zPageName)
455
+ ){
430456
if( db_get_boolean("wysiwyg-wiki", 0) ){
431457
style_submenu_element("Edit", "%s/wikiedit?name=%T&wysiwyg=1",
432458
g.zTop, zPageName);
433459
}else{
434460
style_submenu_element("Edit", "%s/wikiedit?name=%T", g.zTop, zPageName);
@@ -554,10 +580,14 @@
554580
"SELECT rid FROM tagxref"
555581
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
556582
" ORDER BY mtime DESC", zTag
557583
);
558584
free(zTag);
585
+ if( !wiki_special_permission(zPageName) ){
586
+ login_needed(0);
587
+ return;
588
+ }
559589
if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){
560590
login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki);
561591
return;
562592
}
563593
if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
564594
--- src/wiki.c
+++ src/wiki.c
@@ -78,10 +78,14 @@
78 ** Return the tagid associated with a particular wiki page.
79 */
80 int wiki_tagid(const char *zPageName){
81 return db_int(0, "SELECT tagid FROM tag WHERE tagname='wiki-%q'",zPageName);
82 }
 
 
 
 
83
84 /*
85 ** Return the RID of the next or previous version of a wiki page.
86 ** Return 0 if rid is the last/first version.
87 */
@@ -371,10 +375,30 @@
371 }
372 else{
373 style_header("%s%s", zExtra, zPageName);
374 }
375 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
377 /*
378 ** WEBPAGE: wiki
379 ** URL: /wiki?name=PAGENAME
380 */
@@ -424,11 +448,13 @@
424 zMimetype = pWiki->zMimetype;
425 }
426 }
427 zMimetype = wiki_filter_mimetypes(zMimetype);
428 if( !g.isHome ){
429 if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
 
 
430 if( db_get_boolean("wysiwyg-wiki", 0) ){
431 style_submenu_element("Edit", "%s/wikiedit?name=%T&wysiwyg=1",
432 g.zTop, zPageName);
433 }else{
434 style_submenu_element("Edit", "%s/wikiedit?name=%T", g.zTop, zPageName);
@@ -554,10 +580,14 @@
554 "SELECT rid FROM tagxref"
555 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
556 " ORDER BY mtime DESC", zTag
557 );
558 free(zTag);
 
 
 
 
559 if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){
560 login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki);
561 return;
562 }
563 if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
564
--- src/wiki.c
+++ src/wiki.c
@@ -78,10 +78,14 @@
78 ** Return the tagid associated with a particular wiki page.
79 */
80 int wiki_tagid(const char *zPageName){
81 return db_int(0, "SELECT tagid FROM tag WHERE tagname='wiki-%q'",zPageName);
82 }
83 int wiki_tagid2(const char *zPrefix, const char *zPageName){
84 return db_int(0, "SELECT tagid FROM tag WHERE tagname='wiki-%q/%q'",
85 zPrefix, zPageName);
86 }
87
88 /*
89 ** Return the RID of the next or previous version of a wiki page.
90 ** Return 0 if rid is the last/first version.
91 */
@@ -371,10 +375,30 @@
375 }
376 else{
377 style_header("%s%s", zExtra, zPageName);
378 }
379 }
380
381 /*
382 ** Wiki pages with special names "branch/...", "checkin/...", and "tag/..."
383 ** requires perm.Write privilege in addition to perm.WrWiki in order
384 ** to write. This function determines whether the extra perm.Write
385 ** is required and available. Return true if writing to the wiki page
386 ** may proceed, and return false if permission is lacking.
387 */
388 static int wiki_special_permission(const char *zPageName){
389 if( strncmp(zPageName,"branch/",7)!=0
390 && strncmp(zPageName,"checkin/",8)!=0
391 && strncmp(zPageName,"tag/",4)!=0
392 ){
393 return 1;
394 }
395 if( db_get_boolean("wiki-about",1)==0 ){
396 return 1;
397 }
398 return g.perm.Write;
399 }
400
401 /*
402 ** WEBPAGE: wiki
403 ** URL: /wiki?name=PAGENAME
404 */
@@ -424,11 +448,13 @@
448 zMimetype = pWiki->zMimetype;
449 }
450 }
451 zMimetype = wiki_filter_mimetypes(zMimetype);
452 if( !g.isHome ){
453 if( ((rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki))
454 && wiki_special_permission(zPageName)
455 ){
456 if( db_get_boolean("wysiwyg-wiki", 0) ){
457 style_submenu_element("Edit", "%s/wikiedit?name=%T&wysiwyg=1",
458 g.zTop, zPageName);
459 }else{
460 style_submenu_element("Edit", "%s/wikiedit?name=%T", g.zTop, zPageName);
@@ -554,10 +580,14 @@
580 "SELECT rid FROM tagxref"
581 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
582 " ORDER BY mtime DESC", zTag
583 );
584 free(zTag);
585 if( !wiki_special_permission(zPageName) ){
586 login_needed(0);
587 return;
588 }
589 if( (rid && !g.perm.WrWiki) || (!rid && !g.perm.NewWiki) ){
590 login_needed(rid ? g.anon.WrWiki : g.anon.NewWiki);
591 return;
592 }
593 if( zBody==0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
594

Keyboard Shortcuts

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