mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
fix(virtsecrets): saving a secret's value unchanged keeps it
get_secret_value returned bytes, so the edit dialog showed b'cHc=' (the bytes' repr) for the base64 value cHc=. Saving the dialog as shown fed "b'cHc='" to b64decode, which dropped the quotes and the b and stored other bytes: the secret silently changed (pw became m\xc1\xdc). The value is now base64 text, and set_secret_value decodes with validate=True, so a value that is not base64 is refused with a message instead. The field had an invalid pattern ([a-zA-Z0-9]$+, ignored by browsers) and a 45 character limit; it takes base64 of any length.
This commit is contained in:
parent
eb828b364d
commit
f4cdd91210
3 changed files with 28 additions and 5 deletions
|
|
@ -96,7 +96,7 @@
|
|||
<label class="col-sm-3 col-form-label">{% trans "Value" %}</label>
|
||||
<input type="hidden" name="uuid" value="{{ secret.uuid }}">
|
||||
<div class="col-sm-6">
|
||||
<input type="text" name="value" class="form-control" value="{{ secret.value }}" maxlength="45" required pattern="[a-zA-Z0-9]$+">
|
||||
<input type="text" name="value" class="form-control" value="{{ secret.value }}" required pattern="[A-Za-z0-9+\/]*={0,2}">
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- /.modal-content -->
|
||||
|
|
|
|||
|
|
@ -26,3 +26,26 @@ class CreateSecretTests(SimpleTestCase):
|
|||
self.assertEqual((secret.get("ephemeral"), secret.get("private")), ("no", "yes"))
|
||||
self.assertEqual(secret.find("usage").get("type"), usage_type)
|
||||
self.assertEqual(secret.findtext(f"usage/{element}"), data)
|
||||
|
||||
|
||||
class SecretValueTests(SimpleTestCase):
|
||||
def secrets(self):
|
||||
with patch("vrtManager.connection.connection_manager.get_connection") as get:
|
||||
conn = wvmSecrets("host", "login", "pw", 1)
|
||||
secret = get.return_value.secretLookupByUUIDString.return_value
|
||||
return conn, secret
|
||||
|
||||
def test_the_shown_value_written_back_keeps_the_secret(self):
|
||||
conn, secret = self.secrets()
|
||||
secret.value.return_value = b"pw\x00\xff"
|
||||
shown = conn.get_secret_value("uuid")
|
||||
self.assertEqual(shown, "cHcA/w==") # base64 text, what the edit dialog shows
|
||||
conn.set_secret_value("uuid", shown)
|
||||
secret.setValue.assert_called_once_with(b"pw\x00\xff")
|
||||
|
||||
def test_a_value_that_is_not_base64_is_refused(self):
|
||||
conn, secret = self.secrets()
|
||||
for value in ("b'cHc='", "not base64!"):
|
||||
with self.subTest(value=value), self.assertRaises(ValueError):
|
||||
conn.set_secret_value("uuid", value)
|
||||
secret.setValue.assert_not_called()
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ class wvmSecrets(wvmConnect):
|
|||
self.wvm.secretDefineXML(etree.tostring(secret, encoding="unicode"))
|
||||
|
||||
def get_secret_value(self, uuid):
|
||||
"""The value as base64 text, the form set_secret_value takes."""
|
||||
secrt = self.get_secret(uuid)
|
||||
value = secrt.value()
|
||||
return base64.b64encode(value)
|
||||
return base64.b64encode(secrt.value()).decode()
|
||||
|
||||
def set_secret_value(self, uuid, value):
|
||||
secrt = self.get_secret(uuid)
|
||||
value = base64.b64decode(value)
|
||||
secrt.setValue(value)
|
||||
# validate: a value that is not base64 is refused, not decoded to other bytes
|
||||
secrt.setValue(base64.b64decode(value, validate=True))
|
||||
|
||||
def delete_secret(self, uuid):
|
||||
secrt = self.get_secret(uuid)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue