SHA1 Hash: | 5fb14b9a0fa04a788de384897e65458a9d8f8eaa |
---|---|
Date: | 2008-08-21 20:59:01 |
User: | eric |
Comment: | Include non-sym- tags in tagview web page. Also merge mainline into tagview branch. |
Timelines: | ancestors | descendants | both | eric-tagview-rework | trunk |
Other Links: | files | ZIP archive | manifest |
- branch=trunk inherited from [a28c83647d]
- sym-eric-tagview-rework inherited from [3984b1b2c1]
- sym-trunk inherited from [a28c83647d]
Modified src/admin.c from [3d7573884c] to [8499f27819].
@@ -108,10 +108,10 @@ } admin_prepare_submenu(); style_header("Admin"); @ <h2>Links:</h2> @ <ul> - @ <li><a href='%s(g.zBaseURL)/admin/setup'>Fossil WWW Setup</a></li> + @ <li><a href='%s(g.zBaseURL)/setup'>Fossil WWW Setup</a></li> @ <li><a href='%s(g.zBaseURL)/admin/sql'>Run SQL queries</a></li> @ </ul> style_footer(); }
Modified src/checkin.c from [b72cce6453] to [425f4bbcea].
@@ -250,11 +250,15 @@ } if( zEditor==0 ){ zEditor = getenv("EDITOR"); } if( zEditor==0 ){ +#ifdef __MINGW32__ + zEditor = "notepad"; +#else zEditor = "ed"; +#endif } zFile = db_text(0, "SELECT '%qci-comment-' || hex(randomblob(6)) || '.txt'", g.zLocalRoot); #ifdef __MINGW32__ blob_add_cr(&text); @@ -329,11 +333,11 @@ ** ** Usage: %fossil commit ?-m COMMENT? ?--nosign? ?FILE...? ** ** Create a new version containing all of the changes in the current ** checkout. You will be prompted to enter a check-in comment unless -** the "-m" option is used to specify a command line. You will be +** the "-m" option is used to specify a comment line. You will be ** prompted for your GPG passphrase in order to sign the new manifest ** unless the "--nosign" options is used. All files that have ** changed will be committed unless some subset of files is specified ** on the command line. */ @@ -593,11 +597,11 @@ /* ** COMMAND: test-import-manifest ** ** Usage: %fossil test-import-manifest DATE COMMENT ?-p PARENT_RECORDID?... ?-f (FILE_RECORDID PATH)?... ** -** Create a new version containing containing the specified file +** Create a new version containing the specified file ** revisions (if any), and child of the given PARENT version. */ void import_manifest_cmd(void){ const char* zDate; /* argument - timestamp, as seconds since epoch (int) */ const char* zComment; /* argument - manifest comment */
Modified src/db.c from [2755f169fc] to [1ccbb50ea2].
@@ -789,13 +789,15 @@ "INSERT INTO user(login, pw, cap, info)" "VALUES(%Q,'','s','')", zUser ); db_multi_exec( "INSERT INTO user(login,pw,cap,info)" - " VALUES('anonymous','anonymous','hjkorw','Anon');" + " VALUES('anonymous','anonymous','aghknw','Anon');" "INSERT INTO user(login,pw,cap,info)" " VALUES('nobody','','jor','Nobody');" + "INSERT INTO user(login,pw,cap,info)" + " VALUES('developer','','deipt','Dev');" ); user_select(); if (makeInitialVersion){ blob_zero(&manifest);
Modified src/info.c from [3ed7c9edba] to [33a76dcbd4].
@@ -116,11 +116,11 @@ Stmt q; int cnt = 0; db_prepare(&q, "SELECT plink.cid, blob.uuid, datetime(plink.mtime, 'localtime')," " coalesce(event.euser,event.user)," - " coalesce(event.comment,event.ecomment)" + " coalesce(event.ecomment,event.comment)" " FROM plink, blob, event" " WHERE plink.pid=%d" " AND blob.rid=plink.cid" " AND event.objid=plink.cid" " ORDER BY plink.mtime ASC", @@ -168,11 +168,11 @@ Stmt q; int cnt = 0; db_prepare(&q, "SELECT plink.pid, blob.uuid, datetime(event.mtime, 'localtime')," " coalesce(event.euser,event.user)," - " coalesce(event.comment,event.ecomment)" + " coalesce(event.ecomment,event.comment)" " FROM plink, blob, event" " WHERE plink.cid=%d" " AND blob.rid=plink.pid" " AND event.objid=plink.pid" " ORDER BY event.mtime DESC", @@ -354,25 +354,29 @@ }else{ @ <tr><th>Comment:</th><td>%w(zComment)</td></tr> } @ </td></tr> if( g.okHistory ){ + char *zShortUuid = mprintf("%.10s", zUuid); + const char *zProjName = db_get("project-name", "unnamed"); @ <tr><th>Timelines:</th><td> @ <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a> @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a> @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)&p=%d(rid)">both</a> @ </td></tr> @ <tr><th>Commands:</th> @ <td> @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a> - @ | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a> + @ | <a href="%s(g.zBaseURL)/zip/%s(zProjName)-%s(zShortUuid).zip?uuid=%s(zUuid)"> + @ ZIP archive</a> @ | <a href="%s(g.zBaseURL)/artifact/%d(rid)">manifest</a> if( g.okWrite ){ @ | <a href="%s(g.zBaseURL)/vedit?r=%d(rid)">edit</a> } @ </td> @ </tr> + free(zShortUuid); } @ </table></p> }else{ style_header("Baseline Information"); login_anonymous_available(); @@ -655,11 +659,11 @@ Stmt q; int cnt = 0; int nWiki = 0; db_prepare(&q, "SELECT filename.name, datetime(event.mtime), substr(a.uuid,1,10)," - " coalesce(event.comment,event.ecomment)," + " coalesce(event.ecomment,event.comment)," " coalesce(event.euser,event.user)," " b.uuid" " FROM mlink, filename, event, blob a, blob b" " WHERE filename.fnid=mlink.fnid" " AND event.objid=mlink.mid"
Modified src/login.c from [86fb4c3fd8] to [d0f9596e5f].
@@ -113,11 +113,11 @@ ); cgi_redirect(zGoto); return; } } - if( zUsername!=0 && zPasswd!=0 ){ + if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){ int uid = db_int(0, "SELECT uid FROM user" " WHERE login=%Q AND pw=%Q", zUsername, zPasswd); if( uid<=0 || strcmp(zUsername,"nobody")==0 ){ sleep(1); @@ -300,13 +300,15 @@ g.userUid = uid; if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){ g.zLogin = 0; } if( uid && g.zLogin ){ + /* All logged-in users inherit privileges from "nobody" */ zNcap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'"); login_set_capabilities(zNcap); - if( db_get_int("inherit-anon",0) ){ + if( strcmp(g.zLogin, "anonymous")!=0 ){ + /* All logged-in users inherit privileges from "anonymous" */ zAcap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'"); login_set_capabilities(zAcap); } } login_set_capabilities(zCap); @@ -314,10 +316,11 @@ /* ** Set the global capability flags based on a capability string. */ void login_set_capabilities(const char *zCap){ + static char *zDev = 0; int i; for(i=0; zCap[i]; i++){ switch( zCap[i] ){ case 's': g.okSetup = 1; case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = @@ -325,10 +328,11 @@ g.okApndWiki = g.okHistory = g.okClone = g.okNewTkt = g.okPassword = g.okRdAddr = g.okTktFmt = 1; case 'i': g.okRead = g.okWrite = 1; break; case 'o': g.okRead = 1; break; + case 'z': g.okZip = 1; break; case 'd': g.okDelete = 1; break; case 'h': g.okHistory = 1; break; case 'g': g.okClone = 1; break; case 'p': g.okPassword = 1; break; @@ -343,10 +347,20 @@ case 'n': g.okNewTkt = 1; break; case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt = g.okApndTkt = 1; break; case 'c': g.okApndTkt = 1; break; case 't': g.okTktFmt = 1; break; + + /* The "v" privileges is a little different. It recursively + ** inherits all privileges of the user named "developer" */ + case 'v': { + if( zDev==0 ){ + zDev = db_text("", "SELECT cap FROM user WHERE login='developer'"); + login_set_capabilities(zDev); + } + break; + } } } } /* @@ -359,27 +373,35 @@ int rc = 1; if( nCap<0 ) nCap = strlen(zCap); for(i=0; i<nCap && rc && zCap[i]; i++){ switch( zCap[i] ){ case 'a': rc = g.okAdmin; break; + /* case 'b': */ case 'c': rc = g.okApndTkt; break; case 'd': rc = g.okDelete; break; case 'e': rc = g.okRdAddr; break; case 'f': rc = g.okNewWiki; break; case 'g': rc = g.okClone; break; case 'h': rc = g.okHistory; break; case 'i': rc = g.okWrite; break; case 'j': rc = g.okRdWiki; break; case 'k': rc = g.okWrWiki; break; + /* case 'l': */ case 'm': rc = g.okApndWiki; break; case 'n': rc = g.okNewTkt; break; case 'o': rc = g.okRead; break; case 'p': rc = g.okPassword; break; + /* case 'q': */ case 'r': rc = g.okRdTkt; break; case 's': rc = g.okSetup; break; case 't': rc = g.okTktFmt; break; + /* case 'u': */ + /* case 'v': */ case 'w': rc = g.okWrTkt; break; + /* case 'x': */ + /* case 'y': */ + case 'z': rc = g.okZip; break; default: rc = 0; break; } } return rc; }
Modified src/main.c from [7cc029d992] to [e3e3bcd32f].
@@ -117,10 +117,11 @@ int okNewTkt; /* n: create new tickets */ int okApndTkt; /* c: append to tickets via the web */ int okWrTkt; /* w: make changes to tickets via web */ int okTktFmt; /* t: create new ticket report formats */ int okRdAddr; /* e: read email addresses or other private data */ + int okZip; /* z: download zipped artifact via /zip URL */ FILE *fDebug; /* Write debug information here, if the file exists */ /* Storage for the aux() and/or option() SQL function arguments */ int nAux; /* Number of distinct aux() or option() values */
Modified src/my_page.c from [52bd9eb48f] to [98c9467776].
@@ -27,12 +27,12 @@ */ #include <assert.h> #include "config.h" #include "my_page.h" -/** -Renders a logout button. +/* +** Renders a logout button. */ static void mypage_logout_button() { if( g.zLogin ){ @ <br clear="both"/><hr/> @@ -43,12 +43,12 @@ @ <input type="submit" name="out" value="Logout"/></p> @ </form> } } -/** -Renders a password changer. +/* +** Renders a password changer. */ static void mypage_password_changer() { if( g.okPassword ){ @ <br clear="both"/><hr/> @@ -71,12 +71,12 @@ @ </form> } } -/** -Default page rendered for /my. +/* +** Default page rendered for /my. */ static void mypage_page_default() { int uid = g.userUid; char * sql = mprintf( "SELECT login,cap,info FROM user WHERE uid=%d",
Modified src/name.c from [cf54ee1717] to [f2384ef316].
@@ -110,20 +110,21 @@ ** 1 A single UUID was found ** 2 More than one UUID was found, so this is presumably a ** propagating tag. The return UUID is the most recent, ** which is most likely to be the one wanted. */ -int sym_tag_to_uuid(const char *pName, Blob *pUuid){ +int tag_to_uuid(const char *pName, Blob *pUuid,const char *pPrefix){ Stmt q; int count = 0; db_prepare(&q, "SELECT (SELECT uuid FROM blob WHERE rid=objid)" " FROM tagxref JOIN event ON rid=objid" - " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='sym-'||%Q)" + " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q||%Q)" " AND tagtype>0" " AND value IS NULL" " ORDER BY event.mtime DESC", + pPrefix, pName ); blob_zero(pUuid); while( db_step(&q)==SQLITE_ROW ){ count++; @@ -132,10 +133,13 @@ } db_column_blob(&q, 0, pUuid); } db_finalize(&q); return count; +} +int sym_tag_to_uuid(const char *pName, Blob *pUuid){ + return tag_to_uuid(pName,pUuid,"sym-"); } /* ** COMMAND: test-name-to-uuid **
Modified src/schema.c from [d06483adac] to [73d36a924e].
@@ -296,10 +296,13 @@ # define TAG_COMMENT 2 /* The check-in comment */ # define TAG_USER 3 /* User who made a checking */ # define TAG_HIDDEN 4 /* Do not display or sync */ # define TAG_PRIVATE 5 /* Display but do not sync */ # define TAG_CLUSTER 6 /* A cluster */ +#endif +#if EXPORT_INTERFACE +# define MAX_INT_TAG 6 /* The largest pre-assigned tag id */ #endif /* ** The schema for the locate FOSSIL database file found at the root ** of very check-out. This database contains the complete state of
Modified src/setup.c from [7115d9c001] to [9a76b5ae3a].
@@ -134,52 +134,70 @@ @ </table></td></tr></table> @ <td valign="top"> @ <b>Notes:</b> @ <ol> @ <li><p>The permission flags are as follows:</p> - @ <ol type="a"> - @ <li value="1"><b>Admin</b>: Create and delete users</li> - @ <li value="3"><b>Append-Tkt</b>: Append to tickets</li> - @ <li value="4"><b>Delete</b>: Delete wiki and tickets</li> - @ <li value="5"><b>Email</b>: View sensitive data such as EMail addresses</li> - @ <li value="6"><b>New-Wiki</b>: Create new wiki pages</li> - @ <li value="7"><b>Clone</b>: Clone the repository</li> - @ <li value="8"><b>History</b>: View detail repository history</li> - @ <li value="9"><b>Check-In</b>: Commit new versions in the repository</li> - @ <li value="10"><b>Read-Wiki</b>: View wiki pages</li> - @ <li value="11"><b>Write-Wiki</b>: Edit wiki pages</li> - @ <li value="13"><b>Append-Wiki</b>: Append to wiki pages</li> - @ <li value="14"><b>New-Tkt</b>: Create new tickets</li> - @ <li value="15"><b>Check-Out</b>: Check out versions</li> - @ <li value="16"><b>Password</b>: Change your own password</li> - @ <li value="18"><b>Read-Tkt</b>: View tickets</li> - @ <li value="19"><b>Setup:</b> Setup and configure this website</li> - @ <li value="20"><b>Tkt-Report:</b> Create new bug summary reports</li> - @ <li value="23"><b>Write-Tkt</b>: Edit tickets</li> - @ </ol> - @ </p></li> - @ - @ <li><p> - @ Every user, logged in or not, has the privileges of <b>nobody</b>. + @ <table> + @ <tr><td><b>a</b></td><td><i>Admin:</i> Create and delete users</td></tr> + @ <tr><td><b>c</b></td><td><i>Append-Tkt:</i> Append to tickets</td></tr> + @ <tr><td><b>d</b></td><td><i>Delete:</i> Delete wiki and tickets</td></tr> + @ <tr><td><b>e</b></td><td><i>Email:</i> View sensitive data such as EMail addresses</td></tr> + @ <tr><td><b>f</b></td><td><i>New-Wiki:</i> Create new wiki pages</td></tr> + @ <tr><td><b>g</b></td><td><i>Clone:</i> Clone the repository</td></tr> + @ <tr><td><b>h</b></td><td><i>History:</i> View detail repository history</td></tr> + @ <tr><td><b>i</b></td><td><i>Check-In:</i> Commit new versions in the repository</td></tr> + @ <tr><td><b>j</b></td><td><i>Read-Wiki:</i> View wiki pages</td></tr> + @ <tr><td><b>k</b></td><td><i>Write-Wiki:</i> Edit wiki pages</td></tr> + @ <tr><td><b>m</b></td><td><i>Append-Wiki:</i> Append to wiki pages</td></tr> + @ <tr><td><b>n</b></td><td><i>New-Tkt:</i> Create new tickets</td></tr> + @ <tr><td><b>o</b></td><td><i>Check-Out:</i> Check out versions</td></tr> + @ <tr><td><b>p</b></td><td><i>Password:</i> Change your own password</td></tr> + @ <tr><td><b>r</b></td><td><i>Read-Tkt:</i> View tickets</td></tr> + @ <tr><td><b>s</b></td><td><i>Setup:</i> Setup and configure this website</td></tr> + @ <tr><td><b>t</b></td><td><i>Tkt-Report:</i> Create new bug summary reports</td></tr> + @ <tr><td><b>v</b></td><td><i>Developer:</i> Inherit privileges of user <tt>developer</tt></td></tr> + @ <tr><td><b>w</b></td><td><i>Write-Tkt:</i> Edit tickets</td></tr> + @ <tr><td><b>z</b></td><td><i>Zip download:</i> Download a baseline via the + @ <tt>/zip</tt> URL even without check<b>o</b>ut and <b>h</b>istory permissions</td></tr> + @ </table> + @ </li> + @ + @ <li><p> + @ Every user, logged in or not, inherits the privileges of <b>nobody</b>. @ Any human can login as <b>anonymous</b> since the password is @ clearly displayed on the login page for them to type. The purpose @ of requiring anonymous to log in is to prevent access by spiders. + @ Every logged-in user inherits the privileges of <b>anonymous</b>. @ </p></li> @ @ </ol> @ </td></tr></table> style_footer(); } /* +** Return true if zPw is a valid password string. A valid +** password string is: +** +** (1) A zero-length string, or +** (2) a string that contains a character other than '*'. +*/ +static int isValidPwString(const char *zPw){ + if( zPw==0 ) return 0; + if( zPw[0]==0 ) return 1; + while( zPw[0]=='*' ){ zPw++; } + return zPw[0]!=0; +} + +/* ** WEBPAGE: /setup_uedit */ void user_edit(void){ - const char *zId, *zLogin, *zInfo, *zCap; + const char *zId, *zLogin, *zInfo, *zCap, *zPw; char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap; char *oak, *oad, *oac, *oaf, *oam, *oah, *oag, *oae; - char *oat; + char *oat, *oav, *oaz; int doWrite; int uid; int higherUser = 0; /* True if user being edited is SETUP and the */ /* user doing the editing is ADMIN. Disallow editing */ @@ -208,12 +226,10 @@ ** modified user record. After writing the user record, redirect ** to the page that displays a list of users. */ doWrite = cgi_all("login","info","pw") && !higherUser; if( doWrite ){ - const char *zPw; - const char *zLogin; char zCap[50]; int i = 0; int aa = P("aa")!=0; int ad = P("ad")!=0; int ae = P("ae")!=0; @@ -230,10 +246,12 @@ int af = P("af")!=0; int am = P("am")!=0; int ah = P("ah")!=0; int ag = P("ag")!=0; int at = P("at")!=0; + int av = P("av")!=0; + int az = P("az")!=0; if( aa ){ zCap[i++] = 'a'; } if( ac ){ zCap[i++] = 'c'; } if( ad ){ zCap[i++] = 'd'; } if( ae ){ zCap[i++] = 'e'; } if( af ){ zCap[i++] = 'f'; } @@ -247,15 +265,17 @@ if( ao ){ zCap[i++] = 'o'; } if( ap ){ zCap[i++] = 'p'; } if( ar ){ zCap[i++] = 'r'; } if( as ){ zCap[i++] = 's'; } if( at ){ zCap[i++] = 't'; } + if( av ){ zCap[i++] = 'v'; } if( aw ){ zCap[i++] = 'w'; } + if( az ){ zCap[i++] = 'z'; } zCap[i] = 0; zPw = P("pw"); - if( zPw==0 || zPw[0]==0 ){ + if( !isValidPwString(zPw) ){ zPw = db_text(0, "SELECT pw FROM user WHERE uid=%d", uid); } zLogin = P("login"); if( uid>0 && db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid) @@ -280,16 +300,18 @@ /* Load the existing information about the user, if any */ zLogin = ""; zInfo = ""; zCap = ""; + zPw = ""; oaa = oac = oad = oae = oaf = oag = oah = oai = oaj = oak = oam = - oan = oao = oap = oar = oas = oat = oaw = ""; + oan = oao = oap = oar = oas = oat = oav = oaw = oaz = ""; 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); + zPw = db_text("", "SELECT pw 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, 'e') ) oae = " checked"; if( strchr(zCap, 'f') ) oaf = " checked"; @@ -303,11 +325,13 @@ if( strchr(zCap, 'o') ) oao = " checked"; if( strchr(zCap, 'p') ) oap = " checked"; if( strchr(zCap, 'r') ) oar = " checked"; if( strchr(zCap, 's') ) oas = " checked"; if( strchr(zCap, 't') ) oat = " checked"; + if( strchr(zCap, 'v') ) oav = " checked"; if( strchr(zCap, 'w') ) oaw = " checked"; + if( strchr(zCap, 'z') ) oaz = " checked"; } /* Begin generating the page */ style_submenu_element("Cancel", "Cancel", "setup_ulist"); @@ -346,35 +370,46 @@ @ <input type="checkbox" name="ae"%s(oad)>Email</input><br> @ <input type="checkbox" name="ap"%s(oap)>Password</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="av"%s(oav)>Developer</input><br> @ <input type="checkbox" name="ag"%s(oag)>Clone</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> @ <input type="checkbox" name="an"%s(oan)>New Tkt</input><br> @ <input type="checkbox" name="ac"%s(oac)>Append Tkt</input><br> @ <input type="checkbox" name="aw"%s(oaw)>Write Tkt</input><br> - @ <input type="checkbox" name="at"%s(oat)>Tkt Report</input> + @ <input type="checkbox" name="at"%s(oat)>Tkt Report</input><br> + @ <input type="checkbox" name="az"%s(oaz)>Download Zip</input> @ </td> @ </tr> @ <tr> @ <td align="right">Password:</td> - @ <td><input type="password" name="pw" value=""></td> + if( strcmp(zLogin, "anonymous")==0 ){ + /* User the password for "anonymous" as cleartext */ + @ <td><input type="text" name="pw" value="%h(zPw)"></td> + }else if( zPw[0] ){ + /* Obscure the password for all other users */ + @ <td><input type="password" name="pw" value="**********"></td> + }else{ + /* Show an empty password as an empty input field */ + @ <td><input type="password" name="pw" value=""></td> + } @ </tr> if( !higherUser ){ @ <tr> @ <td> </td> @ <td><input type="submit" name="submit" value="Apply Changes"> @ </tr> } @ </table></td></tr></table> - @ <p><b>Notes:</b></p> - @ <ol> + @ <h2>Privileges And Capabilities:</h2> + @ <ul> if( higherUser ){ @ <li><p><font color="blue"><b> @ User %h(zLogin) has Setup privileges and you only have Admin privileges @ so you are not permitted to make changes to %h(zLogin). @ </b></font></p></li> @@ -402,10 +437,24 @@ @ user "nobody" to avoid problems with spiders trying to walk every @ historical version of every baseline and file. @ </p></li> @ @ <li><p> + @ The <b>Zip</b> privilege allows a user to see the download as zip hyperlink + @ as well as permit access to the <tt>/zip</tt> page. It can be allowed for + @ user "nobody" to grant him access to download artifacts he know from the + @ server without giving him other rights like <b>Read</b> or <b>History</b>. + @ So automatic package dowloaders could be able to obtain the sources without + @ going thru the login procedure. + @ </p></li> + @ + @ <li><p> + @ The <b>Developer</b> privilege causes all privileges of the user + @ named "developer" to be inherited by this user. + @ </p></li> + @ + @ <li><p> @ The <b>Check-in</b> privilege allows remote users to "push". @ The <b>Check-out</b> privilege allows remote users to "pull". @ The <b>Clone</b> privilege allows remote users to "clone". @ </li><p> @ @@ -418,39 +467,58 @@ @ ticket report formats. @ </p></li> @ @ <li><p> @ Users with the <b>Password</b> privilege are allowed to change their - @ own password. Recommended ON for most users but OFF for "anonynmous" - @ and "nobody". + @ own password. Recommended ON for most users but OFF for special + @ users "developer, "anonynmous", and "nobody". @ </p></li> @ @ <li><p> @ The <b>EMail</b> privilege allows the display of sensitive information @ such as the email address of users and contact information on tickets. @ Recommended OFF for "anonymous" and for "nobody". @ </p></li> @ @ <li><p> + @ Login is prohibited if the password is an empty string. + @ </p></li> + @ </ul> + @ + @ <h2>Special Logins</h2> + @ + @ <ul> + @ <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 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. + @ of the <b>nobody</b> user are inherited by all users, regardless of + @ whether or not they are logged in. To disable universal access + @ to the repository, make sure no user named "<b>nobody</b>" exists or + @ that the <b>nobody</b> user has no capabilities enabled. + @ The password for <b>nobody</b> is ignore. To avoid problems with + @ spiders overloading the server, it is recommended + @ that the 'h' (History) capability be turned off for the <b>nobody</b> + @ user. @ </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 @ so anybody who can read should be able to login as anonymous. @ On the other hand, spiders and web-crawlers will typically not @ be able to login. Set the capabilities of the anonymous user @ to things that you want any human to be able to do, but not any - @ spider. + @ spider. Every other logged-in user inherits the privileges of + @ <b>anonymous</b>. @ </p></li> + @ + @ <li><p> + @ The "<b>developer</b>" user is intended as a template for trusted users + @ with check-in privileges. When adding new trusted users, simply + @ select the <b>Developer</b> privilege to cause the new user to inherit + @ all privileges of the "developer" user. + @ </li></p> + @ </ul> @ </form> style_footer(); }
Modified src/style.c from [934dddd1ca] to [89fb0defc5].
Modified src/tag.c from [ec276e4852] to [842caf6a79].
@@ -247,18 +247,73 @@ tag_insert(zTag, tagtype, zValue, -1, 0.0, rid); db_end_transaction(0); } /* +** Prepare an artifact that describes a fork from a certain UUID. +** Furthermore a propagating symbolic tag will be inserted and +** all other propagating symbolic tags will be cancelled. +** +** The changes are appended at the Blob pCtrl. However the manifest +** is not complete at that stage. +*/ +static void tag_prepare_fork( + Blob *pCtrl, + const char *zTagname, + int rid +){ + Stmt q; + Manifest origin; + Blob originContent; + char *zDate; + int i; + + blob_appendf(pCtrl, "C Create\\snamed\\sfork\\s%s\n", zTagname+4); + content_get(rid, &originContent); + manifest_parse(&origin, &originContent); + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(pCtrl, "D %s\n", zDate); + for(i=0; i<origin.nFile; ++i){ + blob_appendf(pCtrl, "F %s %s %s\n", + origin.aFile[i].zName, + origin.aFile[i].zUuid, + origin.aFile[i].zPerm); + } + if( origin.nParent>0 ){ + blob_appendf(pCtrl, "P %s\n", origin.azParent[0]); + } + blob_appendf(pCtrl, "R %s\n", origin.zRepoCksum); + blob_appendf(pCtrl, "T *%F *", zTagname); + + /* Cancel any sym- tags that propagate */ + db_prepare(&q, + "SELECT tagname FROM tagxref, tag" + " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid" + " AND tagtype>0 AND tagname LIKE 'sym-%%'" + " ORDER BY tagname", + rid); + while( db_step(&q)==SQLITE_ROW ){ + const char *zTag = db_column_text(&q, 0); + blob_appendf(pCtrl, "\nT -%s *", zTag); + } + db_finalize(&q); + + /* Cleanup */ + manifest_clear(&origin); +} + +/* ** Add a control record to the repository that either creates ** or cancels a tag. */ static void tag_add_artifact( const char *zTagname, /* The tag to add or cancel */ const char *zObjName, /* Name of object attached to */ const char *zValue, /* Value for the tag. Might be NULL */ - int tagtype /* 0:cancel 1:singleton 2:propagated */ + int tagtype, /* 0:cancel 1:singleton 2:propagated */ + int fork /* Should a fork created from zObjName? */ ){ int rid; int nrid; char *zDate; Blob uuid; @@ -278,14 +333,18 @@ if( validate16(zTagname, strlen(zTagname)) ){ fossil_fatal("invalid tag name \"%s\" - might be confused with a UUID", zTagname); } - zDate = db_text(0, "SELECT datetime('now')"); - zDate[10] = 'T'; - blob_appendf(&ctrl, "D %s\n", zDate); - blob_appendf(&ctrl, "T %c%F %b", zTagtype[tagtype], zTagname, &uuid); + if( fork ){ + tag_prepare_fork(&ctrl, zTagname, rid); + }else{ + zDate = db_text(0, "SELECT datetime('now')"); + zDate[10] = 'T'; + blob_appendf(&ctrl, "D %s\n", zDate); + blob_appendf(&ctrl, "T %c%F %b", zTagtype[tagtype], zTagname, &uuid); + } if( tagtype && zValue && zValue[0] ){ blob_appendf(&ctrl, " %F\n", zValue); }else{ blob_appendf(&ctrl, "\n"); } @@ -309,20 +368,31 @@ ** ** %fossil tag add ?--raw? TAGNAME UUID ?VALUE? ** ** Add a new tag or property to UUID. The tag will ** be usable instead of a UUID in commands like -** update and the like. +** update and such. ** ** %fossil tag branch ?--raw? TAGNAME UUID ?VALUE? ** -** Add a new tag or property to UUID and make that -** tag propagate to all direct children. -** -** %fossil tag delete ?--raw? TAGNAME UUID +** A fork of UUID will be created. Then the new tag +** or property will be added to the fork that +** propagate to all direct children. +** +** Additionally all symbolic tags of that fork +** inherited from UUID will be cancelled. +** +** However, if the option '--raw' was given, no +** fork will be created but the tag/property will be +** added to UUID directly and no tag will be +** canceled. +** +** Please see the description of '--raw' below too. +** +** %fossil tag cancel ?--raw? TAGNAME UUID ** -** Delete the tag TAGNAME from UUID +** Cancel the tag TAGNAME from UUID ** ** %fossil tag find ?--raw? TAGNAME ** ** List all baselines that use TAGNAME ** @@ -369,39 +439,43 @@ blob_set(&tagname, prefix); if( strncmp(g.argv[2],"add",n)==0 ){ char *zValue; if( g.argc!=5 && g.argc!=6 ){ - usage("add TAGNAME UUID ?VALUE?"); + usage("add ?--raw? TAGNAME UUID ?VALUE?"); } blob_append(&tagname, g.argv[3], strlen(g.argv[3])); zValue = g.argc==6 ? g.argv[5] : 0; - tag_add_artifact(blob_str(&tagname), g.argv[4], zValue, 1); + tag_add_artifact(blob_str(&tagname), g.argv[4], zValue, 1, 0); }else if( strncmp(g.argv[2],"branch",n)==0 ){ char *zValue; if( g.argc!=5 && g.argc!=6 ){ - usage("branch TAGNAME UUID ?VALUE?"); + usage("branch ?--raw? TAGNAME UUID ?VALUE?"); } blob_append(&tagname, g.argv[3], strlen(g.argv[3])); zValue = g.argc==6 ? g.argv[5] : 0; - tag_add_artifact(blob_str(&tagname), g.argv[4], zValue, 2); + tag_add_artifact(blob_str(&tagname), g.argv[4], zValue, 2, raw==0); + if( !raw ){ + const char *zUuid = db_text(0, "SELECT uuid, MAX(rowid) FROM blob"); + printf("New_Fork \"%s\": %s\n", g.argv[3], zUuid); + } }else - if( strncmp(g.argv[2],"delete",n)==0 ){ + if( strncmp(g.argv[2],"cancel",n)==0 ){ if( g.argc!=5 ){ - usage("delete TAGNAME UUID"); + usage("cancel ?--raw? TAGNAME UUID"); } blob_append(&tagname, g.argv[3], strlen(g.argv[3])); - tag_add_artifact(blob_str(&tagname), g.argv[4], 0, 0); + tag_add_artifact(blob_str(&tagname), g.argv[4], 0, 0, 0); }else if( strncmp(g.argv[2],"find",n)==0 ){ Stmt q; if( g.argc!=4 ){ - usage("find TAGNAME"); + usage("find ?--raw? TAGNAME"); } blob_append(&tagname, g.argv[3], strlen(g.argv[3])); db_prepare(&q, "SELECT blob.uuid FROM tagxref, blob" " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%B)" @@ -415,12 +489,11 @@ if( strncmp(g.argv[2],"list",n)==0 ){ Stmt q; if( g.argc==3 ){ db_prepare(&q, - "SELECT tagname" - " FROM tag" + "SELECT tagname FROM tag" " WHERE EXISTS(SELECT 1 FROM tagxref" " WHERE tagid=tag.tagid" " AND tagtype>0)" " ORDER BY tagname" ); @@ -432,12 +505,11 @@ } db_finalize(&q); }else if( g.argc==4 ){ int rid = name_to_rid(g.argv[3]); db_prepare(&q, - "SELECT tagname, value" - " FROM tagxref, tag" + "SELECT tagname, value FROM tagxref, tag" " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid" " AND tagtype>0" " ORDER BY tagname", rid ); @@ -466,7 +538,7 @@ /* Cleanup */ blob_reset(&tagname); return; tag_cmd_usage: - usage("add|branch|delete|find|list ..."); + usage("add|branch|cancel|find|list ..."); }
Modified src/tagview.c from [b4a9071e7b] to [49b12135cb].
@@ -135,36 +135,10 @@ db_generic_query_view(zSql, 1); free(zSql); } /* -** Get the UUIDs for a tag -*/ -char *tag_query_for_www(const char *pName){ - static const char zBaseSql[] = - @ SELECT - @ blob.rid, - @ uuid, - @ datetime(event.mtime,'localtime') AS timestamp, - @ coalesce(ecomment, comment), - @ coalesce(euser, user), - @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1), - @ (SELECT count(*) FROM plink WHERE cid=blob.rid), - @ NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid), - @ coalesce(bgcolor, brbgcolor), - @ event.type - @ FROM event JOIN blob JOIN tagxref - @ WHERE blob.rid=event.objid - @ AND tagxref.rid = event.objid - @ AND tagxref.tagid = (SELECT tagid FROM tag - @ WHERE tagname = 'sym-'||%Q) - @ ORDER BY 3 desc - ; - return mprintf(zBaseSql,pName); -} - -/* ** WEBP AGE: /tagview */ void old_tagview_page(void){ char const * check = 0; login_check_credentials(); @@ -202,11 +176,31 @@ char *zSql; Stmt q; if( sym_tag_to_uuid(zName, &uuid) > 0){ style_header("Tagged Baselines"); @ <h2>%s(zName):</h2> - zSql = tag_query_for_www(zName); + zSql = mprintf("%s AND EXISTS (SELECT 1" + " FROM tagxref" + " WHERE tagxref.rid = event.objid" + " AND tagxref.tagid = (SELECT tagid FROM tag" + " WHERE tagname = 'sym-'||%Q))" + " ORDER BY 3 desc", + timeline_query_for_www(), zName); + db_prepare(&q, zSql); + free(zSql); + www_print_timeline(&q); + db_finalize(&q); + }else if( tag_to_uuid(zName, &uuid, "") > 0){ + style_header("Tagged Baselines"); + @ <h2>%s(zName):</h2> + zSql = mprintf("%s AND EXISTS (SELECT 1" + " FROM tagxref" + " WHERE tagxref.rid = event.objid" + " AND tagxref.tagid = (SELECT tagid FROM tag" + " WHERE tagname = %Q))" + " ORDER BY 3 desc", + timeline_query_for_www(), zName); db_prepare(&q, zSql); free(zSql); www_print_timeline(&q); db_finalize(&q); }else{ @@ -223,22 +217,29 @@ "SELECT tagname" " FROM tag" " WHERE EXISTS(SELECT 1 FROM tagxref" " WHERE tagid=tag.tagid" " AND tagtype>0)" - " ORDER BY tagname" + " AND tagid > %d" + " AND tagname NOT GLOB 'wiki-*'" + " AND tagname NOT GLOB 'tkt-*'" + " ORDER BY tagname", + MAX_INT_TAG ); @ <ul> while( db_step(&q)==SQLITE_ROW ){ const char *name = db_column_text(&q, 0); if( strncmp(name, prefix, preflen)==0 ){ @ <li><a href=%s(g.zBaseURL)/tagview?name=%s(name+preflen)> - @ %s(name+preflen)</a></li> + @ <strong>%s(name+preflen)</strong></a></li> + }else{ + @ <li><a href=%s(g.zBaseURL)/tagview?name=%s(name)> + @ %s(name)</a></li> } } @ </ul> db_finalize(&q); } style_footer(); } #undef TAGVIEW_DEFAULT_FILTER
Modified src/zip.c from [8367a41493] to [c82f467b68].
@@ -351,31 +351,34 @@ ** Generate a ZIP archive for the baseline. ** Return that ZIP archive as the HTTP reply content. */ void baseline_zip_page(void){ int rid; - char *zName; - int nName; + char *zName, *zRid; + int nName, nRid; Blob zip; login_check_credentials(); - if( !g.okRead || !g.okHistory ){ login_needed(); return; } + if( !g.okZip && (!g.okRead || !g.okHistory) ){ login_needed(); return; } zName = mprintf("%s", PD("name","")); nName = strlen(zName); + zRid = mprintf("%s", PD("uuid","")); + nRid = strlen(zRid); for(nName=strlen(zName)-1; nName>5; nName--){ if( zName[nName]=='.' ){ zName[nName] = 0; break; } } - rid = name_to_rid(zName); + rid = name_to_rid(nRid?zRid:zName); if( rid==0 ){ @ Not found return; } - if( nName>10 ) zName[10] = 0; + if( nRid==0 && nName>10 ) zName[10] = 0; zip_of_baseline(rid, &zip, zName); free( zName ); + free( zRid ); cgi_set_content(&zip); cgi_set_content_type("application/zip"); cgi_reply(); }