mirror of
https://github.com/Significant-Gravitas/AutoModerate.git
synced 2026-11-10 04:42:00 -10:00
Keys are now stored as a SHA-256 digest in the existing key column (64 chars, no schema change). Lookups hash the presented key; rows still holding plaintext are matched and upgraded to their hash on first use. The full key is shown once at creation and the dashboard displays a masked placeholder thereafter.
60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
import hashlib
|
|
import secrets
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from app import db
|
|
|
|
|
|
class APIKey(db.Model):
|
|
__tablename__ = 'api_keys'
|
|
|
|
id = db.Column(db.String(36), primary_key=True,
|
|
default=lambda: str(uuid.uuid4()))
|
|
key = db.Column(db.String(64), unique=True, nullable=False)
|
|
name = db.Column(db.String(100), nullable=False)
|
|
project_id = db.Column(db.String(36), db.ForeignKey(
|
|
'projects.id'), nullable=False)
|
|
is_active = db.Column(db.Boolean, default=True)
|
|
last_used = db.Column(db.DateTime)
|
|
usage_count = db.Column(db.Integer, default=0)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
updated_at = db.Column(
|
|
db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
plaintext_key = None
|
|
|
|
def __init__(self, **kwargs):
|
|
super(APIKey, self).__init__(**kwargs)
|
|
if not self.key:
|
|
raw = self.generate_key()
|
|
self.plaintext_key = raw
|
|
self.key = self.hash_key(raw)
|
|
|
|
@staticmethod
|
|
def generate_key():
|
|
return f"am_{secrets.token_urlsafe(32)}"
|
|
|
|
@staticmethod
|
|
def hash_key(raw_key):
|
|
return hashlib.sha256(raw_key.strip().encode('utf-8')).hexdigest()
|
|
|
|
def increment_usage(self):
|
|
self.usage_count += 1
|
|
self.last_used = datetime.utcnow()
|
|
|
|
def to_dict(self):
|
|
return {
|
|
'id': self.id,
|
|
'name': self.name,
|
|
'project_id': self.project_id,
|
|
'is_active': self.is_active,
|
|
'last_used': self.last_used.isoformat() if self.last_used else None,
|
|
'usage_count': self.usage_count,
|
|
'created_at': self.created_at.isoformat(),
|
|
'updated_at': self.updated_at.isoformat()
|
|
}
|
|
|
|
def __repr__(self):
|
|
return f'<APIKey {self.name}>'
|