proxygen-cli 3.0.1__tar.gz → 4.0.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.
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/PKG-INFO +2 -2
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_credentials.py +14 -8
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_settings.py +12 -3
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/constants.py +0 -3
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/credentials.py +4 -6
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/settings.py +2 -2
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/command_credentials_test.py +27 -22
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/command_settings_test.py +1 -1
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/validate_cli_version_test.py +1 -1
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/pyproject.toml +2 -2
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/README.md +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/__init__.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_docker.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_instance.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_main.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_pytest_nhsd_apim_token.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_secret.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_spec.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/auth.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/dot_proxygen.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/output.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/proxygen_api.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/spec.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/spec_server.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/lib/version.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/__init__.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/command_instance_test.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/command_main_test.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/command_pytest_nhsd_apim_token_test.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/command_secret_test.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/command_spec_test.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/conftest.py +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/fixtures/client.key +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/fixtures/client.pem +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/fixtures/secret.txt +0 -0
- {proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/mock_private_key.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: proxygen-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.0.0
|
|
4
4
|
Summary: CLI for interacting with NHSD APIM's proxygen service
|
|
5
5
|
Author: Ben Strutt
|
|
6
6
|
Author-email: ben.strutt1@nhs.net
|
|
@@ -16,7 +16,7 @@ Requires-Dist: pydantic (>=1.9.1,<2.0.0)
|
|
|
16
16
|
Requires-Dist: pyjwt (>=2.9.0,<3.0.0)
|
|
17
17
|
Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
|
|
18
18
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
19
|
-
Requires-Dist: tabulate (>=0.9
|
|
19
|
+
Requires-Dist: tabulate (>=0.9,<0.11)
|
|
20
20
|
Requires-Dist: yaspin (>=3.2.0,<4.0.0)
|
|
21
21
|
Project-URL: Repository, https://github.com/NHSDigital/proxygen-cli
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
@@ -42,11 +42,11 @@ def get(key):
|
|
|
42
42
|
creds = get_credentials()
|
|
43
43
|
click.echo(getattr(creds, key))
|
|
44
44
|
|
|
45
|
-
|
|
46
45
|
@credentials.command()
|
|
47
46
|
@click.argument("custom_pairs", nargs=-1, metavar="KEY VALUE", required=False)
|
|
48
47
|
@click.option("--force", is_flag=True, help="Force re-entry of standard credentials")
|
|
49
|
-
|
|
48
|
+
@click.option("--env", type=click.Choice(["prod", "ptl"], case_sensitive=False), default="prod", help="Environment to use for authentication")
|
|
49
|
+
def set(custom_pairs, force, env):
|
|
50
50
|
"""
|
|
51
51
|
Write a value to your credentials.
|
|
52
52
|
"""
|
|
@@ -55,16 +55,22 @@ def set(custom_pairs, force):
|
|
|
55
55
|
|
|
56
56
|
current_credentials = _yaml_credentials_file_source(None)
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
KEYCLOAK_URLS = {
|
|
59
|
+
"prod": "https://identity.prod.api.platform.nhs.uk/realms/api-producers",
|
|
60
|
+
"ptl": "https://identity.ptl.api.platform.nhs.uk/realms/api-producers",
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
current_credentials["base_url"] = KEYCLOAK_URLS[env.lower()]
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
context = click.get_current_context()
|
|
66
|
+
if ("private_key_path" not in context.params["custom_pairs"]):
|
|
67
|
+
client_id = click.prompt("Enter client ID", default="", show_default=False)
|
|
68
|
+
client_secret = click.prompt("Enter client secret", default="", show_default=False)
|
|
65
69
|
username = click.prompt("Enter username", default="", show_default=False)
|
|
66
70
|
password = click.prompt("Enter password", default="", show_default=False)
|
|
67
71
|
|
|
72
|
+
current_credentials["client_id"] = client_id
|
|
73
|
+
current_credentials["client_secret"] = client_secret
|
|
68
74
|
current_credentials["username"] = username
|
|
69
75
|
current_credentials["password"] = password
|
|
70
76
|
|
|
@@ -19,7 +19,6 @@ def settings():
|
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
def _get_setting(key):
|
|
24
23
|
return getattr(SETTINGS, key)
|
|
25
24
|
|
|
@@ -31,6 +30,7 @@ def list():
|
|
|
31
30
|
"""
|
|
32
31
|
output.print_spec(json.loads(SETTINGS.json(exclude_none=True)))
|
|
33
32
|
|
|
33
|
+
|
|
34
34
|
@settings.command()
|
|
35
35
|
@click.argument("key", type=CHOICE_OF_SETTINGS_KEYS)
|
|
36
36
|
def get(key):
|
|
@@ -43,14 +43,23 @@ def get(key):
|
|
|
43
43
|
@settings.command()
|
|
44
44
|
@click.argument("key", type=CHOICE_OF_SETTINGS_KEYS)
|
|
45
45
|
@click.argument("value")
|
|
46
|
-
|
|
46
|
+
@click.option("--env", type=click.Choice(["prod", "ptl"], case_sensitive=False), default="prod", help="Environment to use for authentication")
|
|
47
|
+
def set(key, value, env):
|
|
47
48
|
"""
|
|
48
49
|
Write a value to your settings.
|
|
49
50
|
"""
|
|
50
51
|
_get_setting(key)
|
|
51
52
|
|
|
52
53
|
current_settings = _yaml_settings_file_source(None)
|
|
54
|
+
|
|
55
|
+
PROXYGEN_URLS = {
|
|
56
|
+
"prod": "https://proxygen.prod.api.platform.nhs.uk",
|
|
57
|
+
"ptl": "https://proxygen.ptl.api.platform.nhs.uk",
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
current_settings["endpoint_url"] = PROXYGEN_URLS[env.lower()]
|
|
53
61
|
current_settings[key] = value
|
|
62
|
+
|
|
54
63
|
try:
|
|
55
64
|
new_settings = json.loads(Settings(**current_settings).json(exclude_none=True))
|
|
56
65
|
except pydantic.ValidationError as e:
|
|
@@ -71,4 +80,4 @@ def rm(key):
|
|
|
71
80
|
current_settings = _yaml_settings_file_source(None)
|
|
72
81
|
current_settings.pop(key, None)
|
|
73
82
|
with settings_file().open("w") as f:
|
|
74
|
-
yaml.safe_dump(current_settings, f)
|
|
83
|
+
yaml.safe_dump(current_settings, f)
|
|
@@ -31,13 +31,11 @@ def create_yaml_credentials_file():
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class Credentials(BaseSettings):
|
|
34
|
-
base_url: AnyHttpUrl
|
|
35
|
-
"https://identity.prod.api.platform.nhs.uk/realms/api-producers"
|
|
36
|
-
)
|
|
34
|
+
base_url: AnyHttpUrl
|
|
37
35
|
private_key_path: Optional[str] = None
|
|
38
36
|
key_id: Optional[str] = None
|
|
39
|
-
client_id: str =
|
|
40
|
-
client_secret: Optional[str] =
|
|
37
|
+
client_id: Optional[str] = None
|
|
38
|
+
client_secret: Optional[str] = None
|
|
41
39
|
username: Optional[str] = None
|
|
42
40
|
password: Optional[str] = None
|
|
43
41
|
|
|
@@ -137,4 +135,4 @@ def initialise_credentials():
|
|
|
137
135
|
def get_credentials():
|
|
138
136
|
initialise_credentials()
|
|
139
137
|
global _CREDENTIALS
|
|
140
|
-
return _CREDENTIALS
|
|
138
|
+
return _CREDENTIALS
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Literal
|
|
1
|
+
from typing import Literal, Optional
|
|
2
2
|
from pydantic import BaseSettings, AnyUrl
|
|
3
3
|
|
|
4
4
|
import yaml
|
|
@@ -13,7 +13,7 @@ def _yaml_settings_file_source(_):
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class Settings(BaseSettings):
|
|
16
|
-
endpoint_url: AnyUrl =
|
|
16
|
+
endpoint_url: Optional[AnyUrl] = None
|
|
17
17
|
spec_output_format: Literal["json", "yaml"] = "yaml"
|
|
18
18
|
api: str = None
|
|
19
19
|
|
|
@@ -10,10 +10,13 @@ import proxygen_cli.cli.command_credentials as cmd_credentials
|
|
|
10
10
|
from proxygen_cli.lib.credentials import Credentials
|
|
11
11
|
CLIENT_ID = os.environ["PROXYGEN_CLIENT_ID"]
|
|
12
12
|
CLIENT_SECRET = os.environ["PROXYGEN_CLIENT_SECRET"]
|
|
13
|
+
KEYCLOAK_URL = "https://identity.prod.api.platform.nhs.uk/realms/api-producers"
|
|
14
|
+
MOCK_KEYCLOAK_URL = "https://mock-keycloak-url.nhs.uk"
|
|
15
|
+
BASE_URL_LABEL = "base_url: "
|
|
13
16
|
|
|
14
17
|
def get_test_credentials(**kwargs):
|
|
15
18
|
base_credentials = {
|
|
16
|
-
"base_url":
|
|
19
|
+
"base_url": MOCK_KEYCLOAK_URL,
|
|
17
20
|
"client_id": "mock-api-client",
|
|
18
21
|
"client_secret": "1a2f4g5",
|
|
19
22
|
"password": "mock-password",
|
|
@@ -31,7 +34,7 @@ def get_test_credentials(**kwargs):
|
|
|
31
34
|
#get mock values for credentials.yaml file
|
|
32
35
|
def get_test_proxygen_client_credentials(**kwargs):
|
|
33
36
|
client_credentials = {
|
|
34
|
-
"base_url":
|
|
37
|
+
"base_url": MOCK_KEYCLOAK_URL,
|
|
35
38
|
"client_id": CLIENT_ID,
|
|
36
39
|
"client_secret": CLIENT_SECRET,
|
|
37
40
|
"password": "mock-password",
|
|
@@ -52,11 +55,12 @@ def test_set_proxygen_user_credential(patch_config, credentials_file):
|
|
|
52
55
|
|
|
53
56
|
with patch_config(credentials=mock_credentials):
|
|
54
57
|
runner = CliRunner()
|
|
55
|
-
|
|
58
|
+
input_data = "\n".join([CLIENT_ID, CLIENT_SECRET, "new-username", "mock-password"])
|
|
59
|
+
runner.invoke(cmd_credentials.set,[],input=input_data,)
|
|
56
60
|
|
|
57
61
|
expected_credentials = "\n".join(
|
|
58
62
|
[
|
|
59
|
-
|
|
63
|
+
BASE_URL_LABEL + KEYCLOAK_URL,
|
|
60
64
|
"client_id: "+CLIENT_ID,
|
|
61
65
|
"client_secret: "+CLIENT_SECRET,
|
|
62
66
|
"password: mock-password",
|
|
@@ -84,12 +88,12 @@ def test_update_proxygen_user_credentials(patch_config, credentials_file):
|
|
|
84
88
|
|
|
85
89
|
with patch_config(credentials=mock_credentials):
|
|
86
90
|
runner = CliRunner()
|
|
87
|
-
|
|
88
|
-
runner.invoke(cmd_credentials.set,
|
|
91
|
+
input_data = "\n".join([CLIENT_ID, CLIENT_SECRET, "new-username123", "new-password123"])
|
|
92
|
+
runner.invoke(cmd_credentials.set,[],input=input_data,)
|
|
89
93
|
|
|
90
94
|
expected_credentials = "\n".join(
|
|
91
95
|
[
|
|
92
|
-
|
|
96
|
+
BASE_URL_LABEL + KEYCLOAK_URL,
|
|
93
97
|
"client_id: "+CLIENT_ID,
|
|
94
98
|
"client_secret: "+CLIENT_SECRET,
|
|
95
99
|
"password: new-password123",
|
|
@@ -117,16 +121,16 @@ def test_update_proxygen_client_credentials(patch_config, credentials_file):
|
|
|
117
121
|
|
|
118
122
|
with patch_config(credentials=mock_credentials):
|
|
119
123
|
runner = CliRunner()
|
|
120
|
-
|
|
121
|
-
runner.invoke(cmd_credentials.set,
|
|
124
|
+
input_data = "\n".join(["new-clientid123", "new-clientsecret123", "new-user", "new-password"])
|
|
125
|
+
runner.invoke(cmd_credentials.set,[],input=input_data,)
|
|
122
126
|
|
|
123
127
|
expected_credentials = "\n".join(
|
|
124
128
|
[
|
|
125
|
-
|
|
129
|
+
BASE_URL_LABEL + KEYCLOAK_URL,
|
|
126
130
|
"client_id: new-clientid123",
|
|
127
131
|
"client_secret: new-clientsecret123",
|
|
128
|
-
"password:
|
|
129
|
-
"username:
|
|
132
|
+
"password: new-password",
|
|
133
|
+
"username: new-user",
|
|
130
134
|
]
|
|
131
135
|
)
|
|
132
136
|
|
|
@@ -207,13 +211,14 @@ def test_set_credential(patch_config, credentials_file):
|
|
|
207
211
|
|
|
208
212
|
with patch_config(credentials=mock_credentials):
|
|
209
213
|
runner = CliRunner()
|
|
210
|
-
|
|
214
|
+
input_data = "\n".join(["mock-api-client", "mock-api-clientsecret", "new-username", "mock-password"])
|
|
215
|
+
runner.invoke(cmd_credentials.set,[],input=input_data,)
|
|
211
216
|
|
|
212
217
|
expected_credentials = "\n".join(
|
|
213
218
|
[
|
|
214
|
-
|
|
219
|
+
BASE_URL_LABEL + KEYCLOAK_URL,
|
|
215
220
|
"client_id: mock-api-client",
|
|
216
|
-
"client_secret:
|
|
221
|
+
"client_secret: mock-api-clientsecret",
|
|
217
222
|
"password: mock-password",
|
|
218
223
|
"username: new-username",
|
|
219
224
|
]
|
|
@@ -235,13 +240,14 @@ def test_update_credentials(patch_config, credentials_file):
|
|
|
235
240
|
|
|
236
241
|
with patch_config(credentials=mock_credentials):
|
|
237
242
|
runner = CliRunner()
|
|
238
|
-
|
|
243
|
+
input_data = "\n".join(["mock-api-client", "mock-api-clientsecret", "new-username123", "mock-password"])
|
|
244
|
+
runner.invoke(cmd_credentials.set,[],input=input_data,)
|
|
239
245
|
|
|
240
246
|
expected_credentials = "\n".join(
|
|
241
247
|
[
|
|
242
|
-
|
|
248
|
+
BASE_URL_LABEL + KEYCLOAK_URL,
|
|
243
249
|
"client_id: mock-api-client",
|
|
244
|
-
"client_secret:
|
|
250
|
+
"client_secret: mock-api-clientsecret",
|
|
245
251
|
"password: mock-password",
|
|
246
252
|
"username: new-username123", # Updated value
|
|
247
253
|
]
|
|
@@ -260,10 +266,9 @@ def test_add_key_id(patch_config, credentials_file):
|
|
|
260
266
|
|
|
261
267
|
expected_credentials = "\n".join(
|
|
262
268
|
[
|
|
263
|
-
|
|
269
|
+
BASE_URL_LABEL + MOCK_KEYCLOAK_URL,
|
|
264
270
|
"client_id: mock-api-client",
|
|
265
271
|
"client_secret: 1a2f4g5",
|
|
266
|
-
"key_id: test_kid",
|
|
267
272
|
"password: mock-password",
|
|
268
273
|
"username: mock-user",
|
|
269
274
|
]
|
|
@@ -279,7 +284,7 @@ def test_set_invalid_setting(patch_config):
|
|
|
279
284
|
runner = CliRunner()
|
|
280
285
|
result = runner.invoke(cmd_credentials.set, ["invalid", "new-username"])
|
|
281
286
|
|
|
282
|
-
assert "
|
|
287
|
+
assert "Enter client ID:Aborted!" in result.output.strip()
|
|
283
288
|
|
|
284
289
|
|
|
285
290
|
def test_set_invalid_private_key_path(patch_config):
|
|
@@ -302,7 +307,7 @@ def test_remove_setting(patch_config, credentials_file):
|
|
|
302
307
|
|
|
303
308
|
expected_credentials = "\n".join(
|
|
304
309
|
[
|
|
305
|
-
|
|
310
|
+
BASE_URL_LABEL + MOCK_KEYCLOAK_URL,
|
|
306
311
|
"client_id: mock-api-client",
|
|
307
312
|
"client_secret: 1a2f4g5",
|
|
308
313
|
"password: mock-password",
|
|
@@ -73,7 +73,7 @@ def test_set_setting(patch_config, settings_file):
|
|
|
73
73
|
expected_settings = "\n".join(
|
|
74
74
|
[
|
|
75
75
|
"api: new_api_name",
|
|
76
|
-
"endpoint_url: https://
|
|
76
|
+
"endpoint_url: https://proxygen.prod.api.platform.nhs.uk",
|
|
77
77
|
"spec_output_format: json",
|
|
78
78
|
]
|
|
79
79
|
)
|
|
@@ -13,7 +13,7 @@ def test_validate_cli_version_success(patch_request):
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def test_validate_cli_version_failure(patch_request):
|
|
16
|
-
required_version = "
|
|
16
|
+
required_version = "5.0.0"
|
|
17
17
|
|
|
18
18
|
mocked_response = {"proxygen_cli": {"min_version": required_version}}
|
|
19
19
|
with patch_request(200, mocked_response), pytest.raises(RuntimeError) as e:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "proxygen-cli"
|
|
3
|
-
version = "
|
|
3
|
+
version = "4.0.0"
|
|
4
4
|
description = "CLI for interacting with NHSD APIM's proxygen service"
|
|
5
5
|
authors = ["Ben Strutt <ben.strutt1@nhs.net>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -20,7 +20,7 @@ lxml = "^6.0.1"
|
|
|
20
20
|
cryptography = ">= 44.0.1, < 47.0.0" # Not directly imported, but needed by pyjwt for the RS512 algorithm
|
|
21
21
|
pyyaml = "^6.0.3"
|
|
22
22
|
yaspin = "^3.2.0"
|
|
23
|
-
tabulate = "
|
|
23
|
+
tabulate = ">=0.9,<0.11"
|
|
24
24
|
packaging = "^24.2"
|
|
25
25
|
|
|
26
26
|
[tool.poetry.group.dev.dependencies]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/cli/command_pytest_nhsd_apim_token.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proxygen_cli-3.0.1 → proxygen_cli-4.0.0}/proxygen_cli/test/command_pytest_nhsd_apim_token_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|