stsmfa-cli 1.4.6__tar.gz → 1.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,31 +1,29 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stsmfa-cli
3
- Version: 1.4.6
3
+ Version: 1.5.0
4
4
  Summary: A small CLI to help with creating AWS profile for MFA protected sessions
5
- Home-page: https://github.com/browniebroke/stsmfa-cli
5
+ Author-email: Bruno Alla <alla.brunoo@gmail.com>
6
6
  License: MIT
7
- Author: Bruno Alla
8
- Author-email: alla.brunoo@gmail.com
9
- Requires-Python: >=3.9,<4.0
7
+ Project-URL: Bug Tracker, https://github.com/browniebroke/stsmfa-cli/issues
8
+ Project-URL: Changelog, https://github.com/browniebroke/stsmfa-cli/blob/main/CHANGELOG.md
9
+ Project-URL: repository, https://github.com/browniebroke/stsmfa-cli
10
10
  Classifier: Development Status :: 2 - Pre-Alpha
11
11
  Classifier: Intended Audience :: Developers
12
- Classifier: License :: OSI Approved :: MIT License
13
12
  Classifier: Natural Language :: English
14
13
  Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
16
15
  Classifier: Programming Language :: Python :: 3.9
17
16
  Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
19
18
  Classifier: Programming Language :: Python :: 3.12
20
19
  Classifier: Programming Language :: Python :: 3.13
21
20
  Classifier: Topic :: Software Development :: Libraries
22
- Requires-Dist: boto3 (>=1.26,<2.0)
23
- Requires-Dist: rich (>=10.0)
24
- Requires-Dist: typer (>=0.15.0,<0.16.0)
25
- Project-URL: Bug Tracker, https://github.com/browniebroke/stsmfa-cli/issues
26
- Project-URL: Changelog, https://github.com/browniebroke/stsmfa-cli/blob/main/CHANGELOG.md
27
- Project-URL: Repository, https://github.com/browniebroke/stsmfa-cli
21
+ Requires-Python: >=3.9
28
22
  Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: boto3<2,>=1.26
25
+ Requires-Dist: rich>=10
26
+ Requires-Dist: typer<1,>=0.15
29
27
 
30
28
  # STS MFA CLI
31
29
 
@@ -38,8 +36,8 @@ Description-Content-Type: text/markdown
38
36
  </a>
39
37
  </p>
40
38
  <p align="center">
41
- <a href="https://python-poetry.org/">
42
- <img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="Poetry">
39
+ <a href="https://github.com/astral-sh/uv">
40
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
43
41
  </a>
44
42
  <a href="https://github.com/astral-sh/ruff">
45
43
  <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
@@ -72,10 +70,10 @@ Via Homebrew:
72
70
  brew install browniebroke/tap/stsmfa-cli
73
71
  ```
74
72
 
75
- Via pip, pipx, or your favourite Python package manager:
73
+ Via uv, or your favourite Python package manager:
76
74
 
77
75
  ```bash
78
- pip install stsmfa-cli
76
+ uv tool install stsmfa-cli
79
77
  ```
80
78
 
81
79
  ## Usage
@@ -94,7 +92,7 @@ mfa_serial = arn:aws:iam::123456789010:mfa/first.last
94
92
  When running, for example:
95
93
 
96
94
  ```bash
97
- stsmfa --profile my-profile-name 123456
95
+ awsmfa --profile my-profile-name 123456
98
96
  ```
99
97
 
100
98
  This will create a session using the MFA serial defined under `my-profile-name` with the one-time password `123456`, and save the required AWS key, secret and token under as a new profile `my-profile-name-mfa` in you `~/.aws/credentials` file.
@@ -133,4 +131,3 @@ This package was created with
133
131
  [Copier](https://copier.readthedocs.io/) and the
134
132
  [browniebroke/pypackage-template](https://github.com/browniebroke/pypackage-template)
135
133
  project template.
136
-
@@ -9,8 +9,8 @@
9
9
  </a>
10
10
  </p>
11
11
  <p align="center">
12
- <a href="https://python-poetry.org/">
13
- <img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="Poetry">
12
+ <a href="https://github.com/astral-sh/uv">
13
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
14
14
  </a>
15
15
  <a href="https://github.com/astral-sh/ruff">
16
16
  <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
@@ -43,10 +43,10 @@ Via Homebrew:
43
43
  brew install browniebroke/tap/stsmfa-cli
44
44
  ```
45
45
 
46
- Via pip, pipx, or your favourite Python package manager:
46
+ Via uv, or your favourite Python package manager:
47
47
 
48
48
  ```bash
49
- pip install stsmfa-cli
49
+ uv tool install stsmfa-cli
50
50
  ```
51
51
 
52
52
  ## Usage
@@ -65,7 +65,7 @@ mfa_serial = arn:aws:iam::123456789010:mfa/first.last
65
65
  When running, for example:
66
66
 
67
67
  ```bash
68
- stsmfa --profile my-profile-name 123456
68
+ awsmfa --profile my-profile-name 123456
69
69
  ```
70
70
 
71
71
  This will create a session using the MFA serial defined under `my-profile-name` with the one-time password `123456`, and save the required AWS key, secret and token under as a new profile `my-profile-name-mfa` in you `~/.aws/credentials` file.
@@ -1,46 +1,45 @@
1
- [build-system]
2
- build-backend = "poetry.core.masonry.api"
3
- requires = [ "poetry-core>=1" ]
4
-
5
- [tool.poetry]
1
+ [project]
6
2
  name = "stsmfa-cli"
7
- version = "1.4.6"
3
+ version = "1.5.0"
8
4
  description = "A small CLI to help with creating AWS profile for MFA protected sessions"
9
- authors = [ "Bruno Alla <alla.brunoo@gmail.com>" ]
10
- license = "MIT"
11
5
  readme = "README.md"
12
- repository = "https://github.com/browniebroke/stsmfa-cli"
6
+ license = { text = "MIT" }
7
+ authors = [
8
+ { name = "Bruno Alla", email = "alla.brunoo@gmail.com" },
9
+ ]
10
+ requires-python = ">=3.9"
13
11
  classifiers = [
14
12
  "Development Status :: 2 - Pre-Alpha",
15
13
  "Intended Audience :: Developers",
16
14
  "Natural Language :: English",
17
15
  "Operating System :: OS Independent",
18
- "Topic :: Software Development :: Libraries",
16
+ "Programming Language :: Python :: 3 :: Only",
17
+ "Programming Language :: Python :: 3.9",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
19
20
  "Programming Language :: Python :: 3.12",
20
- ]
21
- packages = [
22
- { include = "stsmfa", from = "src" },
21
+ "Programming Language :: Python :: 3.13",
22
+ "Topic :: Software Development :: Libraries",
23
23
  ]
24
24
 
25
- [tool.poetry.urls]
26
- "Bug Tracker" = "https://github.com/browniebroke/stsmfa-cli/issues"
27
- "Changelog" = "https://github.com/browniebroke/stsmfa-cli/blob/main/CHANGELOG.md"
28
-
29
- [tool.poetry.scripts]
30
- stsmfa = "stsmfa.cli:app"
31
- awsmfa = "stsmfa.cli:app"
32
-
33
- [tool.poetry.dependencies]
34
- python = "^3.9"
35
- boto3 = "^1.26"
36
- typer = "^0.15.0"
37
- rich = ">=10.0"
38
-
39
- [tool.poetry.group.dev.dependencies]
40
- pytest = "^8.0.0"
41
- pytest-cov = "^6.0.0"
42
- pyfakefs = "^5.0.0"
43
- pytest-mock = "^3.10.0"
25
+ dependencies = [
26
+ "boto3>=1.26,<2",
27
+ "rich>=10",
28
+ "typer>=0.15,<1",
29
+ ]
30
+ urls."Bug Tracker" = "https://github.com/browniebroke/stsmfa-cli/issues"
31
+ urls.Changelog = "https://github.com/browniebroke/stsmfa-cli/blob/main/CHANGELOG.md"
32
+ urls.repository = "https://github.com/browniebroke/stsmfa-cli"
33
+ scripts.awsmfa = "stsmfa.cli:app"
34
+ scripts.stsmfa = "stsmfa.cli:app"
35
+
36
+ [dependency-groups]
37
+ dev = [
38
+ "pyfakefs>=5,<6",
39
+ "pytest>=8,<9",
40
+ "pytest-cov>=6,<7",
41
+ "pytest-mock>=3.10,<4",
42
+ ]
44
43
 
45
44
  [tool.ruff]
46
45
  target-version = "py39"
@@ -115,11 +114,16 @@ module = "tests.*"
115
114
  allow_untyped_defs = true
116
115
 
117
116
  [tool.semantic_release]
118
- version_toml = [ "pyproject.toml:tool.poetry.version" ]
117
+ version_toml = [ "pyproject.toml:project.version" ]
119
118
  version_variables = [
120
119
  "src/stsmfa/__init__.py:__version__",
121
120
  ]
122
- build_command = "pip install poetry && poetry build"
121
+ build_command = """
122
+ pip install uv
123
+ uv lock
124
+ git add uv.lock
125
+ uv build
126
+ """
123
127
 
124
128
  [tool.semantic_release.changelog]
125
129
  exclude_commit_patterns = [
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env python
2
+
3
+ # This is a shim to allow GitHub to detect the package, build is done with poetry
4
+ # Taken from https://github.com/Textualize/rich
5
+
6
+ import setuptools
7
+
8
+ if __name__ == "__main__":
9
+ setuptools.setup(name="stsmfa-cli")
@@ -0,0 +1 @@
1
+ __version__ = "1.5.0"
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.1
2
+ Name: stsmfa-cli
3
+ Version: 1.5.0
4
+ Summary: A small CLI to help with creating AWS profile for MFA protected sessions
5
+ Author-email: Bruno Alla <alla.brunoo@gmail.com>
6
+ License: MIT
7
+ Project-URL: Bug Tracker, https://github.com/browniebroke/stsmfa-cli/issues
8
+ Project-URL: Changelog, https://github.com/browniebroke/stsmfa-cli/blob/main/CHANGELOG.md
9
+ Project-URL: repository, https://github.com/browniebroke/stsmfa-cli
10
+ Classifier: Development Status :: 2 - Pre-Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Natural Language :: English
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: boto3<2,>=1.26
25
+ Requires-Dist: rich>=10
26
+ Requires-Dist: typer<1,>=0.15
27
+
28
+ # STS MFA CLI
29
+
30
+ <p align="center">
31
+ <a href="https://github.com/browniebroke/stsmfa-cli/actions/workflows/ci.yml?query=branch%3Amain">
32
+ <img src="https://img.shields.io/github/actions/workflow/status/browniebroke/stsmfa-cli/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" >
33
+ </a>
34
+ <a href="https://codecov.io/gh/browniebroke/stsmfa-cli">
35
+ <img src="https://img.shields.io/codecov/c/github/browniebroke/stsmfa-cli.svg?logo=codecov&logoColor=fff&style=flat-square" alt="Test coverage percentage">
36
+ </a>
37
+ </p>
38
+ <p align="center">
39
+ <a href="https://github.com/astral-sh/uv">
40
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
41
+ </a>
42
+ <a href="https://github.com/astral-sh/ruff">
43
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
44
+ </a>
45
+ <a href="https://github.com/pre-commit/pre-commit">
46
+ <img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
47
+ </a>
48
+ </p>
49
+ <p align="center">
50
+ <a href="https://pypi.org/project/stsmfa-cli/">
51
+ <img src="https://img.shields.io/pypi/v/stsmfa-cli.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
52
+ </a>
53
+ <img src="https://img.shields.io/pypi/pyversions/stsmfa-cli.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
54
+ <img src="https://img.shields.io/pypi/l/stsmfa-cli.svg?style=flat-square" alt="License">
55
+ </p>
56
+
57
+ ---
58
+
59
+ **Source Code**: <a href="https://github.com/browniebroke/stsmfa-cli" target="_blank">https://github.com/browniebroke/stsmfa-cli </a>
60
+
61
+ ---
62
+
63
+ Creating temporary profiles for multi-factor auth (MFA) protected accounts using AWS STS is too hard. This is a small CLI that helps with that.
64
+
65
+ ## Installation
66
+
67
+ Via Homebrew:
68
+
69
+ ```bash
70
+ brew install browniebroke/tap/stsmfa-cli
71
+ ```
72
+
73
+ Via uv, or your favourite Python package manager:
74
+
75
+ ```bash
76
+ uv tool install stsmfa-cli
77
+ ```
78
+
79
+ ## Usage
80
+
81
+ The CLI is a simple command `stsmfa` that creates a profile for a temporary session protected by MFA.
82
+
83
+ Assuming your `~/.aws/credentials` file looks like this:
84
+
85
+ ```ini
86
+ [my-profile-name]
87
+ aws_access_key_id = AKIAXXXXX
88
+ aws_secret_access_key = xxxx
89
+ mfa_serial = arn:aws:iam::123456789010:mfa/first.last
90
+ ```
91
+
92
+ When running, for example:
93
+
94
+ ```bash
95
+ awsmfa --profile my-profile-name 123456
96
+ ```
97
+
98
+ This will create a session using the MFA serial defined under `my-profile-name` with the one-time password `123456`, and save the required AWS key, secret and token under as a new profile `my-profile-name-mfa` in you `~/.aws/credentials` file.
99
+
100
+ Now to use that session, you just need to set `AWS_PROFILE=my-profile-name-mfa`.
101
+
102
+ If your MFA serial is defined under the default profile, you don't need to specify the `--profile` option.
103
+
104
+ ## Contributors ✨
105
+
106
+ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
107
+
108
+ <!-- prettier-ignore-start -->
109
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
110
+ <!-- prettier-ignore-start -->
111
+ <!-- markdownlint-disable -->
112
+ <table>
113
+ <tbody>
114
+ <tr>
115
+ <td align="center" valign="top" width="14.28%"><a href="https://browniebroke.com/"><img src="https://avatars.githubusercontent.com/u/861044?v=4?s=80" width="80px;" alt="Bruno Alla"/><br /><sub><b>Bruno Alla</b></sub></a><br /><a href="https://github.com/browniebroke/stsmfa-cli/commits?author=browniebroke" title="Code">💻</a> <a href="#ideas-browniebroke" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/browniebroke/stsmfa-cli/commits?author=browniebroke" title="Documentation">📖</a></td>
116
+ </tr>
117
+ </tbody>
118
+ </table>
119
+
120
+ <!-- markdownlint-restore -->
121
+ <!-- prettier-ignore-end -->
122
+
123
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
124
+ <!-- prettier-ignore-end -->
125
+
126
+ This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
127
+
128
+ ## Credits
129
+
130
+ This package was created with
131
+ [Copier](https://copier.readthedocs.io/) and the
132
+ [browniebroke/pypackage-template](https://github.com/browniebroke/pypackage-template)
133
+ project template.
@@ -0,0 +1,15 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ src/stsmfa/__init__.py
6
+ src/stsmfa/__maIn__.py
7
+ src/stsmfa/cli.py
8
+ src/stsmfa/py.typed
9
+ src/stsmfa_cli.egg-info/PKG-INFO
10
+ src/stsmfa_cli.egg-info/SOURCES.txt
11
+ src/stsmfa_cli.egg-info/dependency_links.txt
12
+ src/stsmfa_cli.egg-info/entry_points.txt
13
+ src/stsmfa_cli.egg-info/requires.txt
14
+ src/stsmfa_cli.egg-info/top_level.txt
15
+ tests/test_cli.py
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ awsmfa = stsmfa.cli:app
3
+ stsmfa = stsmfa.cli:app
@@ -0,0 +1,3 @@
1
+ boto3<2,>=1.26
2
+ rich>=10
3
+ typer<1,>=0.15
@@ -0,0 +1,87 @@
1
+ from pathlib import Path
2
+
3
+ import pytest
4
+ from click.exceptions import Exit
5
+
6
+ from stsmfa.cli import run
7
+
8
+ HOME_PATH = Path.home()
9
+ CREDS_PATH = Path.home() / ".aws" / "credentials"
10
+
11
+
12
+ class TestRun:
13
+ @pytest.fixture()
14
+ def rich_print(self, mocker):
15
+ return mocker.patch("stsmfa.cli.print")
16
+
17
+ def test_no_file(self, fs, rich_print):
18
+ with pytest.raises(Exit):
19
+ run(token="123456", profile="dummy", mfa_profile="") # noqa: S106
20
+ rich_print.assert_called_once_with(
21
+ f"[red]Credentials file not found at {CREDS_PATH}[/red]"
22
+ )
23
+
24
+ def test_profile_missing(self, fs, rich_print):
25
+ fs.create_file(CREDS_PATH)
26
+ with pytest.raises(Exit):
27
+ run(token="123456", profile="dummy", mfa_profile="") # noqa: S106
28
+ rich_print.assert_called_once_with(
29
+ "[red]Profile dummy not found in credentials file " f"{CREDS_PATH}[/red]"
30
+ )
31
+
32
+ def test_mfa_device_missing(self, fs, rich_print):
33
+ fs.create_file(CREDS_PATH, contents="[dummy]\n")
34
+ with pytest.raises(Exit):
35
+ run(token="123456", profile="dummy", mfa_profile="") # noqa: S106
36
+ rich_print.assert_called_once_with(
37
+ "[red]Profile dummy does not have an mfa_serial configured[/red]"
38
+ )
39
+
40
+ def test_get_sts_error(self, fs, rich_print, mocker):
41
+ fs.create_file(
42
+ CREDS_PATH,
43
+ contents="[dummy]\nmfa_serial = arn:aws:iam::123456789012:mfa/dummy\n",
44
+ )
45
+
46
+ boto3 = mocker.patch("stsmfa.cli.boto3")
47
+ sts = boto3.Session.return_value.client.return_value
48
+ sts.get_session_token.side_effect = Exception("SOME ERROR")
49
+
50
+ with pytest.raises(Exit):
51
+ run(token="123456", profile="dummy", mfa_profile="") # noqa: S106
52
+
53
+ rich_print.assert_called_once_with(
54
+ "[red]Error getting session token: SOME ERROR[/red]"
55
+ )
56
+
57
+ def test_get_sts_ok(self, fs, rich_print, mocker):
58
+ fs.create_file(
59
+ CREDS_PATH,
60
+ contents="[dummy]\nmfa_serial = arn:aws:iam::123456789012:mfa/dummy\n",
61
+ )
62
+
63
+ boto3 = mocker.patch("stsmfa.cli.boto3")
64
+ sts = boto3.Session.return_value.client.return_value
65
+ sts.get_session_token.return_value = {
66
+ "Credentials": {
67
+ "AccessKeyId": "AKSOMEACCESSKEY",
68
+ "SecretAccessKey": "SOMESECRET",
69
+ "SessionToken": "SOMETOKEN",
70
+ }
71
+ }
72
+
73
+ run(token="123456", profile="dummy", mfa_profile="") # noqa: S106
74
+
75
+ rich_print.assert_called_once_with(
76
+ f"[green]All written to dummy-mfa profile in {CREDS_PATH}[/green]"
77
+ )
78
+ assert Path(CREDS_PATH).read_text() == (
79
+ "[dummy]\n"
80
+ "mfa_serial = arn:aws:iam::123456789012:mfa/dummy\n"
81
+ "\n"
82
+ "[dummy-mfa]\n"
83
+ "aws_access_key_id = AKSOMEACCESSKEY\n"
84
+ "aws_secret_access_key = SOMESECRET\n"
85
+ "aws_session_token = SOMETOKEN\n"
86
+ "\n"
87
+ )
@@ -1 +0,0 @@
1
- __version__ = "1.4.6"
File without changes
File without changes