Skip to content

Commit da3c8b1

Browse files
Merge pull request #41 from hhslepicka/enh/credentials-methods
ENH: Add update and remove methods to credential handling.
2 parents 3422925 + 522ebc5 commit da3c8b1

File tree

2 files changed

+83
-10
lines changed

2 files changed

+83
-10
lines changed

botcity/maestro/sdk.py

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ def get_credential(self, label: str, key: str) -> str:
10431043
@ensure_access_token()
10441044
def create_credential(self, label: str, key: str, value):
10451045
"""
1046-
Create credential
1046+
Create credential in a credentials set
10471047
Args:
10481048
label: Credential set name
10491049
key: Key name within the credential set
@@ -1052,7 +1052,10 @@ def create_credential(self, label: str, key: str, value):
10521052
credential = self._get_credential_by_label(label=label)
10531053

10541054
if credential is None:
1055-
response = self._create_credential_by_label(label=label, key=key, value=value)
1055+
secrets = [
1056+
{'key': key, 'value': value, 'valid': True}
1057+
]
1058+
response = self._create_credential_by_label(label=label, secrets=secrets)
10561059
if response is None:
10571060
raise ValueError('Error during create credential.')
10581061
return response.to_json()
@@ -1067,28 +1070,73 @@ def create_credential(self, label: str, key: str, value):
10671070
if not req.ok:
10681071
req.raise_for_status()
10691072

1070-
def _get_credential_by_label(self, label):
1073+
@since_version("3.0.0")
1074+
@ensure_access_token()
1075+
def update_credential(self, label: str, key: str, new_value):
1076+
"""Update a credential with a new value
1077+
Args:
1078+
label: Credential set name
1079+
key: Key name within the credential set
1080+
new_value: Credential new value
1081+
"""
1082+
credential = self._get_credential_by_label(label=label, raise_exception=True)
1083+
secrets = credential.get("secrets", [])
1084+
index = self._get_secrets_key_index(label=label, key=key, secrets=secrets)
1085+
secrets[index]['value'] = new_value
1086+
self._edit_credential_by_label(label, secrets=secrets)
1087+
1088+
@since_version("3.0.0")
1089+
@ensure_access_token()
1090+
def remove_credential(self, label: str, key: str):
1091+
"""Removes a credential from the set
1092+
Args:
1093+
label: Credential set name
1094+
key: Key name within the credential set
1095+
"""
1096+
credential = self._get_credential_by_label(label=label, raise_exception=True)
1097+
secrets = credential.get("secrets", [])
1098+
index = self._get_secrets_key_index(label=label, key=key, secrets=secrets)
1099+
del secrets[index]
1100+
self._edit_credential_by_label(label, secrets=secrets)
1101+
1102+
def _get_secrets_key_index(self, label: str, key: str, secrets: list):
1103+
"""
1104+
Find and return the index of a given key in the secrets list.
1105+
Args:
1106+
label: Credential set name
1107+
key: Key name within the credential set
1108+
secrets: List of secret dictionary entries
1109+
Returns:
1110+
The key index or None in case it is not found
1111+
"""
1112+
index = next((i for i, d in enumerate(secrets) if d.get('key') == key), None)
1113+
if index is None:
1114+
raise ValueError(f"Key '{key}' does not exist in credential set '{label}'.")
1115+
return index
1116+
1117+
def _get_credential_by_label(self, label, raise_exception: bool = False):
10711118
"""
10721119
Get dict in key inside credentials
10731120
Args:
10741121
label: Credential set name
1122+
raise_exception: Whether or not to raise exception in case the credential set is not found
10751123
Returns:
10761124
Credential dict
10771125
"""
10781126
url = f'{self._server}/api/v2/credential/{label}'
10791127

10801128
with requests.get(url, headers=self._headers(), timeout=self._timeout, verify=self.VERIFY_SSL_CERT) as req:
10811129
if req.ok:
1082-
return model.ServerMessage.from_json(req.text)
1130+
return json.loads(model.ServerMessage.from_json(req.text).payload)
10831131
else:
1132+
if raise_exception:
1133+
req.raise_for_status()
10841134
return None
10851135

1086-
def _create_credential_by_label(self, label: str, key: str, value):
1136+
def _create_credential_by_label(self, label: str, secrets: list):
10871137
data = {
10881138
'label': label,
1089-
'secrets': [
1090-
{'key': key, 'value': value, 'valid': True}
1091-
]
1139+
'secrets': secrets
10921140
}
10931141
url = f'{self._server}/api/v2/credential'
10941142

@@ -1097,8 +1145,21 @@ def _create_credential_by_label(self, label: str, key: str, value):
10971145
) as req:
10981146
if req.ok:
10991147
return model.ServerMessage.from_json(req.text)
1100-
else:
1101-
return None
1148+
req.raise_for_status()
1149+
1150+
def _edit_credential_by_label(self, label: str, secrets: list):
1151+
data = {
1152+
'label': label,
1153+
'secrets': secrets
1154+
}
1155+
url = f'{self._server}/api/v2/credential/{label}'
1156+
1157+
with requests.post(
1158+
url, json=data, headers=self._headers(), timeout=self._timeout, verify=self.VERIFY_SSL_CERT
1159+
) as req:
1160+
if req.ok:
1161+
return model.ServerMessage.from_json(req.text)
1162+
req.raise_for_status()
11021163

11031164
@since_version("3.0.2")
11041165
@ensure_access_token()

tests/integration/test_credential.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,15 @@ def test_create_credential(maestro: BotMaestroSDK, credential_label, credential_
1313
def test_get_credential(maestro: BotMaestroSDK, credential_label, credential_key):
1414
credential = maestro.get_credential(label=credential_label, key=credential_key)
1515
assert credential == 'testing'
16+
17+
@pytest.mark.depends(on=["test_get_credential"])
18+
def test_update_credential(maestro: BotMaestroSDK, credential_label, credential_key):
19+
maestro.update_credential(label=credential_label, key=credential_key, new_value="testing-update")
20+
credential = maestro.get_credential(label=credential_label, key=credential_key)
21+
assert credential == 'testing-update'
22+
23+
@pytest.mark.depends(on=["test_update_credential"])
24+
def test_remove_credential(maestro: BotMaestroSDK, credential_label, credential_key):
25+
maestro.remove_credential(label=credential_label, key=credential_key)
26+
with pytest.raises(ValueError):
27+
maestro.get_credential(label=credential_label, key=credential_key)

0 commit comments

Comments
 (0)