5 |
5 |
6 """ |
6 """ |
7 Module implementing a class to read login data files. |
7 Module implementing a class to read login data files. |
8 """ |
8 """ |
9 |
9 |
10 from PyQt6.QtCore import ( |
10 from PyQt6.QtCore import QXmlStreamReader, QIODevice, QFile, QCoreApplication, QUrl |
11 QXmlStreamReader, QIODevice, QFile, QCoreApplication, QUrl |
|
12 ) |
|
13 |
11 |
14 |
12 |
15 class PasswordReader(QXmlStreamReader): |
13 class PasswordReader(QXmlStreamReader): |
16 """ |
14 """ |
17 Class implementing a reader object for login data files. |
15 Class implementing a reader object for login data files. |
18 """ |
16 """ |
|
17 |
19 def __init__(self): |
18 def __init__(self): |
20 """ |
19 """ |
21 Constructor |
20 Constructor |
22 """ |
21 """ |
23 super().__init__() |
22 super().__init__() |
24 |
23 |
25 def read(self, fileNameOrDevice): |
24 def read(self, fileNameOrDevice): |
26 """ |
25 """ |
27 Public method to read a login data file. |
26 Public method to read a login data file. |
28 |
27 |
29 @param fileNameOrDevice name of the file to read (string) |
28 @param fileNameOrDevice name of the file to read (string) |
30 or reference to the device to read (QIODevice) |
29 or reference to the device to read (QIODevice) |
31 @return tuple containing the logins, forms and never URLs |
30 @return tuple containing the logins, forms and never URLs |
32 """ |
31 """ |
33 self.__logins = {} |
32 self.__logins = {} |
34 self.__loginForms = {} |
33 self.__loginForms = {} |
35 self.__never = [] |
34 self.__never = [] |
36 |
35 |
37 if isinstance(fileNameOrDevice, QIODevice): |
36 if isinstance(fileNameOrDevice, QIODevice): |
38 self.setDevice(fileNameOrDevice) |
37 self.setDevice(fileNameOrDevice) |
39 else: |
38 else: |
40 f = QFile(fileNameOrDevice) |
39 f = QFile(fileNameOrDevice) |
41 if not f.exists(): |
40 if not f.exists(): |
42 return self.__logins, self.__loginForms, self.__never |
41 return self.__logins, self.__loginForms, self.__never |
43 f.open(QIODevice.OpenModeFlag.ReadOnly) |
42 f.open(QIODevice.OpenModeFlag.ReadOnly) |
44 self.setDevice(f) |
43 self.setDevice(f) |
45 |
44 |
46 while not self.atEnd(): |
45 while not self.atEnd(): |
47 self.readNext() |
46 self.readNext() |
48 if self.isStartElement(): |
47 if self.isStartElement(): |
49 version = self.attributes().value("version") |
48 version = self.attributes().value("version") |
50 if ( |
49 if self.name() == "Password" and (not version or version == "2.0"): |
51 self.name() == "Password" and |
|
52 (not version or version == "2.0") |
|
53 ): |
|
54 self.__readPasswords() |
50 self.__readPasswords() |
55 else: |
51 else: |
56 self.raiseError(QCoreApplication.translate( |
52 self.raiseError( |
57 "PasswordReader", |
53 QCoreApplication.translate( |
58 "The file is not a Passwords version 2.0 file.")) |
54 "PasswordReader", |
59 |
55 "The file is not a Passwords version 2.0 file.", |
|
56 ) |
|
57 ) |
|
58 |
60 return self.__logins, self.__loginForms, self.__never |
59 return self.__logins, self.__loginForms, self.__never |
61 |
60 |
62 def __readPasswords(self): |
61 def __readPasswords(self): |
63 """ |
62 """ |
64 Private method to read and parse the login data file. |
63 Private method to read and parse the login data file. |
65 """ |
64 """ |
66 if not self.isStartElement() and self.name() != "Password": |
65 if not self.isStartElement() and self.name() != "Password": |
67 return |
66 return |
68 |
67 |
69 while not self.atEnd(): |
68 while not self.atEnd(): |
70 self.readNext() |
69 self.readNext() |
71 if self.isEndElement(): |
70 if self.isEndElement(): |
72 break |
71 break |
73 |
72 |
74 if self.isStartElement(): |
73 if self.isStartElement(): |
75 if self.name() == "Logins": |
74 if self.name() == "Logins": |
76 self.__readLogins() |
75 self.__readLogins() |
77 elif self.name() == "Forms": |
76 elif self.name() == "Forms": |
78 self.__readForms() |
77 self.__readForms() |
79 elif self.name() == "Nevers": |
78 elif self.name() == "Nevers": |
80 self.__readNevers() |
79 self.__readNevers() |
81 else: |
80 else: |
82 self.__skipUnknownElement() |
81 self.__skipUnknownElement() |
83 |
82 |
84 def __readLogins(self): |
83 def __readLogins(self): |
85 """ |
84 """ |
86 Private method to read the login information. |
85 Private method to read the login information. |
87 """ |
86 """ |
88 if not self.isStartElement() and self.name() != "Logins": |
87 if not self.isStartElement() and self.name() != "Logins": |
89 return |
88 return |
90 |
89 |
91 while not self.atEnd(): |
90 while not self.atEnd(): |
92 self.readNext() |
91 self.readNext() |
93 if self.isEndElement(): |
92 if self.isEndElement(): |
94 if self.name() == "Login": |
93 if self.name() == "Login": |
95 continue |
94 continue |
96 else: |
95 else: |
97 break |
96 break |
98 |
97 |
99 if self.isStartElement(): |
98 if self.isStartElement(): |
100 if self.name() == "Login": |
99 if self.name() == "Login": |
101 attributes = self.attributes() |
100 attributes = self.attributes() |
102 key = attributes.value("key") |
101 key = attributes.value("key") |
103 user = attributes.value("user") |
102 user = attributes.value("user") |
104 password = attributes.value("password") |
103 password = attributes.value("password") |
105 self.__logins[key] = (user, password) |
104 self.__logins[key] = (user, password) |
106 else: |
105 else: |
107 self.__skipUnknownElement() |
106 self.__skipUnknownElement() |
108 |
107 |
109 def __readForms(self): |
108 def __readForms(self): |
110 """ |
109 """ |
111 Private method to read the forms information. |
110 Private method to read the forms information. |
112 """ |
111 """ |
113 if not self.isStartElement() and self.name() != "Forms": |
112 if not self.isStartElement() and self.name() != "Forms": |
114 return |
113 return |
115 |
114 |
116 while not self.atEnd(): |
115 while not self.atEnd(): |
117 self.readNext() |
116 self.readNext() |
118 if self.isStartElement(): |
117 if self.isStartElement(): |
119 if self.name() == "Form": |
118 if self.name() == "Form": |
120 from .LoginForm import LoginForm |
119 from .LoginForm import LoginForm |
|
120 |
121 attributes = self.attributes() |
121 attributes = self.attributes() |
122 key = attributes.value("key") |
122 key = attributes.value("key") |
123 form = LoginForm() |
123 form = LoginForm() |
124 form.url = QUrl(attributes.value("url")) |
124 form.url = QUrl(attributes.value("url")) |
125 form.name = attributes.value("name") |
125 form.name = attributes.value("name") |
126 |
126 |
127 elif self.name() == "PostData": |
127 elif self.name() == "PostData": |
128 form.postData = self.readElementText() |
128 form.postData = self.readElementText() |
129 else: |
129 else: |
130 self.__skipUnknownElement() |
130 self.__skipUnknownElement() |
131 |
131 |
132 if self.isEndElement(): |
132 if self.isEndElement(): |
133 if self.name() == "Form": |
133 if self.name() == "Form": |
134 self.__loginForms[key] = form |
134 self.__loginForms[key] = form |
135 continue |
135 continue |
136 elif self.name() in ["PostData", "Elements", "Element"]: |
136 elif self.name() in ["PostData", "Elements", "Element"]: |
137 continue |
137 continue |
138 else: |
138 else: |
139 break |
139 break |
140 |
140 |
141 def __readNevers(self): |
141 def __readNevers(self): |
142 """ |
142 """ |
143 Private method to read the never URLs. |
143 Private method to read the never URLs. |
144 """ |
144 """ |
145 if not self.isStartElement() and self.name() != "Nevers": |
145 if not self.isStartElement() and self.name() != "Nevers": |
146 return |
146 return |
147 |
147 |
148 while not self.atEnd(): |
148 while not self.atEnd(): |
149 self.readNext() |
149 self.readNext() |
150 if self.isEndElement(): |
150 if self.isEndElement(): |
151 if self.name() == "Never": |
151 if self.name() == "Never": |
152 continue |
152 continue |
153 else: |
153 else: |
154 break |
154 break |
155 |
155 |
156 if self.isStartElement(): |
156 if self.isStartElement(): |
157 if self.name() == "Never": |
157 if self.name() == "Never": |
158 self.__never.append(self.attributes().value("url")) |
158 self.__never.append(self.attributes().value("url")) |
159 else: |
159 else: |
160 self.__skipUnknownElement() |
160 self.__skipUnknownElement() |
161 |
161 |
162 def __skipUnknownElement(self): |
162 def __skipUnknownElement(self): |
163 """ |
163 """ |
164 Private method to skip over all unknown elements. |
164 Private method to skip over all unknown elements. |
165 """ |
165 """ |
166 if not self.isStartElement(): |
166 if not self.isStartElement(): |
167 return |
167 return |
168 |
168 |
169 while not self.atEnd(): |
169 while not self.atEnd(): |
170 self.readNext() |
170 self.readNext() |
171 if self.isEndElement(): |
171 if self.isEndElement(): |
172 break |
172 break |
173 |
173 |
174 if self.isStartElement(): |
174 if self.isStartElement(): |
175 self.__skipUnknownElement() |
175 self.__skipUnknownElement() |