Fossil

Check-in [e5240c9749]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added 'L' pseudo-capability character to indicate is-logged-in, for use with th1 capexpr. Removed hard-coded addition of login/logout menu entries in skin headers, delegating them to the mainmenu setting, and added Login/Logout entries to the default mainmenu value.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e5240c9749e2b277049244150e5325d01811b6cb9ee8ccb69eb1bdcad167e7b2
User & Date: stephan 2021-02-10 14:25:30.009
Context
2021-02-10
21:21
Corrected the order of the N- and P-cards on edits made to technotes. See [forum:/forumpost/74fd8dac3a|/forumpost/74fd8dac3a] for details. ... (check-in: 1cd6c545ca user: stephan tags: trunk)
14:25
Added 'L' pseudo-capability character to indicate is-logged-in, for use with th1 capexpr. Removed hard-coded addition of login/logout menu entries in skin headers, delegating them to the mainmenu setting, and added Login/Logout entries to the default mainmenu value. ... (check-in: e5240c9749 user: stephan tags: trunk)
14:00
Show the login name on /sitemap for logged in users. ... (check-in: 480aa68d65 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to skins/black_and_white/header.txt.
15
16
17
18
19
20
21
22
23
24
25
26
27
<div class="mainmenu">
<th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a><br/>\n"
}
if {[info exists login]} {
  html "<a href='$home/login'>Logout</a>\n"
} else {
  html "<a href='$home/login'>Login</a>\n"
}
</th1></div>







<
<
<
<
<

15
16
17
18
19
20
21





22
<div class="mainmenu">
<th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a><br/>\n"
}





</th1></div>
Changes to skins/enhanced1/header.txt.
93
94
95
96
97
98
99
100
101
102
103
104
105
</script>
<div class="mainmenu"><th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}
if {[info exists login]} {
  html "<a href='$home/logout'>Logout</a>\n"
} else {
  html "<a href='$home/login'>Login</a>\n"
}
</th1></div>







<
<
<
<
<

93
94
95
96
97
98
99





100
</script>
<div class="mainmenu"><th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}





</th1></div>
Changes to skins/khaki/header.txt.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
html "<a id='hbbtn' href='$home/sitemap' aria-label='Site Map'>&#9776;</a>"
builtin_request_js hbmenu.js
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}
if {[info exists login]} {
  html "<a href='$home/logout'>Logout</a>\n"
} else {
  html "<a href='$home/login'>Login</a>\n"
}
</th1></div>
<div id='hbdrop'></div>







<
<
<
<
<


14
15
16
17
18
19
20





21
22
html "<a id='hbbtn' href='$home/sitemap' aria-label='Site Map'>&#9776;</a>"
builtin_request_js hbmenu.js
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}





</th1></div>
<div id='hbdrop'></div>
Changes to skins/original/header.txt.
13
14
15
16
17
18
19
20
21
22
23
24
25
</div>
<div class="mainmenu"><th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}
if {[info exists login]} {
  html "<a href='$home/logout'>Logout</a>\n"
} else {
  html "<a href='$home/login'>Login</a>\n"
}
</th1></div>







<
<
<
<
<

13
14
15
16
17
18
19





20
</div>
<div class="mainmenu"><th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}





</th1></div>
Changes to skins/plain_gray/header.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="header">
  <div class="title">$<project_name>: $<title></div>
</div>
<div class="mainmenu">
<th1>
html "<a id='hbbtn' href='$home/sitemap' aria-label='Site Map'>&#9776;</a>"
builtin_request_js hbmenu.js
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}
if {[info exists login]} {
  html "<a href='$home/logout'>Logout</a>\n"
} else {
  html "<a href='$home/login'>Login</a>\n"
}
</th1></div>
<div id='hbdrop' class='hbdrop'></div>












<
<
<
<
<


1
2
3
4
5
6
7
8
9
10
11
12





13
14
<div class="header">
  <div class="title">$<project_name>: $<title></div>
</div>
<div class="mainmenu">
<th1>
html "<a id='hbbtn' href='$home/sitemap' aria-label='Site Map'>&#9776;</a>"
builtin_request_js hbmenu.js
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}





</th1></div>
<div id='hbdrop' class='hbdrop'></div>
Changes to skins/rounded1/header.txt.
14
15
16
17
18
19
20
21
22
23
24
25
26
</div>
<div class="mainmenu"><th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}
if {[info exists login]} {
  html "<a href='$home/logout'>Logout</a>\n"
} else {
  html "<a href='$home/login'>Login</a>\n"
}
</th1></div>







<
<
<
<
<

14
15
16
17
18
19
20





21
</div>
<div class="mainmenu"><th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {set url $home$url}
  html "<a href='$url'>$name</a>\n"
}





</th1></div>
Changes to skins/xekri/header.txt.
90
91
92
93
94
95
96




97
98
99
100
101
102
103
104
  }
}
updateClock();
</script>
<div class="mainmenu"><th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue




  html "<a href='$home$url'>$name</a>\n"
}
if {[info exists login]} {
  html "<a href='$home/logout'>Logout</a>\n"
} else {
  html "<a href='$home/login'>Login</a>\n"
}
</th1></div>







>
>
>
>
|
|
<
<
<
|


90
91
92
93
94
95
96
97
98
99
100
101
102



103
104
105
  }
}
updateClock();
</script>
<div class="mainmenu"><th1>
foreach {name url expr class} $mainmenu {
  if {![capexpr $expr]} continue
  if {[string match /* $url]} {
    if {[string match /$current_page* $url]} {
      set class "active $class"
    }
    set url $home$url
  }



  html "<a href='$url' class='$class'>$name</a>\n"
}
</th1></div>
Changes to src/login.c.
1328
1329
1330
1331
1332
1333
1334



1335
1336
1337
1338
1339
1340
1341
  login_anon_once = 1;
}

/*
** If the current login lacks any of the capabilities listed in
** the input, then return 0.  If all capabilities are present, then
** return 1.



*/
int login_has_capability(const char *zCap, int nCap, u32 flgs){
  int i;
  int rc = 1;
  FossilUserPerms *p = (flgs & LOGIN_ANON) ? &g.anon : &g.perm;
  if( nCap<0 ) nCap = strlen(zCap);
  for(i=0; i<nCap && rc && zCap[i]; i++){







>
>
>







1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  login_anon_once = 1;
}

/*
** If the current login lacks any of the capabilities listed in
** the input, then return 0.  If all capabilities are present, then
** return 1.
**
** As a special case, the 'L' pseudo-capability ID means "is logged
** in" and will return true for any non-guest user.
*/
int login_has_capability(const char *zCap, int nCap, u32 flgs){
  int i;
  int rc = 1;
  FossilUserPerms *p = (flgs & LOGIN_ANON) ? &g.anon : &g.perm;
  if( nCap<0 ) nCap = strlen(zCap);
  for(i=0; i<nCap && rc && zCap[i]; i++){
1371
1372
1373
1374
1375
1376
1377




1378
1379
1380
1381
1382
1383
1384
      case '4':  rc = p->WrTForum;  break;
      case '5':  rc = p->ModForum;  break;
      case '6':  rc = p->AdminForum;break;
      case '7':  rc = p->EmailAlert;break;
      case 'A':  rc = p->Announce;  break;
      case 'C':  rc = p->Chat;      break;
      case 'D':  rc = p->Debug;     break;




      default:   rc = 0;            break;
    }
  }
  return rc;
}

/*







>
>
>
>







1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
      case '4':  rc = p->WrTForum;  break;
      case '5':  rc = p->ModForum;  break;
      case '6':  rc = p->AdminForum;break;
      case '7':  rc = p->EmailAlert;break;
      case 'A':  rc = p->Announce;  break;
      case 'C':  rc = p->Chat;      break;
      case 'D':  rc = p->Debug;     break;
      case 'L':  rc = g.zLogin && *g.zLogin; break;
      /* Mainenance reminder: '@' should not be used because
         it would semantically collide with the @ in the
         capexpr TH1 command. */
      default:   rc = 0;            break;
    }
  }
  return rc;
}

/*
Changes to src/style.c.
608
609
610
611
612
613
614


615
616
617
618
619
620
621
@ Branches  /brlist      o              wideonly
@ Tags      /taglist     o              wideonly
@ Forum     /forum       {@2 3 4 5 6}   wideonly
@ Chat      /chat        C              wideonly
@ Tickets   /ticket      r              wideonly
@ Wiki      /wiki        j              wideonly
@ Setup     /setup       s              {}


;

/*
** Return the default menu
*/
const char *style_default_mainmenu(void){
  return zDfltMainMenu;







>
>







608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
@ Branches  /brlist      o              wideonly
@ Tags      /taglist     o              wideonly
@ Forum     /forum       {@2 3 4 5 6}   wideonly
@ Chat      /chat        C              wideonly
@ Tickets   /ticket      r              wideonly
@ Wiki      /wiki        j              wideonly
@ Setup     /setup       s              {}
@ Logout    /logout      L              {}
@ Login     /login       !L              {}
;

/*
** Return the default menu
*/
const char *style_default_mainmenu(void){
  return zDfltMainMenu;
Changes to www/caps/ref.html.
420
421
422
423
424
425
426












427
428
429
430
431
432
  <tr id="D">
    <th>D</th>
    <th>Debug</th>
    <td>
      Enable debugging features. Mnemonic: <b>d</b>ebug.
    </td>
  </tr> 












</table>

<hr/>

<p id="backlink"><a href="./"><em>Back to Administering User
Capabilities</em></a></p>







>
>
>
>
>
>
>
>
>
>
>
>






420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
  <tr id="D">
    <th>D</th>
    <th>Debug</th>
    <td>
      Enable debugging features. Mnemonic: <b>d</b>ebug.
    </td>
  </tr> 

  <tr id="L">
    <th>L</th>
    <th>Is-logged-in</th>
    <td>
      This is not a real capability, but is used in certain capability
      checks, e.g. via <a href="../th1.md#capexpr">capexpr</a>. It
      resolves to true if the current user is logged in.
      Mnemonic: <b>L</b>ogged in.
    </td>
  </tr> 

</table>

<hr/>

<p id="backlink"><a href="./"><em>Back to Administering User
Capabilities</em></a></p>
Changes to www/th1.md.
283
284
285
286
287
288
289


290












291
292
293
294
295
296
297
Examples:

```
  capexpr {j o r}               True if any one of j, o, or r are available
  capexpr {oh}                  True if both o and h are available
  capexpr {@2 @3 4 5 6}         2 or 3 available for anonymous or one of
                                  4, 5 or 6 is available for the user


```













<a id="captureTh1"></a>TH1 captureTh1 Command
-----------------------------------------------------

  *  captureTh1 STRING

Executes its single argument as TH1 code and captures any







>
>

>
>
>
>
>
>
>
>
>
>
>
>







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
Examples:

```
  capexpr {j o r}               True if any one of j, o, or r are available
  capexpr {oh}                  True if both o and h are available
  capexpr {@2 @3 4 5 6}         2 or 3 available for anonymous or one of
                                  4, 5 or 6 is available for the user
  capexpr L                     True if the user is logged in
  capexpr !L                    True if the user is not logged in
```

The `L` pseudo-capability is intended only to be used on its own or with
the `!` prefix for implementing login/logout menus via the `mainmenu`
site configuration option:

```
Login     /login        !L  {}
Logout    /logout        L  {}
```

i.e. if the user is logged in, show the "Logout" link, else show the
"Login" link.

<a id="captureTh1"></a>TH1 captureTh1 Command
-----------------------------------------------------

  *  captureTh1 STRING

Executes its single argument as TH1 code and captures any