1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
|
"""Entry templates for common account types.
This module provides typed template classes for creating entries with predefined
fields and icons. Templates follow KeePass conventions for icon IDs and provide
full IDE autocompletion for field names.
Example:
>>> from kdbxtool import Database, Templates
>>> db = Database.create(password="secret")
>>> entry = db.root_group.create_entry(
... title="GitHub",
... template=Templates.Login(),
... username="user@example.com",
... password="secret123",
... url="https://github.com",
... )
>>> entry = db.root_group.create_entry(
... title="Visa Card",
... template=Templates.CreditCard(
... card_number="4111111111111111",
... expiry_date="12/25",
... cvv="123",
... ),
... )
Custom templates can be created by subclassing EntryTemplate:
>>> from dataclasses import dataclass
>>> from typing import ClassVar
>>> from kdbxtool import EntryTemplate, IconId
>>>
>>> @dataclass
... class VPNConnection(EntryTemplate):
... _icon_id: ClassVar[int] = IconId.TERMINAL_ENCRYPTED
... _protected_fields: ClassVar[frozenset[str]] = frozenset({"certificate"})
...
... server: str | None = None
... protocol: str = "OpenVPN"
... certificate: str | None = None
"""
from __future__ import annotations
from dataclasses import dataclass, fields
from enum import IntEnum
from typing import ClassVar
class IconId(IntEnum):
"""KeePass standard icon IDs.
These correspond to the PwIcon enumeration in KeePass. There are 69
standard icons (0-68) built into KeePass/KeePassXC.
"""
KEY = 0
WORLD = 1
WARNING = 2
NETWORK_SERVER = 3
MARKED_DIRECTORY = 4
USER_COMMUNICATION = 5
PARTS = 6
NOTEPAD = 7
WORLD_SOCKET = 8
IDENTITY = 9
PAPER_READY = 10
DIGICAM = 11
IR_COMMUNICATION = 12
MULTI_KEYS = 13
ENERGY = 14
SCANNER = 15
WORLD_STAR = 16
CDROM = 17
MONITOR = 18
EMAIL = 19
CONFIGURATION = 20
CLIPBOARD_READY = 21
PAPER_NEW = 22
SCREEN = 23
ENERGY_CAREFUL = 24
EMAIL_BOX = 25
DISK = 26
DRIVE = 27
PAPER_Q = 28
TERMINAL_ENCRYPTED = 29
CONSOLE = 30
PRINTER = 31
PROGRAM_ICONS = 32
RUN = 33
SETTINGS = 34
WORLD_COMPUTER = 35
ARCHIVE = 36
HOMEBANKING = 37
DRIVE_WINDOWS = 38
CLOCK = 39
EMAIL_SEARCH = 40
PAPER_FLAG = 41
MEMORY = 42
TRASH_BIN = 43
NOTE = 44
EXPIRED = 45
INFO = 46
PACKAGE = 47
FOLDER = 48
FOLDER_OPEN = 49
FOLDER_PACKAGE = 50
LOCK_OPEN = 51
PAPER_LOCKED = 52
CHECKED = 53
PEN = 54
THUMBNAIL = 55
BOOK = 56
LIST = 57
USER_KEY = 58
TOOL = 59
HOME = 60
STAR = 61
TUX = 62
FEATHER = 63
APPLE = 64
WIKI = 65
MONEY = 66
CERTIFICATE = 67
BLACKBERRY = 68
@dataclass
class EntryTemplate:
"""Base class for entry templates. Subclass to create custom templates.
Class variables to override:
_icon_id: Icon for entries using this template (default: KEY)
_include_standard: Whether to populate username/password/url (default: True)
_protected_fields: Field names that should be memory-protected
Example:
>>> @dataclass
... class VPNConnection(EntryTemplate):
... _icon_id: ClassVar[int] = IconId.TERMINAL_ENCRYPTED
... _protected_fields: ClassVar[frozenset[str]] = frozenset({"certificate"})
...
... server: str | None = None
... protocol: str = "OpenVPN"
... certificate: str | None = None
...
>>> entry = group.create_entry(
... title="Work VPN",
... template=VPNConnection(server="vpn.company.com"),
... )
"""
_icon_id: ClassVar[int] = IconId.KEY
_include_standard: ClassVar[bool] = True
_protected_fields: ClassVar[frozenset[str]] = frozenset()
def _get_fields(self) -> dict[str, tuple[str | None, bool]]:
"""Return template field values with display names and protection status.
Returns:
Dict mapping display name to (value, is_protected) tuple.
Display names are derived from field names by replacing underscores
with spaces and title-casing.
"""
result: dict[str, tuple[str | None, bool]] = {}
for field in fields(self):
if field.name.startswith("_"):
continue # Skip class variables
value = getattr(self, field.name)
display_name = field.name.replace("_", " ").title()
is_protected = field.name in self._protected_fields
result[display_name] = (value, is_protected)
return result
# --- Built-in Templates ---
@dataclass
class Login(EntryTemplate):
"""Standard login entry template.
Uses standard fields (title, username, password, url) without
additional custom fields.
"""
@dataclass
class CreditCard(EntryTemplate):
"""Credit card entry template.
Includes card number, expiry date, CVV, cardholder name, and PIN.
Sensitive fields (card_number, cvv, pin) are memory-protected.
Does not use standard username/password fields.
"""
_icon_id: ClassVar[int] = IconId.MONEY
_include_standard: ClassVar[bool] = False
_protected_fields: ClassVar[frozenset[str]] = frozenset({"card_number", "cvv", "pin"})
card_number: str | None = None
expiry_date: str | None = None
cvv: str | None = None
cardholder_name: str | None = None
pin: str | None = None
@dataclass
class SecureNote(EntryTemplate):
"""Secure note entry template.
For storing text without standard credential fields.
Use the notes parameter in create_entry() for content.
"""
_icon_id: ClassVar[int] = IconId.NOTE
_include_standard: ClassVar[bool] = False
@dataclass
class Identity(EntryTemplate):
"""Identity/personal information entry template.
Includes name, contact, and address fields.
Does not use standard username/password fields.
"""
_icon_id: ClassVar[int] = IconId.IDENTITY
_include_standard: ClassVar[bool] = False
first_name: str | None = None
last_name: str | None = None
email: str | None = None
phone: str | None = None
address: str | None = None
city: str | None = None
state: str | None = None
postal_code: str | None = None
country: str | None = None
@dataclass
class BankAccount(EntryTemplate):
"""Bank account entry template.
Includes account details and routing information.
Sensitive fields (account_number, iban, pin) are memory-protected.
Does not use standard username/password fields.
"""
_icon_id: ClassVar[int] = IconId.HOMEBANKING
_include_standard: ClassVar[bool] = False
_protected_fields: ClassVar[frozenset[str]] = frozenset({"account_number", "iban", "pin"})
bank_name: str | None = None
account_type: str | None = None
account_number: str | None = None
routing_number: str | None = None
swift_bic: str | None = None
iban: str | None = None
pin: str | None = None
@dataclass
class Server(EntryTemplate):
"""Server/SSH entry template.
Includes hostname, port, and SSH key fields.
Uses standard username/password fields for credentials.
SSH key is memory-protected.
"""
_icon_id: ClassVar[int] = IconId.CONSOLE
_protected_fields: ClassVar[frozenset[str]] = frozenset({"ssh_key"})
hostname: str | None = None
port: str = "22"
ssh_key: str | None = None
@dataclass
class WirelessRouter(EntryTemplate):
"""Wireless router entry template.
Includes SSID, security type, and admin credentials.
Admin password is memory-protected.
"""
_icon_id: ClassVar[int] = IconId.IR_COMMUNICATION
_protected_fields: ClassVar[frozenset[str]] = frozenset({"admin_password"})
ssid: str | None = None
security_type: str = "WPA2"
admin_url: str | None = None
admin_username: str | None = None
admin_password: str | None = None
@dataclass
class Email(EntryTemplate):
"""Email account entry template.
Includes email address and server settings.
Uses standard username/password fields for credentials.
"""
_icon_id: ClassVar[int] = IconId.EMAIL
email_address: str | None = None
imap_server: str | None = None
imap_port: str = "993"
smtp_server: str | None = None
smtp_port: str = "587"
@dataclass
class SoftwareLicense(EntryTemplate):
"""Software license entry template.
Includes license key and registration information.
License key is memory-protected.
Does not use standard username/password fields.
"""
_icon_id: ClassVar[int] = IconId.PACKAGE
_include_standard: ClassVar[bool] = False
_protected_fields: ClassVar[frozenset[str]] = frozenset({"license_key"})
license_key: str | None = None
registered_email: str | None = None
registered_name: str | None = None
purchase_date: str | None = None
download_url: str | None = None
@dataclass
class DatabaseConnection(EntryTemplate):
"""Database connection entry template.
Includes database type, host, port, and connection details.
Connection string is memory-protected.
Uses standard username/password fields for credentials.
"""
_icon_id: ClassVar[int] = IconId.DRIVE
_protected_fields: ClassVar[frozenset[str]] = frozenset({"connection_string"})
database_type: str = "PostgreSQL"
host: str | None = None
port: str = "5432"
database_name: str | None = None
connection_string: str | None = None
class Templates:
"""Namespace containing all built-in entry templates.
Provides discoverability via IDE autocompletion.
Usage:
>>> from kdbxtool import Templates
>>>
>>> entry = group.create_entry(
... title="My Card",
... template=Templates.CreditCard(
... card_number="4111111111111111",
... cvv="123",
... ),
... )
Available templates:
- Login: Standard login (username, password, url)
- CreditCard: Card number, expiry, CVV, cardholder, PIN
- SecureNote: Notes-only entry
- Identity: Personal information (name, address, etc.)
- BankAccount: Account and routing numbers
- Server: Hostname, port, SSH key
- WirelessRouter: SSID, security type, admin credentials
- Email: Email address and server settings
- SoftwareLicense: License key and registration info
- Database: Database connection details
"""
Login = Login
CreditCard = CreditCard
SecureNote = SecureNote
Identity = Identity
BankAccount = BankAccount
Server = Server
WirelessRouter = WirelessRouter
Email = Email
SoftwareLicense = SoftwareLicense
Database = DatabaseConnection
|