File size: 2,896 Bytes
bffe657
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Security Models
Models for security tracking, blocked IPs, and incidents.
"""

import uuid

from sqlalchemy import Boolean, Column, DateTime, Integer, String

from core.models.base import Base, utc_now


class BlockedIP(Base):
    """
    Blocked IP Address Model
    Tracks IPs that have been blocked due to suspicious activity.
    """
    __tablename__ = "blocked_ips"

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    ip_address = Column(String, nullable=False, unique=True, index=True)
    reason = Column(String, nullable=False)
    blocked_at = Column(DateTime, default=utc_now, nullable=False)
    expires_at = Column(DateTime, nullable=True)  # Null means permanent
    blocked_by = Column(String, default="system") # system or admin user_id

    # Metadata for analysis
    country_code = Column(String, nullable=True)
    isp = Column(String, nullable=True)
    total_failed_attempts = Column(Integer, default=0)

    def to_dict(self):
        return {
            "id": self.id,
            "ip_address": self.ip_address,
            "reason": self.reason,
            "blocked_at": self.blocked_at.isoformat() if self.blocked_at else None,
            "expires_at": self.expires_at.isoformat() if self.expires_at else None,
            "blocked_by": self.blocked_by,
            "country_code": self.country_code
        }


class APIKey(Base):
    """
    API Key Model for persistent storage
    Tracks authentication keys issued to users or services.
    """
    __tablename__ = "api_keys"

    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    key_prefix = Column(String, nullable=False, index=True) # First 8 chars for identification
    key_hash = Column(String, nullable=False, unique=True, index=True) # Full hashed key
    name = Column(String, nullable=False)
    description = Column(String, nullable=True)
    user_id = Column(String, nullable=False, index=True) # Owner of the key
    permissions = Column(String, nullable=False) # JSON string of permissions
    is_active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=utc_now, nullable=False)
    expires_at = Column(DateTime, nullable=True)
    last_used_at = Column(DateTime, nullable=True)

    def to_dict(self):
        import json
        return {
            "id": self.id,
            "prefix": self.key_prefix,
            "name": self.name,
            "description": self.description,
            "user_id": self.user_id,
            "permissions": json.loads(self.permissions) if self.permissions else [],
            "is_active": self.is_active,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "expires_at": self.expires_at.isoformat() if self.expires_at else None,
            "last_used_at": self.last_used_at.isoformat() if self.last_used_at else None,
        }