This repository has been archived by the owner on Jul 18, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 324
/
Copy pathdatastore.py
133 lines (111 loc) · 3.22 KB
/
datastore.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
import os
import hashlib
try:
import argon2
A2_IMPORT = True
except:
# Maybe we can switch to a built-in passwordHasher?
print("Can't import argon2-cffi, accounts functioning will be disabled.")
A2_IMPORT = False
import pickle
import secrets
accounts = {}
session = {}
if A2_IMPORT:
ph = argon2.PasswordHasher()
else:
ph = None
def loadState():
global accounts
try:
if os.path.exists("server.dat"):
with open("server.dat", "rb") as f:
accounts = pickle.load(f)
except Exception as e:
print(e)
def persistState():
with open("server.dat", "wb") as f:
pickle.dump(accounts, f)
def register(username, password):
if ph is None:
return False, "account system disabled"
if len(username) < 3:
return False, "username too short"
if len(username) > 20:
return False, "username too long"
if len(password) < 8:
return False, "password too short"
if len(password) > 120:
return False, "password too long"
if username in accounts:
return False, "account already registered"
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
pwdhash = ph.hash(password.encode('utf-8')+salt)
acc = { "salt": salt,
"pwdhash": pwdhash,
"nickname": username,
"skin": 0,
"squad": "" }
accounts[username] = acc
persistState()
acc2 = acc.copy()
del acc2["salt"]
del acc2["pwdhash"]
token = secrets.token_urlsafe(32)
session[token] = username
acc2["session"] = token
return True, acc2
def login(username, password):
if ph is None:
return False, "account system disabled"
invalidMsg = "invalid user name or password"
if len(username) < 3:
return False, invalidMsg
if len(username) > 20:
return False, invalidMsg
if len(password) < 8:
return False, invalidMsg
if len(password) > 120:
return False, invalidMsg
if username not in accounts:
return False, invalidMsg
acc = accounts[username]
try:
ph.verify(acc["pwdhash"], password.encode('utf-8')+acc["salt"])
except:
return False, invalidMsg
acc2 = acc.copy()
del acc2["salt"]
del acc2["pwdhash"]
token = secrets.token_urlsafe(32)
session[token] = username
acc2["session"] = token
return True, acc2
def resumeSession(token):
if token not in session:
return False, "session expired, please log in"
username = session[token]
if username not in accounts:
return False, "invalid user name or password"
acc = accounts[username]
acc2 = acc.copy()
del acc2["salt"]
del acc2["pwdhash"]
acc2["username"] = username
acc2["session"] = token
return True, acc2
def updateAccount(username, data):
if username not in accounts:
return
acc = accounts[username]
if "nickname" in data:
acc["nickname"] = data["nickname"]
if "squad" in data:
acc["squad"] = data["squad"]
if "skin" in data:
acc["skin"] = data["skin"]
persistState()
def logout(token):
if token in session:
del session[token]
loadState()