Use Gitea scope permission mask
This commit is contained in:
@@ -168,7 +168,8 @@ logiczny remote tokena.
|
||||
`token_ref` laczy nazwe tokena z markerem po prawej stronie: `*` oznacza, ze
|
||||
remote i `tokens.json` sa zgodne oraz uprawnienia zostaly wczytane, `R` oznacza
|
||||
token tylko w remote, a `S` token tylko w `tokens.json`. Kolumny `scope`, `org`
|
||||
i `repo` sa maskami uprawnien; bez `*` maja wartosc `?????` albo `????`.
|
||||
i `repo` sa maskami uprawnien; bez `*` maja wartosc `?????????`, `?????`
|
||||
albo `????`.
|
||||
Zapis z remote do `tokens.json` oraz odczyt `valid` i uprawnien z API robi
|
||||
dopiero `tokens update --from remotes`.
|
||||
Kolumna `valid` oznacza, czy token zostal zaakceptowany przez API teraz.
|
||||
|
||||
+24
-4
@@ -36,7 +36,7 @@ Aktualny format to `version: 3`. Glownym rekordem jest token. `server`, `user`,
|
||||
},
|
||||
"user": "u1",
|
||||
"valid": "forever",
|
||||
"scope": "+---+",
|
||||
"scope": "-----w---",
|
||||
"remotes": [
|
||||
{
|
||||
"name": "r1",
|
||||
@@ -69,7 +69,7 @@ Pola wzbogacane przez API przy `tokens update --from remotes`:
|
||||
|
||||
- `user` - login wlasciciela tokena odczytany z API
|
||||
- `valid` - `forever`, data `expires_at`, `invalid`, `?` albo `!`
|
||||
- `scope` - maska scope tokena
|
||||
- `scope` - maska scope tokena w kolejnosci `aAimnopru`
|
||||
- `remotes[].org_perm` - maska praw w organizacji
|
||||
- `remotes[].repo_perm` - maska praw w repo
|
||||
|
||||
@@ -95,11 +95,31 @@ wartosc `?`, bo launcher nie pokazuje metadanych API dla niesparowanych wpisow.
|
||||
|
||||
Naglowki masek:
|
||||
|
||||
- `scope`: `awrop-`
|
||||
- `scope`: `aAimnopru`
|
||||
- `org`: `oawrc-`
|
||||
- `repo`: `oawr--`
|
||||
|
||||
Znaki w wartosciach:
|
||||
Kategorie `scope`:
|
||||
|
||||
- `a` - activitypub
|
||||
- `A` - admin
|
||||
- `i` - issue
|
||||
- `m` - misc
|
||||
- `n` - notification
|
||||
- `o` - organization
|
||||
- `p` - package
|
||||
- `r` - repository
|
||||
- `u` - user
|
||||
|
||||
Znaki w `scope`:
|
||||
|
||||
- `w` - read/write
|
||||
- `r` - read
|
||||
- `-` - no access
|
||||
- `?` - nie wczytano
|
||||
- `!` - blad wczytania
|
||||
|
||||
Znaki w `org` i `repo`:
|
||||
|
||||
- `+` - flaga wlaczona
|
||||
- `-` - flaga wylaczona
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
},
|
||||
"scope": {
|
||||
"type": "string",
|
||||
"pattern": "^[+?!-]{5}$"
|
||||
"pattern": "^[rw?!-]{9}$"
|
||||
},
|
||||
"expires_at": {
|
||||
"type": "string"
|
||||
|
||||
@@ -388,6 +388,10 @@ def normalize_remote_record(raw_remote: dict) -> dict | None:
|
||||
return remote_record
|
||||
|
||||
|
||||
def valid_mask(raw_value: str, allowed: str, width: int) -> bool:
|
||||
return len(raw_value) == width and all(char in allowed for char in raw_value)
|
||||
|
||||
|
||||
def normalize_v3_token(config: WorkspaceConfig, raw_token: dict) -> dict | None:
|
||||
if not isinstance(raw_token, dict):
|
||||
return None
|
||||
@@ -409,10 +413,13 @@ def normalize_v3_token(config: WorkspaceConfig, raw_token: dict) -> dict | None:
|
||||
"server": server_record,
|
||||
"remotes": [],
|
||||
}
|
||||
for field_name in ["user", "valid", "scope", "expires_at"]:
|
||||
for field_name in ["user", "valid", "expires_at"]:
|
||||
field_value = raw_token.get(field_name)
|
||||
if isinstance(field_value, str) and field_value:
|
||||
token_record[field_name] = field_value
|
||||
scope_value = raw_token.get("scope")
|
||||
if isinstance(scope_value, str) and valid_mask(scope_value, "rw?!-", 9):
|
||||
token_record["scope"] = scope_value
|
||||
|
||||
raw_remotes = raw_token.get("remotes", [])
|
||||
if isinstance(raw_remotes, dict):
|
||||
@@ -1070,13 +1077,13 @@ TOKEN_COLUMNS = [
|
||||
("token_ref", "token_ref", TOKEN_REF_WIDTH),
|
||||
("token", "token", 12),
|
||||
("valid", "valid", 19),
|
||||
("scope_mask", "scope", 6),
|
||||
("scope_mask", "scope", 9),
|
||||
("org_mask", "org", 6),
|
||||
("repo_mask", "repo", 6),
|
||||
]
|
||||
|
||||
TOKEN_SEPARATOR_OVERRIDES = {
|
||||
"scope_mask": "awrop-",
|
||||
"scope_mask": "aAimnopru",
|
||||
"org_mask": "oawrc-",
|
||||
"repo_mask": "oawr--",
|
||||
}
|
||||
@@ -1250,15 +1257,27 @@ def api_get_json(api_url: str, token_value: str, user_name: str = "", basic: boo
|
||||
|
||||
def scope_mask(scopes: list[str]) -> str:
|
||||
scope_set = {scope.lower() for scope in scopes}
|
||||
return "".join(
|
||||
[
|
||||
"+" if "all" in scope_set else "-",
|
||||
"+" if "write:repository" in scope_set else "-",
|
||||
"+" if "read:repository" in scope_set else "-",
|
||||
"+" if {"read:organization", "write:organization"} & scope_set else "-",
|
||||
"+" if "public-only" in scope_set else "-",
|
||||
]
|
||||
)
|
||||
categories = [
|
||||
"activitypub",
|
||||
"admin",
|
||||
"issue",
|
||||
"misc",
|
||||
"notification",
|
||||
"organization",
|
||||
"package",
|
||||
"repository",
|
||||
"user",
|
||||
]
|
||||
|
||||
values = []
|
||||
for category in categories:
|
||||
if f"write:{category}" in scope_set:
|
||||
values.append("w")
|
||||
elif f"read:{category}" in scope_set:
|
||||
values.append("r")
|
||||
else:
|
||||
values.append("-")
|
||||
return "".join(values)
|
||||
|
||||
|
||||
def org_permission_mask(org_permissions: dict) -> str:
|
||||
@@ -1296,7 +1315,7 @@ def load_gitea_authz(
|
||||
result = {
|
||||
"ok": False,
|
||||
"valid": "!",
|
||||
"scope_mask": "!!!!!",
|
||||
"scope_mask": "!!!!!!!!!",
|
||||
"org_mask": "!!!!!",
|
||||
"repo_mask": "!!!!",
|
||||
"user": "",
|
||||
@@ -1326,7 +1345,7 @@ def load_gitea_authz(
|
||||
scopes = []
|
||||
result["scope_mask"] = scope_mask([str(scope) for scope in scopes])
|
||||
except (OSError, ValueError, urlerror.URLError):
|
||||
result["scope_mask"] = "?????"
|
||||
result["scope_mask"] = "?????????"
|
||||
|
||||
if user_name and owner:
|
||||
org_url = f"{api_base}/users/{quote(user_name, safe='')}/orgs/{quote(owner, safe='')}/permissions"
|
||||
@@ -1394,7 +1413,7 @@ def print_token_item_rows(
|
||||
) -> None:
|
||||
endpoint_values = endpoint_values_by_name.get(endpoint, endpoint_column_values(endpoint, None, None))
|
||||
valid_value = store_row.get("valid", "?") if store_row else "?"
|
||||
scope_value = store_row.get("scope_mask", "?????") if store_row else "?????"
|
||||
scope_value = store_row.get("scope_mask", "?????????") if store_row else "?????????"
|
||||
org_value = store_row.get("org_mask", "?????") if store_row else "?????"
|
||||
repo_value = store_row.get("repo_mask", "????") if store_row else "????"
|
||||
token_rows.append(
|
||||
@@ -1410,7 +1429,7 @@ def print_token_item_rows(
|
||||
"token_ref": format_token_ref(token_id, marker),
|
||||
"token": short_secret(token_value),
|
||||
"valid": valid_value or "?",
|
||||
"scope_mask": scope_value or "?????",
|
||||
"scope_mask": scope_value or "?????????",
|
||||
"org_mask": org_value or "?????",
|
||||
"repo_mask": repo_value or "????",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user