2025-06-02 19:23:04 +08:00
|
|
|
import datetime
|
|
|
|
import hashlib
|
|
|
|
import uuid
|
|
|
|
|
|
|
|
import sqlalchemy as db
|
|
|
|
from .ConnectionString import ConnectionString
|
|
|
|
|
|
|
|
|
|
|
|
class DashboardClientsTOTP:
|
|
|
|
def __init__(self):
|
|
|
|
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
|
|
|
self.metadata = db.MetaData()
|
|
|
|
self.dashboardClientsTOTPTable = db.Table(
|
|
|
|
'DashboardClientsTOTPTokens', self.metadata,
|
|
|
|
db.Column("Token", db.String(500), primary_key=True, index=True),
|
|
|
|
db.Column("ClientID", db.String(500), index=True),
|
|
|
|
db.Column(
|
|
|
|
"ExpireTime", (db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
self.metadata.create_all(self.engine)
|
2025-06-03 03:02:06 +08:00
|
|
|
self.metadata.reflect(self.engine)
|
|
|
|
self.dashboardClientsTable = self.metadata.tables['DashboardClients']
|
2025-06-02 19:23:04 +08:00
|
|
|
|
|
|
|
def GenerateToken(self, ClientID) -> str:
|
|
|
|
token = hashlib.sha512(f"{ClientID}_{datetime.datetime.now()}_{uuid.uuid4()}".encode()).hexdigest()
|
|
|
|
with self.engine.begin() as conn:
|
|
|
|
conn.execute(
|
|
|
|
self.dashboardClientsTOTPTable.update().values({
|
|
|
|
"ExpireTime": datetime.datetime.now()
|
|
|
|
}).where(
|
|
|
|
db.and_(self.dashboardClientsTOTPTable.c.ClientID == ClientID, self.dashboardClientsTOTPTable.c.ExpireTime > datetime.datetime.now())
|
|
|
|
)
|
|
|
|
)
|
|
|
|
conn.execute(
|
|
|
|
self.dashboardClientsTOTPTable.insert().values({
|
|
|
|
"Token": token,
|
|
|
|
"ClientID": ClientID,
|
|
|
|
"ExpireTime": datetime.datetime.now() + datetime.timedelta(minutes=10)
|
|
|
|
})
|
|
|
|
)
|
|
|
|
return token
|
2025-06-03 03:02:06 +08:00
|
|
|
|
2025-06-03 23:37:43 +08:00
|
|
|
def RevokeToken(self, Token) -> bool:
|
|
|
|
try:
|
|
|
|
with self.engine.begin() as conn:
|
|
|
|
conn.execute(
|
|
|
|
self.dashboardClientsTOTPTable.update().values({
|
|
|
|
"ExpireTime": datetime.datetime.now()
|
|
|
|
}).where(
|
|
|
|
self.dashboardClientsTOTPTable.c.Token == Token
|
|
|
|
)
|
|
|
|
)
|
|
|
|
except Exception as e:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2025-06-03 03:02:06 +08:00
|
|
|
def GetTotp(self, token: str) -> tuple[bool, dict] or tuple[bool, None]:
|
|
|
|
with self.engine.connect() as conn:
|
|
|
|
totp = conn.execute(
|
|
|
|
db.select(
|
|
|
|
self.dashboardClientsTable.c.ClientID,
|
|
|
|
self.dashboardClientsTable.c.Email,
|
|
|
|
self.dashboardClientsTable.c.TotpKey,
|
|
|
|
self.dashboardClientsTable.c.TotpKeyVerified,
|
|
|
|
).select_from(
|
|
|
|
self.dashboardClientsTOTPTable
|
|
|
|
).where(
|
|
|
|
db.and_(
|
|
|
|
self.dashboardClientsTOTPTable.c.Token == token,
|
|
|
|
self.dashboardClientsTOTPTable.c.ExpireTime > datetime.datetime.now()
|
|
|
|
)
|
|
|
|
).join(
|
|
|
|
self.dashboardClientsTable,
|
|
|
|
self.dashboardClientsTOTPTable.c.ClientID == self.dashboardClientsTable.c.ClientID
|
|
|
|
)
|
|
|
|
).mappings().fetchone()
|
|
|
|
if totp:
|
|
|
|
return True, dict(totp)
|
|
|
|
return False, None
|
|
|
|
|
2025-06-02 19:23:04 +08:00
|
|
|
|