class Vendor(BaseModel): __tablename__ = "vendors" name = db.Column(db.String(), nullable=False, unique=True) # Relationships products = db.relationship("Product", back_populates="vendor") users = db.relationship("User", secondary=users_vendors) def __repr__(self): return "<Vendor {}>".format(self.name)
class Product(BaseModel): __tablename__ = "products" name = db.Column(db.String(), nullable=False, index=True) # Relationships vendor_id = db.Column(UUIDType(binary=False), db.ForeignKey("vendors.id")) vendor = db.relationship("Vendor", back_populates="products") users = db.relationship("User", secondary=users_products) def __repr__(self): return "<Product {}>".format(self.name)
class Cve(BaseModel): __tablename__ = "cves" # CVE are sorted by last modified date, we need to index it. updated_at = db.Column( db.DateTime(timezone=True), default=db.func.now(), onupdate=db.func.now(), nullable=False, index=True, ) cve_id = db.Column(db.String(), nullable=False, index=True) json = db.Column(JSONB) # We used initially secondary relationships to fetch the list of # associated vendors, products and cwes. But it was complicated # to maintain, and the performance were poor. So we now use the # JSONB data type associated to the GIN index type. vendors = db.Column(JSONB) cwes = db.Column(JSONB) # Keep the summary separated when searching keywords summary = db.Column(db.String(), nullable=False) # Keep CVSS separated when searching a particupal score cvss2 = db.Column(db.Float()) cvss3 = db.Column(db.Float()) # Relationships events = db.relationship("Event", back_populates="cve") changes = db.relationship("Change", back_populates="cve") alerts = db.relationship("Alert", back_populates="cve") # Index __table_args__ = ( db.Index("cves_vendors_gin_idx", vendors, postgresql_using="gin"), db.Index("cves_cwes_gin_idx", cwes, postgresql_using="gin"), ) def __repr__(self): return "<Cve {}>".format(self.cve_id) @property def cvss_weight(self): """Only used to sort several CVE by their CVSS""" w = 0 if self.cvss2: w += self.cvss2 if self.cvss3: w += self.cvss3 return w
class Change(BaseModel): __tablename__ = "changes" json = db.Column(JSONType) # Relationships cve_id = db.Column(UUIDType(binary=False), db.ForeignKey("cves.id")) cve = db.relationship("Cve", back_populates="changes") task_id = db.Column(UUIDType(binary=False), db.ForeignKey("tasks.id")) task = db.relationship("Task", back_populates="changes") events = db.relationship("Event", back_populates="change")
class Report(BaseModel): __tablename__ = "reports" public_link = db.Column(db.String(), default=generate_public_link) seen = db.Column(db.Boolean(), default=False) details = db.Column(JSONType) user_id = db.Column(UUIDType(binary=False), db.ForeignKey("users.id")) user = db.relationship("User", back_populates="reports") alerts = db.relationship("Alert", back_populates="report") def __repr__(self): return "<Report {}>".format(self.id)
class Event(BaseModel): __tablename__ = "events" type = db.Column(ChoiceType(EVENT_TYPES)) details = db.Column(JSONType) review = db.Column(db.Boolean, default=False) # Relationships cve_id = db.Column(UUIDType(binary=False), db.ForeignKey("cves.id")) cve = db.relationship("Cve", back_populates="events") change_id = db.Column(UUIDType(binary=False), db.ForeignKey("changes.id")) change = db.relationship("Change", back_populates="events") alerts = db.relationship("Alert", secondary=alerts_events) def __repr__(self): return "<Event {}>".format(self.type)
class Task(BaseModel): __tablename__ = "tasks" # Relationships changes = db.relationship("Change", back_populates="task") def __repr__(self): return "<Task {}>".format(self.created_at)
class User(BaseModel, UserMixin): __tablename__ = "users" # User authentication information username = db.Column(db.String(50), nullable=False, unique=True) password = db.Column(db.String(255), nullable=False, server_default="") reset_password_token = db.Column(db.String(100), nullable=False, server_default="") # User email information email = db.Column(db.String(255), nullable=False, unique=True) email_confirmed_at = db.Column(db.DateTime(timezone=True)) # Notification parameters enable_notifications = db.Column(db.Boolean(), nullable=False, server_default=expression.true()) filters_notifications = db.Column(JSONType, default=get_default_filters) frequency_notifications = db.Column(ChoiceType(FREQUENCIES_TYPES), default="always") # User information active = db.Column("is_active", db.Boolean(), nullable=False, server_default=expression.false()) first_name = db.Column(db.String(100), nullable=False, server_default="") last_name = db.Column(db.String(100), nullable=False, server_default="") admin = db.Column(db.Boolean, unique=False, server_default=expression.false()) # Relationships vendors = db.relationship("Vendor", secondary=users_vendors) products = db.relationship("Product", secondary=users_products) alerts = db.relationship("Alert", back_populates="user") reports = db.relationship("Report", back_populates="user") @property def is_confirmed(self): return bool(self.email_confirmed_at) def __repr__(self): return "<User {}>".format(self.username)
class Alert(BaseModel): __tablename__ = "alerts" details = db.Column(JSONType) notify = db.Column(db.Boolean, default=False) # Relationships events = db.relationship("Event", secondary=alerts_events) user_id = db.Column(UUIDType(binary=False), db.ForeignKey("users.id")) user = db.relationship("User", back_populates="alerts") cve_id = db.Column(UUIDType(binary=False), db.ForeignKey("cves.id")) cve = db.relationship("Cve", back_populates="alerts") report_id = db.Column(UUIDType(binary=False), db.ForeignKey("reports.id"), nullable=True) report = db.relationship("Report", back_populates="alerts") def __repr__(self): return "<Alert {}>".format(self.id)
class CveTag(BaseModel): __tablename__ = "cves_tags" tags = db.Column(JSONB) # Relationships user_id = db.Column(UUIDType(binary=False), db.ForeignKey("users.id")) user = db.relationship("User", back_populates="cve_tags") cve_id = db.Column(UUIDType(binary=False), db.ForeignKey("cves.id")) # Index __table_args__ = (db.Index("ix_cves_tags", tags, postgresql_using="gin"), ) def __repr__(self): return "<CveTag {}>".format(self.id)
class UserTag(BaseModel): __tablename__ = "users_tags" name = db.Column(db.String(), nullable=False) description = db.Column(db.String()) color = db.Column(db.String(), nullable=False) # Relationships user_id = db.Column(UUIDType(binary=False), db.ForeignKey("users.id"), nullable=False) user = db.relationship("User", back_populates="tags") __table_args__ = (UniqueConstraint("name", "user_id", name="ix_userstags_name_userid"), ) def __repr__(self): return "<UserTag {}>".format(self.id)