Check-in [d57de28756]
Not logged in
Overview

SHA1 Hash:d57de28756ddf7716d08a04ebfe1f5f2fd8c7687
Date: 2008-05-05 23:15:29
User: drh
Comment:The "h" capability is now used to enable hyperlinks to non-wiki pages. When "h" is missing, many pages give a hyperlink to the login page and automatically fill in "anonymous" as the user name. The login page jumps back to the target page after a successful login.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/browse.c from [079928a8a6] to [9050864c16].

@@ -83,15 +83,15 @@
   int i, j;
   char *zSep = "";
 
   for(i=0; zPath[i]; i=j){
     for(j=i; zPath[j] && zPath[j]!='/'; j++){}
-    if( zPath[j] ){
+    if( zPath[j] && g.okHistory ){
       blob_appendf(pOut, "%s<a href=\"%s/dir?name=%#T\">%#h</a>",
                    zSep, g.zBaseURL, j, zPath, j-i, &zPath[i]);
     }else{
-      blob_appendf(pOut, "%s%h", zSep, &zPath[i]);
+      blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]);
     }
     zSep = "/";
     while( zPath[j]=='/' ){ j++; }
   }
 }

Modified src/db.c from [cbb81a64fd] to [5e79625a72].

@@ -1151,15 +1151,17 @@
 ){
   const char *zUuid;         /* The UUID to render */
   char *z;                   /* Rendered HTML text */
 
   zUuid = (const char*)sqlite3_value_text(argv[0]);
-  if( zUuid && strlen(zUuid)>=10 ){
+  if( g.okHistory && zUuid && strlen(zUuid)>=10 ){
     z = mprintf("<tt><a href='%s/vinfo/%t'><span style='font-size:1.5em'>"
                 "%#h</span>%h</a></tt>",
                 g.zBaseURL, zUuid, 10, zUuid, &zUuid[10]);
     sqlite3_result_text(pCxt, z, -1, free);
+  }else{
+    sqlite3_result_text(pCxt, zUuid, -1, SQLITE_TRANSIENT);
   }
 }
 
 /*
 ** SQL function to render a TAGID as a hyperlink to a page describing
@@ -1172,12 +1174,16 @@
 ){
   int tagid;                 /* The tagid to render */
   char *z;                   /* rendered html text */
 
   tagid = sqlite3_value_int(argv[0]);
-  z = mprintf("<a href='%s/tagview?tagid=%d'>%d</a>",
-                g.zBaseURL, tagid, tagid);
+  if( g.okHistory ){
+    z = mprintf("<a href='%s/tagview?tagid=%d'>%d</a>",
+                  g.zBaseURL, tagid, tagid);
+  }else{
+    z = mprintf("%d", tagid);
+  }
   sqlite3_result_text(pCxt, z, -1, free);
 }
 
 /*
 ** SQL function to render a TAGNAME as a hyperlink to a page describing
@@ -1190,12 +1196,16 @@
 ){
   const char *zTag;          /* The tag to render */
   char *z;                   /* rendered html text */
 
   zTag = (const char*)sqlite3_value_text(argv[0]);
-  z = mprintf("<a href='%s/tagview?name=%T'>%h</a>",
-                g.zBaseURL, zTag, zTag);
+  if( g.okHistory ){
+    z = mprintf("<a href='%s/tagview?name=%T'>%h</a>",
+                  g.zBaseURL, zTag, zTag);
+  }else{
+    z = mprintf("%h", zTag);
+  }
   sqlite3_result_text(pCxt, z, -1, free);
 }
 
 /*
 ** SQL function to escape all characters in a string that have special

Modified src/descendents.c from [27267403dd] to [44bebd8abf].

@@ -189,10 +189,11 @@
 
   login_check_credentials();
   if( !g.okRead ){ login_needed(); return; }
 
   style_header("Leaves");
+  login_anonymous_available();
   db_prepare(&q,
     "%s"
     "   AND blob.rid IN"
     "       (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
     " ORDER BY event.mtime DESC",

Modified src/login.c from [b58f50fb1a] to [659c4f23c6].

@@ -74,17 +74,19 @@
 ** Generate the login page
 */
 void login_page(void){
   const char *zUsername, *zPasswd, *zGoto;
   const char *zNew1, *zNew2;
-  const char *zAnonPw;
+  const char *zAnonPw = 0;
+  int anonFlag;
   char *zErrMsg = "";
 
   login_check_credentials();
   zUsername = P("u");
   zPasswd = P("p");
   zGoto = PD("g","index");
+  anonFlag = P("anon")!=0;
   if( P("out")!=0 ){
     const char *zCookieName = login_cookie_name();
     cgi_set_cookie(zCookieName, "", 0, -86400);
     cgi_redirect(zGoto);
   }
@@ -147,21 +149,35 @@
   }
   style_header("Login/Logout");
   @ %s(zErrMsg)
   @ <form action="login" method="POST">
   if( P("g") ){
-    @ <input type="hidden" name="nxp" value="%h(P("g"))">
+    @ <input type="hidden" name="g" value="%h(P("g"))">
   }
   @ <table align="left" hspace="10">
   @ <tr>
   @   <td align="right">User ID:</td>
-  @   <td><input type="text" name="u" value="" size=30></td>
+  if( anonFlag ){
+    @   <td><input type="text" name="u" value="anonymous" size=30></td>
+  }else{
+    @   <td><input type="text" name="u" value="" size=30></td>
+  }
   @ </tr>
   @ <tr>
   @  <td align="right">Password:</td>
   @   <td><input type="password" name="p" value="" size=30></td>
   @ </tr>
+  if( g.zLogin==0 ){
+    zAnonPw = db_text(0, "SELECT pw FROM user"
+                         " WHERE login='anonymous'"
+                         "   AND cap!=''");
+    if( zAnonPw && anonFlag ){
+      @ <tr><td></td>
+      @ <td>The anonymous password is "<b>%h(zAnonPw)</b>".</td>
+      @ </tr>
+    }
+  }
   @ <tr>
   @   <td></td>
   @   <td><input type="submit" name="in" value="Login"></td>
   @ </tr>
   @ </table>
@@ -174,19 +190,15 @@
   @ enter the user-id and password at the left and press the
   @ "Login" button.  Your user name will be stored in a browser cookie.
   @ You must configure your web browser to accept cookies in order for
   @ the login to take.</p>
   if( g.zLogin==0 ){
-    zAnonPw = db_text(0, "SELECT pw FROM user"
-                         " WHERE login='anonymous'"
-                         "   AND cap!=''");
-    if( zAnonPw ){
-      @ <p>If you do not have a user-id, enter "<b>anonymous</b>" with a
-      @ password of "<b>%h(zAnonPw)</b>".</p>
+    if( zAnonPw && !anonFlag ){
+      @ <p>The password for user "anonymous" is "<b>%h(zAnonPw)</b>".</p>
+      @ <p>&nbsp;</p>
     }else{
-      @ <p>A valid user-id and password is required.  Anonymous access
-      @ is not allowed on this installation.</p>
+      @ <p>&nbsp;</p><p>&nbsp;</p>
     }
   }
   if( g.zLogin ){
     @ <br clear="both"><hr>
     @ <p>To log off the system (and delete your login cookie)
@@ -381,11 +393,11 @@
 void login_anonymous_available(void){
   if( !g.okHistory &&
       db_exists("SELECT 1 FROM user"
                 " WHERE login='anonymous'"
                 "   AND cap LIKE '%%h%%'") ){
-    @ <p><b>Note:</b> Many hyperlinks are omitted from this page to discourage
-    @ <a href="http://en.wikipedia.org/wiki/Web_crawler">spiders</a>.
-    @ You will be able to access information more easily if you
-    @ <a href="%s(g.zTop)/login">login</a> as user "anonymous".</p>
+    const char *zUrl = PD("REQUEST_URI", "index");
+    @ <p>Many <font color="red">hyperlinks are disabled.</font><br />
+    @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
+    @ to enable hyperlinks.</p>
   }
 }

Modified src/tagview.c from [f0893454d5] to [9d79e57b4d].

@@ -144,10 +144,11 @@
   login_check_credentials();
   if( !g.okRdWiki ){
     login_needed();
   }
   style_header("Tags");
+  login_anonymous_available();
   tagview_page_search_miniform();
   @ <hr/>
   char const * check = 0;
   if( 0 != (check = P("tagid")) ){
     tagview_page_tag_by_id( atoi(check) );

Modified src/wikiformat.c from [8bd2fe1f58] to [30a93b7778].

@@ -787,10 +787,28 @@
   if( !validate16(z, n) ) return 0;
   return 1;
 }
 
 /*
+** Return true if the given hyperlink should be implemented for
+** the current login.
+*/
+static int okToHyperlink(const char *zTarget){
+  if( g.okHistory ) return 1;
+  if( strncmp(zTarget, "http:", 5)==0
+   || strncmp(zTarget, "https:", 6)==0
+   || strncmp(zTarget, "ftp:", 4)==0
+   || strncmp(zTarget, "mailto:", 7)==0
+  ){
+    return 1;
+  }
+  if( zTarget[0]=='/' || is_valid_uuid(zTarget) ) return 0;
+  if( wiki_name_is_wellformed(zTarget) ) return 1;
+  return 0;
+}
+
+/*
 ** Resolve a hyperlink.  The argument is the content of the [...]
 ** in the wiki.  Append the URL to the output of the Renderer.
 */
 static void resolveHyperlink(const char *zTarget, Renderer *p){
   if( strncmp(zTarget, "http:", 5)==0
@@ -930,10 +948,11 @@
       case TOKEN_LINK: {
         char *zTarget;
         char *zDisplay = 0;
         int i, j;
         int savedState;
+        int ok;
         startAutoParagraph(p);
         zTarget = &z[1];
         for(i=1; z[i] && z[i]!=']'; i++){
           if( z[i]=='|' && zDisplay==0 ){
             zDisplay = &z[i+1];
@@ -945,19 +964,22 @@
         if( zDisplay==0 ){
           zDisplay = zTarget;
         }else{
           while( isspace(*zDisplay) ) zDisplay++;
         }
-        blob_append(p->pOut, "<a href=\"", -1);
-        resolveHyperlink(zTarget, p);
-        blob_append(p->pOut, "\">", -1);
+        ok = okToHyperlink(zTarget);
+        if( ok ){
+          blob_append(p->pOut, "<a href=\"", -1);
+          resolveHyperlink(zTarget, p);
+          blob_append(p->pOut, "\">", -1);
+        }
         savedState = p->state;
         p->state &= ~ALLOW_WIKI;
         p->state |= FONT_MARKUP_ONLY;
         wiki_render(p, zDisplay);
         p->state = savedState;
-        blob_append(p->pOut, "</a>", 4);
+        if( ok ) blob_append(p->pOut, "</a>", 4);
         break;
       }
       case TOKEN_TEXT: {
         startAutoParagraph(p);
         blob_append(p->pOut, z, n);