From 05d4fa846fd2502695d58ec1fc47dd46c7b6f9a1 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sun, 15 Sep 2013 23:49:15 +0200 Subject: [PATCH] config: Deserialize Secret to unicode (fix #473) MPD, Scrobbler, and Spotify extensions have been reviewed for need for changes due to this, without anything being found. --- docs/changelog.rst | 5 +++++ mopidy/config/types.py | 26 +++++++++----------------- tests/config/types_test.py | 8 ++++---- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 1b08a742..42a8f60b 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -64,6 +64,11 @@ v0.15.0 (UNRELEASED) The methods are still not implemented, but now the commands are accepted as valid. +**Extension support** + +- :class:`~mopidy.config.Secret` is now deserialized to unicode strings instead + of bytestrings. This may require modifications to extensions. + v0.14.2 (2013-07-01) ==================== diff --git a/mopidy/config/types.py b/mopidy/config/types.py index d3cd2462..d264de30 100644 --- a/mopidy/config/types.py +++ b/mopidy/config/types.py @@ -82,30 +82,22 @@ class String(ConfigValue): return encode(value) -class Secret(ConfigValue): - """Secret value. +class Secret(String): + """Secret string value. - Should be used for passwords, auth tokens etc. Deserializing will not - convert to unicode. Will mask value when being displayed. + Is decoded as utf-8 and \\n \\t escapes should work and be preserved. + + Should be used for passwords, auth tokens etc. Will mask value when being + displayed. """ def __init__(self, optional=False, choices=None): self._required = not optional - - def deserialize(self, value): - value = value.strip() - validators.validate_required(value, self._required) - if not value: - return None - return value + self._choices = None # Choices doesn't make sense for secrets def serialize(self, value, display=False): - if isinstance(value, unicode): - value = value.encode('utf-8') - if value is None: - return b'' - elif display: + if value is not None and display: return b'********' - return value + return super(Secret, self).serialize(value, display) class Integer(ConfigValue): diff --git a/tests/config/types_test.py b/tests/config/types_test.py index 74e9672d..0df3dfb4 100644 --- a/tests/config/types_test.py +++ b/tests/config/types_test.py @@ -105,11 +105,11 @@ class StringTest(unittest.TestCase): class SecretTest(unittest.TestCase): - def test_deserialize_passes_through(self): + def test_deserialize_decodes_utf8(self): value = types.Secret() - result = value.deserialize(b'foo') - self.assertIsInstance(result, bytes) - self.assertEqual(b'foo', result) + result = value.deserialize('æøå'.encode('utf-8')) + self.assertIsInstance(result, unicode) + self.assertEqual('æøå', result) def test_deserialize_enforces_required(self): value = types.Secret()