diff --git a/.github/workflows/pypi-publish-on-push-on-new-release.yml b/.github/workflows/pypi-publish-on-push-on-new-release.yml index 4bba4d5..468b618 100644 --- a/.github/workflows/pypi-publish-on-push-on-new-release.yml +++ b/.github/workflows/pypi-publish-on-push-on-new-release.yml @@ -11,23 +11,22 @@ permissions: jobs: deploy: - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: '3.9' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install build - - name: Build package - run: python -m build - - name: Publish package - uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: "3.11" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build + - name: Build package + run: python -m build + - name: Publish package + uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/pypi-test-publish-on-push-to-develop-branch.yml b/.github/workflows/pypi-test-publish-on-push-to-develop-branch.yml index 68a15b8..1f7e69e 100644 --- a/.github/workflows/pypi-test-publish-on-push-to-develop-branch.yml +++ b/.github/workflows/pypi-test-publish-on-push-to-develop-branch.yml @@ -12,24 +12,23 @@ permissions: jobs: deploy: - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: '3.9' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install build - - name: Build package - run: python -m build - - name: Publish package - uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 - with: - user: __token__ - password: ${{ secrets.PYPI_TEST_API_TOKEN }} - repository_url: https://test.pypi.org/legacy/ + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: "3.11" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build + - name: Build package + run: python -m build + - name: Publish package + uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 + with: + user: __token__ + password: ${{ secrets.PYPI_TEST_API_TOKEN }} + repository_url: https://test.pypi.org/legacy/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 3235e45..3265dd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## v2.4.0-rc.2 [2026-09-16] + +__What's New:__ + +* Added `tokens [create|get|list|revoke]` command to manage temporary bearer tokens for the authenticated user. + +__Enhancements:__ + +* None + +__Bug Fixes:__ + +* None + +__Dependencies:__ + +* Bumped the `britive` SDK minimum to `4.8.0b0`. +* Dropped `python3.9` support, EOL 2025-10-31, was dropped by `britive` dependency in `v4.5.0`. +* Updated github workflows python version to `python3.11` + +__Other:__ + +* Python lint related changes. + ## v2.4.0-rc.1 [2026-06-08] __What's New:__ diff --git a/docs/index.md b/docs/index.md index 711c022..42f9b0a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,7 @@ Full Britive documentation is available here: [docs.britive.com](https://docs.br ## Requirements -* Python 3.9 or higher +* Python 3.10 or higher * Active Britive tenant (or nothing is really going to work) ## Installation diff --git a/pyproject.toml b/pyproject.toml index 77eed3d..752cfee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,32 +1,29 @@ [build-system] -requires = [ - "setuptools>=42", - "wheel" -] +requires = ["setuptools>=42", "wheel"] build-backend = "setuptools.build_meta" [project] name = "pybritive" -authors = [{name = "Britive Inc.", email = "support@britive.com"}] +authors = [{ name = "Britive Inc.", email = "support@britive.com" }] description = "A pure Python CLI for Britive" readme = "README.md" classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Internet", "Topic :: Security", "Topic :: Utilities", ] -license = {file = "LICENSE"} -requires-python = ">= 3.9" +license = { file = "LICENSE" } +requires-python = ">= 3.10" dependencies = [ - "britive>=4.6.0,<5.0", + "britive>=4.8.0b0,<5.0", "click>=8.1.7", "colored>=2.2.5", "cryptography", @@ -37,7 +34,7 @@ dependencies = [ "PyYAML", "requests>=2.31.0", "tabulate", - "toml" + "toml", ] dynamic = ["version"] keywords = ["britive", "cpam", "identity", "jit", "cli"] @@ -59,10 +56,10 @@ Issues = "https://github.com/britive/python-cli/issues" Changelog = "https://github.com/britive/python-cli/blob/main/CHANGELOG.md" [tool.setuptools] -package-dir = {"" = "src"} +package-dir = { "" = "src" } [tool.setuptools.dynamic] -version = {attr = "pybritive.__version__"} +version = { attr = "pybritive.__version__" } [tool.setuptools.packages.find] where = ["src"] @@ -83,10 +80,10 @@ line-ending = "auto" [tool.ruff.lint] select = [ - "E", # pycodestyle - "F", # Pyflakes - "I", # isort - "PL", #pylint + "E", # pycodestyle + "F", # Pyflakes + "I", # isort + "PL", #pylint "SIM", # flake8-simplify ] @@ -95,4 +92,4 @@ allow-magic-value-types = ["int", "str"] max-args = 18 max-branches = 30 max-returns = 8 -max-statements = 72 +max-statements = 72 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index f96f964..6dbf81d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ beautifulsoup4 boto3 -britive>=4.1.2,<5.0 +britive>=4.8.0b0,<5.0 certifi charset-normalizer click>=8.1.7 diff --git a/src/pybritive/__init__.py b/src/pybritive/__init__.py index 2c72544..4e18e72 100644 --- a/src/pybritive/__init__.py +++ b/src/pybritive/__init__.py @@ -1 +1 @@ -__version__ = '2.4.0-rc.1' +__version__ = '2.4.0-rc.2' diff --git a/src/pybritive/britive_cli.py b/src/pybritive/britive_cli.py index 0b068eb..ea5af12 100644 --- a/src/pybritive/britive_cli.py +++ b/src/pybritive/britive_cli.py @@ -315,6 +315,29 @@ def user(self): output += f' (alias: {alias})' self.print(output, ignore_silent=True) + def create_temp_token(self, duration_seconds: Optional[int] = None): + self.login() + token = self.b.security.temp_tokens.create(duration_seconds=duration_seconds) + output = [token] if self.output_format in ['csv', 'list'] else token + self.print(output, ignore_silent=True) + + def list_temp_tokens(self): + self.login() + tokens = self.b.security.temp_tokens.list() + if not tokens and self.output_format == 'csv': + return # There are no fields from which to build a CSV header. + self.print(tokens, ignore_silent=True) + + def get_temp_token(self, token_id: str): + self.login() + token = self.b.security.temp_tokens.get(token_id=token_id) + output = [token] if self.output_format in ['csv', 'list'] else token + self.print(output, ignore_silent=True) + + def revoke_temp_token(self, token_id: str): + self.login() + self.b.security.temp_tokens.revoke(token_id=token_id) + def list_secrets(self, search_text: Optional[str] = None): self.login() self.print(self.b.my_secrets.list(search=search_text), ignore_silent=True) diff --git a/src/pybritive/cli_interface.py b/src/pybritive/cli_interface.py index 5021822..f6cc625 100644 --- a/src/pybritive/cli_interface.py +++ b/src/pybritive/cli_interface.py @@ -16,6 +16,7 @@ from pybritive.commands.request import request as group_request from pybritive.commands.secret import secret as group_secret from pybritive.commands.ssh import ssh as group_ssh +from pybritive.commands.tokens import tokens as group_tokens from pybritive.commands.user import user as command_user from pybritive.options.britive_options import britive_options @@ -55,6 +56,7 @@ def cli(version): cli.add_command(command_api) cli.add_command(group_ssh) cli.add_command(group_aws) +cli.add_command(group_tokens) if __name__ == '__main__': diff --git a/src/pybritive/commands/checkout.py b/src/pybritive/commands/checkout.py index d994378..ffa15e5 100644 --- a/src/pybritive/commands/checkout.py +++ b/src/pybritive/commands/checkout.py @@ -12,7 +12,7 @@ 'gcloud_key_file,verbose,extend,profile_type,tenant,token,passphrase,federation_provider' ) @click_smart_profile_argument -def checkout( # noqa: PLR0913 +def checkout( # noqa: PLR0913, PLR0917 ctx, alias, blocktime, diff --git a/src/pybritive/commands/tokens.py b/src/pybritive/commands/tokens.py new file mode 100644 index 0000000..85576a9 --- /dev/null +++ b/src/pybritive/commands/tokens.py @@ -0,0 +1,66 @@ +import click + +from pybritive.helpers.build_britive import build_britive +from pybritive.options.britive_options import britive_options + + +@click.group() +def tokens(): + """Manage temporary tokens for your authenticated identity.""" + + +@tokens.command() +@build_britive +@britive_options(names='format,tenant,token,silent,passphrase,federation_provider') +@click.option( + '--duration-seconds', + type=click.IntRange(1, 86400), + default=None, + help='Requested lifetime in seconds. Omit to use the tenant default. The tenant maximum also applies.', +) +def create(ctx, output_format, tenant, token, silent, passphrase, federation_provider, duration_seconds): + """Create a temporary bearer token for your authenticated identity. + + Requires securityadmin.temptoken.create. A temporary token cannot create another temporary token. + Prints accessToken and expiresOn, including when --silent is set. The token is returned only once + and is not saved as your CLI login credential. + """ + ctx.obj.britive.create_temp_token(duration_seconds=duration_seconds) + + +@tokens.command() +@build_britive +@britive_options(names='format,tenant,token,silent,passphrase,federation_provider') +def list(ctx, output_format, tenant, token, silent, passphrase, federation_provider): + """List temporary tokens (not yet implemented).""" + # Remove this guard when the SDK implements the operation. + raise click.ClickException('Listing temporary tokens is not yet implemented.') + ctx.obj.britive.list_temp_tokens() + + +@tokens.command() +@build_britive +@britive_options(names='format,tenant,token,silent,passphrase,federation_provider') +@click.argument('token_id') +def get(ctx, output_format, tenant, token, silent, passphrase, federation_provider, token_id): + """View a temporary token (not yet implemented). + + TOKEN_ID is provisional, pending the API contract. + """ + # Remove this guard when the SDK implements the operation. + raise click.ClickException('Viewing temporary tokens is not yet implemented.') + ctx.obj.britive.get_temp_token(token_id=token_id) + + +@tokens.command() +@build_britive +@britive_options(names='tenant,token,silent,passphrase,federation_provider') +@click.argument('token_id') +def revoke(ctx, tenant, token, silent, passphrase, federation_provider, token_id): + """Revoke a temporary token (not yet implemented). + + TOKEN_ID is provisional, pending the API contract. + """ + # Remove this guard when the SDK implements the operation. + raise click.ClickException('Revoking temporary tokens is not yet implemented.') + ctx.obj.britive.revoke_temp_token(token_id=token_id) diff --git a/src/pybritive/helpers/checkout_lock.py b/src/pybritive/helpers/checkout_lock.py index c29a6bf..30867f1 100644 --- a/src/pybritive/helpers/checkout_lock.py +++ b/src/pybritive/helpers/checkout_lock.py @@ -1,3 +1,4 @@ +import contextlib import hashlib import os import time @@ -36,10 +37,8 @@ def _lock_fd(fd: int) -> None: raise _WouldBlock() def _unlock_fd(fd: int) -> None: - try: + with contextlib.suppress(OSError, IOError): msvcrt.locking(fd, msvcrt.LK_UNLCK, 1) - except (OSError, IOError): - pass class CheckoutLock: @@ -66,9 +65,7 @@ def acquire(self) -> None: if time.monotonic() >= deadline: os.close(self._fd) self._fd = None - raise CheckoutLockTimeout( - f'Timed out after {self.timeout}s waiting for checkout lock' - ) + raise CheckoutLockTimeout(f'Timed out after {self.timeout}s waiting for checkout lock') time.sleep(self.poll_interval) def release(self) -> None: diff --git a/tests/test_0200_configure.py b/tests/test_0200_configure.py index 6731f46..4cb4a26 100644 --- a/tests/test_0200_configure.py +++ b/tests/test_0200_configure.py @@ -19,32 +19,32 @@ def common_asserts(result, substring: Optional[list] = None, exit_code: int = 0) def test_configure_tenant_via_flags_no_alias(runner, cli): - result = runner.invoke(cli, 'configure tenant -t pybritivetest1.dev -f yaml'.split(' ')) + result = runner.invoke(cli, ['configure', 'tenant', '-t', 'pybritivetest1.dev', '-f', 'yaml']) common_asserts(result, substring='[tenant-pybritivetest1.dev]') def test_configure_tenant_via_flags_no_alias_no_format(runner, cli): - result = runner.invoke(cli, 'configure tenant -t pybritivetest2.dev'.split(' ')) + result = runner.invoke(cli, ['configure', 'tenant', '-t', 'pybritivetest2.dev']) common_asserts(result, substring='[tenant-pybritivetest2.dev]') def test_configure_tenant_via_flags_yes_alias(runner, cli): - result = runner.invoke(cli, 'configure tenant -t pybritivetest1.dev -f yaml -a testalias1'.split(' ')) + result = runner.invoke(cli, ['configure', 'tenant', '-t', 'pybritivetest1.dev', '-f', 'yaml', '-a', 'testalias1']) common_asserts(result, substring='[tenant-testalias1]') def test_configure_tenant_via_flags_yes_alias_no_format(runner, cli): - result = runner.invoke(cli, 'configure tenant -t pybritivetest2.dev -a testalias2'.split(' ')) + result = runner.invoke(cli, ['configure', 'tenant', '-t', 'pybritivetest2.dev', '-a', 'testalias2']) common_asserts(result, substring='[tenant-testalias2]') def test_configure_tenant_via_prompt_no_alias(runner, cli): - result = runner.invoke(cli, 'configure tenant'.split(' '), input='pybritivetest3.dev\n\njson\n') + result = runner.invoke(cli, ['configure', 'tenant'], input='pybritivetest3.dev\n\njson\n') common_asserts(result, substring='[tenant-pybritivetest3.dev]') def test_configure_tenant_via_prompt_no_alias_no_format(runner, cli): - result = runner.invoke(cli, 'configure tenant'.split(' '), input='pybritivetest4.dev\n\n\n') + result = runner.invoke(cli, ['configure', 'tenant'], input='pybritivetest4.dev\n\n\n') common_asserts(result, substring='[tenant-pybritivetest4.dev]') @@ -59,14 +59,16 @@ def test_configure_tenant_via_prompt_yes_alias_no_format(runner, cli): def test_configure_global_via_flags_file_backend(runner, cli): - result = runner.invoke(cli, 'configure global -t pybritivetest1.dev -f table -b file'.split(' ')) + result = runner.invoke(cli, ['configure', 'global', '-t', 'pybritivetest1.dev', '-f', 'table', '-b', 'file']) common_asserts( result, substring=['default_tenant=pybritivetest1.dev', 'output_format=table', 'credential_backend=file'] ) def test_configure_global_via_flags_encrypted_file_backend(runner, cli): - result = runner.invoke(cli, 'configure global -t pybritivetest2.dev -f yaml -b encrypted-file'.split(' ')) + result = runner.invoke( + cli, ['configure', 'global', '-t', 'pybritivetest2.dev', '-f', 'yaml', '-b', 'encrypted-file'] + ) common_asserts( result, substring=['default_tenant=pybritivetest2.dev', 'output_format=yaml', 'credential_backend=encrypted-file'], @@ -74,14 +76,14 @@ def test_configure_global_via_flags_encrypted_file_backend(runner, cli): def test_configure_global_via_prompt_file_backend(runner, cli): - result = runner.invoke(cli, 'configure global'.split(' '), input='pybritivetest1.dev\ntable-pretty\nfile\n') + result = runner.invoke(cli, ['configure', 'global'], input='pybritivetest1.dev\ntable-pretty\nfile\n') common_asserts( result, substring=['default_tenant=pybritivetest1.dev', 'output_format=table-pretty', 'credential_backend=file'] ) def test_configure_global_via_prompt_encrypted_file_backend(runner, cli): - result = runner.invoke(cli, 'configure global'.split(' '), input='pybritivetest2.dev\n\nencrypted-file\n') + result = runner.invoke(cli, ['configure', 'global'], input='pybritivetest2.dev\n\nencrypted-file\n') common_asserts( result, substring=['default_tenant=pybritivetest2.dev', 'output_format=json', 'credential_backend=encrypted-file'], @@ -89,23 +91,23 @@ def test_configure_global_via_prompt_encrypted_file_backend(runner, cli): def test_configure_global_with_invalid_format(runner, cli): - result = runner.invoke(cli, 'configure global -f error -P'.split(' ')) + result = runner.invoke(cli, ['configure', 'global', '-f', 'error', '-P']) assert "Invalid value for '--format' / '-f'" in result.output def test_configure_global_with_invalid_tenant(runner, cli): - result = runner.invoke(cli, 'configure global -t incorrect'.split(' ')) + result = runner.invoke(cli, ['configure', 'global', '-t', 'incorrect']) assert 'Invalid global field default_tenant value incorrect provided. Tenant not found.' in result.output def test_configure_update_global_invalid_data(runner, cli): - result = runner.invoke(cli, 'configure update global default_tenant incorrect'.split(' ')) + result = runner.invoke(cli, ['configure', 'update', 'global', 'default_tenant', 'incorrect']) assert result.exit_code == 1 assert 'Invalid global field default_tenant value incorrect provided. Tenant not found.' in result.output def test_configure_update_invalid_section(runner, cli): - result = runner.invoke(cli, 'configure update test default_tenant incorrect'.split(' ')) + result = runner.invoke(cli, ['configure', 'update', 'test', 'default_tenant', 'incorrect']) assert result.exit_code == 1 assert 'Cannot save config file due to invalid data provided.' in result.output @@ -123,5 +125,5 @@ def test_configure_update_global_correct_data(runner, cli): def test_configure_update_aws_data(runner, cli): - result = runner.invoke(cli, 'configure update aws default_checkout_mode integrate'.split(' ')) + result = runner.invoke(cli, ['configure', 'update', 'aws', 'default_checkout_mode', 'integrate']) common_asserts(result, substring=['aws', 'default_checkout_mode=integrate']) diff --git a/tests/test_0400_ls.py b/tests/test_0400_ls.py index 5c263c1..abba913 100644 --- a/tests/test_0400_ls.py +++ b/tests/test_0400_ls.py @@ -7,22 +7,22 @@ def common_asserts(result, substring=None, exit_code=0): def test_ls_profiles(runner, cli): - result = runner.invoke(cli, 'ls profiles -f yaml'.split(' ')) + result = runner.invoke(cli, ['ls', 'profiles', '-f', 'yaml']) common_asserts(result, ['Application', 'Description', 'Environment', 'Profile', 'Type']) def test_ls_applications(runner, cli): - result = runner.invoke(cli, 'ls applications -f yaml'.split(' ')) + result = runner.invoke(cli, ['ls', 'applications', '-f', 'yaml']) common_asserts(result, ['Application', 'Description', 'Type']) def test_ls_environments(runner, cli): - result = runner.invoke(cli, 'ls environments -f yaml'.split(' ')) + result = runner.invoke(cli, ['ls', 'environments', '-f', 'yaml']) common_asserts(result, ['Application', 'Description', 'Environment', 'Type']) def test_ls_secrets(runner, cli): - result = runner.invoke(cli, 'ls secrets -f yaml'.split(' ')) + result = runner.invoke(cli, ['ls', 'secrets', '-f', 'yaml']) common_asserts( result, ['entityType', 'id', 'metadata', 'name', 'path', 'rotationInterval', 'secretNature', 'secretType', 'status'], diff --git a/tests/test_0500_api.py b/tests/test_0500_api.py index b3af4e6..c03c6d3 100644 --- a/tests/test_0500_api.py +++ b/tests/test_0500_api.py @@ -7,5 +7,5 @@ def common_asserts(result, substring=None, exit_code=0): def test_api(runner, cli): - result = runner.invoke(cli, 'api identity_management.users.list'.split(' ')) + result = runner.invoke(cli, ['api', 'identity_management.users.list']) common_asserts(result, ['userId', 'status', 'email', 'identityProvider']) diff --git a/tests/test_0600_secret.py b/tests/test_0600_secret.py index 7e2f758..129ea42 100644 --- a/tests/test_0600_secret.py +++ b/tests/test_0600_secret.py @@ -10,13 +10,13 @@ def common_asserts(result, substring=None, exit_code=0): def test_view(runner, cli): - result = runner.invoke(cli, 'secret view /pybritive-test-standard -f yaml'.split(' ')) + result = runner.invoke(cli, ['secret', 'view', '/pybritive-test-standard', '-f', 'yaml']) common_asserts(result, 'test') def test_download(runner, cli): filename = 'pybritive-test-secret-file.txt' - result = runner.invoke(cli, 'secret download /pybritive-test-file'.split(' ')) + result = runner.invoke(cli, ['secret', 'download', '/pybritive-test-file']) message = 'wrote contents of secret file to' common_asserts(result, message) with open(filename, encoding='utf-8') as f: diff --git a/tests/test_0700_cache.py b/tests/test_0700_cache.py index 733c35f..5b7e91a 100644 --- a/tests/test_0700_cache.py +++ b/tests/test_0700_cache.py @@ -4,7 +4,7 @@ def test_cache_profiles(runner, cli): - result = runner.invoke(cli, 'cache profiles'.split(' ')) + result = runner.invoke(cli, ['cache', 'profiles']) local_home = os.getenv('PYBRITIVE_HOME_DIR') path = Path(Path(local_home) / '.britive' / 'pybritive.cache') with open(str(path), encoding='utf-8') as f: diff --git a/tests/test_0950_tokens.py b/tests/test_0950_tokens.py new file mode 100644 index 0000000..571d266 --- /dev/null +++ b/tests/test_0950_tokens.py @@ -0,0 +1,41 @@ +def common_asserts(result, substring=None, exit_code=0): + assert result.exit_code == exit_code + if isinstance(substring, str): + substring = [substring] + for sub in substring: + assert sub in result.output + + +def test_create(runner, cli): + result = runner.invoke(cli, ['tokens', 'create', '-f', 'json', '--silent']) + common_asserts(result, ['accessToken', 'expiresOn']) + + +def test_create_with_duration(runner, cli): + result = runner.invoke(cli, ['tokens', 'create', '--duration-seconds', '900', '-f', 'json', '--silent']) + common_asserts(result, ['accessToken', 'expiresOn']) + + +def test_help(runner, cli): + result = runner.invoke(cli, ['tokens', '--help']) + common_asserts(result, ['create', 'get', 'list', 'revoke']) + + +def test_create_help(runner, cli): + result = runner.invoke(cli, ['tokens', 'create', '--help']) + common_asserts(result, ['--duration-seconds', '--format', '--tenant', '--token', '--silent']) + + +def test_list_not_implemented(runner, cli): + result = runner.invoke(cli, ['tokens', 'list', '--tenant', 'example']) + common_asserts(result, 'Listing temporary tokens is not yet implemented.', exit_code=1) + + +def test_get_not_implemented(runner, cli): + result = runner.invoke(cli, ['tokens', 'get', 'example-id', '--tenant', 'example']) + common_asserts(result, 'Viewing temporary tokens is not yet implemented.', exit_code=1) + + +def test_revoke_not_implemented(runner, cli): + result = runner.invoke(cli, ['tokens', 'revoke', 'example-id', '--tenant', 'example']) + common_asserts(result, 'Revoking temporary tokens is not yet implemented.', exit_code=1) diff --git a/tests/test_1000_clear.py b/tests/test_1000_clear.py index 42c0af1..952f617 100644 --- a/tests/test_1000_clear.py +++ b/tests/test_1000_clear.py @@ -4,7 +4,7 @@ def test_clear_cache(runner, cli): - result = runner.invoke(cli, 'clear cache'.split(' ')) + result = runner.invoke(cli, ['clear', 'cache']) local_home = os.getenv('PYBRITIVE_HOME_DIR') path = Path(Path(local_home) / '.britive' / 'pybritive.cache') with open(str(path), encoding='utf-8') as f: @@ -28,7 +28,7 @@ def test_clear_gcloud_key_files(runner, cli): assert file1.is_file() assert file2.is_file() - result = runner.invoke(cli, 'clear gcloud-auth-key-files'.split(' ')) + result = runner.invoke(cli, ['clear', 'gcloud-auth-key-files']) assert result.exit_code == 0 assert not file1.is_file() assert not file2.is_file()