11from flask_sqlalchemy import SQLAlchemy
22from flask_login import UserMixin
33from werkzeug .security import generate_password_hash , check_password_hash
4+ from cryptography .fernet import Fernet
45import pyotp
56import base64
67import os
@@ -18,12 +19,49 @@ class User(UserMixin, db.Model):
1819 created_at = db .Column (db .DateTime , default = datetime .utcnow )
1920 last_login = db .Column (db .DateTime , nullable = True )
2021
22+ # DirectAdmin Settings (encrypted)
23+ da_server = db .Column (db .String (255 ), nullable = True )
24+ da_username = db .Column (db .String (255 ), nullable = True )
25+ da_password_encrypted = db .Column (db .Text , nullable = True )
26+ da_domain = db .Column (db .String (255 ), nullable = True )
27+
28+ # Encryption key for DA password (unique per user)
29+ encryption_key = db .Column (db .String (255 ), nullable = True )
30+
31+ def __init__ (self , ** kwargs ):
32+ super (User , self ).__init__ (** kwargs )
33+ # Generate encryption key for this user
34+ if not self .encryption_key :
35+ self .encryption_key = Fernet .generate_key ().decode ()
36+
2137 def set_password (self , password ):
2238 self .password_hash = generate_password_hash (password )
2339
2440 def check_password (self , password ):
2541 return check_password_hash (self .password_hash , password )
2642
43+ def set_da_password (self , password ):
44+ """Encrypt and store DirectAdmin password"""
45+ if password :
46+ f = Fernet (self .encryption_key .encode ())
47+ self .da_password_encrypted = f .encrypt (password .encode ()).decode ()
48+ else :
49+ self .da_password_encrypted = None
50+
51+ def get_da_password (self ):
52+ """Decrypt and return DirectAdmin password"""
53+ if self .da_password_encrypted and self .encryption_key :
54+ try :
55+ f = Fernet (self .encryption_key .encode ())
56+ return f .decrypt (self .da_password_encrypted .encode ()).decode ()
57+ except :
58+ return None
59+ return None
60+
61+ def has_da_config (self ):
62+ """Check if user has configured DirectAdmin settings"""
63+ return all ([self .da_server , self .da_username , self .da_password_encrypted , self .da_domain ])
64+
2765 def generate_totp_secret (self ):
2866 secret = base64 .b32encode (os .urandom (10 )).decode ('utf-8' )
2967 self .totp_secret = secret
@@ -48,5 +86,6 @@ def to_dict(self):
4886 'is_admin' : self .is_admin ,
4987 'totp_enabled' : self .totp_enabled ,
5088 'created_at' : self .created_at .isoformat () if self .created_at else None ,
51- 'last_login' : self .last_login .isoformat () if self .last_login else None
89+ 'last_login' : self .last_login .isoformat () if self .last_login else None ,
90+ 'has_da_config' : self .has_da_config ()
5291 }
0 commit comments