Some checks failed
Deployment Verification / deploy-and-test (push) Failing after 29s
356 lines
8.8 KiB
Python
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() |