From f1aee38b94ed4348c1168fd74b6feb6d263774e2 Mon Sep 17 00:00:00 2001 From: Maciej Urbanski Date: Mon, 22 Apr 2024 22:28:35 +0200 Subject: [PATCH 1/2] fix `create-key --all-capabilities` when account doesnt have access to notification-rules cap --- b2/_internal/console_tool.py | 13 ++++++-- changelog.d/+create_key.fixed.md | 1 + .../console_tool/test_authorize_account.py | 31 ++----------------- test/unit/test_console_tool.py | 4 +-- 4 files changed, 16 insertions(+), 33 deletions(-) create mode 100644 changelog.d/+create_key.fixed.md diff --git a/b2/_internal/console_tool.py b/b2/_internal/console_tool.py index 9376eb4ab..b3d6cc57e 100644 --- a/b2/_internal/console_tool.py +++ b/b2/_internal/console_tool.py @@ -291,6 +291,8 @@ def apply_or_none(fcn, value): def format_account_info(account_info: AbstractAccountInfo) -> dict: + allowed = account_info.get_allowed() + allowed['capabilities'] = sorted(allowed['capabilities']) return dict( accountId=account_info.get_account_id(), accountFilePath=getattr( @@ -298,7 +300,7 @@ def format_account_info(account_info: AbstractAccountInfo) -> dict: 'filename', None, ), # missing in StubAccountInfo in tests - allowed=account_info.get_allowed(), + allowed=allowed, applicationKeyId=account_info.get_application_key_id(), applicationKey=account_info.get_application_key(), isMasterKey=account_info.is_master_key(), @@ -1643,7 +1645,14 @@ def _run(self, args): bucket_id_or_none = self.api.get_bucket_by_name(args.bucket).id_ if args.all_capabilities: - args.capabilities = ALL_CAPABILITIES + current_key_caps = set(self.api.account_info.get_allowed()['capabilities']) + preview_feature_caps = { + 'readBucketNotifications', + 'writeBucketNotifications', + } + args.capabilities = sorted( + set(ALL_CAPABILITIES) - preview_feature_caps | current_key_caps + ) application_key = self.api.create_key( capabilities=args.capabilities, diff --git a/changelog.d/+create_key.fixed.md b/changelog.d/+create_key.fixed.md new file mode 100644 index 000000000..a7c9bab99 --- /dev/null +++ b/changelog.d/+create_key.fixed.md @@ -0,0 +1 @@ +Fix `create-key --all-capabilities` erroring out when new b2sdk is installed. diff --git a/test/unit/console_tool/test_authorize_account.py b/test/unit/console_tool/test_authorize_account.py index 4d32c8c54..5c9767bef 100644 --- a/test/unit/console_tool/test_authorize_account.py +++ b/test/unit/console_tool/test_authorize_account.py @@ -10,6 +10,7 @@ from unittest import mock import pytest +from b2sdk.v2 import ALL_CAPABILITIES from b2._internal._cli.const import ( B2_APPLICATION_KEY_ENV_VAR, @@ -133,35 +134,7 @@ def test_authorize_account_prints_account_info(b2_cli): { 'bucketId': None, 'bucketName': None, - 'capabilities': - [ - 'listKeys', - 'writeKeys', - 'deleteKeys', - 'listBuckets', - 'listAllBucketNames', - 'readBuckets', - 'writeBuckets', - 'deleteBuckets', - 'readBucketEncryption', - 'writeBucketEncryption', - 'readBucketRetentions', - 'writeBucketRetentions', - 'readFileRetentions', - 'writeFileRetentions', - 'readFileLegalHolds', - 'writeFileLegalHolds', - 'readBucketReplications', - 'writeBucketReplications', - 'bypassGovernance', - 'listFiles', - 'readFiles', - 'shareFiles', - 'writeFiles', - 'deleteFiles', - 'readBucketNotifications', - 'writeBucketNotifications', - ], + 'capabilities': sorted(ALL_CAPABILITIES), 'namePrefix': None, }, 'apiUrl': 'http://api.example.com', diff --git a/test/unit/test_console_tool.py b/test/unit/test_console_tool.py index 044b8e4ea..0843d6947 100644 --- a/test/unit/test_console_tool.py +++ b/test/unit/test_console_tool.py @@ -744,7 +744,7 @@ def test_keys(self): appKeyId1 goodKeyName-Two my-bucket-a - - '' readFiles,listBuckets,readBucketEncryption appKeyId3 goodKeyName-Four - - - '' {} appKeyId4 goodKeyName-Five id=bucket_1 - - '' readFiles,listBuckets - """.format(','.join(ALL_CAPABILITIES)) + """.format(','.join(sorted(ALL_CAPABILITIES))) self._run_command(['list-keys'], expected_list_keys_out, '', 0) self._run_command(['list-keys', '--long'], expected_list_keys_out_long, '', 0) @@ -1584,7 +1584,7 @@ def test_get_account_info(self): { "bucketId": None, "bucketName": None, - "capabilities": ALL_CAPABILITIES, + "capabilities": sorted(ALL_CAPABILITIES), "namePrefix": None }, "apiUrl": "http://api.example.com", From 113d7dc168059eac2bc79e57af242bd59fa00a11 Mon Sep 17 00:00:00 2001 From: Maciej Urbanski Date: Tue, 23 Apr 2024 09:46:02 +0200 Subject: [PATCH 2/2] normalize stdout newlines in tests to prevent errors under Windows --- test/integration/helpers.py | 2 +- test/integration/test_b2_command_line.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/integration/helpers.py b/test/integration/helpers.py index d6ddce59a..91a4c8fc8 100755 --- a/test/integration/helpers.py +++ b/test/integration/helpers.py @@ -422,7 +422,7 @@ def should_succeed( assert re.search(expected_pattern, stdout), \ f'did not match pattern="{expected_pattern}", stdout="{stdout}"' - return stdout + return stdout.replace(os.linesep, '\n') @classmethod def prepare_env(self, additional_env: dict | None = None): diff --git a/test/integration/test_b2_command_line.py b/test/integration/test_b2_command_line.py index 6143e0eff..f7d9da683 100755 --- a/test/integration/test_b2_command_line.py +++ b/test/integration/test_b2_command_line.py @@ -2954,10 +2954,10 @@ def test_download_file_stdout( ): assert b2_tool.should_succeed( ['download-file', '--quiet', f"b2://{bucket_name}/{uploaded_sample_file['fileName']}", '-'], - ).replace("\r", "") == sample_filepath.read_text() + ) == sample_filepath.read_text() assert b2_tool.should_succeed( ['download-file', '--quiet', f"b2id://{uploaded_sample_file['fileId']}", '-'], - ).replace("\r", "") == sample_filepath.read_text() + ) == sample_filepath.read_text() def test_download_file_to_directory( @@ -3003,9 +3003,9 @@ def test_download_file_to_directory( def test_cat(b2_tool, bucket_name, sample_filepath, tmp_path, uploaded_sample_file): assert b2_tool.should_succeed( ['cat', f"b2://{bucket_name}/{uploaded_sample_file['fileName']}"], - ).replace("\r", "") == sample_filepath.read_text() - assert b2_tool.should_succeed(['cat', f"b2id://{uploaded_sample_file['fileId']}" - ],).replace("\r", "") == sample_filepath.read_text() + ) == sample_filepath.read_text() + assert b2_tool.should_succeed(['cat', f"b2id://{uploaded_sample_file['fileId']}"] + ) == sample_filepath.read_text() def test_header_arguments(b2_tool, bucket_name, sample_filepath, tmp_path):