Esempio n. 1
0
def test_merge(sources):
    runner = CliRunner(env={"KEEPASS_PASSWORD": '******'})
    result_file = 'merged.kdbx'
    files = sources + [result_file]
    file_paths = [os.path.join('tests', fname) for fname in files]
    try:
        result = runner.invoke(main, file_paths)
        print(result.stdout)
        assert not result.exception, exc_to_str(result.exc_info)
        assert result.exit_code == 0, " ".join(file_paths)

        assert os.path.exists(file_paths[-1])
        dest = PyKeePass(file_paths[-1], 'password')
        entries = dest.entries
        assert len(entries) == 3

        michael = dest.find_entries_by_username('Michael321', first=True)
        assert michael.password == 'replaced'

        user = dest.find_entries_by_username('User Name', first=True)
        assert user.password == 'Password'

        orig = dest.find_entries_by_title('OnlyOriginal', first=True)
        assert orig is not None

    finally:
        if os.path.exists(file_paths[-1]):
            os.remove(file_paths[-1])
Esempio n. 2
0
 def test_processor(self):
     processor = Processor(vault_settings=self.vault_config,
                           kdb_settings=self.kdb_config)
     processor.sync_from_kdb()
     processor.sync_from_vault()
     processor.write_vault()
     file_like = io.BytesIO()
     processor._kdb_settings["filename"] = file_like
     processor.write_kdb()
     file_like.seek(0)
     kdb = PyKeePass(filename=file_like, password=self.kdb_password)
     entry = kdb.find_entries_by_title(title="test_entry", first=True)
     self.assertEqual(entry.path, ["test", "sub", "test_entry"])
Esempio n. 3
0
class EntryFunctionTests(unittest.TestCase):

    # get some things ready before testing
    def setUp(self):
        self.kp = PyKeePass(os.path.join(base_dir, 'test.kdbx'),
                            password='******',
                            keyfile=os.path.join(base_dir, 'test.key'))

    #---------- Finding entries -----------

    def test_find_entries_by_title(self):
        results = self.kp.find_entries_by_title('root_entry')
        self.assertEqual(len(results), 1)
        results = self.kp.find_entries_by_title('Root_entry',
                                                regex=True,
                                                flags='i',
                                                first=True)
        self.assertEqual('root_entry', results.title)

    def test_find_entries_by_username(self):
        results = self.kp.find_entries_by_username('foobar_user')
        self.assertEqual(len(results), 2)
        results = self.kp.find_entries_by_username('Foobar_user',
                                                   regex=True,
                                                   flags='i',
                                                   first=True)
        self.assertEqual('foobar_user', results.username)

    def test_find_entries_by_password(self):
        results = self.kp.find_entries_by_password('passw0rd')
        self.assertEqual(len(results), 2)
        results = self.kp.find_entries_by_password('Passw0rd',
                                                   regex=True,
                                                   flags='i',
                                                   first=True)
        self.assertEqual('passw0rd', results.password)

    def test_find_entries_by_url(self):
        results = self.kp.find_entries_by_url('http://example.com')
        self.assertEqual(len(results), 2)
        results = self.kp.find_entries_by_url('http://example.com', first=True)
        self.assertEqual('http://example.com', results.url)

    def test_find_entries_by_notes(self):
        results = self.kp.find_entries_by_notes('entry notes')
        self.assertEqual(len(results), 1)
        results = self.kp.find_entries_by_notes('entry notes', regex=True)
        self.assertEqual(len(results), 2)
        results = self.kp.find_entries_by_notes('Entry notes',
                                                regex=True,
                                                flags='i',
                                                first=True)
        self.assertEqual('root entry notes', results.notes)

    def test_find_entries_by_path(self):
        results = self.kp.find_entries_by_path('foobar_group/group_entry')
        self.assertEqual(len(results), 1)
        results = self.kp.find_entries_by_path('foobar_group/Group_entry',
                                               regex=True,
                                               flags='i',
                                               first=True)
        self.assertIsInstance(results, Entry)
        self.assertEqual('group_entry', results.title)

    def test_find_entries_by_uuid(self):
        results = self.kp.find_entries_by_uuid('zF9+zSoASMqWIcIio0ewuw==')[0]
        self.assertIsInstance(results, Entry)
        self.assertEqual('zF9+zSoASMqWIcIio0ewuw==', results.uuid)
        self.assertEqual('foobar_user', results.username)

    def test_find_entries_by_string(self):
        results = self.kp.find_entries_by_string(
            {'custom_field': 'custom field value'})[0]
        self.assertIsInstance(results, Entry)
        self.assertEqual('custom field value',
                         results.get_custom_property('custom_field'))
        self.assertEqual('HnN4bHSVjEybPf8nOq1bVA==', results.uuid)

    def test_find_entries(self):
        results = self.kp.find_entries(title='Root_entry', regex=True)
        self.assertEqual(len(results), 0)
        results = self.kp.find_entries(title='Root_entry',
                                       regex=True,
                                       flags='i',
                                       first=True)
        self.assertEqual('root_entry', results.title)
        results = self.kp.find_entries(url="http://example.com")
        self.assertEqual(len(results), 2)
        results = self.kp.find_entries(notes="entry notes",
                                       url="http://example.com")
        self.assertEqual(len(results), 1)
        self.assertTrue(
            self.kp.find_entries(title='group_entry', first=True) in results)

        # test `group` argument
        results = self.kp.find_entries(title='foobar_entry', group=None)
        self.assertEqual(len(results), 3)
        group = self.kp.find_groups(name='foobar_group', first=True)
        results = self.kp.find_entries(title='foobar_entry', group=group)
        self.assertEqual(len(results), 2)

    #---------- Adding/Deleting entries -----------

    def test_add_delete_move_entry(self):
        unique_str = 'test_add_entry_'
        expiry_time = datetime.now()
        entry = self.kp.add_entry(self.kp.root_group,
                                  unique_str + 'title',
                                  unique_str + 'user',
                                  unique_str + 'pass',
                                  url=unique_str + 'url',
                                  notes=unique_str + 'notes',
                                  tags=unique_str + 'tags',
                                  expiry_time=expiry_time,
                                  icon=icons.KEY)
        results = self.kp.find_entries_by_title(unique_str + 'title')
        self.assertEqual(len(results), 1)
        results = self.kp.find_entries_by_title(unique_str + 'title',
                                                first=True)

        self.assertEqual(results.title, unique_str + 'title')
        self.assertEqual(results.username, unique_str + 'user')
        self.assertEqual(results.password, unique_str + 'pass')
        self.assertEqual(results.url, unique_str + 'url')
        self.assertEqual(results.notes, unique_str + 'notes')
        self.assertEqual(results.tags, [unique_str + 'tags'])
        # convert naive datetime to utc
        expiry_time_utc = expiry_time.replace(tzinfo=tz.gettz()).astimezone(
            tz.gettz('UTC'))
        self.assertEqual(results.icon, icons.KEY)

        sub_group = self.kp.add_group(self.kp.root_group, 'sub_group')
        self.kp.move_entry(entry, sub_group)
        results = self.kp.find_entries(path='sub_group/' +
                                       'test_add_entry_title',
                                       first=True)
        self.assertEqual(results.title, entry.title)

        self.kp.delete_entry(entry)
        results = self.kp.find_entries_by_title(unique_str + 'title',
                                                first=True)
        self.assertIsNone(results)

        # test adding entry which exists in another group
        subgroup = self.kp.find_groups(name='subgroup2', first=True)
        self.kp.add_entry(subgroup,
                          title='foobar_entry',
                          username='******',
                          password='******')

        # test adding entry to root which exists in subgroup
        self.kp.add_entry(subgroup,
                          title='foobar_entry2',
                          username='******',
                          password='******')
        self.kp.add_entry(self.kp.root_group,
                          title='foobar_entry2',
                          username='******',
                          password='******')

    #---------- Entries name collision exception -----------

    def test_raise_exception_entry(self):
        unique_str = 'test_add_entry_'
        entry = self.kp.add_entry(self.kp.root_group,
                                  unique_str + 'title',
                                  unique_str + 'user',
                                  unique_str + 'pass',
                                  url=unique_str + 'url',
                                  notes=unique_str + 'notes',
                                  tags=unique_str + 'tags',
                                  icon=icons.KEY)
        self.assertRaises(Exception, entry)

    # ---------- Entries representation -----------

    def test_print_entries(self):
        self.assertIsInstance(self.kp.entries.__repr__(), str)
Esempio n. 4
0
class KeeFinder(object):
    def __init__(self, db_path, db_pass, verbosity):
        self.db = PyKeePass(db_path, db_pass)
        self.verbosity = verbosity
        self.found_entries = list()

    def find(self, strings):
        if not isinstance(strings, list):
            raise TypeError("Passed value has to be list type")
        self.found_entries = self._find_entries(strings[-1])
        if not self.found_entries:
            return
        if len(strings) > 1:
            self.found_entries = self._find_in_entries(self.found_entries,
                                                       strings[:-1])

    def print_found(self):
        if not self.found_entries:
            print('Nothing found')
            return
        for entr in self.found_entries:
            self._print_entry(entr, self.verbosity)

    def _find_entries(self, substring, glob=True):
        search_string = substring.lower()
        res = list()
        if glob:
            search_string = '.*%s.*' % search_string
        method_names = ['title', 'username', 'url', 'password', 'path']
        for method_name in method_names:
            method = getattr(self.db, 'find_entries_by_%s' % method_name)
            results = method(search_string, regex=True, flags='i')
            for result in results:
                if result not in res:
                    res.append(result)

        root_group = self.db.find_groups_by_path('/')
        res_groups = list()
        # Now any group in res_groups will have a substring in path
        self._find_groups(substring, root_group, res_groups)
        for grp in res_groups:
            # As group has substring in path, it means any entry in this group
            # will have this substring in path too. There is no other way to do
            # this, sorry
            group_entries = self.db.find_entries_by_title('.*',
                                                          regex=True,
                                                          group=grp)
            for entr in group_entries:
                if entr not in res:
                    res.append(entr)
        return res

    def _find_in_entries(self, entries, entry_names):
        survivors = entries.copy()
        while entry_names:
            entry_name = entry_names.pop()
            for index, entr in enumerate(entries):
                if not self._find_in_entry(entry_name, entr):
                    survivors.remove(entr)
            survivors = self._find_in_entries(survivors, entry_names)
        return survivors

    def _find_in_entry(self, substring, entr):
        substring = substring.lower()
        if isinstance(entr, entry.Entry):
            subentries = [
                entr.group.path, entr.title, entr.username, entr.password,
                entr.url
            ]
        elif isinstance(entr, group.Group):
            subentries = [entr.path]
        for subentry in subentries:
            if subentry and (substring in subentry.lower()):
                return True
        return False

    def _find_groups(self, name, root_groups, result=[]):
        for grp in root_groups:
            if name.lower() in grp.path.lower():
                result.append(grp)
            subgroups = grp.subgroups
            self._find_groups(name, subgroups, result)

    def _print_entry(self, entr, verbosity):
        info = dict()

        def _get_fields(count):
            _info = dict()
            fields = ('group', 'username', 'password', 'title', 'url')
            if count == 2:
                fields = fields[:3]
            for field in fields:
                if field == 'group':
                    _info[field] = entr.group.path
                else:
                    _info[field] = getattr(entr, field)
            return _info

        if not verbosity:
            print(entr.password)
        elif verbosity == 1:
            print("%s - %s" % (entr.group.path, entr.username),
                  file=sys.stderr)
            print(entr.password, end="")
            sys.stdout.flush()
            print("", file=sys.stderr)
        else:
            info = _get_fields(verbosity)

        if info:
            pprint.pprint(info)
            print()