Check-in [fd36718ad9]
Not logged in
Overview

SHA1 Hash:fd36718ad98c4a01632eeccb777fec847c1de7af
Date: 2007-07-31 23:33:15
User: drh
Comment:Add the new "history" permission. Merge in changes that require permissions to view the timeline.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/info.c from [199807a9fd] to [a530681566].

@@ -116,10 +116,12 @@
   Stmt q;
   int rid;
   char cType;
   char *zType;
 
+  login_check_credentials();
+  if( !g.okHistory ){ login_needed(); return; }
   style_header("Version Information");
   rid = name_to_rid(g.zExtra);
   if( rid==0 ){
     @ No such object: %h(g.argv[2])
     style_footer();

Modified src/login.c from [8a96b84fb6] to [8638b80caa].

@@ -260,20 +260,24 @@
   }
   if( zCap==0 ){
     if( uid ){
       Stmt s;
       db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
-      db_step(&s);
-      g.zLogin = db_column_malloc(&s, 0);
-      zCap = db_column_malloc(&s, 1);
+      if( db_step(&s)==SQLITE_ROW ){
+        g.zLogin = db_column_malloc(&s, 0);
+        zCap = db_column_malloc(&s, 1);
+      }
       db_finalize(&s);
     }
     if( zCap==0 ){
       zCap = "";
     }
   }
   g.userUid = uid;
+  if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
+    g.zLogin = 0;
+  }
   login_set_capabilities(zCap);
 }
 
 /*
 ** Set the global capability flags based on a capability string.
@@ -282,16 +286,17 @@
   int i;
   for(i=0; zCap[i]; i++){
     switch( zCap[i] ){
       case 's':   g.okSetup = g.okDelete = 1;
       case 'a':   g.okAdmin = g.okRdTkt = g.okWrTkt = g.okQuery =
-                              g.okRdWiki = g.okWrWiki =
+                              g.okRdWiki = g.okWrWiki = g.okHistory =
                               g.okNewTkt = g.okPassword = 1;
       case 'i':   g.okRead = g.okWrite = 1;                     break;
       case 'o':   g.okRead = 1;                                 break;
 
       case 'd':   g.okDelete = 1;                               break;
+      case 'h':   g.okHistory = 1;                              break;
       case 'p':   g.okPassword = 1;                             break;
       case 'q':   g.okQuery = 1;                                break;
 
       case 'j':   g.okRdWiki = 1;                               break;
       case 'k':   g.okWrWiki = g.okRdWiki = g.okApndWiki =1;    break;
@@ -311,9 +316,9 @@
 ** Call this routine when the credential check fails.  It causes
 ** a redirect to the "login" page.
 */
 void login_needed(void){
   const char *zUrl = PD("REQUEST_URI", "index");
-  cgi_redirect(mprintf("login?nxp=%T", zUrl));
+  cgi_redirect(mprintf("login?g=%T", zUrl));
   /* NOTREACHED */
   assert(0);
 }

Modified src/main.c from [21f5fffa72] to [e3d8b5d0b9].

@@ -98,10 +98,11 @@
   int okApndWiki;         /* append to wiki via web */
   int okPassword;         /* change password */
   int okAdmin;            /* administrative permission */
   int okDelete;           /* delete wiki or tickets */
   int okQuery;            /* create new reports */
+  int okHistory;          /* access historical information */
 
   FILE *fDebug;           /* Write debug information here, if the file exists */
 };
 
 /*

Modified src/setup.c from [288da0d25b] to [b21a277cb9].

@@ -112,19 +112,21 @@
     @ <td align="center">%s(db_column_text(&s,2))</td>
     @ <td align="left">%s(db_column_text(&s,3))</td>
     @ </tr>
   }
   @ </table></td></tr></table>
-  @ <p>
+  @ <p style="clear:both">
   @ <b>Notes:</b>
   @ <ol>
   @ <li><p>The permission flags are as follows:</p>
   @ <table>
   @ <tr><td>a</td><td width="10"></td>
   @     <td>Admin: Create or delete users and ticket report formats</td></tr>
   @ <tr><td>d</td><td></td>
   @     <td>Delete: Erase anonymous wiki, tickets, and attachments</td></tr>
+  @ <tr><td>h</td><td></td>
+  @     <td>History: Access older version of code, tickets, or wiki</td></tr>
   @ <tr><td>i</td><td></td>
   @     <td>Check-in: Add new code to the repository</td></tr>
   @ <tr><td>j</td><td></td><td>Read-Wiki: View wiki pages</td></tr>
   @ <tr><td>k</td><td></td><td>Wiki: Create or modify wiki pages</td></tr>
   @ <tr><td>n</td><td></td><td>New: Create new tickets</td></tr>
@@ -153,11 +155,11 @@
 ** WEBPAGE: /setup_uedit
 */
 void user_edit(void){
   const char *zId, *zLogin, *zInfo, *zCap;
   char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ;
-  char *oak, *oad, *oaq, *oac, *oaf, *oam;
+  char *oak, *oad, *oaq, *oac, *oaf, *oam, *oah;
   int doWrite;
   int uid;
   int higherUser = 0;  /* True if user being edited is SETUP and the */
                        /* user doing the editing is ADMIN.  Disallow editing */
 
@@ -188,11 +190,11 @@
   */
   doWrite = cgi_all("login","info","pw") && !higherUser;
   if( doWrite ){
     const char *zPw;
     const char *zLogin;
-    char zCap[20];
+    char zCap[30];
     int i = 0;
     int aa = P("aa")!=0;
     int ad = P("ad")!=0;
     int ai = P("ai")!=0;
     int aj = P("aj")!=0;
@@ -205,21 +207,16 @@
     int as = g.okSetup && P("as")!=0;
     int aw = P("aw")!=0;
     int ac = P("ac")!=0;
     int af = P("af")!=0;
     int am = P("am")!=0;
-#if 0
-    if( as ) aa = 1;
-    if( aa ) ai = aw = ap = 1;
-    if( aw ) an = ar = 1;
-    if( ai ) ao = 1;
-    if( ak ) aj = 1;
-#endif
+    int ah = P("ah")!=0;
     if( aa ){ zCap[i++] = 'a'; }
     if( ac ){ zCap[i++] = 'c'; }
     if( ad ){ zCap[i++] = 'd'; }
     if( af ){ zCap[i++] = 'f'; }
+    if( ah ){ zCap[i++] = 'h'; }
     if( ai ){ zCap[i++] = 'i'; }
     if( aj ){ zCap[i++] = 'j'; }
     if( ak ){ zCap[i++] = 'k'; }
     if( am ){ zCap[i++] = 'm'; }
     if( an ){ zCap[i++] = 'n'; }
@@ -259,20 +256,21 @@
   /* Load the existing information about the user, if any
   */
   zLogin = "";
   zInfo = "";
   zCap = "";
-  oaa = oac = oad = oaf = oai = oaj = oak = oam =
+  oaa = oac = oad = oaf = oah = oai = oaj = oak = oam =
         oan = oao = oap = oaq = oar = oas = oaw = "";
   if( uid ){
     zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
     zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
     zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
     if( strchr(zCap, 'a') ) oaa = " checked";
     if( strchr(zCap, 'c') ) oac = " checked";
     if( strchr(zCap, 'd') ) oad = " checked";
     if( strchr(zCap, 'f') ) oaf = " checked";
+    if( strchr(zCap, 'h') ) oah = " checked";
     if( strchr(zCap, 'i') ) oai = " checked";
     if( strchr(zCap, 'j') ) oaj = " checked";
     if( strchr(zCap, 'k') ) oak = " checked";
     if( strchr(zCap, 'm') ) oam = " checked";
     if( strchr(zCap, 'n') ) oan = " checked";
@@ -321,10 +319,11 @@
   @     <input type="checkbox" name="ad"%s(oad)>Delete</input><br>
   @     <input type="checkbox" name="ap"%s(oap)>Password</input><br>
   @     <input type="checkbox" name="aq"%s(oaq)>Query</input><br>
   @     <input type="checkbox" name="ai"%s(oai)>Check-In</input><br>
   @     <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br>
+  @     <input type="checkbox" name="ah"%s(oah)>History</input><br>
   @     <input type="checkbox" name="aj"%s(oaj)>Read Wiki</input><br>
   @     <input type="checkbox" name="af"%s(oaf)>New Wiki</input><br>
   @     <input type="checkbox" name="am"%s(oam)>Append Wiki</input><br>
   @     <input type="checkbox" name="ak"%s(oak)>Write Wiki</input><br>
   @     <input type="checkbox" name="ar"%s(oar)>Read Tkt</input><br>
@@ -376,11 +375,13 @@
   @ <li><p>
   @ No login is required for user "<b>nobody</b>".  The capabilities
   @ of this user are available to anyone without supplying a username or
   @ password.  To disable nobody access, make sure there is no user
   @ with an ID of <b>nobody</b> or that the nobody user has no
-  @ capabilities enabled.  The password for the noloing user is ignore.
+  @ capabilities enabled.  The password for nobody is ignore.  To
+  @ avoid problems with spiders overloading the server, it is suggested
+  @ that the 'h' (History) capability be turned off for user nobody.
   @ </p></li>
   @
   @ <li><p>
   @ Login is required for user "<b>anonymous</b>" but the password
   @ is displayed on the login screen beside the password entry box

Modified src/style.c from [ed5f94f215] to [9a943b5a17].

@@ -84,11 +84,13 @@
   }else{
     @ <small>logged in as %h(g.zLogin)</small>
   }
   @ </td><td valign="top" align="right">
   @ <a href="%s(g.zBaseURL)/index">Home</a>
-  @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
+  if( g.okRead ){
+    @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
+  }
   if( g.okRdWiki ){
     @ | <a href="%s(g.zBaseURL)/wiki">Wiki</a>
   }
 #if 0
   @ | <font color="#888888">Search</font>

Modified src/timeline.c from [b52c0c0c75] to [ccb6f43a3a].

@@ -31,21 +31,27 @@
 ** Generate a hyperlink to a version.
 */
 void hyperlink_to_uuid(const char *zUuid){
   char zShortUuid[UUID_SIZE+1];
   sprintf(zShortUuid, "%.10s", zUuid);
-  @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
+  if( g.okHistory ){
+    @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
+  }else{
+    @ <b>[%s(zShortUuid)]</b>
+  }
 }
 
 /*
 ** Generate a hyperlink to a diff between two versions.
 */
 void hyperlink_to_diff(const char *zV1, const char *zV2){
-  if( zV2==0 ){
-    @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
-  }else{
-    @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
+  if( g.okHistory ){
+    if( zV2==0 ){
+      @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
+    }else{
+      @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
+    }
   }
 }
 
 
 /*
@@ -52,10 +58,16 @@
 ** WEBPAGE: timeline
 */
 void page_timeline(void){
   Stmt q;
   char zPrevDate[20];
+
+  /* To view the timeline, must have permission to read project data.
+  */
+  login_check_credentials();
+  if( !g.okRead ){ login_needed(); return; }
+
   style_header("Timeline");
   zPrevDate[0] = 0;
   db_prepare(&q,
     "SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
     "  FROM event, blob"