| | @@ -157,755 +157,10 @@ |
| 157 | 157 | "Enter raw TH1 commands"); |
| 158 | 158 | @ </table> |
| 159 | 159 | |
| 160 | 160 | style_footer(); |
| 161 | 161 | } |
| 162 | | - |
| 163 | | -/* |
| 164 | | -** WEBPAGE: setup_ulist |
| 165 | | -** |
| 166 | | -** Show a list of users. Clicking on any user jumps to the edit |
| 167 | | -** screen for that user. Requires Admin privileges. |
| 168 | | -** |
| 169 | | -** Query parameters: |
| 170 | | -** |
| 171 | | -** with=CAP Only show users that have one or more capabilities in CAP. |
| 172 | | -*/ |
| 173 | | -void setup_ulist(void){ |
| 174 | | - Stmt s; |
| 175 | | - double rNow; |
| 176 | | - const char *zWith = P("with"); |
| 177 | | - |
| 178 | | - login_check_credentials(); |
| 179 | | - if( !g.perm.Admin ){ |
| 180 | | - login_needed(0); |
| 181 | | - return; |
| 182 | | - } |
| 183 | | - |
| 184 | | - if( zWith==0 || zWith[0]==0 ){ |
| 185 | | - style_submenu_element("Add", "setup_uedit"); |
| 186 | | - style_submenu_element("Log", "access_log"); |
| 187 | | - style_submenu_element("Help", "setup_ulist_notes"); |
| 188 | | - style_header("User List"); |
| 189 | | - @ <table border=1 cellpadding=2 cellspacing=0 class='userTable'> |
| 190 | | - @ <thead><tr> |
| 191 | | - @ <th>Category |
| 192 | | - @ <th>Capabilities (<a href='%R/setup_ucap_list'>key</a>) |
| 193 | | - @ <th>Info <th>Last Change</tr></thead> |
| 194 | | - @ <tbody> |
| 195 | | - db_prepare(&s, |
| 196 | | - "SELECT uid, login, cap, date(mtime,'unixepoch')" |
| 197 | | - " FROM user" |
| 198 | | - " WHERE login IN ('anonymous','nobody','developer','reader')" |
| 199 | | - " ORDER BY login" |
| 200 | | - ); |
| 201 | | - while( db_step(&s)==SQLITE_ROW ){ |
| 202 | | - int uid = db_column_int(&s, 0); |
| 203 | | - const char *zLogin = db_column_text(&s, 1); |
| 204 | | - const char *zCap = db_column_text(&s, 2); |
| 205 | | - const char *zDate = db_column_text(&s, 4); |
| 206 | | - @ <tr> |
| 207 | | - @ <td><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a> |
| 208 | | - @ <td>%h(zCap) |
| 209 | | - |
| 210 | | - if( fossil_strcmp(zLogin,"anonymous")==0 ){ |
| 211 | | - @ <td>All logged-in users |
| 212 | | - }else if( fossil_strcmp(zLogin,"developer")==0 ){ |
| 213 | | - @ <td>Users with '<b>v</b>' capability |
| 214 | | - }else if( fossil_strcmp(zLogin,"nobody")==0 ){ |
| 215 | | - @ <td>All users without login |
| 216 | | - }else if( fossil_strcmp(zLogin,"reader")==0 ){ |
| 217 | | - @ <td>Users with '<b>u</b>' capability |
| 218 | | - }else{ |
| 219 | | - @ <td> |
| 220 | | - } |
| 221 | | - if( zDate && zDate[0] ){ |
| 222 | | - @ <td>%h(zDate) |
| 223 | | - }else{ |
| 224 | | - @ <td> |
| 225 | | - } |
| 226 | | - @ </tr> |
| 227 | | - } |
| 228 | | - db_finalize(&s); |
| 229 | | - }else{ |
| 230 | | - style_header("Users With Capabilities \"%h\"", zWith); |
| 231 | | - } |
| 232 | | - @ </tbody></table> |
| 233 | | - @ <div class='section'>Users</div> |
| 234 | | - @ <table border=1 cellpadding=2 cellspacing=0 class='userTable sortable' \ |
| 235 | | - @ data-column-types='ktxTTK' data-init-sort='2'> |
| 236 | | - @ <thead><tr> |
| 237 | | - @ <th>Login Name<th>Caps<th>Info<th>Date<th>Expire<th>Last Login</tr></thead> |
| 238 | | - @ <tbody> |
| 239 | | - db_multi_exec( |
| 240 | | - "CREATE TEMP TABLE lastAccess(uname TEXT PRIMARY KEY, atime REAL)" |
| 241 | | - "WITHOUT ROWID;" |
| 242 | | - ); |
| 243 | | - if( db_table_exists("repository","accesslog") ){ |
| 244 | | - db_multi_exec( |
| 245 | | - "INSERT INTO lastAccess(uname, atime)" |
| 246 | | - " SELECT uname, max(mtime) FROM (" |
| 247 | | - " SELECT uname, mtime FROM accesslog WHERE success" |
| 248 | | - " UNION ALL" |
| 249 | | - " SELECT login AS uname, rcvfrom.mtime AS mtime" |
| 250 | | - " FROM rcvfrom JOIN user USING(uid))" |
| 251 | | - " GROUP BY 1;" |
| 252 | | - ); |
| 253 | | - } |
| 254 | | - if( zWith && zWith[0] ){ |
| 255 | | - zWith = mprintf(" AND fullcap(cap) GLOB '*[%q]*'", zWith); |
| 256 | | - }else{ |
| 257 | | - zWith = ""; |
| 258 | | - } |
| 259 | | - db_prepare(&s, |
| 260 | | - "SELECT uid, login, cap, info, date(mtime,'unixepoch')," |
| 261 | | - " lower(login) AS sortkey, " |
| 262 | | - " CASE WHEN info LIKE '%%expires 20%%'" |
| 263 | | - " THEN substr(info,instr(lower(info),'expires')+8,10)" |
| 264 | | - " END AS exp," |
| 265 | | - "atime" |
| 266 | | - " FROM user LEFT JOIN lastAccess ON login=uname" |
| 267 | | - " WHERE login NOT IN ('anonymous','nobody','developer','reader') %s" |
| 268 | | - " ORDER BY sortkey", zWith/*safe-for-%s*/ |
| 269 | | - ); |
| 270 | | - rNow = db_double(0.0, "SELECT julianday('now');"); |
| 271 | | - while( db_step(&s)==SQLITE_ROW ){ |
| 272 | | - int uid = db_column_int(&s, 0); |
| 273 | | - const char *zLogin = db_column_text(&s, 1); |
| 274 | | - const char *zCap = db_column_text(&s, 2); |
| 275 | | - const char *zInfo = db_column_text(&s, 3); |
| 276 | | - const char *zDate = db_column_text(&s, 4); |
| 277 | | - const char *zSortKey = db_column_text(&s,5); |
| 278 | | - const char *zExp = db_column_text(&s,6); |
| 279 | | - double rATime = db_column_double(&s,7); |
| 280 | | - char *zAge = 0; |
| 281 | | - if( rATime>0.0 ){ |
| 282 | | - zAge = human_readable_age(rNow - rATime); |
| 283 | | - } |
| 284 | | - @ <tr> |
| 285 | | - @ <td data-sortkey='%h(zSortKey)'>\ |
| 286 | | - @ <a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a> |
| 287 | | - @ <td>%h(zCap) |
| 288 | | - @ <td>%h(zInfo) |
| 289 | | - @ <td>%h(zDate?zDate:"") |
| 290 | | - @ <td>%h(zExp?zExp:"") |
| 291 | | - @ <td data-sortkey='%f(rATime)' style='white-space:nowrap'>%s(zAge?zAge:"") |
| 292 | | - @ </tr> |
| 293 | | - fossil_free(zAge); |
| 294 | | - } |
| 295 | | - @ </tbody></table> |
| 296 | | - db_finalize(&s); |
| 297 | | - style_table_sorter(); |
| 298 | | - style_footer(); |
| 299 | | -} |
| 300 | | - |
| 301 | | -/* |
| 302 | | -** WEBPAGE: setup_ulist_notes |
| 303 | | -** |
| 304 | | -** A documentation page showing notes about user configuration. This |
| 305 | | -** information used to be a side-bar on the user list page, but has been |
| 306 | | -** factored out for improved presentation. |
| 307 | | -*/ |
| 308 | | -void setup_ulist_notes(void){ |
| 309 | | - style_header("User Configuration Notes"); |
| 310 | | - @ <h1>User Configuration Notes:</h1> |
| 311 | | - @ <ol> |
| 312 | | - @ <li><p> |
| 313 | | - @ Every user, logged in or not, inherits the privileges of |
| 314 | | - @ <span class="usertype">nobody</span>. |
| 315 | | - @ </p></li> |
| 316 | | - @ |
| 317 | | - @ <li><p> |
| 318 | | - @ Any human can login as <span class="usertype">anonymous</span> since the |
| 319 | | - @ password is clearly displayed on the login page for them to type. The |
| 320 | | - @ purpose of requiring anonymous to log in is to prevent access by spiders. |
| 321 | | - @ Every logged-in user inherits the combined privileges of |
| 322 | | - @ <span class="usertype">anonymous</span> and |
| 323 | | - @ <span class="usertype">nobody</span>. |
| 324 | | - @ </p></li> |
| 325 | | - @ |
| 326 | | - @ <li><p> |
| 327 | | - @ Users with privilege <span class="capability">u</span> inherit the combined |
| 328 | | - @ privileges of <span class="usertype">reader</span>, |
| 329 | | - @ <span class="usertype">anonymous</span>, and |
| 330 | | - @ <span class="usertype">nobody</span>. |
| 331 | | - @ </p></li> |
| 332 | | - @ |
| 333 | | - @ <li><p> |
| 334 | | - @ Users with privilege <span class="capability">v</span> inherit the combined |
| 335 | | - @ privileges of <span class="usertype">developer</span>, |
| 336 | | - @ <span class="usertype">anonymous</span>, and |
| 337 | | - @ <span class="usertype">nobody</span>. |
| 338 | | - @ </p></li> |
| 339 | | - @ |
| 340 | | - @ <li><p>The permission flags are as follows:</p> |
| 341 | | - capabilities_table(); |
| 342 | | - @ </li> |
| 343 | | - @ </ol> |
| 344 | | - style_footer(); |
| 345 | | -} |
| 346 | | - |
| 347 | | -/* |
| 348 | | -** WEBPAGE: setup_ucap_list |
| 349 | | -** |
| 350 | | -** A documentation page showing the meaning of the various user capabilities |
| 351 | | -** code letters. |
| 352 | | -*/ |
| 353 | | -void setup_ucap_list(void){ |
| 354 | | - style_header("User Capability Codes"); |
| 355 | | - capabilities_table(); |
| 356 | | - style_footer(); |
| 357 | | -} |
| 358 | | - |
| 359 | | -/* |
| 360 | | -** Return true if zPw is a valid password string. A valid |
| 361 | | -** password string is: |
| 362 | | -** |
| 363 | | -** (1) A zero-length string, or |
| 364 | | -** (2) a string that contains a character other than '*'. |
| 365 | | -*/ |
| 366 | | -static int isValidPwString(const char *zPw){ |
| 367 | | - if( zPw==0 ) return 0; |
| 368 | | - if( zPw[0]==0 ) return 1; |
| 369 | | - while( zPw[0]=='*' ){ zPw++; } |
| 370 | | - return zPw[0]!=0; |
| 371 | | -} |
| 372 | | - |
| 373 | | -/* |
| 374 | | -** WEBPAGE: setup_uedit |
| 375 | | -** |
| 376 | | -** Edit information about a user or create a new user. |
| 377 | | -** Requires Admin privileges. |
| 378 | | -*/ |
| 379 | | -void user_edit(void){ |
| 380 | | - const char *zId, *zLogin, *zInfo, *zCap, *zPw; |
| 381 | | - const char *zGroup; |
| 382 | | - const char *zOldLogin; |
| 383 | | - int doWrite; |
| 384 | | - int uid, i; |
| 385 | | - int higherUser = 0; /* True if user being edited is SETUP and the */ |
| 386 | | - /* user doing the editing is ADMIN. Disallow editing */ |
| 387 | | - const char *inherit[128]; |
| 388 | | - int a[128]; |
| 389 | | - const char *oa[128]; |
| 390 | | - |
| 391 | | - /* Must have ADMIN privileges to access this page |
| 392 | | - */ |
| 393 | | - login_check_credentials(); |
| 394 | | - if( !g.perm.Admin ){ login_needed(0); return; } |
| 395 | | - |
| 396 | | - /* Check to see if an ADMIN user is trying to edit a SETUP account. |
| 397 | | - ** Don't allow that. |
| 398 | | - */ |
| 399 | | - zId = PD("id", "0"); |
| 400 | | - uid = atoi(zId); |
| 401 | | - if( zId && !g.perm.Setup && uid>0 ){ |
| 402 | | - char *zOldCaps; |
| 403 | | - zOldCaps = db_text(0, "SELECT cap FROM user WHERE uid=%d",uid); |
| 404 | | - higherUser = zOldCaps && strchr(zOldCaps,'s'); |
| 405 | | - } |
| 406 | | - |
| 407 | | - if( P("can") ){ |
| 408 | | - /* User pressed the cancel button */ |
| 409 | | - cgi_redirect(cgi_referer("setup_ulist")); |
| 410 | | - return; |
| 411 | | - } |
| 412 | | - |
| 413 | | - /* If we have all the necessary information, write the new or |
| 414 | | - ** modified user record. After writing the user record, redirect |
| 415 | | - ** to the page that displays a list of users. |
| 416 | | - */ |
| 417 | | - doWrite = cgi_all("login","info","pw") && !higherUser && cgi_csrf_safe(1); |
| 418 | | - if( doWrite ){ |
| 419 | | - char c; |
| 420 | | - char zCap[70], zNm[4]; |
| 421 | | - zNm[0] = 'a'; |
| 422 | | - zNm[2] = 0; |
| 423 | | - for(i=0, c='a'; c<='z'; c++){ |
| 424 | | - zNm[1] = c; |
| 425 | | - a[c&0x7f] = (c!='s' || g.perm.Setup) && P(zNm)!=0; |
| 426 | | - if( a[c&0x7f] ) zCap[i++] = c; |
| 427 | | - } |
| 428 | | - for(c='0'; c<='9'; c++){ |
| 429 | | - zNm[1] = c; |
| 430 | | - a[c&0x7f] = P(zNm)!=0; |
| 431 | | - if( a[c&0x7f] ) zCap[i++] = c; |
| 432 | | - } |
| 433 | | - for(c='A'; c<='Z'; c++){ |
| 434 | | - zNm[1] = c; |
| 435 | | - a[c&0x7f] = P(zNm)!=0; |
| 436 | | - if( a[c&0x7f] ) zCap[i++] = c; |
| 437 | | - } |
| 438 | | - |
| 439 | | - zCap[i] = 0; |
| 440 | | - zPw = P("pw"); |
| 441 | | - zLogin = P("login"); |
| 442 | | - if( strlen(zLogin)==0 ){ |
| 443 | | - const char *zRef = cgi_referer("setup_ulist"); |
| 444 | | - style_header("User Creation Error"); |
| 445 | | - @ <span class="loginError">Empty login not allowed.</span> |
| 446 | | - @ |
| 447 | | - @ <p><a href="setup_uedit?id=%d(uid)&referer=%T(zRef)"> |
| 448 | | - @ [Bummer]</a></p> |
| 449 | | - style_footer(); |
| 450 | | - return; |
| 451 | | - } |
| 452 | | - if( isValidPwString(zPw) ){ |
| 453 | | - zPw = sha1_shared_secret(zPw, zLogin, 0); |
| 454 | | - }else{ |
| 455 | | - zPw = db_text(0, "SELECT pw FROM user WHERE uid=%d", uid); |
| 456 | | - } |
| 457 | | - zOldLogin = db_text(0, "SELECT login FROM user WHERE uid=%d", uid); |
| 458 | | - if( db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d",zLogin,uid) ){ |
| 459 | | - const char *zRef = cgi_referer("setup_ulist"); |
| 460 | | - style_header("User Creation Error"); |
| 461 | | - @ <span class="loginError">Login "%h(zLogin)" is already used by |
| 462 | | - @ a different user.</span> |
| 463 | | - @ |
| 464 | | - @ <p><a href="setup_uedit?id=%d(uid)&referer=%T(zRef)"> |
| 465 | | - @ [Bummer]</a></p> |
| 466 | | - style_footer(); |
| 467 | | - return; |
| 468 | | - } |
| 469 | | - login_verify_csrf_secret(); |
| 470 | | - db_multi_exec( |
| 471 | | - "REPLACE INTO user(uid,login,info,pw,cap,mtime) " |
| 472 | | - "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())", |
| 473 | | - uid, zLogin, P("info"), zPw, zCap |
| 474 | | - ); |
| 475 | | - setup_incr_cfgcnt(); |
| 476 | | - admin_log( "Updated user [%q] with capabilities [%q].", |
| 477 | | - zLogin, zCap ); |
| 478 | | - if( atoi(PD("all","0"))>0 ){ |
| 479 | | - Blob sql; |
| 480 | | - char *zErr = 0; |
| 481 | | - blob_zero(&sql); |
| 482 | | - if( zOldLogin==0 ){ |
| 483 | | - blob_appendf(&sql, |
| 484 | | - "INSERT INTO user(login)" |
| 485 | | - " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM user WHERE login=%Q);", |
| 486 | | - zLogin, zLogin |
| 487 | | - ); |
| 488 | | - zOldLogin = zLogin; |
| 489 | | - } |
| 490 | | - blob_appendf(&sql, |
| 491 | | - "UPDATE user SET login=%Q," |
| 492 | | - " pw=coalesce(shared_secret(%Q,%Q," |
| 493 | | - "(SELECT value FROM config WHERE name='project-code')),pw)," |
| 494 | | - " info=%Q," |
| 495 | | - " cap=%Q," |
| 496 | | - " mtime=now()" |
| 497 | | - " WHERE login=%Q;", |
| 498 | | - zLogin, P("pw"), zLogin, P("info"), zCap, |
| 499 | | - zOldLogin |
| 500 | | - ); |
| 501 | | - login_group_sql(blob_str(&sql), "<li> ", " </li>\n", &zErr); |
| 502 | | - blob_reset(&sql); |
| 503 | | - admin_log( "Updated user [%q] in all login groups " |
| 504 | | - "with capabilities [%q].", |
| 505 | | - zLogin, zCap ); |
| 506 | | - if( zErr ){ |
| 507 | | - const char *zRef = cgi_referer("setup_ulist"); |
| 508 | | - style_header("User Change Error"); |
| 509 | | - admin_log( "Error updating user '%q': %s'.", zLogin, zErr ); |
| 510 | | - @ <span class="loginError">%h(zErr)</span> |
| 511 | | - @ |
| 512 | | - @ <p><a href="setup_uedit?id=%d(uid)&referer=%T(zRef)"> |
| 513 | | - @ [Bummer]</a></p> |
| 514 | | - style_footer(); |
| 515 | | - return; |
| 516 | | - } |
| 517 | | - } |
| 518 | | - cgi_redirect(cgi_referer("setup_ulist")); |
| 519 | | - return; |
| 520 | | - } |
| 521 | | - |
| 522 | | - /* Load the existing information about the user, if any |
| 523 | | - */ |
| 524 | | - zLogin = ""; |
| 525 | | - zInfo = ""; |
| 526 | | - zCap = ""; |
| 527 | | - zPw = ""; |
| 528 | | - for(i='a'; i<='z'; i++) oa[i] = ""; |
| 529 | | - for(i='0'; i<='9'; i++) oa[i] = ""; |
| 530 | | - for(i='A'; i<='Z'; i++) oa[i] = ""; |
| 531 | | - if( uid ){ |
| 532 | | - zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid); |
| 533 | | - zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid); |
| 534 | | - zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid); |
| 535 | | - zPw = db_text("", "SELECT pw FROM user WHERE uid=%d", uid); |
| 536 | | - for(i=0; zCap[i]; i++){ |
| 537 | | - char c = zCap[i]; |
| 538 | | - if( (c>='a' && c<='z') || (c>='0' && c<='9') || (c>='A' && c<='Z') ){ |
| 539 | | - oa[c&0x7f] = " checked=\"checked\""; |
| 540 | | - } |
| 541 | | - } |
| 542 | | - } |
| 543 | | - |
| 544 | | - /* figure out inherited permissions */ |
| 545 | | - memset((char *)inherit, 0, sizeof(inherit)); |
| 546 | | - if( fossil_strcmp(zLogin, "developer") ){ |
| 547 | | - char *z1, *z2; |
| 548 | | - z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); |
| 549 | | - while( z1 && *z1 ){ |
| 550 | | - inherit[0x7f & *(z1++)] = |
| 551 | | - "<span class=\"ueditInheritDeveloper\"><sub>[D]</sub></span>"; |
| 552 | | - } |
| 553 | | - free(z2); |
| 554 | | - } |
| 555 | | - if( fossil_strcmp(zLogin, "reader") ){ |
| 556 | | - char *z1, *z2; |
| 557 | | - z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); |
| 558 | | - while( z1 && *z1 ){ |
| 559 | | - inherit[0x7f & *(z1++)] = |
| 560 | | - "<span class=\"ueditInheritReader\"><sub>[R]</sub></span>"; |
| 561 | | - } |
| 562 | | - free(z2); |
| 563 | | - } |
| 564 | | - if( fossil_strcmp(zLogin, "anonymous") ){ |
| 565 | | - char *z1, *z2; |
| 566 | | - z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); |
| 567 | | - while( z1 && *z1 ){ |
| 568 | | - inherit[0x7f & *(z1++)] = |
| 569 | | - "<span class=\"ueditInheritAnonymous\"><sub>[A]</sub></span>"; |
| 570 | | - } |
| 571 | | - free(z2); |
| 572 | | - } |
| 573 | | - if( fossil_strcmp(zLogin, "nobody") ){ |
| 574 | | - char *z1, *z2; |
| 575 | | - z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); |
| 576 | | - while( z1 && *z1 ){ |
| 577 | | - inherit[0x7f & *(z1++)] = |
| 578 | | - "<span class=\"ueditInheritNobody\"><sub>[N]</sub></span>"; |
| 579 | | - } |
| 580 | | - free(z2); |
| 581 | | - } |
| 582 | | - |
| 583 | | - /* Begin generating the page |
| 584 | | - */ |
| 585 | | - style_submenu_element("Cancel", "%s", cgi_referer("setup_ulist")); |
| 586 | | - if( uid ){ |
| 587 | | - style_header("Edit User %h", zLogin); |
| 588 | | - style_submenu_element("Access Log", "%R/access_log?u=%t", zLogin); |
| 589 | | - }else{ |
| 590 | | - style_header("Add A New User"); |
| 591 | | - } |
| 592 | | - @ <div class="ueditCapBox"> |
| 593 | | - @ <form action="%s(g.zPath)" method="post"><div> |
| 594 | | - login_insert_csrf_secret(); |
| 595 | | - if( login_is_special(zLogin) ){ |
| 596 | | - @ <input type="hidden" name="login" value="%s(zLogin)"> |
| 597 | | - @ <input type="hidden" name="info" value=""> |
| 598 | | - @ <input type="hidden" name="pw" value="*"> |
| 599 | | - } |
| 600 | | - @ <input type="hidden" name="referer" value="%h(cgi_referer("setup_ulist"))"> |
| 601 | | - @ <table> |
| 602 | | - @ <tr> |
| 603 | | - @ <td class="usetupEditLabel">User ID:</td> |
| 604 | | - if( uid ){ |
| 605 | | - @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td> |
| 606 | | - }else{ |
| 607 | | - @ <td>(new user)<input type="hidden" name="id" value="0" /></td> |
| 608 | | - } |
| 609 | | - @ </tr> |
| 610 | | - @ <tr> |
| 611 | | - @ <td class="usetupEditLabel">Login:</td> |
| 612 | | - if( login_is_special(zLogin) ){ |
| 613 | | - @ <td><b>%h(zLogin)</b></td> |
| 614 | | - }else{ |
| 615 | | - @ <td><input type="text" name="login" value="%h(zLogin)" /></td> |
| 616 | | - @ </tr> |
| 617 | | - @ <tr> |
| 618 | | - @ <td class="usetupEditLabel">Contact Info:</td> |
| 619 | | - @ <td><textarea name="info" cols="40" rows="2">%h(zInfo)</textarea></td> |
| 620 | | - } |
| 621 | | - @ </tr> |
| 622 | | - @ <tr> |
| 623 | | - @ <td class="usetupEditLabel">Capabilities:</td> |
| 624 | | - @ <td> |
| 625 | | -#define B(x) inherit[x] |
| 626 | | - @ <table border=0><tr><td valign="top"> |
| 627 | | - if( g.perm.Setup ){ |
| 628 | | - @ <label><input type="checkbox" name="as"%s(oa['s']) /> |
| 629 | | - @ Setup%s(B('s'))</label><br /> |
| 630 | | - } |
| 631 | | - @ <label><input type="checkbox" name="aa"%s(oa['a']) /> |
| 632 | | - @ Admin%s(B('a'))</label><br /> |
| 633 | | - @ <label><input type="checkbox" name="au"%s(oa['u']) /> |
| 634 | | - @ Reader%s(B('u'))</label><br> |
| 635 | | - @ <label><input type="checkbox" name="av"%s(oa['v']) /> |
| 636 | | - @ Developer%s(B('v'))</label><br /> |
| 637 | | - @ <label><input type="checkbox" name="ad"%s(oa['d']) /> |
| 638 | | - @ Delete%s(B('d'))</label><br /> |
| 639 | | - @ <label><input type="checkbox" name="ae"%s(oa['e']) /> |
| 640 | | - @ View-PII%s(B('e'))</label><br /> |
| 641 | | - @ <label><input type="checkbox" name="ap"%s(oa['p']) /> |
| 642 | | - @ Password%s(B('p'))</label><br /> |
| 643 | | - @ <label><input type="checkbox" name="ai"%s(oa['i']) /> |
| 644 | | - @ Check-In%s(B('i'))</label><br /> |
| 645 | | - @ <label><input type="checkbox" name="ao"%s(oa['o']) /> |
| 646 | | - @ Check-Out%s(B('o'))</label><br /> |
| 647 | | - @ <label><input type="checkbox" name="ah"%s(oa['h']) /> |
| 648 | | - @ Hyperlinks%s(B('h'))</label><br /> |
| 649 | | - @ <label><input type="checkbox" name="ab"%s(oa['b']) /> |
| 650 | | - @ Attachments%s(B('b'))</label><br> |
| 651 | | - @ <label><input type="checkbox" name="ag"%s(oa['g']) /> |
| 652 | | - @ Clone%s(B('g'))</label><br /> |
| 653 | | - |
| 654 | | - @ </td><td><td width="40"></td><td valign="top"> |
| 655 | | - @ <label><input type="checkbox" name="aj"%s(oa['j']) /> |
| 656 | | - @ Read Wiki%s(B('j'))</label><br> |
| 657 | | - @ <label><input type="checkbox" name="af"%s(oa['f']) /> |
| 658 | | - @ New Wiki%s(B('f'))</label><br /> |
| 659 | | - @ <label><input type="checkbox" name="am"%s(oa['m']) /> |
| 660 | | - @ Append Wiki%s(B('m'))</label><br /> |
| 661 | | - @ <label><input type="checkbox" name="ak"%s(oa['k']) /> |
| 662 | | - @ Write Wiki%s(B('k'))</label><br /> |
| 663 | | - @ <label><input type="checkbox" name="al"%s(oa['l']) /> |
| 664 | | - @ Moderate Wiki%s(B('l'))</label><br /> |
| 665 | | - @ <label><input type="checkbox" name="ar"%s(oa['r']) /> |
| 666 | | - @ Read Ticket%s(B('r'))</label><br /> |
| 667 | | - @ <label><input type="checkbox" name="an"%s(oa['n']) /> |
| 668 | | - @ New Tickets%s(B('n'))</label><br /> |
| 669 | | - @ <label><input type="checkbox" name="ac"%s(oa['c']) /> |
| 670 | | - @ Append To Ticket%s(B('c'))</label><br> |
| 671 | | - @ <label><input type="checkbox" name="aw"%s(oa['w']) /> |
| 672 | | - @ Write Tickets%s(B('w'))</label><br /> |
| 673 | | - @ <label><input type="checkbox" name="aq"%s(oa['q']) /> |
| 674 | | - @ Moderate Tickets%s(B('q'))</label><br> |
| 675 | | - @ <label><input type="checkbox" name="at"%s(oa['t']) /> |
| 676 | | - @ Ticket Report%s(B('t'))</label><br /> |
| 677 | | - @ <label><input type="checkbox" name="ax"%s(oa['x']) /> |
| 678 | | - @ Private%s(B('x'))</label> |
| 679 | | - |
| 680 | | - @ </td><td><td width="40"></td><td valign="top"> |
| 681 | | - @ <label><input type="checkbox" name="ay"%s(oa['y']) /> |
| 682 | | - @ Write Unversioned%s(B('y'))</label><br /> |
| 683 | | - @ <label><input type="checkbox" name="az"%s(oa['z']) /> |
| 684 | | - @ Download Zip%s(B('z'))</label><br /> |
| 685 | | - @ <label><input type="checkbox" name="a2"%s(oa['2']) /> |
| 686 | | - @ Read Forum%s(B('2'))</label><br /> |
| 687 | | - @ <label><input type="checkbox" name="a3"%s(oa['3']) /> |
| 688 | | - @ Write Forum%s(B('3'))</label><br /> |
| 689 | | - @ <label><input type="checkbox" name="a4"%s(oa['4']) /> |
| 690 | | - @ WriteTrusted Forum%s(B('4'))</label><br> |
| 691 | | - @ <label><input type="checkbox" name="a5"%s(oa['5']) /> |
| 692 | | - @ Moderate Forum%s(B('5'))</label><br> |
| 693 | | - @ <label><input type="checkbox" name="a6"%s(oa['6']) /> |
| 694 | | - @ Supervise Forum%s(B('6'))</label><br> |
| 695 | | - @ <label><input type="checkbox" name="a7"%s(oa['7']) /> |
| 696 | | - @ Email Alerts%s(B('7'))</label><br> |
| 697 | | - @ <label><input type="checkbox" name="aA"%s(oa['A']) /> |
| 698 | | - @ Send Announcements%s(B('A'))</label><br> |
| 699 | | - @ <label><input type="checkbox" name="aD"%s(oa['D']) /> |
| 700 | | - @ Enable Debug%s(B('D'))</label> |
| 701 | | - @ </td></tr> |
| 702 | | - @ </table> |
| 703 | | - @ </td> |
| 704 | | - @ </tr> |
| 705 | | - @ <tr> |
| 706 | | - @ <td class="usetupEditLabel">Selected Cap.:</td> |
| 707 | | - @ <td> |
| 708 | | - @ <span id="usetupEditCapability">(missing JS?)</span> |
| 709 | | - @ <a href="%R/setup_ucap_list">(key)</a> |
| 710 | | - @ </td> |
| 711 | | - @ </tr> |
| 712 | | - if( !login_is_special(zLogin) ){ |
| 713 | | - @ <tr> |
| 714 | | - @ <td align="right">Password:</td> |
| 715 | | - if( zPw[0] ){ |
| 716 | | - /* Obscure the password for all users */ |
| 717 | | - @ <td><input type="password" name="pw" value="**********" /></td> |
| 718 | | - }else{ |
| 719 | | - /* Show an empty password as an empty input field */ |
| 720 | | - @ <td><input type="password" name="pw" value="" /></td> |
| 721 | | - } |
| 722 | | - @ </tr> |
| 723 | | - } |
| 724 | | - zGroup = login_group_name(); |
| 725 | | - if( zGroup ){ |
| 726 | | - @ <tr> |
| 727 | | - @ <td valign="top" align="right">Scope:</td> |
| 728 | | - @ <td valign="top"> |
| 729 | | - @ <input type="radio" name="all" checked value="0"> |
| 730 | | - @ Apply changes to this repository only.<br /> |
| 731 | | - @ <input type="radio" name="all" value="1"> |
| 732 | | - @ Apply changes to all repositories in the "<b>%h(zGroup)</b>" |
| 733 | | - @ login group.</td></tr> |
| 734 | | - } |
| 735 | | - if( !higherUser ){ |
| 736 | | - @ <tr> |
| 737 | | - @ <td> </td> |
| 738 | | - @ <td><input type="submit" name="submit" value="Apply Changes" /></td> |
| 739 | | - @ </tr> |
| 740 | | - } |
| 741 | | - @ </table> |
| 742 | | - @ </div></form> |
| 743 | | - @ </div> |
| 744 | | - style_load_one_js_file("useredit.js"); |
| 745 | | - @ <h2>Privileges And Capabilities:</h2> |
| 746 | | - @ <ul> |
| 747 | | - if( higherUser ){ |
| 748 | | - @ <li><p class="missingPriv"> |
| 749 | | - @ User %h(zLogin) has Setup privileges and you only have Admin privileges |
| 750 | | - @ so you are not permitted to make changes to %h(zLogin). |
| 751 | | - @ </p></li> |
| 752 | | - @ |
| 753 | | - } |
| 754 | | - @ <li><p> |
| 755 | | - @ The <span class="capability">Setup</span> user can make arbitrary |
| 756 | | - @ configuration changes. An <span class="usertype">Admin</span> user |
| 757 | | - @ can add other users and change user privileges |
| 758 | | - @ and reset user passwords. Both automatically get all other privileges |
| 759 | | - @ listed below. Use these two settings with discretion. |
| 760 | | - @ </p></li> |
| 761 | | - @ |
| 762 | | - @ <li><p> |
| 763 | | - @ The "<span class="ueditInheritNobody"><sub>N</sub></span>" subscript suffix |
| 764 | | - @ indicates the privileges of <span class="usertype">nobody</span> that |
| 765 | | - @ are available to all users regardless of whether or not they are logged in. |
| 766 | | - @ </p></li> |
| 767 | | - @ |
| 768 | | - @ <li><p> |
| 769 | | - @ The "<span class="ueditInheritAnonymous"><sub>A</sub></span>" |
| 770 | | - @ subscript suffix |
| 771 | | - @ indicates the privileges of <span class="usertype">anonymous</span> that |
| 772 | | - @ are inherited by all logged-in users. |
| 773 | | - @ </p></li> |
| 774 | | - @ |
| 775 | | - @ <li><p> |
| 776 | | - @ The "<span class="ueditInheritDeveloper"><sub>D</sub></span>" |
| 777 | | - @ subscript suffix indicates the privileges of |
| 778 | | - @ <span class="usertype">developer</span> that |
| 779 | | - @ are inherited by all users with the |
| 780 | | - @ <span class="capability">Developer</span> privilege. |
| 781 | | - @ </p></li> |
| 782 | | - @ |
| 783 | | - @ <li><p> |
| 784 | | - @ The "<span class="ueditInheritReader"><sub>R</sub></span>" subscript suffix |
| 785 | | - @ indicates the privileges of <span class="usertype">reader</span> that |
| 786 | | - @ are inherited by all users with the <span class="capability">Reader</span> |
| 787 | | - @ privilege. |
| 788 | | - @ </p></li> |
| 789 | | - @ |
| 790 | | - @ <li><p> |
| 791 | | - @ The <span class="capability">Delete</span> privilege give the user the |
| 792 | | - @ ability to erase wiki, tickets, and attachments that have been added |
| 793 | | - @ by anonymous users. This capability is intended for deletion of spam. |
| 794 | | - @ The delete capability is only in effect for 24 hours after the item |
| 795 | | - @ is first posted. The <span class="usertype">Setup</span> user can |
| 796 | | - @ delete anything at any time. |
| 797 | | - @ </p></li> |
| 798 | | - @ |
| 799 | | - @ <li><p> |
| 800 | | - @ The <span class="capability">Hyperlinks</span> privilege allows a user |
| 801 | | - @ to see most hyperlinks. This is recommended ON for most logged-in users |
| 802 | | - @ but OFF for user "nobody" to avoid problems with spiders trying to walk |
| 803 | | - @ every diff and annotation of every historical check-in and file. |
| 804 | | - @ </p></li> |
| 805 | | - @ |
| 806 | | - @ <li><p> |
| 807 | | - @ The <span class="capability">Zip</span> privilege allows a user to |
| 808 | | - @ see the "download as ZIP" |
| 809 | | - @ hyperlink and permits access to the <tt>/zip</tt> page. This allows |
| 810 | | - @ users to download ZIP archives without granting other rights like |
| 811 | | - @ <span class="capability">Read</span> or |
| 812 | | - @ <span class="capability">Hyperlink</span>. The "z" privilege is recommended |
| 813 | | - @ for user <span class="usertype">nobody</span> so that automatic package |
| 814 | | - @ downloaders can obtain the sources without going through the login |
| 815 | | - @ procedure. |
| 816 | | - @ </p></li> |
| 817 | | - @ |
| 818 | | - @ <li><p> |
| 819 | | - @ The <span class="capability">Check-in</span> privilege allows remote |
| 820 | | - @ users to "push". The <span class="capability">Check-out</span> privilege |
| 821 | | - @ allows remote users to "pull". The <span class="capability">Clone</span> |
| 822 | | - @ privilege allows remote users to "clone". |
| 823 | | - @ </p></li> |
| 824 | | - @ |
| 825 | | - @ <li><p> |
| 826 | | - @ The <span class="capability">Read Wiki</span>, |
| 827 | | - @ <span class="capability">New Wiki</span>, |
| 828 | | - @ <span class="capability">Append Wiki</span>, and |
| 829 | | - @ <b>Write Wiki</b> privileges control access to wiki pages. The |
| 830 | | - @ <span class="capability">Read Ticket</span>, |
| 831 | | - @ <span class="capability">New Ticket</span>, |
| 832 | | - @ <span class="capability">Append Ticket</span>, and |
| 833 | | - @ <span class="capability">Write Ticket</span> privileges control access |
| 834 | | - @ to trouble tickets. |
| 835 | | - @ The <span class="capability">Ticket Report</span> privilege allows |
| 836 | | - @ the user to create or edit ticket report formats. |
| 837 | | - @ </p></li> |
| 838 | | - @ |
| 839 | | - @ <li><p> |
| 840 | | - @ Users with the <span class="capability">Password</span> privilege |
| 841 | | - @ are allowed to change their own password. Recommended ON for most |
| 842 | | - @ users but OFF for special users <span class="usertype">developer</span>, |
| 843 | | - @ <span class="usertype">anonymous</span>, |
| 844 | | - @ and <span class="usertype">nobody</span>. |
| 845 | | - @ </p></li> |
| 846 | | - @ |
| 847 | | - @ <li><p> |
| 848 | | - @ The <span class="capability">View-PII</span> privilege allows the display |
| 849 | | - @ of personally-identifiable information information such as the |
| 850 | | - @ email address of users and contact |
| 851 | | - @ information on tickets. Recommended OFF for |
| 852 | | - @ <span class="usertype">anonymous</span> and for |
| 853 | | - @ <span class="usertype">nobody</span> but ON for |
| 854 | | - @ <span class="usertype">developer</span>. |
| 855 | | - @ </p></li> |
| 856 | | - @ |
| 857 | | - @ <li><p> |
| 858 | | - @ The <span class="capability">Attachment</span> privilege is needed in |
| 859 | | - @ order to add attachments to tickets or wiki. Write privilege on the |
| 860 | | - @ ticket or wiki is also required. |
| 861 | | - @ </p></li> |
| 862 | | - @ |
| 863 | | - @ <li><p> |
| 864 | | - @ Login is prohibited if the password is an empty string. |
| 865 | | - @ </p></li> |
| 866 | | - @ </ul> |
| 867 | | - @ |
| 868 | | - @ <h2>Special Logins</h2> |
| 869 | | - @ |
| 870 | | - @ <ul> |
| 871 | | - @ <li><p> |
| 872 | | - @ No login is required for user <span class="usertype">nobody</span>. The |
| 873 | | - @ capabilities of the <span class="usertype">nobody</span> user are |
| 874 | | - @ inherited by all users, regardless of whether or not they are logged in. |
| 875 | | - @ To disable universal access to the repository, make sure that the |
| 876 | | - @ <span class="usertype">nobody</span> user has no capabilities |
| 877 | | - @ enabled. The password for <span class="usertype">nobody</span> is ignored. |
| 878 | | - @ </p></li> |
| 879 | | - @ |
| 880 | | - @ <li><p> |
| 881 | | - @ Login is required for user <span class="usertype">anonymous</span> but the |
| 882 | | - @ password is displayed on the login screen beside the password entry box |
| 883 | | - @ so anybody who can read should be able to login as anonymous. |
| 884 | | - @ On the other hand, spiders and web-crawlers will typically not |
| 885 | | - @ be able to login. Set the capabilities of the |
| 886 | | - @ <span class="usertype">anonymous</span> |
| 887 | | - @ user to things that you want any human to be able to do, but not any |
| 888 | | - @ spider. Every other logged-in user inherits the privileges of |
| 889 | | - @ <span class="usertype">anonymous</span>. |
| 890 | | - @ </p></li> |
| 891 | | - @ |
| 892 | | - @ <li><p> |
| 893 | | - @ The <span class="usertype">developer</span> user is intended as a template |
| 894 | | - @ for trusted users with check-in privileges. When adding new trusted users, |
| 895 | | - @ simply select the <span class="capability">developer</span> privilege to |
| 896 | | - @ cause the new user to inherit all privileges of the |
| 897 | | - @ <span class="usertype">developer</span> |
| 898 | | - @ user. Similarly, the <span class="usertype">reader</span> user is a |
| 899 | | - @ template for users who are allowed more access than |
| 900 | | - @ <span class="usertype">anonymous</span>, |
| 901 | | - @ but less than a <span class="usertype">developer</span>. |
| 902 | | - @ </p></li> |
| 903 | | - @ </ul> |
| 904 | | - style_footer(); |
| 905 | | -} |
| 906 | | - |
| 907 | 162 | |
| 908 | 163 | /* |
| 909 | 164 | ** Generate a checkbox for an attribute. |
| 910 | 165 | */ |
| 911 | 166 | void onoff_attribute( |
| 912 | 167 | |
| 913 | 168 | ADDED src/setupuser.c |