Tokens page lists every scope the hub checks, each with what it grants b45384c909c1
- Author
- Andy McCall @andymccall <[email protected]>
- When
- · 2026-09-27 22:52 UTC
- Signature
- ✔ signed by Andy McCall
- Hash
b45384c909c19ecb69915e69e0395441aaf509e1156dd94d0f38794449ec26b1- Depends on
- 19bb31ff1f5c 3f4b0ea6eabf d23464c0ac60
- Depended on by
- 00ef7b83b340 101740454617
- In bookmarks
- api-unknown-fields cancel-landed-runs clear-waiting close-proposal-140 diffusion-pin-bookmark draft-ready image-check job-waits main oh-comment-body-file proposal-list-fast run-one-job wiki-says-so
- In tags
- v0.1.0 v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.4.1 v0.4.2 v0.5.0 v0.5.1 v0.5.2 v0.6.0 v0.6.1 v0.7.0 v0.8.0 v0.9.0 v0.9.1 v0.9.11 v0.9.15 v0.9.16 v0.9.19 v0.9.2 v0.9.20 v0.9.21 v0.9.22 v0.9.23 v0.9.24 v0.9.3 v0.9.4 v0.9.5 v0.9.6 v0.9.7 v0.9.8 v0.9.9
- Edits
- 8 atoms, 0 tree operations, 3 files
Browse the tree at this change
modified crates/hub/src/web/settings.rs +12 −5
| … | 349 unchanged lines |
||
| 350 | 350 | #[template(path = "settings_tokens.html")] |
|
| 351 | 351 | pub struct TokensPage { |
|
| 352 | 352 | shell: Shell, |
|
| 353 | + | scopes: &'static [(&'static str, &'static str)], |
|
| 353 | 354 | me: accounts::Account, |
|
| 354 | 355 | tokens: Vec<accounts::Token>, |
|
| 355 | 356 | /// A freshly created token, shown once. |
|
| … | 11 unchanged lines |
||
| 367 | 368 | error: Option<String>, |
|
| 368 | 369 | ) -> Result<Page<TokensPage>, Error> { |
|
| 369 | 370 | let tokens = accounts::tokens_of(&app.db, me.id).await.map_err(|e| Error::from_db(shell.clone(), e))?; |
|
| 370 | - | Ok(Page(TokensPage { shell, me, tokens, fresh, notice, error })) |
|
| 371 | + | Ok(Page(TokensPage { shell, scopes: SCOPES, me, tokens, fresh, notice, error })) |
|
| 371 | 372 | } |
|
| 372 | 373 | ||
| 373 | 374 | pub async fn tokens(State(app): State<Shared>, viewer: Viewer) -> Result<Page<TokensPage>, Error> { |
|
| … | 15 unchanged lines |
||
| 389 | 390 | expires_days: String, |
|
| 390 | 391 | } |
|
| 391 | 392 | ||
| 393 | + | /// Every scope the hub checks, with what it grants. The tokens page lists |
|
| 394 | + | /// exactly these, so a scope cannot exist without a checkbox. |
|
| 392 | 395 | pub const SCOPES: &[(&str, &str)] = &[ |
|
| 393 | - | ("repo:read", "read repositories you can see (clone, fetch, pull)"), |
|
| 394 | - | ("repo:write", "push to repositories you can write to"), |
|
| 395 | - | ("repo:admin", "change repository settings through the API"), |
|
| 396 | - | ("user:read", "read your profile through the API"), |
|
| 396 | + | ("repo:read", "read repositories you can see: clone, fetch, pull, and the read API"), |
|
| 397 | + | ("repo:write", "push to repositories you can write to; also covers proposals, issues and checks"), |
|
| 398 | + | ("repo:admin", "create repositories and change settings through the API"), |
|
| 399 | + | ("proposals:write", "open, comment on and review proposals, without push access"), |
|
| 400 | + | ("issues:write", "open, comment on and close issues, without push access"), |
|
| 401 | + | ("checks:write", "report checks on states, for CI systems, without push access"), |
|
| 402 | + | ("hooks:admin", "manage webhooks through the API"), |
|
| 403 | + | ("user:read", "read your own profile through the API"), |
|
| 397 | 404 | ]; |
|
| 398 | 405 | ||
| 399 | 406 | pub async fn tokens_create( |
|
| … | 38 unchanged lines |
modified templates/settings_tokens.html +2 −5
| … | 26 unchanged lines |
||
| 27 | 27 | <h2>New token</h2> |
|
| 28 | 28 | <label for="name">Name</label><input type="text" id="name" name="name" required placeholder="laptop, CI, …"> |
|
| 29 | 29 | <label>Scopes</label> |
|
| 30 | - | <div class="choice"> |
|
| 31 | - | <label><input type="checkbox" name="scopes" value="repo:read" checked> repo:read</label> |
|
| 32 | - | <label><input type="checkbox" name="scopes" value="repo:write" checked> repo:write</label> |
|
| 33 | - | <label><input type="checkbox" name="scopes" value="repo:admin"> repo:admin</label> |
|
| 34 | - | <label><input type="checkbox" name="scopes" value="user:read"> user:read</label> |
|
| 30 | + | <div class="scopes"> |
|
| 31 | + | {% for (name, what) in scopes %}<label><input type="checkbox" name="scopes" value="{{ name }}"{% if *name == "repo:read" || *name == "repo:write" %} checked{% endif %}> <code>{{ name }}</code> <span class="small mute">{{ what }}</span></label>{% endfor %} |
|
| 35 | 32 | </div> |
|
| 36 | 33 | <label for="repos">Only these repositories (comma-separated owner/name; empty for all)</label><input type="text" id="repos" name="repos"> |
|
| 37 | 34 | <label for="expires_days">Expires after (days; empty for never)</label><input type="number" id="expires_days" name="expires_days" min="1"> |
|
| … | 3 unchanged lines |
modified templates/style.css +2 −0
| … | 300 unchanged lines |
||
| 301 | 301 | .inline-find { flex: 0 1 220px; } |
|
| 302 | 302 | .hits .hit { margin: 0; padding: 4px 8px; border-bottom: 1px solid var(--line); background: var(--panel); font-size: 13px; overflow-x: auto; white-space: nowrap; } |
|
| 303 | 303 | .hits .hit code { background: none; } |
|
| 304 | + | ||
| 305 | + | .scopes label { display: block; text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--ink); margin: 4px 0; } |