This repository has been archived by the owner on Dec 15, 2024. It is now read-only.
forked from davidnemec/bitwarden-to-keepass
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitem.py
168 lines (123 loc) · 4.08 KB
/
item.py
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
"""Item management functionality for Bitwarden to KeePass conversion.
Provides classes and functions for handling different types of Bitwarden items
when converting them to KeePass entries.
"""
from enum import IntEnum
from urllib.parse import parse_qsl, urlsplit
class ItemType(IntEnum):
"""Enumeration of Bitwarden item types.
Attributes:
LOGIN: Login credentials
SECURE_NOTE: Secure note
CARD: Credit/debit card
IDENTITY: Identity information
"""
LOGIN = 1
SECURE_NOTE = 2
CARD = 3
IDENTITY = 4
class CustomFieldType(IntEnum):
"""Enumeration of Bitwarden custom field types.
Attributes:
TEXT: Plain text field
HIDDEN: Hidden/masked field
BOOLEAN: Boolean/checkbox field
"""
TEXT = 0
HIDDEN = 1
BOOLEAN = 2
class Item:
"""Wrapper for Bitwarden vault items.
Provides methods to access and format item data for conversion to KeePass.
"""
def __init__(self, item):
"""Initialize a new item wrapper.
Args:
item: Raw Bitwarden item data
"""
self.item = item
def get_id(self) -> str:
"""Get item's unique identifier.
Returns:
Bitwarden item ID
"""
return self.item["id"]
def get_name(self) -> str:
"""Get item's display name.
Returns:
Item name/title
"""
return self.item["name"]
def get_folder_id(self) -> str:
"""Get ID of folder containing this item.
Returns:
Bitwarden folder ID
"""
return self.item["folderId"]
def get_username(self) -> str:
"""Get username for login items.
Returns:
Username string or empty string if not a login
"""
if "login" not in self.item:
return ""
return self.item["login"]["username"] if self.item["login"]["username"] else ""
def get_password(self) -> str:
"""Get password for login items.
Returns:
Password string or empty string if not a login
"""
if "login" not in self.item:
return ""
return self.item["login"]["password"] if self.item["login"]["password"] else ""
def get_notes(self):
"""Get item's notes field.
Returns:
Notes text
"""
return self.item["notes"]
def get_uris(self):
"""Get URIs associated with login items.
Returns:
List of URI objects
"""
if "login" not in self.item or "uris" not in self.item["login"]:
return []
for uri in self.item["login"]["uris"]:
uri["uri"] = uri["uri"] if uri["uri"] is not None else ""
return self.item["login"]["uris"]
def get_custom_fields(self):
"""Get item's custom fields.
Returns:
List of custom field objects
"""
if "fields" not in self.item:
return []
for field in self.item["fields"]:
field["name"] = field["name"] if field["name"] is not None else ""
field["value"] = field["value"] if field["value"] is not None else ""
field["type"] = CustomFieldType(field["type"])
return self.item["fields"]
def get_attachments(self):
"""Get item's attachments.
Returns:
List of attachment objects
"""
if "attachments" not in self.item:
return []
return self.item["attachments"]
def get_totp(self):
"""Get TOTP configuration for login items.
Returns:
Tuple of (secret, settings) or (None, None) if not configured
"""
if "login" not in self.item:
return None, None
if not self.item["login"]["totp"]:
return None, None
params = urlsplit(self.item["login"]["totp"]).query
params = dict(parse_qsl(params))
period = params.get("period", 30)
digits = params.get("digits", 6)
secret = params.get("secret", self.item["login"]["totp"])
return secret, f"{period};{digits}"