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

Add support to set or get AutoType/Association/Window text #367

Merged
merged 1 commit into from
Nov 27, 2023
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ dist/
*.egg-info/
build/
*.xml
Pipfile
Pipfile.lock
*.kdbx
*.kdbx.out
.idea
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Finding Entries

**find_entries** (title=None, username=None, password=None, url=None, notes=None, otp=None, path=None, uuid=None, tags=None, string=None, group=None, recursive=True, regex=False, flags=None, history=False, first=False)

Returns entries which match all provided parameters, where ``title``, ``username``, ``password``, ``url``, ``notes``, ``otp``, and ``autotype_sequence`` are strings, ``path`` is a list, ``string`` is a dict, ``autotype_enabled`` is a boolean, ``uuid`` is a ``uuid.UUID`` and ``tags`` is a list of strings. This function has optional ``regex`` boolean and ``flags`` string arguments, which means to interpret search strings as `XSLT style`_ regular expressions with `flags`_.
Returns entries which match all provided parameters, where ``title``, ``username``, ``password``, ``url``, ``notes``, ``otp``, ``autotype_window`` and ``autotype_sequence`` are strings, ``path`` is a list, ``string`` is a dict, ``autotype_enabled`` is a boolean, ``uuid`` is a ``uuid.UUID`` and ``tags`` is a list of strings. This function has optional ``regex`` boolean and ``flags`` string arguments, which means to interpret search strings as `XSLT style`_ regular expressions with `flags`_.

.. _XSLT style: https://www.xml.com/pub/a/2003/06/04/tr.html
.. _flags: https://www.w3.org/TR/xpath-functions/#flags
Expand Down
20 changes: 18 additions & 2 deletions pykeepass/entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Entry(BaseElement):

def __init__(self, title=None, username=None, password=None, url=None,
notes=None, otp=None, tags=None, expires=False, expiry_time=None,
icon=None, autotype_sequence=None, autotype_enabled=True,
icon=None, autotype_sequence=None, autotype_enabled=True, autotype_window=None,
element=None, kp=None):

self._kp = kp
Expand Down Expand Up @@ -60,7 +60,11 @@ def __init__(self, title=None, username=None, password=None, url=None,
E.AutoType(
E.Enabled(str(autotype_enabled)),
E.DataTransferObfuscation('0'),
E.DefaultSequence(str(autotype_sequence) if autotype_sequence else '')
E.DefaultSequence(str(autotype_sequence) if autotype_sequence else ''),
E.Association(
E.Window(str(autotype_window) if autotype_window else ''),
E.KeystrokeSequence('')
)
)
)
# FIXME: include custom_properties in constructor
Expand Down Expand Up @@ -268,6 +272,18 @@ def autotype_sequence(self):
def autotype_sequence(self, value):
self._element.find('AutoType/DefaultSequence').text = value

@property
def autotype_window(self):
"""str: get or set [autotype target window filter](https://keepass.info/help/base/autotype.html#autowindows)"""
sequence = self._element.find('AutoType/Association/Window')
if sequence is None or sequence.text == '':
return None
return sequence.text

@autotype_window.setter
def autotype_window(self, value):
self._element.find('AutoType/Association/Window').text = value

@property
def is_a_history_entry(self):
"""bool: check if entry is History entry"""
Expand Down
2 changes: 2 additions & 0 deletions pykeepass/xpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
'tags': '/Tags[text()="{}"]/..',
'string': '/String/Key[text()="{}"]/../Value[text()="{}"]/../..',
'autotype_sequence': '/AutoType/DefaultSequence[text()="{}"]/../..',
'autotype_window': '/AutoType/Association/Window[text()="{}"]/../../..',
'autotype_enabled': '/AutoType/Enabled[text()="{}"]/../..',
'otp': '/String/Key[text()="otp"]/../Value[text()="{}"]/../..',
},
Expand All @@ -44,6 +45,7 @@
'tags': '/Tags[re:test(text(), "{}", "{flags}")]/..',
'string': '/String/Key[text()="{}"]/../Value[re:test(text(), "{}", "{flags}")]/../..',
'autotype_sequence': '/AutoType/DefaultSequence[re:test(text(), "{}", "{flags}")]/../..',
'autotype_window': '/AutoType/Association/Window[re:test(text(), "{}", "{flags}")]/../../..',
'autotype_enabled': '/AutoType/Enabled[re:test(text(), "{}", "{flags}")]/../..',
'otp': '/String/Key[text()="otp"]/../Value[re:test(text(), "{}", "{flags}")]/../..',
}
Expand Down
Binary file modified tests/test3.kdbx
Binary file not shown.
7 changes: 5 additions & 2 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
from datetime import datetime, timedelta

from dateutil import tz
from lxml.etree import Element
from pathlib import Path

from io import BytesIO

from pykeepass import PyKeePass, icons
from pykeepass.entry import Entry
from pykeepass.group import Group
from pykeepass.kdbx_parsing import KDBX
from pykeepass.exceptions import BinaryError, CredentialsError, HeaderChecksumError

"""
Expand Down Expand Up @@ -144,6 +142,11 @@ def test_find_entries_by_autotype_sequence(self):
self.assertEqual(len(results), 1)
self.assertEqual(results[0].autotype_sequence, '{USERNAME}{TAB}{PASSWORD}{ENTER}')

def test_find_entries_by_autotype_window(self):
results = self.kp.find_entries(autotype_window='test', regex=True, flags="i")
self.assertEqual(len(results), 1)
self.assertEqual(results[0].autotype_window, 'TEST')

def test_find_entries_by_autotype_enabled(self):
results = self.kp.find_entries(autotype_enabled=True)
self.assertEqual(len(results), len(self.kp.entries) - 1)
Expand Down
Loading