hcornet 506716e703
Some checks failed
Deployment Verification / deploy-and-test (push) Failing after 29s
first sync
2025-03-04 07:59:21 +01:00

356 lines
8.8 KiB
Python

#!/usr/bin/env python3
#
# IRIS Source Code
# Copyright (C) 2021 - Airbus CyberSecurity (SAS)
# ir@cyberactionlab.net
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from flask_login import current_user
from sqlalchemy import and_
from app import db
from app.datamgmt.states import update_ioc_state
from app.iris_engine.access_control.utils import ac_get_fast_user_cases_access
from app.models import CaseEventsIoc
from app.models import Cases
from app.models import Client
from app.models import Comments
from app.models import Ioc
from app.models import IocAssetLink
from app.models import IocComments
from app.models import IocLink
from app.models import IocType
from app.models import Tlp
from app.models.authorization import User
def get_iocs(caseid):
iocs = IocLink.query.with_entities(
Ioc.ioc_value,
Ioc.ioc_id,
Ioc.ioc_uuid
).filter(
IocLink.case_id == caseid,
IocLink.ioc_id == Ioc.ioc_id
).all()
return iocs
def get_ioc(ioc_id, caseid=None):
if caseid:
return IocLink.query.with_entities(
Ioc
).filter(and_(
Ioc.ioc_id == ioc_id,
IocLink.case_id == caseid
)).join(
IocLink.ioc
).first()
return Ioc.query.filter(Ioc.ioc_id == ioc_id).first()
def update_ioc(ioc_type, ioc_tags, ioc_value, ioc_description, ioc_tlp, userid, ioc_id):
ioc = get_ioc(ioc_id)
if ioc:
ioc.ioc_type = ioc_type
ioc.ioc_tags = ioc_tags
ioc.ioc_value = ioc_value
ioc.ioc_description = ioc_description
ioc.ioc_tlp_id = ioc_tlp
ioc.user_id = userid
db.session.commit()
else:
return False
def delete_ioc(ioc, caseid):
with db.session.begin_nested():
IocLink.query.filter(
and_(
IocLink.ioc_id == ioc.ioc_id,
IocLink.case_id == caseid
)
).delete()
res = IocLink.query.filter(
IocLink.ioc_id == ioc.ioc_id,
).all()
if res:
return False
IocAssetLink.query.filter(
IocAssetLink.ioc_id == ioc.ioc_id
).delete()
CaseEventsIoc.query.filter(
CaseEventsIoc.ioc_id == ioc.ioc_id
).delete()
com_ids = IocComments.query.with_entities(
IocComments.comment_id
).filter(
IocComments.comment_ioc_id == ioc.ioc_id
).all()
com_ids = [c.comment_id for c in com_ids]
IocComments.query.filter(IocComments.comment_id.in_(com_ids)).delete()
Comments.query.filter(Comments.comment_id.in_(com_ids)).delete()
db.session.delete(ioc)
update_ioc_state(caseid=caseid)
return True
def get_detailed_iocs(caseid):
detailed_iocs = IocLink.query.with_entities(
Ioc.ioc_id,
Ioc.ioc_uuid,
Ioc.ioc_value,
Ioc.ioc_type_id,
IocType.type_name.label('ioc_type'),
Ioc.ioc_type_id,
Ioc.ioc_description,
Ioc.ioc_tags,
Ioc.ioc_misp,
Tlp.tlp_name,
Tlp.tlp_bscolor,
Ioc.ioc_tlp_id
).filter(
and_(IocLink.case_id == caseid,
IocLink.ioc_id == Ioc.ioc_id)
).join(IocLink.ioc,
Ioc.tlp,
Ioc.ioc_type
).order_by(IocType.type_name).all()
return detailed_iocs
def get_ioc_links(ioc_id, caseid):
search_condition = and_(Cases.case_id.in_([]))
user_search_limitations = ac_get_fast_user_cases_access(current_user.id)
if user_search_limitations:
search_condition = and_(Cases.case_id.in_(user_search_limitations))
ioc_link = IocLink.query.with_entities(
Cases.case_id,
Cases.name.label('case_name'),
Client.name.label('client_name')
).filter(and_(
IocLink.ioc_id == ioc_id,
IocLink.case_id != caseid,
search_condition)
).join(IocLink.case, Cases.client).all()
return ioc_link
def find_ioc(ioc_value, ioc_type_id):
ioc = Ioc.query.filter(Ioc.ioc_value == ioc_value,
Ioc.ioc_type_id == ioc_type_id).first()
return ioc
def add_ioc(ioc, user_id, caseid):
if not ioc:
return None, False
ioc.user_id = user_id
db_ioc = find_ioc(ioc.ioc_value, ioc.ioc_type_id)
if not db_ioc:
db.session.add(ioc)
update_ioc_state(caseid=caseid)
db.session.commit()
return ioc, False
else:
# IoC already exists
return db_ioc, True
def find_ioc_link(ioc_id, caseid):
db_link = IocLink.query.filter(
IocLink.case_id == caseid,
IocLink.ioc_id == ioc_id
).first()
return db_link
def add_ioc_link(ioc_id, caseid):
db_link = find_ioc_link(ioc_id, caseid)
if db_link:
# Link already exists
return True
else:
link = IocLink()
link.case_id = caseid
link.ioc_id = ioc_id
db.session.add(link)
db.session.commit()
return False
def get_ioc_types_list():
ioc_types = IocType.query.with_entities(
IocType.type_id,
IocType.type_name,
IocType.type_description,
IocType.type_taxonomy,
IocType.type_validation_regex,
IocType.type_validation_expect,
).all()
l_types = [row._asdict() for row in ioc_types]
return l_types
def add_ioc_type(name:str, description:str, taxonomy:str):
ioct = IocType(type_name=name,
type_description=description,
type_taxonomy=taxonomy
)
db.session.add(ioct)
db.session.commit()
return ioct
def check_ioc_type_id(type_id: int):
type_id = IocType.query.filter(
IocType.type_id == type_id
).first()
return type_id
def get_ioc_type_id(type_name: str):
type_id = IocType.query.filter(
IocType.type_name == type_name
).first()
return type_id if type_id else None
def get_tlps():
return [(tlp.tlp_id, tlp.tlp_name) for tlp in Tlp.query.all()]
def get_tlps_dict():
tlpDict = {}
for tlp in Tlp.query.all():
tlpDict[tlp.tlp_name]=tlp.tlp_id
return tlpDict
def get_case_ioc_comments(ioc_id):
return Comments.query.filter(
IocComments.comment_ioc_id == ioc_id
).with_entities(
Comments
).join(
IocComments,
Comments.comment_id == IocComments.comment_id
).order_by(
Comments.comment_date.asc()
).all()
def add_comment_to_ioc(ioc_id, comment_id):
ec = IocComments()
ec.comment_ioc_id = ioc_id
ec.comment_id = comment_id
db.session.add(ec)
db.session.commit()
def get_case_iocs_comments_count(iocs_list):
return IocComments.query.filter(
IocComments.comment_ioc_id.in_(iocs_list)
).with_entities(
IocComments.comment_ioc_id,
IocComments.comment_id
).group_by(
IocComments.comment_ioc_id,
IocComments.comment_id
).all()
def get_case_ioc_comment(ioc_id, comment_id):
return IocComments.query.filter(
IocComments.comment_ioc_id == ioc_id,
IocComments.comment_id == comment_id
).with_entities(
Comments.comment_id,
Comments.comment_text,
Comments.comment_date,
Comments.comment_update_date,
Comments.comment_uuid,
User.name,
User.user
).join(
IocComments.comment,
Comments.user
).first()
def delete_ioc_comment(ioc_id, comment_id):
comment = Comments.query.filter(
Comments.comment_id == comment_id,
Comments.comment_user_id == current_user.id
).first()
if not comment:
return False, "You are not allowed to delete this comment"
IocComments.query.filter(
IocComments.comment_ioc_id == ioc_id,
IocComments.comment_id == comment_id
).delete()
db.session.delete(comment)
db.session.commit()
return True, "Comment deleted"
def get_ioc_by_value(ioc_value, caseid=None):
if caseid:
return IocLink.query.with_entities(
Ioc
).filter(and_(
Ioc.ioc_value == ioc_value,
IocLink.case_id == caseid
)).join(
IocLink.ioc
).first()
return Ioc.query.filter(Ioc.ioc_value == ioc_value).first()