Extensions: send access token for HTTP requests
- The access token is used when connecting to the server. - Mention an invalid access token as a possible cause for 403 errors. Based on !122234. Co-authored-by: Dalai Felinto <dalai@blender.org>
This commit is contained in:
@@ -170,6 +170,7 @@ def sync_status_generator(repos_notify):
|
||||
directory=repo_item.directory,
|
||||
remote_url=repo_item.remote_url,
|
||||
online_user_agent=bl_extension_ops.online_user_agent_from_blender(),
|
||||
access_token=repo_item.access_token if repo_item.use_access_token else "",
|
||||
# Never sleep while there is no input, as this blocks Blender.
|
||||
use_idle=False,
|
||||
# Needed so the user can exit blender without warnings about a broken pipe.
|
||||
|
||||
@@ -264,6 +264,7 @@ class RepoItem(NamedTuple):
|
||||
remote_url: str
|
||||
module: str
|
||||
use_cache: bool
|
||||
access_token: str
|
||||
|
||||
|
||||
def repo_cache_store_refresh_from_prefs(include_disabled=False):
|
||||
@@ -483,6 +484,7 @@ def extension_repos_read_index(index, *, include_disabled=False):
|
||||
remote_url=remote_url,
|
||||
module=repo_item.module,
|
||||
use_cache=repo_item.use_cache,
|
||||
access_token=repo_item.access_token if repo_item.use_access_token else "",
|
||||
)
|
||||
index_test += 1
|
||||
return None
|
||||
@@ -519,6 +521,7 @@ def extension_repos_read(*, include_disabled=False, use_active_only=False):
|
||||
remote_url=remote_url,
|
||||
module=repo_item.module,
|
||||
use_cache=repo_item.use_cache,
|
||||
access_token=repo_item.access_token if repo_item.use_access_token else "",
|
||||
))
|
||||
return result
|
||||
|
||||
@@ -1002,6 +1005,7 @@ class BlPkgRepoSync(Operator, _BlPkgCmdMixIn):
|
||||
directory=directory,
|
||||
remote_url=repo_item.remote_url,
|
||||
online_user_agent=online_user_agent_from_blender(),
|
||||
access_token=repo_item.access_token,
|
||||
use_idle=is_modal,
|
||||
)
|
||||
)
|
||||
@@ -1078,6 +1082,7 @@ class BlPkgRepoSyncAll(Operator, _BlPkgCmdMixIn):
|
||||
directory=repo_item.directory,
|
||||
remote_url=repo_item.remote_url,
|
||||
online_user_agent=online_user_agent_from_blender(),
|
||||
access_token=repo_item.access_token,
|
||||
use_idle=is_modal,
|
||||
))
|
||||
|
||||
@@ -1206,6 +1211,7 @@ class BlPkgPkgUpgradeAll(Operator, _BlPkgCmdMixIn):
|
||||
remote_url=repo_item.remote_url,
|
||||
pkg_id_sequence=pkg_id_sequence,
|
||||
online_user_agent=online_user_agent_from_blender(),
|
||||
access_token=repo_item.access_token,
|
||||
use_cache=repo_item.use_cache,
|
||||
use_idle=is_modal,
|
||||
))
|
||||
@@ -1305,6 +1311,7 @@ class BlPkgPkgInstallMarked(Operator, _BlPkgCmdMixIn):
|
||||
remote_url=repo_item.remote_url,
|
||||
pkg_id_sequence=pkg_id_sequence,
|
||||
online_user_agent=online_user_agent_from_blender(),
|
||||
access_token=repo_item.access_token,
|
||||
use_cache=repo_item.use_cache,
|
||||
use_idle=is_modal,
|
||||
))
|
||||
@@ -1822,6 +1829,7 @@ class BlPkgPkgInstall(Operator, _BlPkgCmdMixIn):
|
||||
remote_url=repo_item.remote_url,
|
||||
pkg_id_sequence=(pkg_id,),
|
||||
online_user_agent=online_user_agent_from_blender(),
|
||||
access_token=repo_item.access_token,
|
||||
use_cache=repo_item.use_cache,
|
||||
use_idle=is_modal,
|
||||
)
|
||||
|
||||
@@ -286,6 +286,7 @@ def repo_sync(
|
||||
directory: str,
|
||||
remote_url: str,
|
||||
online_user_agent: str,
|
||||
access_token: str,
|
||||
use_idle: bool,
|
||||
force_exit_ok: bool = False,
|
||||
extension_override: str = "",
|
||||
@@ -299,6 +300,7 @@ def repo_sync(
|
||||
"--local-dir", directory,
|
||||
"--remote-url", remote_url,
|
||||
"--online-user-agent", online_user_agent,
|
||||
"--access-token", access_token,
|
||||
*(("--force-exit-ok",) if force_exit_ok else ()),
|
||||
*(("--extension-override", extension_override) if extension_override else ()),
|
||||
], use_idle=use_idle)
|
||||
@@ -310,6 +312,7 @@ def repo_upgrade(
|
||||
directory: str,
|
||||
remote_url: str,
|
||||
online_user_agent: str,
|
||||
access_token: str,
|
||||
use_idle: bool,
|
||||
) -> Generator[InfoItemSeq, None, None]:
|
||||
"""
|
||||
@@ -321,6 +324,7 @@ def repo_upgrade(
|
||||
"--local-dir", directory,
|
||||
"--remote-url", remote_url,
|
||||
"--online-user-agent", online_user_agent,
|
||||
"--access-token", access_token,
|
||||
], use_idle=use_idle)
|
||||
yield [COMPLETE_ITEM]
|
||||
|
||||
@@ -367,6 +371,7 @@ def pkg_install(
|
||||
remote_url: str,
|
||||
pkg_id_sequence: Sequence[str],
|
||||
online_user_agent: str,
|
||||
access_token: str,
|
||||
use_cache: bool,
|
||||
use_idle: bool,
|
||||
) -> Generator[InfoItemSeq, None, None]:
|
||||
@@ -379,6 +384,7 @@ def pkg_install(
|
||||
"--local-dir", directory,
|
||||
"--remote-url", remote_url,
|
||||
"--online-user-agent", online_user_agent,
|
||||
"--access-token", access_token,
|
||||
"--local-cache", str(int(use_cache)),
|
||||
], use_idle=use_idle)
|
||||
yield [COMPLETE_ITEM]
|
||||
|
||||
@@ -906,8 +906,6 @@ class PathPatternMatch:
|
||||
# URL Downloading
|
||||
|
||||
# Originally based on `urllib.request.urlretrieve`.
|
||||
|
||||
|
||||
def url_retrieve_to_data_iter(
|
||||
url: str,
|
||||
*,
|
||||
@@ -1079,6 +1077,10 @@ def url_retrieve_exception_as_message(
|
||||
if isinstance(ex, TimeoutError):
|
||||
return "{:s}: timeout ({:s}) reading {!r}!".format(prefix, str(ex), url)
|
||||
if isinstance(ex, urllib.error.URLError):
|
||||
if isinstance(ex, urllib.error.HTTPError):
|
||||
if ex.code == 403:
|
||||
return "{:s}: HTTP error (403) access token may be incorrect, reading {!r}!".format(prefix, url)
|
||||
return "{:s}: HTTP error ({:s}) reading {!r}!".format(prefix, str(ex), url)
|
||||
return "{:s}: URL error ({:s}) reading {!r}!".format(prefix, str(ex), url)
|
||||
|
||||
return "{:s}: unexpected error ({:s}) reading {!r}!".format(prefix, str(ex), url)
|
||||
@@ -1498,7 +1500,7 @@ def pkg_manifest_is_valid_or_error_all(
|
||||
# Standalone Utilities
|
||||
|
||||
|
||||
def url_request_headers_create(*, accept_json: bool, user_agent: str) -> Dict[str, str]:
|
||||
def url_request_headers_create(*, accept_json: bool, user_agent: str, access_token: str) -> Dict[str, str]:
|
||||
headers = {}
|
||||
if accept_json:
|
||||
# Default for JSON requests this allows top-level URL's to be used.
|
||||
@@ -1507,6 +1509,10 @@ def url_request_headers_create(*, accept_json: bool, user_agent: str) -> Dict[st
|
||||
if user_agent:
|
||||
# Typically: `Blender/4.2.0 (Linux x84_64; cycle=alpha)`.
|
||||
headers["User-Agent"] = user_agent
|
||||
|
||||
if access_token:
|
||||
headers["Authorization"] = "Bearer {:s}".format(access_token)
|
||||
|
||||
return headers
|
||||
|
||||
|
||||
@@ -1624,6 +1630,7 @@ def repo_sync_from_remote(
|
||||
remote_url: str,
|
||||
local_dir: str,
|
||||
online_user_agent: str,
|
||||
access_token: str,
|
||||
timeout_in_seconds: float,
|
||||
extension_override: str,
|
||||
) -> bool:
|
||||
@@ -1659,7 +1666,11 @@ def repo_sync_from_remote(
|
||||
for (read, size) in url_retrieve_to_filepath_iter_or_filesystem(
|
||||
remote_json_url,
|
||||
local_json_path_temp,
|
||||
headers=url_request_headers_create(accept_json=True, user_agent=online_user_agent),
|
||||
headers=url_request_headers_create(
|
||||
accept_json=True,
|
||||
user_agent=online_user_agent,
|
||||
access_token=access_token,
|
||||
),
|
||||
chunk_size=CHUNK_SIZE_DEFAULT,
|
||||
timeout_in_seconds=timeout_in_seconds,
|
||||
):
|
||||
@@ -1937,6 +1948,19 @@ def generic_arg_online_user_agent(subparse: argparse.ArgumentParser) -> None:
|
||||
)
|
||||
|
||||
|
||||
def generic_arg_access_token(subparse: argparse.ArgumentParser) -> None:
|
||||
subparse.add_argument(
|
||||
"--access-token",
|
||||
dest="access_token",
|
||||
type=str,
|
||||
help=(
|
||||
"Access token for remote repositories which require authorized access."
|
||||
),
|
||||
default="",
|
||||
required=False,
|
||||
)
|
||||
|
||||
|
||||
def generic_arg_timeout(subparse: argparse.ArgumentParser) -> None:
|
||||
subparse.add_argument(
|
||||
"--timeout",
|
||||
@@ -2077,6 +2101,7 @@ class subcmd_client:
|
||||
msg_fn: MessageFn,
|
||||
remote_url: str,
|
||||
online_user_agent: str,
|
||||
access_token: str,
|
||||
timeout_in_seconds: float,
|
||||
) -> bool:
|
||||
remote_json_url = remote_url_get(remote_url)
|
||||
@@ -2086,7 +2111,11 @@ class subcmd_client:
|
||||
result = io.BytesIO()
|
||||
for block in url_retrieve_to_data_iter_or_filesystem(
|
||||
remote_json_url,
|
||||
headers=url_request_headers_create(accept_json=True, user_agent=online_user_agent),
|
||||
headers=url_request_headers_create(
|
||||
accept_json=True,
|
||||
user_agent=online_user_agent,
|
||||
access_token=access_token,
|
||||
),
|
||||
chunk_size=CHUNK_SIZE_DEFAULT,
|
||||
timeout_in_seconds=timeout_in_seconds,
|
||||
):
|
||||
@@ -2122,6 +2151,7 @@ class subcmd_client:
|
||||
remote_url: str,
|
||||
local_dir: str,
|
||||
online_user_agent: str,
|
||||
access_token: str,
|
||||
timeout_in_seconds: float,
|
||||
force_exit_ok: bool,
|
||||
extension_override: str,
|
||||
@@ -2134,6 +2164,7 @@ class subcmd_client:
|
||||
remote_url=remote_url,
|
||||
local_dir=local_dir,
|
||||
online_user_agent=online_user_agent,
|
||||
access_token=access_token,
|
||||
timeout_in_seconds=timeout_in_seconds,
|
||||
extension_override=extension_override,
|
||||
)
|
||||
@@ -2281,6 +2312,7 @@ class subcmd_client:
|
||||
local_cache: bool,
|
||||
packages: Sequence[str],
|
||||
online_user_agent: str,
|
||||
access_token: str,
|
||||
timeout_in_seconds: float,
|
||||
) -> bool:
|
||||
# Extract...
|
||||
@@ -2375,7 +2407,11 @@ class subcmd_client:
|
||||
with open(filepath_local_cache_archive, "wb") as fh_cache:
|
||||
for block in url_retrieve_to_data_iter_or_filesystem(
|
||||
filepath_remote_archive,
|
||||
headers=url_request_headers_create(accept_json=False, user_agent=online_user_agent),
|
||||
headers=url_request_headers_create(
|
||||
accept_json=False,
|
||||
user_agent=online_user_agent,
|
||||
access_token=access_token,
|
||||
),
|
||||
chunk_size=CHUNK_SIZE_DEFAULT,
|
||||
timeout_in_seconds=timeout_in_seconds,
|
||||
):
|
||||
@@ -2937,6 +2973,7 @@ def argparse_create_client_list(subparsers: "argparse._SubParsersAction[argparse
|
||||
generic_arg_remote_url(subparse)
|
||||
generic_arg_local_dir(subparse)
|
||||
generic_arg_online_user_agent(subparse)
|
||||
generic_arg_access_token(subparse)
|
||||
|
||||
generic_arg_output_type(subparse)
|
||||
generic_arg_timeout(subparse)
|
||||
@@ -2946,6 +2983,7 @@ def argparse_create_client_list(subparsers: "argparse._SubParsersAction[argparse
|
||||
msg_fn_from_args(args),
|
||||
args.remote_url,
|
||||
online_user_agent=args.online_user_agent,
|
||||
access_token=args.access_token,
|
||||
timeout_in_seconds=args.timeout,
|
||||
),
|
||||
)
|
||||
@@ -2965,6 +3003,7 @@ def argparse_create_client_sync(subparsers: "argparse._SubParsersAction[argparse
|
||||
generic_arg_remote_url(subparse)
|
||||
generic_arg_local_dir(subparse)
|
||||
generic_arg_online_user_agent(subparse)
|
||||
generic_arg_access_token(subparse)
|
||||
|
||||
generic_arg_output_type(subparse)
|
||||
generic_arg_timeout(subparse)
|
||||
@@ -2977,6 +3016,7 @@ def argparse_create_client_sync(subparsers: "argparse._SubParsersAction[argparse
|
||||
remote_url=args.remote_url,
|
||||
local_dir=args.local_dir,
|
||||
online_user_agent=args.online_user_agent,
|
||||
access_token=args.access_token,
|
||||
timeout_in_seconds=args.timeout,
|
||||
force_exit_ok=args.force_exit_ok,
|
||||
extension_override=args.extension_override,
|
||||
@@ -3018,6 +3058,7 @@ def argparse_create_client_install(subparsers: "argparse._SubParsersAction[argpa
|
||||
generic_arg_local_dir(subparse)
|
||||
generic_arg_local_cache(subparse)
|
||||
generic_arg_online_user_agent(subparse)
|
||||
generic_arg_access_token(subparse)
|
||||
|
||||
generic_arg_output_type(subparse)
|
||||
generic_arg_timeout(subparse)
|
||||
@@ -3030,6 +3071,7 @@ def argparse_create_client_install(subparsers: "argparse._SubParsersAction[argpa
|
||||
local_cache=args.local_cache,
|
||||
packages=args.packages.split(","),
|
||||
online_user_agent=args.online_user_agent,
|
||||
access_token=args.access_token,
|
||||
timeout_in_seconds=args.timeout,
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user