Repository navigation
Expand file tree
/
Copy pathauth.py
More file actions
196 lines (148 loc) · 4.62 KB
/
Copy pathauth.py
File metadata and controls
196 lines (148 loc) · 4.62 KB
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import hashlib
from time import sleep
from decorators import log
from storage import load_users, save_users, get_next_id
from models import User
def hash_password(password):
return hashlib.sha256(password.encode()).hexdigest()
def find_user_by_username(user_list, username):
for user in user_list:
if user["username"] == username:
return user
return None
def username_is_valid(username):
if username == "":
print("Username cannot be empty.")
return False
if len(username) < 5:
print("Username must be at least 5 characters.")
return False
if len(username) > 20:
print("Username must be at most 20 characters.")
return False
return True
def password_is_valid(password):
if password == "":
print("Password cannot be empty.")
return False
if len(password) < 5:
print("Password must be at least 5 characters.")
return False
if " " in password:
print("Password cannot contain spaces.")
return False
has_letter = False
has_number = False
for ch in password:
if ch.isalpha():
has_letter = True
if ch.isdigit():
has_number = True
if has_letter == False:
print("Password must contain at least 1 letter.")
return False
if has_number == False:
print("Password must contain at least 1 number.")
return False
return True
@log
def register():
users_list = load_users()
print("\n---- REGISTER ----")
print("Type 0 to cancel.")
while True:
username = input("Create username: ").strip()
if username == "0":
print("Cancelled.")
sleep(1)
return None
if not username_is_valid(username):
sleep(1)
continue
if find_user_by_username(users_list, username) is not None:
print("Username already exists.")
sleep(1)
continue
break
print("\nPassword rules:")
print("- At least 5 characters")
print("- Must contain at least 1 letter")
print("- Must contain at least 1 number")
print("- No spaces")
print("Type 0 to cancel.")
while True:
password = input("Create a password: ").strip()
if password == "0":
print("Cancelled.")
sleep(1)
return None
if not password_is_valid(password):
sleep(1)
continue
confirm = input("Confirm password: ").strip()
if confirm == "0":
print("Cancelled.")
sleep(1)
return None
if confirm != password:
print("Passwords do not match.")
sleep(1)
continue
break
new_id = get_next_id(users_list)
user_object = User(
user_id=new_id,
username=username,
password_hash=hash_password(password),
is_locked=False
)
users_list.append(user_object.user_to_dict())
save_users(users_list)
print("Account has been created.")
sleep(1)
return user_object.user_to_dict()
@log
def login():
users_list = load_users()
print("\n---- LOGIN ----")
print("Type 0 to cancel.")
user = None
user_tries = 0
while user is None:
username = input("Username: ").strip()
if username == "0":
print("Cancelled.")
sleep(1)
return None
user = find_user_by_username(users_list, username)
if user is None:
user_tries = user_tries + 1
wait_seconds = 1 + (user_tries * 2)
print("User not found.")
print(f"Please wait {wait_seconds} seconds...")
sleep(wait_seconds)
if user.get("is_locked") == True:
print("Account locked. Please contact support.")
sleep(2)
return None
password_tries = 0
while password_tries < 3:
password = input("Password: ").strip()
if password == "0":
print("Cancelled.")
sleep(1)
return None
if hash_password(password) == user["password_hash"]:
print("Login successful.")
sleep(1)
return user
password_tries = password_tries + 1
wait_seconds = 1 + (password_tries * 2)
print(f"Wrong password {3 - password_tries} tries remaining.")
print(f"Please wait {wait_seconds} seconds...")
sleep(wait_seconds)
user["is_locked"] = True
save_users(users_list)
print("Too many tries. Account has been locked.")
sleep(2)
return None