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.
This commit is contained in:
Stein Magnus Jodal 2013-09-15 23:49:15 +02:00
parent 82077ace02
commit 05d4fa846f
3 changed files with 18 additions and 21 deletions

View File

@ -64,6 +64,11 @@ v0.15.0 (UNRELEASED)
The methods are still not implemented, but now the commands are accepted as The methods are still not implemented, but now the commands are accepted as
valid. 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) v0.14.2 (2013-07-01)
==================== ====================

View File

@ -82,30 +82,22 @@ class String(ConfigValue):
return encode(value) return encode(value)
class Secret(ConfigValue): class Secret(String):
"""Secret value. """Secret string value.
Should be used for passwords, auth tokens etc. Deserializing will not Is decoded as utf-8 and \\n \\t escapes should work and be preserved.
convert to unicode. Will mask value when being displayed.
Should be used for passwords, auth tokens etc. Will mask value when being
displayed.
""" """
def __init__(self, optional=False, choices=None): def __init__(self, optional=False, choices=None):
self._required = not optional self._required = not optional
self._choices = None # Choices doesn't make sense for secrets
def deserialize(self, value):
value = value.strip()
validators.validate_required(value, self._required)
if not value:
return None
return value
def serialize(self, value, display=False): def serialize(self, value, display=False):
if isinstance(value, unicode): if value is not None and display:
value = value.encode('utf-8')
if value is None:
return b''
elif display:
return b'********' return b'********'
return value return super(Secret, self).serialize(value, display)
class Integer(ConfigValue): class Integer(ConfigValue):

View File

@ -105,11 +105,11 @@ class StringTest(unittest.TestCase):
class SecretTest(unittest.TestCase): class SecretTest(unittest.TestCase):
def test_deserialize_passes_through(self): def test_deserialize_decodes_utf8(self):
value = types.Secret() value = types.Secret()
result = value.deserialize(b'foo') result = value.deserialize('æøå'.encode('utf-8'))
self.assertIsInstance(result, bytes) self.assertIsInstance(result, unicode)
self.assertEqual(b'foo', result) self.assertEqual('æøå', result)
def test_deserialize_enforces_required(self): def test_deserialize_enforces_required(self):
value = types.Secret() value = types.Secret()