| Server IP : 61.19.30.66 / Your IP : 216.73.216.15 Web Server : Apache/2.2.22 (Ubuntu) System : Linux klw 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:39:31 UTC 2014 x86_64 User : www-data ( 33) PHP Version : 5.3.10-1ubuntu3.48 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, MySQL : ON | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /usr/share/pyshared/keyring/tests/ |
Upload File : |
"""
test_backend.py
Test case for keyring basic function
created by Kang Zhang 2009-07-14
"""
import contextlib
import os
import random
import string
import sys
import tempfile
import types
import getpass
try:
# Python < 2.7 annd Python >= 3.0 < 3.1
import unittest2 as unittest
except ImportError:
import unittest
import keyring.backend
ALPHABET = string.ascii_letters + string.digits
DIFFICULT_CHARS = string.whitespace + string.punctuation
class ImportKiller(object):
"Context manager to make an import of a given name or names fail."
def __init__(self, *names):
self.names = names
def find_module(self, fullname, path=None):
if fullname in self.names:
return self
def load_module(self, fullname):
assert fullname in self.names
raise ImportError(fullname)
def __enter__(self):
self.original = {}
for name in self.names:
self.original[name] = sys.modules.pop(name, None)
sys.meta_path.append(self)
def __exit__(self, *args):
sys.meta_path.remove(self)
for key, value in self.original.items():
if value is not None:
sys.modules[key] = value
@contextlib.contextmanager
def NoNoneDictMutator(destination, **changes):
"""Helper context manager to make and unmake changes to a dict.
A None is not a valid value for the destination, and so means that the
associated name should be removed."""
original = {}
for key, value in changes.items():
original[key] = destination.get(key)
if value is None:
if key in destination:
del destination[key]
else:
destination[key] = value
yield
for key, value in original.items():
if value is None:
if key in destination:
del destination[key]
else:
destination[key] = value
def Environ(**changes):
"""A context manager to temporarily change the os.environ"""
return NoNoneDictMutator(os.environ, **changes)
def ImportBlesser(*names, **changes):
"""A context manager to temporarily make it possible to import a module"""
for name in names:
changes[name] = types.ModuleType(name)
return NoNoneDictMutator(sys.modules, **changes)
def random_string(k, source = ALPHABET):
"""Generate a random string with length <i>k</i>
"""
result = ''
for i in range(0, k):
result += random.choice(source)
return result
def is_win32_crypto_supported():
try:
__import__('keyring.backends.win32_crypto')
except ImportError:
return False
return sys.platform in ['win32'] and sys.getwindowsversion()[-2] == 2
def is_osx_keychain_supported():
return sys.platform in ('mac','darwin')
def is_kwallet_supported():
supported = keyring.backend.KDEKWallet().supported()
if supported == -1:
return False
return True
def is_crypto_supported():
try:
__import__('Crypto.Cipher.AES')
__import__('Crypto.Protocol.KDF')
__import__('Crypto.Random')
except ImportError:
return False
return True
def is_gnomekeyring_supported():
supported = keyring.backend.GnomeKeyring().supported()
if supported == -1:
return False
return True
def is_qt4_supported():
try:
__import__('PyQt4.QtGui')
except ImportError:
return False
return True
def is_winvault_supported():
try:
__import__('win32cred')
has_pywin32 = True
except ImportError:
has_pywin32 = False
return (
sys.platform in ['win32'] and sys.getwindowsversion().major >= 6
and has_pywin32
)
def is_dbus_supported():
try:
__import__('dbus')
except ImportError:
return False
return True
class BackendBasicTests(object):
"""Test for the keyring's basic funtions. password_set and password_get
"""
def setUp(self):
self.keyring = self.init_keyring()
self.credentials_created = set()
def set_password(self, service, username, password):
# set the password and save the result so the test runner can clean
# up after if necessary.
self.keyring.set_password(service, username, password)
self.credentials_created.add((service, username))
def check_set_get(self, service, username, password):
keyring = self.keyring
# for the non-existent password
self.assertEqual(keyring.get_password(service, username), None)
# common usage
self.set_password(service, username, password)
self.assertEqual(keyring.get_password(service, username), password)
# for the empty password
self.set_password(service, username, "")
self.assertEqual(keyring.get_password(service, username), "")
def test_password_set_get(self):
password = random_string(20)
username = random_string(20)
service = random_string(20)
self.check_set_get(service, username, password)
def test_difficult_chars(self):
password = random_string(20, DIFFICULT_CHARS)
username = random_string(20, DIFFICULT_CHARS)
service = random_string(20, DIFFICULT_CHARS)
self.check_set_get(service, username, password)
def test_different_user(self):
"""
Issue #47 reports that WinVault isn't storing passwords for
multiple users. This test exercises that test for each of the
backends.
"""
keyring = self.keyring
self.set_password('service1', 'user1', 'password1')
self.set_password('service1', 'user2', 'password2')
self.assertEqual(keyring.get_password('service1', 'user1'),
'password1')
self.assertEqual(keyring.get_password('service1', 'user2'),
'password2')
self.set_password('service2', 'user3', 'password3')
self.assertEqual(keyring.get_password('service1', 'user1'),
'password1')
@unittest.skipUnless(is_osx_keychain_supported(),
"Need OS X")
class OSXKeychainTestCase(BackendBasicTests, unittest.TestCase):
def init_keyring(self):
return keyring.backend.OSXKeychain()
@unittest.skipUnless(is_gnomekeyring_supported(),
"Need GnomeKeyring")
class GnomeKeyringTestCase(BackendBasicTests, unittest.TestCase):
def environ(self):
return dict(GNOME_KEYRING_CONTROL='1',
DISPLAY='1',
DBUS_SESSION_BUS_ADDRESS='1')
def init_keyring(self):
k = keyring.backend.GnomeKeyring()
# Store passwords in the session (in-memory) keyring for the tests. This
# is going to be automatically cleared when the user logoff.
k.KEYRING_NAME = 'session'
return k
def test_supported(self):
with ImportBlesser('gnomekeyring'):
with Environ(**self.environ()):
self.assertEqual(1, self.keyring.supported())
def test_supported_no_module(self):
with ImportKiller('gnomekeyring'):
with Environ(**self.environ()):
self.assertEqual(-1, self.keyring.supported())
def test_supported_no_keyring(self):
with ImportBlesser('gnomekeyring'):
environ = self.environ()
environ['GNOME_KEYRING_CONTROL'] = None
with Environ(**environ):
self.assertEqual(0, self.keyring.supported())
def test_supported_no_display(self):
with ImportBlesser('gnomekeyring'):
environ = self.environ()
environ['DISPLAY'] = None
with Environ(**environ):
self.assertEqual(0, self.keyring.supported())
def test_supported_no_session(self):
with ImportBlesser('gnomekeyring'):
environ = self.environ()
environ['DBUS_SESSION_BUS_ADDRESS'] = None
with Environ(**environ):
self.assertEqual(0, self.keyring.supported())
@unittest.skipUnless(is_kwallet_supported(),
"Need KWallet")
class KDEKWalletTestCase(BackendBasicTests, unittest.TestCase):
def init_keyring(self):
return keyring.backend.KDEKWallet()
class UnOpenableKWallet(object):
"""A module-like object used to test KDE wallet fall-back."""
Synchronous = None
def openWallet(self, *args):
return None
def NetworkWallet(self):
return None
class FauxQtGui(object):
"""A fake module-like object used in testing the open_kwallet function."""
class qApp:
@staticmethod
def instance():
pass
class QApplication(object):
def __init__(self, *args):
pass
def exit(self):
pass
class QWidget(object):
def __init__(self, *args):
pass
def winId(self):
pass
class KDEWalletCanceledTestCase(unittest.TestCase):
def test_user_canceled(self):
# If the user cancels either the "enter your password to unlock the
# keyring" dialog or clicks "deny" on the "can this application access
# the wallet" dialog then openWallet() will return None. The
# open_wallet() function should handle that eventuality by returning
# None to signify that the KWallet backend is not available.
self.assertEqual(
keyring.backend.open_kwallet(UnOpenableKWallet(), FauxQtGui()),
None)
@unittest.skipUnless(is_kwallet_supported() and
is_qt4_supported(),
"Need KWallet and Qt4")
class KDEKWalletInQApplication(unittest.TestCase):
def test_QApplication(self):
try:
from PyKDE4.kdeui import KWallet
from PyQt4.QtGui import QApplication
except:
return
app = QApplication([])
wallet = keyring.backend.open_kwallet()
self.assertTrue(isinstance(wallet, KWallet.Wallet),
msg="The object wallet should be type "
"<KWallet.Wallet> but it is: %s" % repr(wallet))
app.exit()
class FileKeyringTests(BackendBasicTests):
def setUp(self):
super(FileKeyringTests, self).setUp()
self.keyring = self.init_keyring()
self.keyring.file_path = self.tmp_keyring_file = os.path.join(
tempfile.mkdtemp(), "test_pass.cfg")
def tearDown(self):
try:
os.unlink(self.tmp_keyring_file)
except OSError, e:
if e.errno != 2: # No such file or directory
raise
def test_encrypt_decrypt(self):
password = random_string(20)
# keyring.encrypt expects bytes
password = password.encode('utf-8')
encrypted = self.keyring.encrypt(password)
self.assertEqual(password, self.keyring.decrypt(encrypted))
class UncryptedFileKeyringTestCase(FileKeyringTests, unittest.TestCase):
def init_keyring(self):
return keyring.backend.UncryptedFileKeyring()
@unittest.skipUnless(is_crypto_supported(),
"Need Crypto module")
class CryptedFileKeyringTestCase(FileKeyringTests, unittest.TestCase):
def setUp(self):
super(self.__class__, self).setUp()
# patch the getpass module to bypass user input
self.getpass_orig = getpass.getpass
getpass.getpass = lambda *args, **kwargs: "abcdef"
def tearDown(self):
getpass.getpass = self.getpass_orig
del self.getpass_orig
def init_keyring(self):
return keyring.backend.CryptedFileKeyring()
@unittest.skipUnless(is_win32_crypto_supported(),
"Need Windows")
class Win32CryptoKeyringTestCase(FileKeyringTests, unittest.TestCase):
def init_keyring(self):
return keyring.backend.Win32CryptoKeyring()
@unittest.skipUnless(is_winvault_supported(),
"Need WinVault")
class WinVaultKeyringTestCase(BackendBasicTests, unittest.TestCase):
def tearDown(self):
# clean up any credentials created
for cred in self.credentials_created:
try:
self.keyring.delete_password(*cred)
except Exception, e:
print >> sys.stderr, e
def init_keyring(self):
return keyring.backend.WinVaultKeyring()
@unittest.skipUnless(is_dbus_supported(),
"DBus needed for SecretServiceKeyring")
class SecretServiceKeyringTestCase(BackendBasicTests, unittest.TestCase):
__test__ = True
def environ(self):
return dict(DISPLAY='1',
DBUS_SESSION_BUS_ADDRESS='1')
def init_keyring(self):
print >> sys.stderr, "Testing SecretServiceKeyring, following password prompts are for this keyring"
return keyring.backend.SecretServiceKeyring()
def test_supported_no_module(self):
with ImportKiller('dbus'):
with Environ(**self.environ()):
self.assertEqual(-1, self.keyring.supported())
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(OSXKeychainTestCase))
suite.addTest(unittest.makeSuite(GnomeKeyringTestCase))
suite.addTest(unittest.makeSuite(SecretServiceKeyringTestCase))
suite.addTest(unittest.makeSuite(KDEWalletCanceledTestCase))
suite.addTest(unittest.makeSuite(KDEKWalletTestCase))
suite.addTest(unittest.makeSuite(KDEKWalletInQApplication))
suite.addTest(unittest.makeSuite(UncryptedFileKeyringTestCase))
suite.addTest(unittest.makeSuite(CryptedFileKeyringTestCase))
suite.addTest(unittest.makeSuite(Win32CryptoKeyringTestCase))
suite.addTest(unittest.makeSuite(WinVaultKeyringTestCase))
return suite
if __name__ == '__main__':
unittest.main(defaultTest="test_suite")