Skip to content

Commit e2dd0a7

Browse files
committed
pep-8
1 parent 4668a57 commit e2dd0a7

1 file changed

Lines changed: 68 additions & 71 deletions

File tree

dop/credentials.py

Lines changed: 68 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3,82 +3,79 @@
33
import os
44
import textwrap
55
import getpass
6+
67
from binascii import hexlify, unhexlify as hex2bin
78
from Crypto.Hash import SHA256
89
from Crypto.Cipher import AES
910
from Crypto.Random import new as srand
1011

1112
bin2hex = lambda i: hexlify(i).decode('utf8')
1213

13-
class Credentials:
14-
15-
def __init__(self, filename):
16-
self.filename = filename
17-
self.client_id = None
18-
self.api_key = None
19-
20-
def available(self):
21-
return os.path.isfile(self.filename)
22-
23-
24-
def load(self):
25-
with open(self.filename, 'r') as f:
26-
data = json.loads(f.read())
27-
for i in range(0, 3):
28-
password = getpass.getpass('Password to restore Digital Ocean credentials: ')
29-
try:
30-
(self.client_id, self.api_key) = self.decrypt(data, password)
31-
break
32-
except UnicodeDecodeError:
33-
print("bad password.", 2 - i, "retries left")
34-
if self.client_id is None or self.api_key is None:
35-
raise RuntimeError('Failed to decrypt Digital Ocean credentials: bad password')
36-
37-
38-
def input(self):
39-
print(textwrap.dedent("""\
40-
Every API call needs Client Id and API Key.
41-
This credentials could be obtained here: https://cloud.digitalocean.com/api_access
42-
"""))
43-
self.client_id = input("Please enter DO Client Id: ")
44-
self.api_key = input("Please enter DO API Key: ")
45-
4614

47-
def get(self):
48-
return (self.client_id, self.api_key)
49-
50-
51-
def save(self):
52-
with open(self.filename, 'w') as f:
53-
print("You're going to store Digital Ocean credentials in file: ", self.filename)
54-
password = getpass.getpass("Please enter encryption password: ")
55-
f.write(self.encrypt(self.client_id, self.api_key, password))
56-
57-
58-
def makeKey(self, password, salt):
59-
salt_hash = SHA256.new()
60-
salt_hash.update(salt)
61-
pass_hash = SHA256.new()
62-
pass_hash.update(salt_hash.hexdigest().encode('utf8'))
63-
pass_hash.update(password.encode('utf8'))
64-
return pass_hash.digest()
65-
66-
67-
def encrypt(self, client_id, api_key, password):
68-
rand = srand()
69-
salt = rand.read(32)
70-
iv = rand.read(AES.block_size)
71-
key = self.makeKey(password, salt)
72-
cipher = AES.new(key, AES.MODE_CFB, iv)
73-
encdata = cipher.encrypt(json.dumps([client_id, api_key]).encode('utf8'))
74-
return json.dumps([bin2hex(salt), bin2hex(iv), bin2hex(encdata)])
75-
76-
77-
def decrypt(self, file_json_data, password):
78-
salt = hex2bin(file_json_data[0])
79-
iv = hex2bin(file_json_data[1])
80-
encdata = hex2bin(file_json_data[2])
81-
key = self.makeKey(password, salt)
82-
cipher = AES.new(key, AES.MODE_CFB, iv)
83-
decdata = cipher.decrypt(encdata).decode('utf8')
84-
return tuple(json.loads(decdata))
15+
class Credentials:
16+
def __init__(self, filename):
17+
self.filename = filename
18+
self.client_id = None
19+
self.api_key = None
20+
21+
def available(self):
22+
return os.path.isfile(self.filename)
23+
24+
def load(self):
25+
with open(self.filename, 'r') as f:
26+
data = json.loads(f.read())
27+
for i in range(0, 3):
28+
password = getpass.getpass(
29+
'Password to restore Digital Ocean credentials: ')
30+
try:
31+
(self.client_id, self.api_key) = self.decrypt(data, password)
32+
break
33+
except UnicodeDecodeError:
34+
print("bad password.", 2 - i, "retries left")
35+
if self.client_id is None or self.api_key is None:
36+
raise RuntimeError(
37+
'Failed to decrypt Digital Ocean credentials: bad password')
38+
39+
def input(self):
40+
print(textwrap.dedent("""\
41+
Every API call needs Client Id and API Key.
42+
This credentials could be obtained here: https://cloud.digitalocean.com/api_access
43+
"""))
44+
self.client_id = input("Please enter DO Client Id: ")
45+
self.api_key = input("Please enter DO API Key: ")
46+
47+
def get(self):
48+
return self.client_id, self.api_key
49+
50+
def save(self):
51+
with open(self.filename, 'w') as f:
52+
print("You're going to store Digital Ocean credentials in file: ",
53+
self.filename)
54+
password = getpass.getpass("Please enter encryption password: ")
55+
f.write(self.encrypt(self.client_id, self.api_key, password))
56+
57+
def makeKey(self, password, salt):
58+
salt_hash = SHA256.new()
59+
salt_hash.update(salt)
60+
pass_hash = SHA256.new()
61+
pass_hash.update(salt_hash.hexdigest().encode('utf8'))
62+
pass_hash.update(password.encode('utf8'))
63+
return pass_hash.digest()
64+
65+
def encrypt(self, client_id, api_key, password):
66+
rand = srand()
67+
salt = rand.read(32)
68+
iv = rand.read(AES.block_size)
69+
key = self.makeKey(password, salt)
70+
cipher = AES.new(key, AES.MODE_CFB, iv)
71+
encdata = cipher.encrypt(json.dumps([client_id, api_key]).encode('utf8'))
72+
return json.dumps([bin2hex(salt), bin2hex(iv), bin2hex(encdata)])
73+
74+
def decrypt(self, file_json_data, password):
75+
salt = hex2bin(file_json_data[0])
76+
iv = hex2bin(file_json_data[1])
77+
encdata = hex2bin(file_json_data[2])
78+
key = self.makeKey(password, salt)
79+
cipher = AES.new(key, AES.MODE_CFB, iv)
80+
decdata = cipher.decrypt(encdata).decode('utf8')
81+
return tuple(json.loads(decdata))

0 commit comments

Comments
 (0)