Index: src/report.c
==================================================================
--- src/report.c
+++ src/report.c
@@ -873,11 +873,11 @@
Stmt q;
char *zErr1 = 0;
char *zErr2 = 0;
login_check_credentials();
- if( !g.okRead ){ login_needed(); return; }
+ if( !g.okRdTkt ){ login_needed(); return; }
rn = atoi(PD("rn","0"));
if( rn==0 ){
cgi_redirect("reportlist");
return;
}
Index: src/search.c
==================================================================
--- src/search.c
+++ src/search.c
@@ -175,11 +175,11 @@
** Testing the search function.
**
** COMMAND: search
** %fossil search pattern...
**
-** Search for timeline entrys matching the pattern.
+** Search for timeline entries matching the pattern.
*/
void search_cmd(void){
Search *p;
Blob pattern;
int i;
Index: src/skins.c
==================================================================
--- src/skins.c
+++ src/skins.c
@@ -188,14 +188,16 @@
@ if {[hascap h]} {
@ html "Files "
@ }
@ if {[hascap o]} {
@ html "Leaves "
-@ html "Timeline "
@ html "Branches "
@ html "Tags "
@ }
+@ if {[hascap h]} {
+@ html "Timeline "
+@ }
@ if {[hascap r]} {
@ html "Tickets "
@ }
@ if {[hascap j]} {
@ html "Wiki "
@@ -388,14 +390,16 @@
@ if {[hascap h]} {
@ html "Files "
@ }
@ if {[hascap o]} {
@ html "Leaves "
-@ html "Timeline "
@ html "Branches "
@ html "Tags "
@ }
+@ if {[hascap h]} {
+@ html "Timeline "
+@ }
@ if {[hascap r]} {
@ html "Tickets "
@ }
@ if {[hascap j]} {
@ html "Wiki "
@@ -621,14 +625,16 @@
@ if {[hascap h]} {
@ html "
Files"
@ }
@ if {[hascap o]} {
@ html "Leaves"
-@ html "Timeline"
@ html "Branches"
@ html "Tags"
@ }
+@ if {[hascap h]} {
+@ html "Timeline"
+@ }
@ if {[hascap r]} {
@ html "Tickets"
@ }
@ if {[hascap j]} {
@ html "Wiki"
Index: src/style.c
==================================================================
--- src/style.c
+++ src/style.c
@@ -210,14 +210,16 @@
@ if {[hascap h]} {
@ html "Files "
@ }
@ if {[hascap o]} {
@ html "Leaves "
-@ html "Timeline "
@ html "Branches "
@ html "Tags "
@ }
+@ if {[hascap h]} {
+@ html "Timeline "
+@ }
@ if {[hascap r]} {
@ html "Tickets "
@ }
@ if {[hascap j]} {
@ html "Wiki "
Index: src/timeline.c
==================================================================
--- src/timeline.c
+++ src/timeline.c
@@ -445,14 +445,20 @@
const char *zString = P("s"); /* String text search of comment and brief */
HQuery url; /* URL for various branch links */
int tagid; /* Tag ID */
int tmFlags; /* Timeline flags */
- /* To view the timeline, must have permission to read project data.
- */
+ /* To view the timeline, must have permission to project history.*/
login_check_credentials();
- if( !g.okRead ){ login_needed(); return; }
+ if( !g.okHistory ){ login_needed(); return; }
+
+ /* Prevent them from getting an empty list due to security constraints */
+ if( (p_rid || d_rid) && !g.okRead ){ login_needed(); return; }
+ if( zType[0]=='c' && zType[1]=='i' && !g.okRead){ login_needed(); return; }
+ if( zType[0]=='t' && !g.okRdTkt){ login_needed(); return; }
+ if( zType[0]=='w' && !g.okRdWiki){ login_needed(); return; }
+
if( zTagName ){
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
}else{
tagid = 0;
}
@@ -467,10 +473,20 @@
timeline_temp_table();
blob_zero(&sql);
blob_zero(&desc);
blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1);
blob_append(&sql, timeline_query_for_www(), -1);
+ /* limit the types of objects found in history */
+ if( !g.okRead ){
+ blob_appendf(&sql, " AND event.type<>'ci'");
+ }
+ if( !g.okRdTkt ){
+ blob_appendf(&sql, " AND event.type<>'t'");
+ }
+ if( !g.okRdWiki ){
+ blob_appendf(&sql, " AND event.type<>'w'");
+ }
if( p_rid || d_rid ){
/* If p= or d= is present, ignore all other parameters other than n= */
char *zUuid;
int np, nd;
@@ -636,17 +652,17 @@
free(zDate);
}else if( tagid==0 ){
if( zType[0]!='a' ){
timeline_submenu(&url, "All Types", "y", "all", 0);
}
- if( zType[0]!='w' ){
+ if( zType[0]!='w' && g.okRdWiki ){
timeline_submenu(&url, "Wiki Only", "y", "w", 0);
}
- if( zType[0]!='c' ){
+ if( zType[0]!='c' && g.okRead ){
timeline_submenu(&url, "Checkins Only", "y", "ci", 0);
}
- if( zType[0]!='t' ){
+ if( zType[0]!='t' && g.okRdTkt ){
timeline_submenu(&url, "Tickets Only", "y", "t", 0);
}
}
if( nEntry>20 ){
timeline_submenu(&url, "20 Events", "n", "20", 0);