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
|
`token_ref` laczy nazwe tokena z markerem po prawej stronie: `*` oznacza, ze
|
||||||
remote i `tokens.json` sa zgodne oraz uprawnienia zostaly wczytane, `R` oznacza
|
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`
|
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
|
Zapis z remote do `tokens.json` oraz odczyt `valid` i uprawnien z API robi
|
||||||
dopiero `tokens update --from remotes`.
|
dopiero `tokens update --from remotes`.
|
||||||
Kolumna `valid` oznacza, czy token zostal zaakceptowany przez API teraz.
|
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",
|
"user": "u1",
|
||||||
"valid": "forever",
|
"valid": "forever",
|
||||||
"scope": "+---+",
|
"scope": "-----w---",
|
||||||
"remotes": [
|
"remotes": [
|
||||||
{
|
{
|
||||||
"name": "r1",
|
"name": "r1",
|
||||||
@@ -69,7 +69,7 @@ Pola wzbogacane przez API przy `tokens update --from remotes`:
|
|||||||
|
|
||||||
- `user` - login wlasciciela tokena odczytany z API
|
- `user` - login wlasciciela tokena odczytany z API
|
||||||
- `valid` - `forever`, data `expires_at`, `invalid`, `?` albo `!`
|
- `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[].org_perm` - maska praw w organizacji
|
||||||
- `remotes[].repo_perm` - maska praw w repo
|
- `remotes[].repo_perm` - maska praw w repo
|
||||||
|
|
||||||
@@ -95,11 +95,31 @@ wartosc `?`, bo launcher nie pokazuje metadanych API dla niesparowanych wpisow.
|
|||||||
|
|
||||||
Naglowki masek:
|
Naglowki masek:
|
||||||
|
|
||||||
- `scope`: `awrop-`
|
- `scope`: `aAimnopru`
|
||||||
- `org`: `oawrc-`
|
- `org`: `oawrc-`
|
||||||
- `repo`: `oawr--`
|
- `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 wlaczona
|
||||||
- `-` - flaga wylaczona
|
- `-` - flaga wylaczona
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
},
|
},
|
||||||
"scope": {
|
"scope": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^[+?!-]{5}$"
|
"pattern": "^[rw?!-]{9}$"
|
||||||
},
|
},
|
||||||
"expires_at": {
|
"expires_at": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|||||||
@@ -388,6 +388,10 @@ def normalize_remote_record(raw_remote: dict) -> dict | None:
|
|||||||
return remote_record
|
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:
|
def normalize_v3_token(config: WorkspaceConfig, raw_token: dict) -> dict | None:
|
||||||
if not isinstance(raw_token, dict):
|
if not isinstance(raw_token, dict):
|
||||||
return None
|
return None
|
||||||
@@ -409,10 +413,13 @@ def normalize_v3_token(config: WorkspaceConfig, raw_token: dict) -> dict | None:
|
|||||||
"server": server_record,
|
"server": server_record,
|
||||||
"remotes": [],
|
"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)
|
field_value = raw_token.get(field_name)
|
||||||
if isinstance(field_value, str) and field_value:
|
if isinstance(field_value, str) and field_value:
|
||||||
token_record[field_name] = 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", [])
|
raw_remotes = raw_token.get("remotes", [])
|
||||||
if isinstance(raw_remotes, dict):
|
if isinstance(raw_remotes, dict):
|
||||||
@@ -1070,13 +1077,13 @@ TOKEN_COLUMNS = [
|
|||||||
("token_ref", "token_ref", TOKEN_REF_WIDTH),
|
("token_ref", "token_ref", TOKEN_REF_WIDTH),
|
||||||
("token", "token", 12),
|
("token", "token", 12),
|
||||||
("valid", "valid", 19),
|
("valid", "valid", 19),
|
||||||
("scope_mask", "scope", 6),
|
("scope_mask", "scope", 9),
|
||||||
("org_mask", "org", 6),
|
("org_mask", "org", 6),
|
||||||
("repo_mask", "repo", 6),
|
("repo_mask", "repo", 6),
|
||||||
]
|
]
|
||||||
|
|
||||||
TOKEN_SEPARATOR_OVERRIDES = {
|
TOKEN_SEPARATOR_OVERRIDES = {
|
||||||
"scope_mask": "awrop-",
|
"scope_mask": "aAimnopru",
|
||||||
"org_mask": "oawrc-",
|
"org_mask": "oawrc-",
|
||||||
"repo_mask": "oawr--",
|
"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:
|
def scope_mask(scopes: list[str]) -> str:
|
||||||
scope_set = {scope.lower() for scope in scopes}
|
scope_set = {scope.lower() for scope in scopes}
|
||||||
return "".join(
|
categories = [
|
||||||
[
|
"activitypub",
|
||||||
"+" if "all" in scope_set else "-",
|
"admin",
|
||||||
"+" if "write:repository" in scope_set else "-",
|
"issue",
|
||||||
"+" if "read:repository" in scope_set else "-",
|
"misc",
|
||||||
"+" if {"read:organization", "write:organization"} & scope_set else "-",
|
"notification",
|
||||||
"+" if "public-only" in scope_set else "-",
|
"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:
|
def org_permission_mask(org_permissions: dict) -> str:
|
||||||
@@ -1296,7 +1315,7 @@ def load_gitea_authz(
|
|||||||
result = {
|
result = {
|
||||||
"ok": False,
|
"ok": False,
|
||||||
"valid": "!",
|
"valid": "!",
|
||||||
"scope_mask": "!!!!!",
|
"scope_mask": "!!!!!!!!!",
|
||||||
"org_mask": "!!!!!",
|
"org_mask": "!!!!!",
|
||||||
"repo_mask": "!!!!",
|
"repo_mask": "!!!!",
|
||||||
"user": "",
|
"user": "",
|
||||||
@@ -1326,7 +1345,7 @@ def load_gitea_authz(
|
|||||||
scopes = []
|
scopes = []
|
||||||
result["scope_mask"] = scope_mask([str(scope) for scope in scopes])
|
result["scope_mask"] = scope_mask([str(scope) for scope in scopes])
|
||||||
except (OSError, ValueError, urlerror.URLError):
|
except (OSError, ValueError, urlerror.URLError):
|
||||||
result["scope_mask"] = "?????"
|
result["scope_mask"] = "?????????"
|
||||||
|
|
||||||
if user_name and owner:
|
if user_name and owner:
|
||||||
org_url = f"{api_base}/users/{quote(user_name, safe='')}/orgs/{quote(owner, safe='')}/permissions"
|
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:
|
) -> None:
|
||||||
endpoint_values = endpoint_values_by_name.get(endpoint, endpoint_column_values(endpoint, None, 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 "?"
|
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 "?????"
|
org_value = store_row.get("org_mask", "?????") if store_row else "?????"
|
||||||
repo_value = store_row.get("repo_mask", "????") if store_row else "????"
|
repo_value = store_row.get("repo_mask", "????") if store_row else "????"
|
||||||
token_rows.append(
|
token_rows.append(
|
||||||
@@ -1410,7 +1429,7 @@ def print_token_item_rows(
|
|||||||
"token_ref": format_token_ref(token_id, marker),
|
"token_ref": format_token_ref(token_id, marker),
|
||||||
"token": short_secret(token_value),
|
"token": short_secret(token_value),
|
||||||
"valid": valid_value or "?",
|
"valid": valid_value or "?",
|
||||||
"scope_mask": scope_value or "?????",
|
"scope_mask": scope_value or "?????????",
|
||||||
"org_mask": org_value or "?????",
|
"org_mask": org_value or "?????",
|
||||||
"repo_mask": repo_value or "????",
|
"repo_mask": repo_value or "????",
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user