hotspot / App /Users /Model.py
Mbonea's picture
testing deployment
9e798a1
raw
history blame
2.7 kB
from tortoise import fields, models
from passlib.context import CryptContext
import datetime
import uuid
import random
import string
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def generate_short_uuid() -> str:
return "".join(random.choices(string.ascii_letters + string.digits, k=5))
class User(models.Model):
id = fields.CharField(primary_key=True, max_length=5, default=generate_short_uuid)
name = fields.CharField(max_length=100)
password = fields.CharField(max_length=100)
phoneNumber = fields.CharField(max_length=15, unique=True)
balance = fields.DecimalField(max_digits=10, decimal_places=2, default=0.00)
mac_address = fields.CharField(max_length=17)
createdAt = fields.DatetimeField(auto_now_add=True)
updatedAt = fields.DatetimeField(auto_now=True)
lastLogin = fields.DatetimeField(default=datetime.datetime.now)
failed_attempts = fields.IntField(default=0)
account_locked = fields.BooleanField(default=False)
reset_token = fields.CharField(max_length=6, null=True, unique=True)
reset_token_expiration = fields.DatetimeField(null=True)
class Meta:
table = "users"
def hash_password(self, plain_password: str) -> str:
return pwd_context.hash(plain_password)
def verify_password(self, plain_password: str) -> bool:
if (
self.account_locked
and datetime.datetime.now()
< self.lastLogin + datetime.timedelta(minutes=15)
):
print("Account is locked due to too many failed attempts. Try again later.")
return False
if pwd_context.verify(plain_password, self.password):
self.failed_attempts = 0
self.account_locked = False
self.lastLogin = datetime.datetime.now()
self.save()
return True
else:
self.failed_attempts += 1
if self.failed_attempts >= 5:
self.account_locked = True
self.save()
return False
async def initiate_password_reset(self):
self.reset_token = f"{random.randint(100000, 999999)}"
self.reset_token_expiration = datetime.datetime.now() + datetime.timedelta(
minutes=15
)
await self.save()
async def reset_password(self, reset_token: str, new_password: str):
if (
self.reset_token != reset_token
or datetime.datetime.now() > self.reset_token_expiration
):
return False
self.password = self.hash_password(new_password)
self.reset_token = None
self.reset_token_expiration = None
await self.save()
return True