Skip to content

Commit cb4cf24

Browse files
committed
Import Local Blob fetching code, with changes from erikson1970/lastpass-python.
Import SecureNote parsing code, with changes from nadavshalev/lastpass-python. Pylint pass and uncrustify code. Fix pycodestyle issues.
1 parent 403efc2 commit cb4cf24

9 files changed

Lines changed: 250 additions & 75 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ example/credentials.json
44

55
*.egg-info/
66
dist/
7+
build
78
.tox
9+
.eggs
810

911
.python-version
1012
.idea/

example/example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@
3636

3737

3838
for index, i in enumerate(vault.accounts):
39-
print("{} {} {} {} {} {} {} {}".format(index + 1, i.id, i.name, i.username, i.password, i.url, i.group, i.notes))
39+
print("{} {}".format(index + 1, str(i)))

lastpass/account.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,47 @@
11
# coding: utf-8
2+
import types
3+
4+
25
class Account(object):
3-
def __init__(self, id, name, username, password, url, group, notes=None):
4-
self.id = id
6+
"""
7+
Lastpass Password Account
8+
"""
9+
def __init__(self, _id, name, username, password, url, group, notes=None):
10+
self.id = _id
511
self.name = name
612
self.username = username
713
self.password = password
814
self.url = url
915
self.group = group
1016
self.notes = notes
17+
18+
def notes_string(self):
19+
if type(self.notes) == bytes:
20+
note_str = '{}'.format(self.notes.decode())
21+
else:
22+
note_str = '{}'.format(str(self.notes))
23+
return note_str
24+
25+
def fields(self):
26+
result_fields = []
27+
for field in dir(self):
28+
if not field.startswith('_') and not callable(getattr(self, field)):
29+
result_fields.append(field)
30+
return result_fields
31+
32+
def __str__(self):
33+
return "name: {}\n\tusername: {}\n\tpassword: {}\n\turl: {}\n\tgroup: {}\n\tnotes: {}".format(self.name, self.username, self.password, self.url, self.group, self.notes_string())
34+
35+
36+
class SecureNote(Account):
37+
"""
38+
Lastpass Secure Note
39+
"""
40+
def __init__(self):
41+
pass
42+
43+
def __str__(self):
44+
try:
45+
return getattr(self, 'unparsed_notes_0').decode()
46+
except AttributeError:
47+
return '\n'.join(['\t\t{}: {}'.format(field, getattr(self, field).decode()) for field in self.fields()])

lastpass/blob.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# coding: utf-8
22
class Blob(object):
3-
def __init__(self, bytes, key_iteration_count):
4-
self.bytes = bytes
3+
def __init__(self, bytes_, key_iteration_count):
4+
self.bytes = bytes_
55
self.key_iteration_count = key_iteration_count
66

77
def encryption_key(self, username, password):

lastpass/chunk.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# coding: utf-8
22
class Chunk(object):
3-
def __init__(self, id, payload):
4-
self.id = id
3+
def __init__(self, id_, payload):
4+
self.id = id_
55
self.payload = payload
66

77
def __eq__(self, other):

lastpass/fetcher.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import string
55
from base64 import b64decode
66
from binascii import hexlify
7-
import requests
87
from xml.etree import ElementTree as etree
8+
import requests
9+
910
from . import blob
1011
from .exceptions import (
1112
NetworkError,
@@ -59,7 +60,7 @@ def request_iteration_count(username, web_client=http):
5960

6061
try:
6162
count = int(response.content)
62-
except:
63+
except Exception:
6364
raise InvalidResponseError('Key iteration count is invalid')
6465

6566
if count > 0:
@@ -123,7 +124,6 @@ def oob_login(web_client, parsed_response, body, key_iteration_count, trust_id):
123124
'error')
124125
if 'outofbandname' not in error.attrib or 'capabilities' not in error.attrib:
125126
return (None, parsed_response)
126-
oob_name = error.attrib['outofbandname']
127127
oob_capabilities = error.attrib['capabilities'].split(',')
128128
can_do_passcode = 'passcode' in oob_capabilities
129129
if can_do_passcode and 'outofband' not in oob_capabilities:
@@ -173,11 +173,12 @@ def create_session(parsed_response, key_iteration_count, trust_id):
173173
token = ok_response.attrib.get('token')
174174
if isinstance(session_id, str):
175175
return Session(session_id, key_iteration_count, token, trust_id)
176+
return None
176177

177178

178179
def login_error(parsed_response):
179180
error = None if parsed_response.tag != 'response' else parsed_response.find('error')
180-
if error is None or len(error.attrib) == 0:
181+
if error is None or not error.attrib:
181182
raise UnknownResponseSchemaError()
182183

183184
exceptions = {
@@ -198,27 +199,25 @@ def login_error(parsed_response):
198199
return InvalidResponseError(message)
199200

200201

201-
def decode_blob(blob):
202-
return b64decode(blob)
202+
def decode_blob(blob_):
203+
return b64decode(blob_)
203204

204205

205206
def make_key(username, password, key_iteration_count):
206207
# type: (str, str, int) -> bytes
207208
if key_iteration_count == 1:
208209
return hashlib.sha256(username.encode('utf-8') + password.encode('utf-8')).digest()
209-
else:
210-
return hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), username.encode('utf-8'), key_iteration_count, 32)
210+
return hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), username.encode('utf-8'), key_iteration_count, 32)
211211

212212

213213
def make_hash(username, password, key_iteration_count):
214214
# type: (str, str, int) -> bytes
215215
if key_iteration_count == 1:
216216
return bytearray(hashlib.sha256(hexlify(make_key(username, password, 1)) + password.encode('utf-8')).hexdigest(), 'ascii')
217-
else:
218-
return hexlify(hashlib.pbkdf2_hmac(
219-
'sha256',
220-
make_key(username, password, key_iteration_count),
221-
password.encode('utf-8'),
222-
1,
223-
32
224-
))
217+
return hexlify(hashlib.pbkdf2_hmac(
218+
'sha256',
219+
make_key(username, password, key_iteration_count),
220+
password.encode('utf-8'),
221+
1,
222+
32
223+
))

0 commit comments

Comments
 (0)