Skip to content

Commit

Permalink
Fix code style issues
Browse files Browse the repository at this point in the history
  • Loading branch information
mitya57 committed Aug 13, 2022
1 parent f155e31 commit b6ad692
Show file tree
Hide file tree
Showing 14 changed files with 65 additions and 33 deletions.
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3

import sys, os
import os
import sys

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
Expand Down
1 change: 1 addition & 0 deletions secretstorage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
'search_items',
]


def dbus_init() -> DBusConnection:
"""Returns a new connection to the session bus, instance of
jeepney's :class:`DBusConnection` class. This connection can
Expand Down
11 changes: 8 additions & 3 deletions secretstorage/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
format_secret, open_session, unlock_objects

COLLECTION_IFACE = SS_PREFIX + 'Collection'
SERVICE_IFACE = SS_PREFIX + 'Service'
SERVICE_IFACE = SS_PREFIX + 'Service'
DEFAULT_COLLECTION = '/org/freedesktop/secrets/aliases/default'
SESSION_COLLECTION = '/org/freedesktop/secrets/collection/session'


class Collection(object):
"""Represents a collection."""

Expand Down Expand Up @@ -160,21 +161,23 @@ def create_collection(connection: DBusConnection, label: str, alias: str = '',
assert signature == 'o'
return Collection(connection, collection_path, session=session)


def get_all_collections(connection: DBusConnection) -> Iterator[Collection]:
"""Returns a generator of all available collections."""
service = DBusAddressWrapper(SS_PATH, SERVICE_IFACE, connection)
for collection_path in service.get_property('Collections'):
yield Collection(connection, collection_path)


def get_default_collection(connection: DBusConnection,
session: Optional[Session] = None) -> Collection:
"""Returns the default collection. If it doesn't exist,
creates it."""
try:
return Collection(connection)
except ItemNotFoundException:
return create_collection(connection, 'Default',
'default', session)
return create_collection(connection, 'Default', 'default', session)


def get_any_collection(connection: DBusConnection) -> Collection:
"""Returns any collection, in the following order of preference:
Expand All @@ -198,6 +201,7 @@ def get_any_collection(connection: DBusConnection) -> Collection:
else:
raise ItemNotFoundException('No collections found.')


def get_collection_by_alias(connection: DBusConnection,
alias: str) -> Collection:
"""Returns the collection with the given `alias`. If there is no
Expand All @@ -209,6 +213,7 @@ def get_collection_by_alias(connection: DBusConnection,
raise ItemNotFoundException('No collection with such alias.')
return Collection(connection, collection_path)


def search_items(connection: DBusConnection,
attributes: Dict[str, str]) -> Iterator[Item]:
"""Returns a generator of items in all collections with the given
Expand Down
12 changes: 6 additions & 6 deletions secretstorage/defines.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
SS_PREFIX = 'org.freedesktop.Secret.'
SS_PATH = '/org/freedesktop/secrets'

DBUS_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
DBUS_ACCESS_DENIED = 'org.freedesktop.DBus.Error.AccessDenied'
DBUS_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
DBUS_ACCESS_DENIED = 'org.freedesktop.DBus.Error.AccessDenied'
DBUS_SERVICE_UNKNOWN = 'org.freedesktop.DBus.Error.ServiceUnknown'
DBUS_EXEC_FAILED = 'org.freedesktop.DBus.Error.Spawn.ExecFailed'
DBUS_NO_REPLY = 'org.freedesktop.DBus.Error.NoReply'
DBUS_NOT_SUPPORTED = 'org.freedesktop.DBus.Error.NotSupported'
DBUS_NO_SUCH_OBJECT = 'org.freedesktop.Secret.Error.NoSuchObject'
DBUS_EXEC_FAILED = 'org.freedesktop.DBus.Error.Spawn.ExecFailed'
DBUS_NO_REPLY = 'org.freedesktop.DBus.Error.NoReply'
DBUS_NOT_SUPPORTED = 'org.freedesktop.DBus.Error.NotSupported'
DBUS_NO_SUCH_OBJECT = 'org.freedesktop.Secret.Error.NoSuchObject'

ALGORITHM_PLAIN = 'plain'
ALGORITHM_DH = 'dh-ietf1024-sha256-aes128-cbc-pkcs7'
23 changes: 14 additions & 9 deletions secretstorage/dhcrypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,26 @@

# A standard 1024 bits (128 bytes) prime number for use in Diffie-Hellman exchange
DH_PRIME_1024_BYTES = (
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68,
0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08,
0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A,
0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51,
0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38,
0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF
)


def int_to_bytes(number: int) -> bytes:
return number.to_bytes(math.ceil(number.bit_length() / 8), 'big')


DH_PRIME_1024 = int.from_bytes(DH_PRIME_1024_BYTES, 'big')


class Session(object):
def __init__(self) -> None:
self.object_path = None # type: Optional[str]
Expand All @@ -42,7 +47,7 @@ def __init__(self) -> None:

def set_server_public_key(self, server_public_key: int) -> None:
common_secret_int = pow(server_public_key, self.my_private_key,
DH_PRIME_1024)
DH_PRIME_1024)
common_secret = int_to_bytes(common_secret_int)
# Prepend NULL bytes if needed
common_secret = b'\x00' * (0x80 - len(common_secret)) + common_secret
Expand Down
7 changes: 6 additions & 1 deletion secretstorage/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,26 @@
something goes wrong. All exceptions derive from base
:exc:`SecretStorageException` class."""


class SecretStorageException(Exception):
"""All exceptions derive from this class."""


class SecretServiceNotAvailableException(SecretStorageException):
"""Raised by :class:`~secretstorage.item.Item` or
:class:`~secretstorage.collection.Collection` constructors, or by
other functions in the :mod:`secretstorage.collection` module, when
the Secret Service API is not available."""


class LockedException(SecretStorageException):
"""Raised when an action cannot be performed because the collection
is locked. Use :meth:`~secretstorage.collection.Collection.is_locked`
to check if the collection is locked, and
:meth:`~secretstorage.collection.Collection.unlock` to unlock it.
"""


class ItemNotFoundException(SecretStorageException):
"""Raised when an item does not exist or has been deleted. Example of
handling:
Expand All @@ -34,10 +38,11 @@ class ItemNotFoundException(SecretStorageException):
... item = secretstorage.Item(connection, item_path)
... except secretstorage.ItemNotFoundException:
... print('Item not found!')
...
...
Item not found!
"""


class PromptDismissedException(ItemNotFoundException):
"""Raised when a prompt was dismissed by the user.
Expand Down
1 change: 1 addition & 0 deletions secretstorage/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

ITEM_IFACE = SS_PREFIX + 'Item'


class Item(object):
"""Represents a secret item."""

Expand Down
9 changes: 6 additions & 3 deletions secretstorage/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,15 @@ def open_session(connection: DBusConnection) -> Session:
service = DBusAddressWrapper(SS_PATH, SERVICE_IFACE, connection)
session = Session()
try:
output, result = service.call('OpenSession', 'sv',
output, result = service.call(
'OpenSession', 'sv',
ALGORITHM_DH,
('ay', int_to_bytes(session.my_public_key)))
except DBusErrorResponse as resp:
if resp.name != DBUS_NOT_SUPPORTED:
raise
output, result = service.call('OpenSession', 'sv',
output, result = service.call(
'OpenSession', 'sv',
ALGORITHM_PLAIN,
('s', ''))
session.encrypted = False
Expand All @@ -95,6 +97,7 @@ def open_session(connection: DBusConnection) -> Session:
session.object_path = result
return session


def format_secret(session: Session, secret: bytes,
content_type: str) -> Tuple[str, bytes, bytes, str]:
"""Formats `secret` to make possible to pass it to the
Expand Down Expand Up @@ -123,7 +126,7 @@ def format_secret(session: Session, secret: bytes,


def exec_prompt(connection: DBusConnection,
prompt_path: str) -> Tuple[bool, List[str]]:
prompt_path: str) -> Tuple[bool, List[str]]:
"""Executes the prompt in a blocking mode.
:returns: a tuple; the first element is a boolean value showing
Expand Down
4 changes: 3 additions & 1 deletion tests/cleanup_test_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import secretstorage

with closing(secretstorage.dbus_init()) as connection:
items = secretstorage.search_items(connection, {'application': 'secretstorage-test'})
items = secretstorage.search_items(
connection, {'application': 'secretstorage-test'}
)

for item in items:
print('Deleting item with label %r.' % item.get_label())
Expand Down
2 changes: 1 addition & 1 deletion tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
tests_dir = os.path.dirname(__file__)
sys.path.insert(0, os.path.dirname(tests_dir))

import secretstorage
import secretstorage # noqa

if __name__ == '__main__':
major, minor, patch = sys.version_info[:3]
Expand Down
3 changes: 2 additions & 1 deletion tests/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from secretstorage.util import BUS_NAME
from secretstorage.exceptions import ItemNotFoundException


class CollectionTest(unittest.TestCase):
"""A test case that tests that all common methods of Collection
class work and do not crash."""
Expand Down Expand Up @@ -43,7 +44,7 @@ def test_label(self) -> None:


@unittest.skipIf(BUS_NAME == "org.freedesktop.secrets",
"This test should only be run with the mocked server.")
"This test should only be run with the mocked server.")
class MockCollectionTest(unittest.TestCase):
def setUp(self) -> None:
self.connection = dbus_init()
Expand Down
1 change: 1 addition & 0 deletions tests/test_dhcrypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import unittest
from secretstorage.dhcrypto import int_to_bytes


class ConversionTest(unittest.TestCase):
"""A test case that tests conversion functions
between bytes and long."""
Expand Down
10 changes: 7 additions & 3 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import secretstorage
from secretstorage.exceptions import ItemNotFoundException


class ExceptionsTest(unittest.TestCase):
"""A test case that ensures that all SecretStorage exceptions
are raised correctly."""
Expand All @@ -20,16 +21,19 @@ def tearDown(self) -> None:
self.connection.close()

def test_double_deleting(self) -> None:
item = self.collection.create_item('MyItem',
item = self.collection.create_item(
'MyItem',
{'application': 'secretstorage-test'}, b'pa$$word')
item.delete()
self.assertRaises(ItemNotFoundException, item.delete)

def test_non_existing_item(self) -> None:
self.assertRaises(ItemNotFoundException, secretstorage.Item,
self.assertRaises(
ItemNotFoundException, secretstorage.Item,
self.connection, '/not/existing/path')

def test_non_existing_collection(self) -> None:
self.assertRaises(ItemNotFoundException,
self.assertRaises(
ItemNotFoundException,
secretstorage.get_collection_by_alias,
self.connection, 'non-existing-alias')
11 changes: 7 additions & 4 deletions tests/test_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

ATTRIBUTES = {'application': 'secretstorage-test', 'attribute': 'qwerty'}
NEW_ATTRIBUTES = {'application': 'secretstorage-test',
'newattribute': 'asdfgh'}
'newattribute': 'asdfgh'}


class ItemTest(unittest.TestCase):
"""A test case that tests that all common methods of Item
Expand All @@ -20,9 +21,11 @@ def setUp(self) -> None:
self.connection = dbus_init()
self.collection = get_any_collection(self.connection)
self.created_timestamp = time.time()
self.item = self.collection.create_item('My item', ATTRIBUTES,
self.item = self.collection.create_item(
'My item', ATTRIBUTES,
b'pa$$word')
self.other_item = self.collection.create_item('My item',
self.other_item = self.collection.create_item(
'My item',
ATTRIBUTES, b'', content_type='data/null')

def tearDown(self) -> None:
Expand Down Expand Up @@ -80,7 +83,7 @@ def test_secret_content_type(self) -> None:
self.assertEqual(self.item.get_secret_content_type(), 'text/plain')
# The check below fails in gnome-keyring because it doesn't really
# support content types.
#self.assertEqual(self.other_item.get_secret_content_type(), 'data/null')
# self.assertEqual(self.other_item.get_secret_content_type(), 'data/null')

def test_modified(self) -> None:
now = time.time()
Expand Down

0 comments on commit b6ad692

Please sign in to comment.