Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Credentials: handling password credentials error #2354

Merged
merged 1 commit into from
Jun 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions Orange/widgets/credentials.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import logging

import keyring

SERVICE_NAME = 'Orange3 - {}'

log = logging.getLogger(__name__)


class CredentialManager:
"""
Expand All @@ -13,13 +17,11 @@ class CredentialManager:

Examples:
>>> cm = CredentialManager('Widget Name')
>>> cm.username = 'Orange' # store username
>>> cm.password = 'Secret' # store password

>>> cm.username # get username
'Orange'
>>> cm.password # get password
'Secret'
>>> cm.some_secret = 'api-key-1234'
>>> cm.some_secret
'api-key-1234'
>>> del cm.some_secret
>>> cm.some_secret
"""
def __init__(self, service_name):
self.__dict__['__service_name'] = SERVICE_NAME.format(service_name)
Expand All @@ -29,10 +31,22 @@ def service_name(self):
return self.__dict__['__service_name']

def __setattr__(self, key, value):
keyring.set_password(self.service_name, key, value)
try:
keyring.set_password(self.service_name, key, value)
except Exception:
log.exception("Failed to set secret '%s' of '%r'.",
key, self.service_name)

def __getattr__(self, item):
return keyring.get_password(self.service_name, item)
try:
return keyring.get_password(self.service_name, item)
except Exception:
log.exception("Failed to get secret '%s' of '%r'.",
item, self.service_name)

def __delattr__(self, item):
keyring.delete_password(self.service_name, item)
try:
keyring.delete_password(self.service_name, item)
except Exception:
log.exception("Failed to delete secret '%s' of '%r'.",
item, self.service_name)
31 changes: 30 additions & 1 deletion Orange/widgets/tests/test_credentials.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,41 @@
import unittest
from unittest.mock import patch

from Orange.widgets.credentials import CredentialManager


class CredentialManagerTests(unittest.TestCase):
class TestCredentialManager(unittest.TestCase):
def setUp(self):
self.cm = CredentialManager('Orange')
self.cm.key = "Foo"

def test_credential_manager(self):
cm = CredentialManager('Orange')
cm.key = 'Foo'
self.assertEqual(cm.key, 'Foo')
del cm.key
self.assertEqual(cm.key, None)

def test_set_password(self):
"""
Handle error when setting password fails.
GH-2354
"""
with patch("keyring.set_password", side_effect=Exception):
self.cm.key = ""

def test_delete_password(self):
"""
Handling error when deleting password fails
GH-2354
"""
with patch("keyring.delete_password", side_effect=Exception):
del self.cm.key

def test_get_password(self):
"""
Handling errors when getting password fails.
GH-2354
"""
with patch("keyring.get_password", side_effect=Exception):
self.assertEqual(self.cm.key, None)