Fossil SCM

Add the new "history" permission. Merge in changes that require permissions to view the timeline.

drh 2007-07-31 23:33 trunk merge
Commit fd36718ad98c4a01632eeccb777fec847c1de7af
+2
--- src/info.c
+++ src/info.c
@@ -116,10 +116,12 @@
116116
Stmt q;
117117
int rid;
118118
char cType;
119119
char *zType;
120120
121
+ login_check_credentials();
122
+ if( !g.okHistory ){ login_needed(); return; }
121123
style_header("Version Information");
122124
rid = name_to_rid(g.zExtra);
123125
if( rid==0 ){
124126
@ No such object: %h(g.argv[2])
125127
style_footer();
126128
--- src/info.c
+++ src/info.c
@@ -116,10 +116,12 @@
116 Stmt q;
117 int rid;
118 char cType;
119 char *zType;
120
 
 
121 style_header("Version Information");
122 rid = name_to_rid(g.zExtra);
123 if( rid==0 ){
124 @ No such object: %h(g.argv[2])
125 style_footer();
126
--- src/info.c
+++ src/info.c
@@ -116,10 +116,12 @@
116 Stmt q;
117 int rid;
118 char cType;
119 char *zType;
120
121 login_check_credentials();
122 if( !g.okHistory ){ login_needed(); return; }
123 style_header("Version Information");
124 rid = name_to_rid(g.zExtra);
125 if( rid==0 ){
126 @ No such object: %h(g.argv[2])
127 style_footer();
128
+2
--- src/info.c
+++ src/info.c
@@ -116,10 +116,12 @@
116116
Stmt q;
117117
int rid;
118118
char cType;
119119
char *zType;
120120
121
+ login_check_credentials();
122
+ if( !g.okHistory ){ login_needed(); return; }
121123
style_header("Version Information");
122124
rid = name_to_rid(g.zExtra);
123125
if( rid==0 ){
124126
@ No such object: %h(g.argv[2])
125127
style_footer();
126128
--- src/info.c
+++ src/info.c
@@ -116,10 +116,12 @@
116 Stmt q;
117 int rid;
118 char cType;
119 char *zType;
120
 
 
121 style_header("Version Information");
122 rid = name_to_rid(g.zExtra);
123 if( rid==0 ){
124 @ No such object: %h(g.argv[2])
125 style_footer();
126
--- src/info.c
+++ src/info.c
@@ -116,10 +116,12 @@
116 Stmt q;
117 int rid;
118 char cType;
119 char *zType;
120
121 login_check_credentials();
122 if( !g.okHistory ){ login_needed(); return; }
123 style_header("Version Information");
124 rid = name_to_rid(g.zExtra);
125 if( rid==0 ){
126 @ No such object: %h(g.argv[2])
127 style_footer();
128
+11 -6
--- src/login.c
+++ src/login.c
@@ -260,20 +260,24 @@
260260
}
261261
if( zCap==0 ){
262262
if( uid ){
263263
Stmt s;
264264
db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
265
- db_step(&s);
266
- g.zLogin = db_column_malloc(&s, 0);
267
- zCap = db_column_malloc(&s, 1);
265
+ if( db_step(&s)==SQLITE_ROW ){
266
+ g.zLogin = db_column_malloc(&s, 0);
267
+ zCap = db_column_malloc(&s, 1);
268
+ }
268269
db_finalize(&s);
269270
}
270271
if( zCap==0 ){
271272
zCap = "";
272273
}
273274
}
274275
g.userUid = uid;
276
+ if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
277
+ g.zLogin = 0;
278
+ }
275279
login_set_capabilities(zCap);
276280
}
277281
278282
/*
279283
** Set the global capability flags based on a capability string.
@@ -282,16 +286,17 @@
282286
int i;
283287
for(i=0; zCap[i]; i++){
284288
switch( zCap[i] ){
285289
case 's': g.okSetup = g.okDelete = 1;
286290
case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = g.okQuery =
287
- g.okRdWiki = g.okWrWiki =
291
+ g.okRdWiki = g.okWrWiki = g.okHistory =
288292
g.okNewTkt = g.okPassword = 1;
289293
case 'i': g.okRead = g.okWrite = 1; break;
290294
case 'o': g.okRead = 1; break;
291295
292296
case 'd': g.okDelete = 1; break;
297
+ case 'h': g.okHistory = 1; break;
293298
case 'p': g.okPassword = 1; break;
294299
case 'q': g.okQuery = 1; break;
295300
296301
case 'j': g.okRdWiki = 1; break;
297302
case 'k': g.okWrWiki = g.okRdWiki = g.okApndWiki =1; break;
@@ -298,11 +303,11 @@
298303
case 'm': g.okApndWiki = 1; break;
299304
case 'f': g.okNewWiki = 1; break;
300305
301306
case 'r': g.okRdTkt = 1; break;
302307
case 'n': g.okNewTkt = 1; break;
303
- case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt =
308
+ case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt =
304309
g.okApndTkt = 1; break;
305310
case 'c': g.okApndTkt = 1; break;
306311
}
307312
}
308313
}
@@ -311,9 +316,9 @@
311316
** Call this routine when the credential check fails. It causes
312317
** a redirect to the "login" page.
313318
*/
314319
void login_needed(void){
315320
const char *zUrl = PD("REQUEST_URI", "index");
316
- cgi_redirect(mprintf("login?nxp=%T", zUrl));
321
+ cgi_redirect(mprintf("login?g=%T", zUrl));
317322
/* NOTREACHED */
318323
assert(0);
319324
}
320325
--- src/login.c
+++ src/login.c
@@ -260,20 +260,24 @@
260 }
261 if( zCap==0 ){
262 if( uid ){
263 Stmt s;
264 db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
265 db_step(&s);
266 g.zLogin = db_column_malloc(&s, 0);
267 zCap = db_column_malloc(&s, 1);
 
268 db_finalize(&s);
269 }
270 if( zCap==0 ){
271 zCap = "";
272 }
273 }
274 g.userUid = uid;
 
 
 
275 login_set_capabilities(zCap);
276 }
277
278 /*
279 ** Set the global capability flags based on a capability string.
@@ -282,16 +286,17 @@
282 int i;
283 for(i=0; zCap[i]; i++){
284 switch( zCap[i] ){
285 case 's': g.okSetup = g.okDelete = 1;
286 case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = g.okQuery =
287 g.okRdWiki = g.okWrWiki =
288 g.okNewTkt = g.okPassword = 1;
289 case 'i': g.okRead = g.okWrite = 1; break;
290 case 'o': g.okRead = 1; break;
291
292 case 'd': g.okDelete = 1; break;
 
293 case 'p': g.okPassword = 1; break;
294 case 'q': g.okQuery = 1; break;
295
296 case 'j': g.okRdWiki = 1; break;
297 case 'k': g.okWrWiki = g.okRdWiki = g.okApndWiki =1; break;
@@ -298,11 +303,11 @@
298 case 'm': g.okApndWiki = 1; break;
299 case 'f': g.okNewWiki = 1; break;
300
301 case 'r': g.okRdTkt = 1; break;
302 case 'n': g.okNewTkt = 1; break;
303 case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt =
304 g.okApndTkt = 1; break;
305 case 'c': g.okApndTkt = 1; break;
306 }
307 }
308 }
@@ -311,9 +316,9 @@
311 ** Call this routine when the credential check fails. It causes
312 ** a redirect to the "login" page.
313 */
314 void login_needed(void){
315 const char *zUrl = PD("REQUEST_URI", "index");
316 cgi_redirect(mprintf("login?nxp=%T", zUrl));
317 /* NOTREACHED */
318 assert(0);
319 }
320
--- src/login.c
+++ src/login.c
@@ -260,20 +260,24 @@
260 }
261 if( zCap==0 ){
262 if( uid ){
263 Stmt s;
264 db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
265 if( db_step(&s)==SQLITE_ROW ){
266 g.zLogin = db_column_malloc(&s, 0);
267 zCap = db_column_malloc(&s, 1);
268 }
269 db_finalize(&s);
270 }
271 if( zCap==0 ){
272 zCap = "";
273 }
274 }
275 g.userUid = uid;
276 if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
277 g.zLogin = 0;
278 }
279 login_set_capabilities(zCap);
280 }
281
282 /*
283 ** Set the global capability flags based on a capability string.
@@ -282,16 +286,17 @@
286 int i;
287 for(i=0; zCap[i]; i++){
288 switch( zCap[i] ){
289 case 's': g.okSetup = g.okDelete = 1;
290 case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = g.okQuery =
291 g.okRdWiki = g.okWrWiki = g.okHistory =
292 g.okNewTkt = g.okPassword = 1;
293 case 'i': g.okRead = g.okWrite = 1; break;
294 case 'o': g.okRead = 1; break;
295
296 case 'd': g.okDelete = 1; break;
297 case 'h': g.okHistory = 1; break;
298 case 'p': g.okPassword = 1; break;
299 case 'q': g.okQuery = 1; break;
300
301 case 'j': g.okRdWiki = 1; break;
302 case 'k': g.okWrWiki = g.okRdWiki = g.okApndWiki =1; break;
@@ -298,11 +303,11 @@
303 case 'm': g.okApndWiki = 1; break;
304 case 'f': g.okNewWiki = 1; break;
305
306 case 'r': g.okRdTkt = 1; break;
307 case 'n': g.okNewTkt = 1; break;
308 case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt =
309 g.okApndTkt = 1; break;
310 case 'c': g.okApndTkt = 1; break;
311 }
312 }
313 }
@@ -311,9 +316,9 @@
316 ** Call this routine when the credential check fails. It causes
317 ** a redirect to the "login" page.
318 */
319 void login_needed(void){
320 const char *zUrl = PD("REQUEST_URI", "index");
321 cgi_redirect(mprintf("login?g=%T", zUrl));
322 /* NOTREACHED */
323 assert(0);
324 }
325
+11 -6
--- src/login.c
+++ src/login.c
@@ -260,20 +260,24 @@
260260
}
261261
if( zCap==0 ){
262262
if( uid ){
263263
Stmt s;
264264
db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
265
- db_step(&s);
266
- g.zLogin = db_column_malloc(&s, 0);
267
- zCap = db_column_malloc(&s, 1);
265
+ if( db_step(&s)==SQLITE_ROW ){
266
+ g.zLogin = db_column_malloc(&s, 0);
267
+ zCap = db_column_malloc(&s, 1);
268
+ }
268269
db_finalize(&s);
269270
}
270271
if( zCap==0 ){
271272
zCap = "";
272273
}
273274
}
274275
g.userUid = uid;
276
+ if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
277
+ g.zLogin = 0;
278
+ }
275279
login_set_capabilities(zCap);
276280
}
277281
278282
/*
279283
** Set the global capability flags based on a capability string.
@@ -282,16 +286,17 @@
282286
int i;
283287
for(i=0; zCap[i]; i++){
284288
switch( zCap[i] ){
285289
case 's': g.okSetup = g.okDelete = 1;
286290
case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = g.okQuery =
287
- g.okRdWiki = g.okWrWiki =
291
+ g.okRdWiki = g.okWrWiki = g.okHistory =
288292
g.okNewTkt = g.okPassword = 1;
289293
case 'i': g.okRead = g.okWrite = 1; break;
290294
case 'o': g.okRead = 1; break;
291295
292296
case 'd': g.okDelete = 1; break;
297
+ case 'h': g.okHistory = 1; break;
293298
case 'p': g.okPassword = 1; break;
294299
case 'q': g.okQuery = 1; break;
295300
296301
case 'j': g.okRdWiki = 1; break;
297302
case 'k': g.okWrWiki = g.okRdWiki = g.okApndWiki =1; break;
@@ -298,11 +303,11 @@
298303
case 'm': g.okApndWiki = 1; break;
299304
case 'f': g.okNewWiki = 1; break;
300305
301306
case 'r': g.okRdTkt = 1; break;
302307
case 'n': g.okNewTkt = 1; break;
303
- case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt =
308
+ case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt =
304309
g.okApndTkt = 1; break;
305310
case 'c': g.okApndTkt = 1; break;
306311
}
307312
}
308313
}
@@ -311,9 +316,9 @@
311316
** Call this routine when the credential check fails. It causes
312317
** a redirect to the "login" page.
313318
*/
314319
void login_needed(void){
315320
const char *zUrl = PD("REQUEST_URI", "index");
316
- cgi_redirect(mprintf("login?nxp=%T", zUrl));
321
+ cgi_redirect(mprintf("login?g=%T", zUrl));
317322
/* NOTREACHED */
318323
assert(0);
319324
}
320325
--- src/login.c
+++ src/login.c
@@ -260,20 +260,24 @@
260 }
261 if( zCap==0 ){
262 if( uid ){
263 Stmt s;
264 db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
265 db_step(&s);
266 g.zLogin = db_column_malloc(&s, 0);
267 zCap = db_column_malloc(&s, 1);
 
268 db_finalize(&s);
269 }
270 if( zCap==0 ){
271 zCap = "";
272 }
273 }
274 g.userUid = uid;
 
 
 
275 login_set_capabilities(zCap);
276 }
277
278 /*
279 ** Set the global capability flags based on a capability string.
@@ -282,16 +286,17 @@
282 int i;
283 for(i=0; zCap[i]; i++){
284 switch( zCap[i] ){
285 case 's': g.okSetup = g.okDelete = 1;
286 case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = g.okQuery =
287 g.okRdWiki = g.okWrWiki =
288 g.okNewTkt = g.okPassword = 1;
289 case 'i': g.okRead = g.okWrite = 1; break;
290 case 'o': g.okRead = 1; break;
291
292 case 'd': g.okDelete = 1; break;
 
293 case 'p': g.okPassword = 1; break;
294 case 'q': g.okQuery = 1; break;
295
296 case 'j': g.okRdWiki = 1; break;
297 case 'k': g.okWrWiki = g.okRdWiki = g.okApndWiki =1; break;
@@ -298,11 +303,11 @@
298 case 'm': g.okApndWiki = 1; break;
299 case 'f': g.okNewWiki = 1; break;
300
301 case 'r': g.okRdTkt = 1; break;
302 case 'n': g.okNewTkt = 1; break;
303 case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt =
304 g.okApndTkt = 1; break;
305 case 'c': g.okApndTkt = 1; break;
306 }
307 }
308 }
@@ -311,9 +316,9 @@
311 ** Call this routine when the credential check fails. It causes
312 ** a redirect to the "login" page.
313 */
314 void login_needed(void){
315 const char *zUrl = PD("REQUEST_URI", "index");
316 cgi_redirect(mprintf("login?nxp=%T", zUrl));
317 /* NOTREACHED */
318 assert(0);
319 }
320
--- src/login.c
+++ src/login.c
@@ -260,20 +260,24 @@
260 }
261 if( zCap==0 ){
262 if( uid ){
263 Stmt s;
264 db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
265 if( db_step(&s)==SQLITE_ROW ){
266 g.zLogin = db_column_malloc(&s, 0);
267 zCap = db_column_malloc(&s, 1);
268 }
269 db_finalize(&s);
270 }
271 if( zCap==0 ){
272 zCap = "";
273 }
274 }
275 g.userUid = uid;
276 if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
277 g.zLogin = 0;
278 }
279 login_set_capabilities(zCap);
280 }
281
282 /*
283 ** Set the global capability flags based on a capability string.
@@ -282,16 +286,17 @@
286 int i;
287 for(i=0; zCap[i]; i++){
288 switch( zCap[i] ){
289 case 's': g.okSetup = g.okDelete = 1;
290 case 'a': g.okAdmin = g.okRdTkt = g.okWrTkt = g.okQuery =
291 g.okRdWiki = g.okWrWiki = g.okHistory =
292 g.okNewTkt = g.okPassword = 1;
293 case 'i': g.okRead = g.okWrite = 1; break;
294 case 'o': g.okRead = 1; break;
295
296 case 'd': g.okDelete = 1; break;
297 case 'h': g.okHistory = 1; break;
298 case 'p': g.okPassword = 1; break;
299 case 'q': g.okQuery = 1; break;
300
301 case 'j': g.okRdWiki = 1; break;
302 case 'k': g.okWrWiki = g.okRdWiki = g.okApndWiki =1; break;
@@ -298,11 +303,11 @@
303 case 'm': g.okApndWiki = 1; break;
304 case 'f': g.okNewWiki = 1; break;
305
306 case 'r': g.okRdTkt = 1; break;
307 case 'n': g.okNewTkt = 1; break;
308 case 'w': g.okWrTkt = g.okRdTkt = g.okNewTkt =
309 g.okApndTkt = 1; break;
310 case 'c': g.okApndTkt = 1; break;
311 }
312 }
313 }
@@ -311,9 +316,9 @@
316 ** Call this routine when the credential check fails. It causes
317 ** a redirect to the "login" page.
318 */
319 void login_needed(void){
320 const char *zUrl = PD("REQUEST_URI", "index");
321 cgi_redirect(mprintf("login?g=%T", zUrl));
322 /* NOTREACHED */
323 assert(0);
324 }
325
+1
--- src/main.c
+++ src/main.c
@@ -98,10 +98,11 @@
9898
int okApndWiki; /* append to wiki via web */
9999
int okPassword; /* change password */
100100
int okAdmin; /* administrative permission */
101101
int okDelete; /* delete wiki or tickets */
102102
int okQuery; /* create new reports */
103
+ int okHistory; /* access historical information */
103104
104105
FILE *fDebug; /* Write debug information here, if the file exists */
105106
};
106107
107108
/*
108109
--- src/main.c
+++ src/main.c
@@ -98,10 +98,11 @@
98 int okApndWiki; /* append to wiki via web */
99 int okPassword; /* change password */
100 int okAdmin; /* administrative permission */
101 int okDelete; /* delete wiki or tickets */
102 int okQuery; /* create new reports */
 
103
104 FILE *fDebug; /* Write debug information here, if the file exists */
105 };
106
107 /*
108
--- src/main.c
+++ src/main.c
@@ -98,10 +98,11 @@
98 int okApndWiki; /* append to wiki via web */
99 int okPassword; /* change password */
100 int okAdmin; /* administrative permission */
101 int okDelete; /* delete wiki or tickets */
102 int okQuery; /* create new reports */
103 int okHistory; /* access historical information */
104
105 FILE *fDebug; /* Write debug information here, if the file exists */
106 };
107
108 /*
109
+1
--- src/main.c
+++ src/main.c
@@ -98,10 +98,11 @@
9898
int okApndWiki; /* append to wiki via web */
9999
int okPassword; /* change password */
100100
int okAdmin; /* administrative permission */
101101
int okDelete; /* delete wiki or tickets */
102102
int okQuery; /* create new reports */
103
+ int okHistory; /* access historical information */
103104
104105
FILE *fDebug; /* Write debug information here, if the file exists */
105106
};
106107
107108
/*
108109
--- src/main.c
+++ src/main.c
@@ -98,10 +98,11 @@
98 int okApndWiki; /* append to wiki via web */
99 int okPassword; /* change password */
100 int okAdmin; /* administrative permission */
101 int okDelete; /* delete wiki or tickets */
102 int okQuery; /* create new reports */
 
103
104 FILE *fDebug; /* Write debug information here, if the file exists */
105 };
106
107 /*
108
--- src/main.c
+++ src/main.c
@@ -98,10 +98,11 @@
98 int okApndWiki; /* append to wiki via web */
99 int okPassword; /* change password */
100 int okAdmin; /* administrative permission */
101 int okDelete; /* delete wiki or tickets */
102 int okQuery; /* create new reports */
103 int okHistory; /* access historical information */
104
105 FILE *fDebug; /* Write debug information here, if the file exists */
106 };
107
108 /*
109
+13 -12
--- src/setup.c
+++ src/setup.c
@@ -112,19 +112,21 @@
112112
@ <td align="center">%s(db_column_text(&s,2))</td>
113113
@ <td align="left">%s(db_column_text(&s,3))</td>
114114
@ </tr>
115115
}
116116
@ </table></td></tr></table>
117
- @ <p>
117
+ @ <p style="clear:both">
118118
@ <b>Notes:</b>
119119
@ <ol>
120120
@ <li><p>The permission flags are as follows:</p>
121121
@ <table>
122122
@ <tr><td>a</td><td width="10"></td>
123123
@ <td>Admin: Create or delete users and ticket report formats</td></tr>
124124
@ <tr><td>d</td><td></td>
125125
@ <td>Delete: Erase anonymous wiki, tickets, and attachments</td></tr>
126
+ @ <tr><td>h</td><td></td>
127
+ @ <td>History: Access older version of code, tickets, or wiki</td></tr>
126128
@ <tr><td>i</td><td></td>
127129
@ <td>Check-in: Add new code to the repository</td></tr>
128130
@ <tr><td>j</td><td></td><td>Read-Wiki: View wiki pages</td></tr>
129131
@ <tr><td>k</td><td></td><td>Wiki: Create or modify wiki pages</td></tr>
130132
@ <tr><td>n</td><td></td><td>New: Create new tickets</td></tr>
@@ -153,11 +155,11 @@
153155
** WEBPAGE: /setup_uedit
154156
*/
155157
void user_edit(void){
156158
const char *zId, *zLogin, *zInfo, *zCap;
157159
char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ;
158
- char *oak, *oad, *oaq, *oac, *oaf, *oam;
160
+ char *oak, *oad, *oaq, *oac, *oaf, *oam, *oah;
159161
int doWrite;
160162
int uid;
161163
int higherUser = 0; /* True if user being edited is SETUP and the */
162164
/* user doing the editing is ADMIN. Disallow editing */
163165
@@ -188,11 +190,11 @@
188190
*/
189191
doWrite = cgi_all("login","info","pw") && !higherUser;
190192
if( doWrite ){
191193
const char *zPw;
192194
const char *zLogin;
193
- char zCap[20];
195
+ char zCap[30];
194196
int i = 0;
195197
int aa = P("aa")!=0;
196198
int ad = P("ad")!=0;
197199
int ai = P("ai")!=0;
198200
int aj = P("aj")!=0;
@@ -205,21 +207,16 @@
205207
int as = g.okSetup && P("as")!=0;
206208
int aw = P("aw")!=0;
207209
int ac = P("ac")!=0;
208210
int af = P("af")!=0;
209211
int am = P("am")!=0;
210
-#if 0
211
- if( as ) aa = 1;
212
- if( aa ) ai = aw = ap = 1;
213
- if( aw ) an = ar = 1;
214
- if( ai ) ao = 1;
215
- if( ak ) aj = 1;
216
-#endif
212
+ int ah = P("ah")!=0;
217213
if( aa ){ zCap[i++] = 'a'; }
218214
if( ac ){ zCap[i++] = 'c'; }
219215
if( ad ){ zCap[i++] = 'd'; }
220216
if( af ){ zCap[i++] = 'f'; }
217
+ if( ah ){ zCap[i++] = 'h'; }
221218
if( ai ){ zCap[i++] = 'i'; }
222219
if( aj ){ zCap[i++] = 'j'; }
223220
if( ak ){ zCap[i++] = 'k'; }
224221
if( am ){ zCap[i++] = 'm'; }
225222
if( an ){ zCap[i++] = 'n'; }
@@ -259,20 +256,21 @@
259256
/* Load the existing information about the user, if any
260257
*/
261258
zLogin = "";
262259
zInfo = "";
263260
zCap = "";
264
- oaa = oac = oad = oaf = oai = oaj = oak = oam =
261
+ oaa = oac = oad = oaf = oah = oai = oaj = oak = oam =
265262
oan = oao = oap = oaq = oar = oas = oaw = "";
266263
if( uid ){
267264
zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
268265
zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
269266
zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
270267
if( strchr(zCap, 'a') ) oaa = " checked";
271268
if( strchr(zCap, 'c') ) oac = " checked";
272269
if( strchr(zCap, 'd') ) oad = " checked";
273270
if( strchr(zCap, 'f') ) oaf = " checked";
271
+ if( strchr(zCap, 'h') ) oah = " checked";
274272
if( strchr(zCap, 'i') ) oai = " checked";
275273
if( strchr(zCap, 'j') ) oaj = " checked";
276274
if( strchr(zCap, 'k') ) oak = " checked";
277275
if( strchr(zCap, 'm') ) oam = " checked";
278276
if( strchr(zCap, 'n') ) oan = " checked";
@@ -321,10 +319,11 @@
321319
@ <input type="checkbox" name="ad"%s(oad)>Delete</input><br>
322320
@ <input type="checkbox" name="ap"%s(oap)>Password</input><br>
323321
@ <input type="checkbox" name="aq"%s(oaq)>Query</input><br>
324322
@ <input type="checkbox" name="ai"%s(oai)>Check-In</input><br>
325323
@ <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br>
324
+ @ <input type="checkbox" name="ah"%s(oah)>History</input><br>
326325
@ <input type="checkbox" name="aj"%s(oaj)>Read Wiki</input><br>
327326
@ <input type="checkbox" name="af"%s(oaf)>New Wiki</input><br>
328327
@ <input type="checkbox" name="am"%s(oam)>Append Wiki</input><br>
329328
@ <input type="checkbox" name="ak"%s(oak)>Write Wiki</input><br>
330329
@ <input type="checkbox" name="ar"%s(oar)>Read Tkt</input><br>
@@ -376,11 +375,13 @@
376375
@ <li><p>
377376
@ No login is required for user "<b>nobody</b>". The capabilities
378377
@ of this user are available to anyone without supplying a username or
379378
@ password. To disable nobody access, make sure there is no user
380379
@ with an ID of <b>nobody</b> or that the nobody user has no
381
- @ capabilities enabled. The password for the noloing user is ignore.
380
+ @ capabilities enabled. The password for nobody is ignore. To
381
+ @ avoid problems with spiders overloading the server, it is suggested
382
+ @ that the 'h' (History) capability be turned off for user nobody.
382383
@ </p></li>
383384
@
384385
@ <li><p>
385386
@ Login is required for user "<b>anonymous</b>" but the password
386387
@ is displayed on the login screen beside the password entry box
387388
--- src/setup.c
+++ src/setup.c
@@ -112,19 +112,21 @@
112 @ <td align="center">%s(db_column_text(&s,2))</td>
113 @ <td align="left">%s(db_column_text(&s,3))</td>
114 @ </tr>
115 }
116 @ </table></td></tr></table>
117 @ <p>
118 @ <b>Notes:</b>
119 @ <ol>
120 @ <li><p>The permission flags are as follows:</p>
121 @ <table>
122 @ <tr><td>a</td><td width="10"></td>
123 @ <td>Admin: Create or delete users and ticket report formats</td></tr>
124 @ <tr><td>d</td><td></td>
125 @ <td>Delete: Erase anonymous wiki, tickets, and attachments</td></tr>
 
 
126 @ <tr><td>i</td><td></td>
127 @ <td>Check-in: Add new code to the repository</td></tr>
128 @ <tr><td>j</td><td></td><td>Read-Wiki: View wiki pages</td></tr>
129 @ <tr><td>k</td><td></td><td>Wiki: Create or modify wiki pages</td></tr>
130 @ <tr><td>n</td><td></td><td>New: Create new tickets</td></tr>
@@ -153,11 +155,11 @@
153 ** WEBPAGE: /setup_uedit
154 */
155 void user_edit(void){
156 const char *zId, *zLogin, *zInfo, *zCap;
157 char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ;
158 char *oak, *oad, *oaq, *oac, *oaf, *oam;
159 int doWrite;
160 int uid;
161 int higherUser = 0; /* True if user being edited is SETUP and the */
162 /* user doing the editing is ADMIN. Disallow editing */
163
@@ -188,11 +190,11 @@
188 */
189 doWrite = cgi_all("login","info","pw") && !higherUser;
190 if( doWrite ){
191 const char *zPw;
192 const char *zLogin;
193 char zCap[20];
194 int i = 0;
195 int aa = P("aa")!=0;
196 int ad = P("ad")!=0;
197 int ai = P("ai")!=0;
198 int aj = P("aj")!=0;
@@ -205,21 +207,16 @@
205 int as = g.okSetup && P("as")!=0;
206 int aw = P("aw")!=0;
207 int ac = P("ac")!=0;
208 int af = P("af")!=0;
209 int am = P("am")!=0;
210 #if 0
211 if( as ) aa = 1;
212 if( aa ) ai = aw = ap = 1;
213 if( aw ) an = ar = 1;
214 if( ai ) ao = 1;
215 if( ak ) aj = 1;
216 #endif
217 if( aa ){ zCap[i++] = 'a'; }
218 if( ac ){ zCap[i++] = 'c'; }
219 if( ad ){ zCap[i++] = 'd'; }
220 if( af ){ zCap[i++] = 'f'; }
 
221 if( ai ){ zCap[i++] = 'i'; }
222 if( aj ){ zCap[i++] = 'j'; }
223 if( ak ){ zCap[i++] = 'k'; }
224 if( am ){ zCap[i++] = 'm'; }
225 if( an ){ zCap[i++] = 'n'; }
@@ -259,20 +256,21 @@
259 /* Load the existing information about the user, if any
260 */
261 zLogin = "";
262 zInfo = "";
263 zCap = "";
264 oaa = oac = oad = oaf = oai = oaj = oak = oam =
265 oan = oao = oap = oaq = oar = oas = oaw = "";
266 if( uid ){
267 zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
268 zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
269 zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
270 if( strchr(zCap, 'a') ) oaa = " checked";
271 if( strchr(zCap, 'c') ) oac = " checked";
272 if( strchr(zCap, 'd') ) oad = " checked";
273 if( strchr(zCap, 'f') ) oaf = " checked";
 
274 if( strchr(zCap, 'i') ) oai = " checked";
275 if( strchr(zCap, 'j') ) oaj = " checked";
276 if( strchr(zCap, 'k') ) oak = " checked";
277 if( strchr(zCap, 'm') ) oam = " checked";
278 if( strchr(zCap, 'n') ) oan = " checked";
@@ -321,10 +319,11 @@
321 @ <input type="checkbox" name="ad"%s(oad)>Delete</input><br>
322 @ <input type="checkbox" name="ap"%s(oap)>Password</input><br>
323 @ <input type="checkbox" name="aq"%s(oaq)>Query</input><br>
324 @ <input type="checkbox" name="ai"%s(oai)>Check-In</input><br>
325 @ <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br>
 
326 @ <input type="checkbox" name="aj"%s(oaj)>Read Wiki</input><br>
327 @ <input type="checkbox" name="af"%s(oaf)>New Wiki</input><br>
328 @ <input type="checkbox" name="am"%s(oam)>Append Wiki</input><br>
329 @ <input type="checkbox" name="ak"%s(oak)>Write Wiki</input><br>
330 @ <input type="checkbox" name="ar"%s(oar)>Read Tkt</input><br>
@@ -376,11 +375,13 @@
376 @ <li><p>
377 @ No login is required for user "<b>nobody</b>". The capabilities
378 @ of this user are available to anyone without supplying a username or
379 @ password. To disable nobody access, make sure there is no user
380 @ with an ID of <b>nobody</b> or that the nobody user has no
381 @ capabilities enabled. The password for the noloing user is ignore.
 
 
382 @ </p></li>
383 @
384 @ <li><p>
385 @ Login is required for user "<b>anonymous</b>" but the password
386 @ is displayed on the login screen beside the password entry box
387
--- src/setup.c
+++ src/setup.c
@@ -112,19 +112,21 @@
112 @ <td align="center">%s(db_column_text(&s,2))</td>
113 @ <td align="left">%s(db_column_text(&s,3))</td>
114 @ </tr>
115 }
116 @ </table></td></tr></table>
117 @ <p style="clear:both">
118 @ <b>Notes:</b>
119 @ <ol>
120 @ <li><p>The permission flags are as follows:</p>
121 @ <table>
122 @ <tr><td>a</td><td width="10"></td>
123 @ <td>Admin: Create or delete users and ticket report formats</td></tr>
124 @ <tr><td>d</td><td></td>
125 @ <td>Delete: Erase anonymous wiki, tickets, and attachments</td></tr>
126 @ <tr><td>h</td><td></td>
127 @ <td>History: Access older version of code, tickets, or wiki</td></tr>
128 @ <tr><td>i</td><td></td>
129 @ <td>Check-in: Add new code to the repository</td></tr>
130 @ <tr><td>j</td><td></td><td>Read-Wiki: View wiki pages</td></tr>
131 @ <tr><td>k</td><td></td><td>Wiki: Create or modify wiki pages</td></tr>
132 @ <tr><td>n</td><td></td><td>New: Create new tickets</td></tr>
@@ -153,11 +155,11 @@
155 ** WEBPAGE: /setup_uedit
156 */
157 void user_edit(void){
158 const char *zId, *zLogin, *zInfo, *zCap;
159 char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ;
160 char *oak, *oad, *oaq, *oac, *oaf, *oam, *oah;
161 int doWrite;
162 int uid;
163 int higherUser = 0; /* True if user being edited is SETUP and the */
164 /* user doing the editing is ADMIN. Disallow editing */
165
@@ -188,11 +190,11 @@
190 */
191 doWrite = cgi_all("login","info","pw") && !higherUser;
192 if( doWrite ){
193 const char *zPw;
194 const char *zLogin;
195 char zCap[30];
196 int i = 0;
197 int aa = P("aa")!=0;
198 int ad = P("ad")!=0;
199 int ai = P("ai")!=0;
200 int aj = P("aj")!=0;
@@ -205,21 +207,16 @@
207 int as = g.okSetup && P("as")!=0;
208 int aw = P("aw")!=0;
209 int ac = P("ac")!=0;
210 int af = P("af")!=0;
211 int am = P("am")!=0;
212 int ah = P("ah")!=0;
 
 
 
 
 
 
213 if( aa ){ zCap[i++] = 'a'; }
214 if( ac ){ zCap[i++] = 'c'; }
215 if( ad ){ zCap[i++] = 'd'; }
216 if( af ){ zCap[i++] = 'f'; }
217 if( ah ){ zCap[i++] = 'h'; }
218 if( ai ){ zCap[i++] = 'i'; }
219 if( aj ){ zCap[i++] = 'j'; }
220 if( ak ){ zCap[i++] = 'k'; }
221 if( am ){ zCap[i++] = 'm'; }
222 if( an ){ zCap[i++] = 'n'; }
@@ -259,20 +256,21 @@
256 /* Load the existing information about the user, if any
257 */
258 zLogin = "";
259 zInfo = "";
260 zCap = "";
261 oaa = oac = oad = oaf = oah = oai = oaj = oak = oam =
262 oan = oao = oap = oaq = oar = oas = oaw = "";
263 if( uid ){
264 zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
265 zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
266 zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
267 if( strchr(zCap, 'a') ) oaa = " checked";
268 if( strchr(zCap, 'c') ) oac = " checked";
269 if( strchr(zCap, 'd') ) oad = " checked";
270 if( strchr(zCap, 'f') ) oaf = " checked";
271 if( strchr(zCap, 'h') ) oah = " checked";
272 if( strchr(zCap, 'i') ) oai = " checked";
273 if( strchr(zCap, 'j') ) oaj = " checked";
274 if( strchr(zCap, 'k') ) oak = " checked";
275 if( strchr(zCap, 'm') ) oam = " checked";
276 if( strchr(zCap, 'n') ) oan = " checked";
@@ -321,10 +319,11 @@
319 @ <input type="checkbox" name="ad"%s(oad)>Delete</input><br>
320 @ <input type="checkbox" name="ap"%s(oap)>Password</input><br>
321 @ <input type="checkbox" name="aq"%s(oaq)>Query</input><br>
322 @ <input type="checkbox" name="ai"%s(oai)>Check-In</input><br>
323 @ <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br>
324 @ <input type="checkbox" name="ah"%s(oah)>History</input><br>
325 @ <input type="checkbox" name="aj"%s(oaj)>Read Wiki</input><br>
326 @ <input type="checkbox" name="af"%s(oaf)>New Wiki</input><br>
327 @ <input type="checkbox" name="am"%s(oam)>Append Wiki</input><br>
328 @ <input type="checkbox" name="ak"%s(oak)>Write Wiki</input><br>
329 @ <input type="checkbox" name="ar"%s(oar)>Read Tkt</input><br>
@@ -376,11 +375,13 @@
375 @ <li><p>
376 @ No login is required for user "<b>nobody</b>". The capabilities
377 @ of this user are available to anyone without supplying a username or
378 @ password. To disable nobody access, make sure there is no user
379 @ with an ID of <b>nobody</b> or that the nobody user has no
380 @ capabilities enabled. The password for nobody is ignore. To
381 @ avoid problems with spiders overloading the server, it is suggested
382 @ that the 'h' (History) capability be turned off for user nobody.
383 @ </p></li>
384 @
385 @ <li><p>
386 @ Login is required for user "<b>anonymous</b>" but the password
387 @ is displayed on the login screen beside the password entry box
388
+13 -12
--- src/setup.c
+++ src/setup.c
@@ -112,19 +112,21 @@
112112
@ <td align="center">%s(db_column_text(&s,2))</td>
113113
@ <td align="left">%s(db_column_text(&s,3))</td>
114114
@ </tr>
115115
}
116116
@ </table></td></tr></table>
117
- @ <p>
117
+ @ <p style="clear:both">
118118
@ <b>Notes:</b>
119119
@ <ol>
120120
@ <li><p>The permission flags are as follows:</p>
121121
@ <table>
122122
@ <tr><td>a</td><td width="10"></td>
123123
@ <td>Admin: Create or delete users and ticket report formats</td></tr>
124124
@ <tr><td>d</td><td></td>
125125
@ <td>Delete: Erase anonymous wiki, tickets, and attachments</td></tr>
126
+ @ <tr><td>h</td><td></td>
127
+ @ <td>History: Access older version of code, tickets, or wiki</td></tr>
126128
@ <tr><td>i</td><td></td>
127129
@ <td>Check-in: Add new code to the repository</td></tr>
128130
@ <tr><td>j</td><td></td><td>Read-Wiki: View wiki pages</td></tr>
129131
@ <tr><td>k</td><td></td><td>Wiki: Create or modify wiki pages</td></tr>
130132
@ <tr><td>n</td><td></td><td>New: Create new tickets</td></tr>
@@ -153,11 +155,11 @@
153155
** WEBPAGE: /setup_uedit
154156
*/
155157
void user_edit(void){
156158
const char *zId, *zLogin, *zInfo, *zCap;
157159
char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ;
158
- char *oak, *oad, *oaq, *oac, *oaf, *oam;
160
+ char *oak, *oad, *oaq, *oac, *oaf, *oam, *oah;
159161
int doWrite;
160162
int uid;
161163
int higherUser = 0; /* True if user being edited is SETUP and the */
162164
/* user doing the editing is ADMIN. Disallow editing */
163165
@@ -188,11 +190,11 @@
188190
*/
189191
doWrite = cgi_all("login","info","pw") && !higherUser;
190192
if( doWrite ){
191193
const char *zPw;
192194
const char *zLogin;
193
- char zCap[20];
195
+ char zCap[30];
194196
int i = 0;
195197
int aa = P("aa")!=0;
196198
int ad = P("ad")!=0;
197199
int ai = P("ai")!=0;
198200
int aj = P("aj")!=0;
@@ -205,21 +207,16 @@
205207
int as = g.okSetup && P("as")!=0;
206208
int aw = P("aw")!=0;
207209
int ac = P("ac")!=0;
208210
int af = P("af")!=0;
209211
int am = P("am")!=0;
210
-#if 0
211
- if( as ) aa = 1;
212
- if( aa ) ai = aw = ap = 1;
213
- if( aw ) an = ar = 1;
214
- if( ai ) ao = 1;
215
- if( ak ) aj = 1;
216
-#endif
212
+ int ah = P("ah")!=0;
217213
if( aa ){ zCap[i++] = 'a'; }
218214
if( ac ){ zCap[i++] = 'c'; }
219215
if( ad ){ zCap[i++] = 'd'; }
220216
if( af ){ zCap[i++] = 'f'; }
217
+ if( ah ){ zCap[i++] = 'h'; }
221218
if( ai ){ zCap[i++] = 'i'; }
222219
if( aj ){ zCap[i++] = 'j'; }
223220
if( ak ){ zCap[i++] = 'k'; }
224221
if( am ){ zCap[i++] = 'm'; }
225222
if( an ){ zCap[i++] = 'n'; }
@@ -259,20 +256,21 @@
259256
/* Load the existing information about the user, if any
260257
*/
261258
zLogin = "";
262259
zInfo = "";
263260
zCap = "";
264
- oaa = oac = oad = oaf = oai = oaj = oak = oam =
261
+ oaa = oac = oad = oaf = oah = oai = oaj = oak = oam =
265262
oan = oao = oap = oaq = oar = oas = oaw = "";
266263
if( uid ){
267264
zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
268265
zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
269266
zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
270267
if( strchr(zCap, 'a') ) oaa = " checked";
271268
if( strchr(zCap, 'c') ) oac = " checked";
272269
if( strchr(zCap, 'd') ) oad = " checked";
273270
if( strchr(zCap, 'f') ) oaf = " checked";
271
+ if( strchr(zCap, 'h') ) oah = " checked";
274272
if( strchr(zCap, 'i') ) oai = " checked";
275273
if( strchr(zCap, 'j') ) oaj = " checked";
276274
if( strchr(zCap, 'k') ) oak = " checked";
277275
if( strchr(zCap, 'm') ) oam = " checked";
278276
if( strchr(zCap, 'n') ) oan = " checked";
@@ -321,10 +319,11 @@
321319
@ <input type="checkbox" name="ad"%s(oad)>Delete</input><br>
322320
@ <input type="checkbox" name="ap"%s(oap)>Password</input><br>
323321
@ <input type="checkbox" name="aq"%s(oaq)>Query</input><br>
324322
@ <input type="checkbox" name="ai"%s(oai)>Check-In</input><br>
325323
@ <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br>
324
+ @ <input type="checkbox" name="ah"%s(oah)>History</input><br>
326325
@ <input type="checkbox" name="aj"%s(oaj)>Read Wiki</input><br>
327326
@ <input type="checkbox" name="af"%s(oaf)>New Wiki</input><br>
328327
@ <input type="checkbox" name="am"%s(oam)>Append Wiki</input><br>
329328
@ <input type="checkbox" name="ak"%s(oak)>Write Wiki</input><br>
330329
@ <input type="checkbox" name="ar"%s(oar)>Read Tkt</input><br>
@@ -376,11 +375,13 @@
376375
@ <li><p>
377376
@ No login is required for user "<b>nobody</b>". The capabilities
378377
@ of this user are available to anyone without supplying a username or
379378
@ password. To disable nobody access, make sure there is no user
380379
@ with an ID of <b>nobody</b> or that the nobody user has no
381
- @ capabilities enabled. The password for the noloing user is ignore.
380
+ @ capabilities enabled. The password for nobody is ignore. To
381
+ @ avoid problems with spiders overloading the server, it is suggested
382
+ @ that the 'h' (History) capability be turned off for user nobody.
382383
@ </p></li>
383384
@
384385
@ <li><p>
385386
@ Login is required for user "<b>anonymous</b>" but the password
386387
@ is displayed on the login screen beside the password entry box
387388
--- src/setup.c
+++ src/setup.c
@@ -112,19 +112,21 @@
112 @ <td align="center">%s(db_column_text(&s,2))</td>
113 @ <td align="left">%s(db_column_text(&s,3))</td>
114 @ </tr>
115 }
116 @ </table></td></tr></table>
117 @ <p>
118 @ <b>Notes:</b>
119 @ <ol>
120 @ <li><p>The permission flags are as follows:</p>
121 @ <table>
122 @ <tr><td>a</td><td width="10"></td>
123 @ <td>Admin: Create or delete users and ticket report formats</td></tr>
124 @ <tr><td>d</td><td></td>
125 @ <td>Delete: Erase anonymous wiki, tickets, and attachments</td></tr>
 
 
126 @ <tr><td>i</td><td></td>
127 @ <td>Check-in: Add new code to the repository</td></tr>
128 @ <tr><td>j</td><td></td><td>Read-Wiki: View wiki pages</td></tr>
129 @ <tr><td>k</td><td></td><td>Wiki: Create or modify wiki pages</td></tr>
130 @ <tr><td>n</td><td></td><td>New: Create new tickets</td></tr>
@@ -153,11 +155,11 @@
153 ** WEBPAGE: /setup_uedit
154 */
155 void user_edit(void){
156 const char *zId, *zLogin, *zInfo, *zCap;
157 char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ;
158 char *oak, *oad, *oaq, *oac, *oaf, *oam;
159 int doWrite;
160 int uid;
161 int higherUser = 0; /* True if user being edited is SETUP and the */
162 /* user doing the editing is ADMIN. Disallow editing */
163
@@ -188,11 +190,11 @@
188 */
189 doWrite = cgi_all("login","info","pw") && !higherUser;
190 if( doWrite ){
191 const char *zPw;
192 const char *zLogin;
193 char zCap[20];
194 int i = 0;
195 int aa = P("aa")!=0;
196 int ad = P("ad")!=0;
197 int ai = P("ai")!=0;
198 int aj = P("aj")!=0;
@@ -205,21 +207,16 @@
205 int as = g.okSetup && P("as")!=0;
206 int aw = P("aw")!=0;
207 int ac = P("ac")!=0;
208 int af = P("af")!=0;
209 int am = P("am")!=0;
210 #if 0
211 if( as ) aa = 1;
212 if( aa ) ai = aw = ap = 1;
213 if( aw ) an = ar = 1;
214 if( ai ) ao = 1;
215 if( ak ) aj = 1;
216 #endif
217 if( aa ){ zCap[i++] = 'a'; }
218 if( ac ){ zCap[i++] = 'c'; }
219 if( ad ){ zCap[i++] = 'd'; }
220 if( af ){ zCap[i++] = 'f'; }
 
221 if( ai ){ zCap[i++] = 'i'; }
222 if( aj ){ zCap[i++] = 'j'; }
223 if( ak ){ zCap[i++] = 'k'; }
224 if( am ){ zCap[i++] = 'm'; }
225 if( an ){ zCap[i++] = 'n'; }
@@ -259,20 +256,21 @@
259 /* Load the existing information about the user, if any
260 */
261 zLogin = "";
262 zInfo = "";
263 zCap = "";
264 oaa = oac = oad = oaf = oai = oaj = oak = oam =
265 oan = oao = oap = oaq = oar = oas = oaw = "";
266 if( uid ){
267 zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
268 zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
269 zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
270 if( strchr(zCap, 'a') ) oaa = " checked";
271 if( strchr(zCap, 'c') ) oac = " checked";
272 if( strchr(zCap, 'd') ) oad = " checked";
273 if( strchr(zCap, 'f') ) oaf = " checked";
 
274 if( strchr(zCap, 'i') ) oai = " checked";
275 if( strchr(zCap, 'j') ) oaj = " checked";
276 if( strchr(zCap, 'k') ) oak = " checked";
277 if( strchr(zCap, 'm') ) oam = " checked";
278 if( strchr(zCap, 'n') ) oan = " checked";
@@ -321,10 +319,11 @@
321 @ <input type="checkbox" name="ad"%s(oad)>Delete</input><br>
322 @ <input type="checkbox" name="ap"%s(oap)>Password</input><br>
323 @ <input type="checkbox" name="aq"%s(oaq)>Query</input><br>
324 @ <input type="checkbox" name="ai"%s(oai)>Check-In</input><br>
325 @ <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br>
 
326 @ <input type="checkbox" name="aj"%s(oaj)>Read Wiki</input><br>
327 @ <input type="checkbox" name="af"%s(oaf)>New Wiki</input><br>
328 @ <input type="checkbox" name="am"%s(oam)>Append Wiki</input><br>
329 @ <input type="checkbox" name="ak"%s(oak)>Write Wiki</input><br>
330 @ <input type="checkbox" name="ar"%s(oar)>Read Tkt</input><br>
@@ -376,11 +375,13 @@
376 @ <li><p>
377 @ No login is required for user "<b>nobody</b>". The capabilities
378 @ of this user are available to anyone without supplying a username or
379 @ password. To disable nobody access, make sure there is no user
380 @ with an ID of <b>nobody</b> or that the nobody user has no
381 @ capabilities enabled. The password for the noloing user is ignore.
 
 
382 @ </p></li>
383 @
384 @ <li><p>
385 @ Login is required for user "<b>anonymous</b>" but the password
386 @ is displayed on the login screen beside the password entry box
387
--- src/setup.c
+++ src/setup.c
@@ -112,19 +112,21 @@
112 @ <td align="center">%s(db_column_text(&s,2))</td>
113 @ <td align="left">%s(db_column_text(&s,3))</td>
114 @ </tr>
115 }
116 @ </table></td></tr></table>
117 @ <p style="clear:both">
118 @ <b>Notes:</b>
119 @ <ol>
120 @ <li><p>The permission flags are as follows:</p>
121 @ <table>
122 @ <tr><td>a</td><td width="10"></td>
123 @ <td>Admin: Create or delete users and ticket report formats</td></tr>
124 @ <tr><td>d</td><td></td>
125 @ <td>Delete: Erase anonymous wiki, tickets, and attachments</td></tr>
126 @ <tr><td>h</td><td></td>
127 @ <td>History: Access older version of code, tickets, or wiki</td></tr>
128 @ <tr><td>i</td><td></td>
129 @ <td>Check-in: Add new code to the repository</td></tr>
130 @ <tr><td>j</td><td></td><td>Read-Wiki: View wiki pages</td></tr>
131 @ <tr><td>k</td><td></td><td>Wiki: Create or modify wiki pages</td></tr>
132 @ <tr><td>n</td><td></td><td>New: Create new tickets</td></tr>
@@ -153,11 +155,11 @@
155 ** WEBPAGE: /setup_uedit
156 */
157 void user_edit(void){
158 const char *zId, *zLogin, *zInfo, *zCap;
159 char *oaa, *oas, *oar, *oaw, *oan, *oai, *oaj, *oao, *oap ;
160 char *oak, *oad, *oaq, *oac, *oaf, *oam, *oah;
161 int doWrite;
162 int uid;
163 int higherUser = 0; /* True if user being edited is SETUP and the */
164 /* user doing the editing is ADMIN. Disallow editing */
165
@@ -188,11 +190,11 @@
190 */
191 doWrite = cgi_all("login","info","pw") && !higherUser;
192 if( doWrite ){
193 const char *zPw;
194 const char *zLogin;
195 char zCap[30];
196 int i = 0;
197 int aa = P("aa")!=0;
198 int ad = P("ad")!=0;
199 int ai = P("ai")!=0;
200 int aj = P("aj")!=0;
@@ -205,21 +207,16 @@
207 int as = g.okSetup && P("as")!=0;
208 int aw = P("aw")!=0;
209 int ac = P("ac")!=0;
210 int af = P("af")!=0;
211 int am = P("am")!=0;
212 int ah = P("ah")!=0;
 
 
 
 
 
 
213 if( aa ){ zCap[i++] = 'a'; }
214 if( ac ){ zCap[i++] = 'c'; }
215 if( ad ){ zCap[i++] = 'd'; }
216 if( af ){ zCap[i++] = 'f'; }
217 if( ah ){ zCap[i++] = 'h'; }
218 if( ai ){ zCap[i++] = 'i'; }
219 if( aj ){ zCap[i++] = 'j'; }
220 if( ak ){ zCap[i++] = 'k'; }
221 if( am ){ zCap[i++] = 'm'; }
222 if( an ){ zCap[i++] = 'n'; }
@@ -259,20 +256,21 @@
256 /* Load the existing information about the user, if any
257 */
258 zLogin = "";
259 zInfo = "";
260 zCap = "";
261 oaa = oac = oad = oaf = oah = oai = oaj = oak = oam =
262 oan = oao = oap = oaq = oar = oas = oaw = "";
263 if( uid ){
264 zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
265 zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
266 zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
267 if( strchr(zCap, 'a') ) oaa = " checked";
268 if( strchr(zCap, 'c') ) oac = " checked";
269 if( strchr(zCap, 'd') ) oad = " checked";
270 if( strchr(zCap, 'f') ) oaf = " checked";
271 if( strchr(zCap, 'h') ) oah = " checked";
272 if( strchr(zCap, 'i') ) oai = " checked";
273 if( strchr(zCap, 'j') ) oaj = " checked";
274 if( strchr(zCap, 'k') ) oak = " checked";
275 if( strchr(zCap, 'm') ) oam = " checked";
276 if( strchr(zCap, 'n') ) oan = " checked";
@@ -321,10 +319,11 @@
319 @ <input type="checkbox" name="ad"%s(oad)>Delete</input><br>
320 @ <input type="checkbox" name="ap"%s(oap)>Password</input><br>
321 @ <input type="checkbox" name="aq"%s(oaq)>Query</input><br>
322 @ <input type="checkbox" name="ai"%s(oai)>Check-In</input><br>
323 @ <input type="checkbox" name="ao"%s(oao)>Check-Out</input><br>
324 @ <input type="checkbox" name="ah"%s(oah)>History</input><br>
325 @ <input type="checkbox" name="aj"%s(oaj)>Read Wiki</input><br>
326 @ <input type="checkbox" name="af"%s(oaf)>New Wiki</input><br>
327 @ <input type="checkbox" name="am"%s(oam)>Append Wiki</input><br>
328 @ <input type="checkbox" name="ak"%s(oak)>Write Wiki</input><br>
329 @ <input type="checkbox" name="ar"%s(oar)>Read Tkt</input><br>
@@ -376,11 +375,13 @@
375 @ <li><p>
376 @ No login is required for user "<b>nobody</b>". The capabilities
377 @ of this user are available to anyone without supplying a username or
378 @ password. To disable nobody access, make sure there is no user
379 @ with an ID of <b>nobody</b> or that the nobody user has no
380 @ capabilities enabled. The password for nobody is ignore. To
381 @ avoid problems with spiders overloading the server, it is suggested
382 @ that the 'h' (History) capability be turned off for user nobody.
383 @ </p></li>
384 @
385 @ <li><p>
386 @ Login is required for user "<b>anonymous</b>" but the password
387 @ is displayed on the login screen beside the password entry box
388
+3 -1
--- src/style.c
+++ src/style.c
@@ -84,11 +84,13 @@
8484
}else{
8585
@ <small>logged in as %h(g.zLogin)</small>
8686
}
8787
@ </td><td valign="top" align="right">
8888
@ <a href="%s(g.zBaseURL)/index">Home</a>
89
- @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
89
+ if( g.okRead ){
90
+ @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
91
+ }
9092
if( g.okRdWiki ){
9193
@ | <a href="%s(g.zBaseURL)/wiki">Wiki</a>
9294
}
9395
#if 0
9496
@ | <font color="#888888">Search</font>
9597
--- src/style.c
+++ src/style.c
@@ -84,11 +84,13 @@
84 }else{
85 @ <small>logged in as %h(g.zLogin)</small>
86 }
87 @ </td><td valign="top" align="right">
88 @ <a href="%s(g.zBaseURL)/index">Home</a>
89 @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
 
 
90 if( g.okRdWiki ){
91 @ | <a href="%s(g.zBaseURL)/wiki">Wiki</a>
92 }
93 #if 0
94 @ | <font color="#888888">Search</font>
95
--- src/style.c
+++ src/style.c
@@ -84,11 +84,13 @@
84 }else{
85 @ <small>logged in as %h(g.zLogin)</small>
86 }
87 @ </td><td valign="top" align="right">
88 @ <a href="%s(g.zBaseURL)/index">Home</a>
89 if( g.okRead ){
90 @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
91 }
92 if( g.okRdWiki ){
93 @ | <a href="%s(g.zBaseURL)/wiki">Wiki</a>
94 }
95 #if 0
96 @ | <font color="#888888">Search</font>
97
+3 -1
--- src/style.c
+++ src/style.c
@@ -84,11 +84,13 @@
8484
}else{
8585
@ <small>logged in as %h(g.zLogin)</small>
8686
}
8787
@ </td><td valign="top" align="right">
8888
@ <a href="%s(g.zBaseURL)/index">Home</a>
89
- @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
89
+ if( g.okRead ){
90
+ @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
91
+ }
9092
if( g.okRdWiki ){
9193
@ | <a href="%s(g.zBaseURL)/wiki">Wiki</a>
9294
}
9395
#if 0
9496
@ | <font color="#888888">Search</font>
9597
--- src/style.c
+++ src/style.c
@@ -84,11 +84,13 @@
84 }else{
85 @ <small>logged in as %h(g.zLogin)</small>
86 }
87 @ </td><td valign="top" align="right">
88 @ <a href="%s(g.zBaseURL)/index">Home</a>
89 @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
 
 
90 if( g.okRdWiki ){
91 @ | <a href="%s(g.zBaseURL)/wiki">Wiki</a>
92 }
93 #if 0
94 @ | <font color="#888888">Search</font>
95
--- src/style.c
+++ src/style.c
@@ -84,11 +84,13 @@
84 }else{
85 @ <small>logged in as %h(g.zLogin)</small>
86 }
87 @ </td><td valign="top" align="right">
88 @ <a href="%s(g.zBaseURL)/index">Home</a>
89 if( g.okRead ){
90 @ | <a href="%s(g.zBaseURL)/timeline">Timeline</a>
91 }
92 if( g.okRdWiki ){
93 @ | <a href="%s(g.zBaseURL)/wiki">Wiki</a>
94 }
95 #if 0
96 @ | <font color="#888888">Search</font>
97
+17 -5
--- src/timeline.c
+++ src/timeline.c
@@ -31,21 +31,27 @@
3131
** Generate a hyperlink to a version.
3232
*/
3333
void hyperlink_to_uuid(const char *zUuid){
3434
char zShortUuid[UUID_SIZE+1];
3535
sprintf(zShortUuid, "%.10s", zUuid);
36
- @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
36
+ if( g.okHistory ){
37
+ @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
38
+ }else{
39
+ @ <b>[%s(zShortUuid)]</b>
40
+ }
3741
}
3842
3943
/*
4044
** Generate a hyperlink to a diff between two versions.
4145
*/
4246
void hyperlink_to_diff(const char *zV1, const char *zV2){
43
- if( zV2==0 ){
44
- @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
45
- }else{
46
- @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
47
+ if( g.okHistory ){
48
+ if( zV2==0 ){
49
+ @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
50
+ }else{
51
+ @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
52
+ }
4753
}
4854
}
4955
5056
5157
/*
@@ -52,10 +58,16 @@
5258
** WEBPAGE: timeline
5359
*/
5460
void page_timeline(void){
5561
Stmt q;
5662
char zPrevDate[20];
63
+
64
+ /* To view the timeline, must have permission to read project data.
65
+ */
66
+ login_check_credentials();
67
+ if( !g.okRead ){ login_needed(); return; }
68
+
5769
style_header("Timeline");
5870
zPrevDate[0] = 0;
5971
db_prepare(&q,
6072
"SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
6173
" FROM event, blob"
6274
--- src/timeline.c
+++ src/timeline.c
@@ -31,21 +31,27 @@
31 ** Generate a hyperlink to a version.
32 */
33 void hyperlink_to_uuid(const char *zUuid){
34 char zShortUuid[UUID_SIZE+1];
35 sprintf(zShortUuid, "%.10s", zUuid);
36 @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
 
 
 
 
37 }
38
39 /*
40 ** Generate a hyperlink to a diff between two versions.
41 */
42 void hyperlink_to_diff(const char *zV1, const char *zV2){
43 if( zV2==0 ){
44 @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
45 }else{
46 @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
 
 
47 }
48 }
49
50
51 /*
@@ -52,10 +58,16 @@
52 ** WEBPAGE: timeline
53 */
54 void page_timeline(void){
55 Stmt q;
56 char zPrevDate[20];
 
 
 
 
 
 
57 style_header("Timeline");
58 zPrevDate[0] = 0;
59 db_prepare(&q,
60 "SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
61 " FROM event, blob"
62
--- src/timeline.c
+++ src/timeline.c
@@ -31,21 +31,27 @@
31 ** Generate a hyperlink to a version.
32 */
33 void hyperlink_to_uuid(const char *zUuid){
34 char zShortUuid[UUID_SIZE+1];
35 sprintf(zShortUuid, "%.10s", zUuid);
36 if( g.okHistory ){
37 @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
38 }else{
39 @ <b>[%s(zShortUuid)]</b>
40 }
41 }
42
43 /*
44 ** Generate a hyperlink to a diff between two versions.
45 */
46 void hyperlink_to_diff(const char *zV1, const char *zV2){
47 if( g.okHistory ){
48 if( zV2==0 ){
49 @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
50 }else{
51 @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
52 }
53 }
54 }
55
56
57 /*
@@ -52,10 +58,16 @@
58 ** WEBPAGE: timeline
59 */
60 void page_timeline(void){
61 Stmt q;
62 char zPrevDate[20];
63
64 /* To view the timeline, must have permission to read project data.
65 */
66 login_check_credentials();
67 if( !g.okRead ){ login_needed(); return; }
68
69 style_header("Timeline");
70 zPrevDate[0] = 0;
71 db_prepare(&q,
72 "SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
73 " FROM event, blob"
74
+17 -5
--- src/timeline.c
+++ src/timeline.c
@@ -31,21 +31,27 @@
3131
** Generate a hyperlink to a version.
3232
*/
3333
void hyperlink_to_uuid(const char *zUuid){
3434
char zShortUuid[UUID_SIZE+1];
3535
sprintf(zShortUuid, "%.10s", zUuid);
36
- @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
36
+ if( g.okHistory ){
37
+ @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
38
+ }else{
39
+ @ <b>[%s(zShortUuid)]</b>
40
+ }
3741
}
3842
3943
/*
4044
** Generate a hyperlink to a diff between two versions.
4145
*/
4246
void hyperlink_to_diff(const char *zV1, const char *zV2){
43
- if( zV2==0 ){
44
- @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
45
- }else{
46
- @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
47
+ if( g.okHistory ){
48
+ if( zV2==0 ){
49
+ @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
50
+ }else{
51
+ @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
52
+ }
4753
}
4854
}
4955
5056
5157
/*
@@ -52,10 +58,16 @@
5258
** WEBPAGE: timeline
5359
*/
5460
void page_timeline(void){
5561
Stmt q;
5662
char zPrevDate[20];
63
+
64
+ /* To view the timeline, must have permission to read project data.
65
+ */
66
+ login_check_credentials();
67
+ if( !g.okRead ){ login_needed(); return; }
68
+
5769
style_header("Timeline");
5870
zPrevDate[0] = 0;
5971
db_prepare(&q,
6072
"SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
6173
" FROM event, blob"
6274
--- src/timeline.c
+++ src/timeline.c
@@ -31,21 +31,27 @@
31 ** Generate a hyperlink to a version.
32 */
33 void hyperlink_to_uuid(const char *zUuid){
34 char zShortUuid[UUID_SIZE+1];
35 sprintf(zShortUuid, "%.10s", zUuid);
36 @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
 
 
 
 
37 }
38
39 /*
40 ** Generate a hyperlink to a diff between two versions.
41 */
42 void hyperlink_to_diff(const char *zV1, const char *zV2){
43 if( zV2==0 ){
44 @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
45 }else{
46 @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
 
 
47 }
48 }
49
50
51 /*
@@ -52,10 +58,16 @@
52 ** WEBPAGE: timeline
53 */
54 void page_timeline(void){
55 Stmt q;
56 char zPrevDate[20];
 
 
 
 
 
 
57 style_header("Timeline");
58 zPrevDate[0] = 0;
59 db_prepare(&q,
60 "SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
61 " FROM event, blob"
62
--- src/timeline.c
+++ src/timeline.c
@@ -31,21 +31,27 @@
31 ** Generate a hyperlink to a version.
32 */
33 void hyperlink_to_uuid(const char *zUuid){
34 char zShortUuid[UUID_SIZE+1];
35 sprintf(zShortUuid, "%.10s", zUuid);
36 if( g.okHistory ){
37 @ <a href="%s(g.zBaseURL)/vinfo/%s(zUuid)">[%s(zShortUuid)]</a>
38 }else{
39 @ <b>[%s(zShortUuid)]</b>
40 }
41 }
42
43 /*
44 ** Generate a hyperlink to a diff between two versions.
45 */
46 void hyperlink_to_diff(const char *zV1, const char *zV2){
47 if( g.okHistory ){
48 if( zV2==0 ){
49 @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
50 }else{
51 @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
52 }
53 }
54 }
55
56
57 /*
@@ -52,10 +58,16 @@
58 ** WEBPAGE: timeline
59 */
60 void page_timeline(void){
61 Stmt q;
62 char zPrevDate[20];
63
64 /* To view the timeline, must have permission to read project data.
65 */
66 login_check_credentials();
67 if( !g.okRead ){ login_needed(); return; }
68
69 style_header("Timeline");
70 zPrevDate[0] = 0;
71 db_prepare(&q,
72 "SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
73 " FROM event, blob"
74

Keyboard Shortcuts

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