Нет описания

manage_templates_routes.py 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. # IRIS Source Code
  2. # Copyright (C) 2024 - DFIR-IRIS
  3. # contact@dfir-iris.org
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU Lesser General Public
  7. # License as published by the Free Software Foundation; either
  8. # version 3 of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # Lesser General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public License
  16. # along with this program; if not, write to the Free Software Foundation,
  17. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. import os
  19. import random
  20. import string
  21. from datetime import datetime
  22. from flask import Blueprint, url_for
  23. from flask import flash
  24. from flask import redirect
  25. from flask import request
  26. from flask import send_file
  27. from flask_login import current_user
  28. from werkzeug.utils import secure_filename
  29. from app import app
  30. from app import db
  31. from app.iris_engine.utils.tracker import track_activity
  32. from app.models.authorization import Permissions
  33. from app.models.authorization import User
  34. from app.models.models import CaseTemplateReport
  35. from app.models.models import Languages
  36. from app.models.models import ReportType
  37. from app.blueprints.access_controls import ac_api_requires
  38. from app.blueprints.responses import response_error
  39. from app.blueprints.responses import response_success
  40. _ALLOWED_EXTENSIONS = {'md', 'html', 'doc', 'docx'}
  41. manage_templates_rest_blueprint = Blueprint('manage_templates_rest', __name__)
  42. # TODO should move this function out in a module dedicated to random generation
  43. def _get_random_string(length):
  44. letters = string.ascii_lowercase
  45. result_str = ''.join(random.choice(letters) for i in range(length))
  46. return result_str
  47. @manage_templates_rest_blueprint.route('/manage/templates/list')
  48. @ac_api_requires(Permissions.server_administrator)
  49. def report_templates_list():
  50. # Get all templates
  51. templates = CaseTemplateReport.query.with_entities(
  52. CaseTemplateReport.name,
  53. CaseTemplateReport.description,
  54. CaseTemplateReport.naming_format,
  55. CaseTemplateReport.date_created,
  56. User.name.label('created_by'),
  57. Languages.code,
  58. ReportType.name.label('type_name'),
  59. CaseTemplateReport.id
  60. ).join(
  61. CaseTemplateReport.created_by_user
  62. ).join(
  63. CaseTemplateReport.language
  64. ).join(
  65. CaseTemplateReport.report_type
  66. ).all()
  67. data = [row._asdict() for row in templates]
  68. # Return the assets
  69. return response_success("", data=data)
  70. def _allowed_file(filename):
  71. return '.' in filename and \
  72. filename.rsplit('.', 1)[1].lower() in _ALLOWED_EXTENSIONS
  73. @manage_templates_rest_blueprint.route('/manage/templates/add', methods=['POST'])
  74. @ac_api_requires(Permissions.server_administrator)
  75. def add_template():
  76. report_template = CaseTemplateReport()
  77. report_template.name = request.form.get('report_name', '', type=str)
  78. report_template.description = request.form.get('report_description', '', type=str)
  79. report_template.naming_format = request.form.get('report_name_format', '', type=str)
  80. report_template.language_id = request.form.get('report_language', '', type=int)
  81. report_template.report_type_id = request.form.get('report_type', '', type=int)
  82. report_template.created_by_user_id = current_user.id
  83. report_template.date_created = datetime.utcnow()
  84. template_file = request.files['file']
  85. if template_file.filename == '':
  86. flash('No selected file')
  87. return redirect(url_for('manage_templates.manage_templates'))
  88. if template_file and _allowed_file(template_file.filename):
  89. filename = secure_filename(template_file.filename)
  90. _, extension = os.path.splitext(filename)
  91. filename = _get_random_string(18) + extension
  92. try:
  93. template_file.save(os.path.join(app.config['TEMPLATES_PATH'], filename))
  94. except Exception as e:
  95. return response_error(f"Unable to add template. {e}")
  96. report_template.internal_reference = filename
  97. db.session.add(report_template)
  98. db.session.commit()
  99. track_activity(f"report template '{report_template.name}' added", ctx_less=True)
  100. ret = {
  101. "report_id": report_template.id,
  102. "report_name": report_template.name,
  103. "report_description": report_template.description,
  104. "report_language_id": report_template.language_id,
  105. "report_name_format": report_template.naming_format,
  106. "report_type_id": report_template.report_type_id
  107. }
  108. return response_success("Added successfully", data=ret)
  109. return response_error("File is invalid")
  110. @manage_templates_rest_blueprint.route('/manage/templates/download/<report_id>', methods=['GET'])
  111. @ac_api_requires(Permissions.server_administrator)
  112. def download_template(report_id):
  113. if report_id != 0:
  114. report_template = CaseTemplateReport.query.filter(CaseTemplateReport.id == report_id).first()
  115. fpath = os.path.join(app.config['TEMPLATES_PATH'], report_template.internal_reference)
  116. _, extension = os.path.splitext(report_template.internal_reference)
  117. resp = send_file(fpath, as_attachment=True, download_name=f"{report_template.name}.{extension}")
  118. return resp
  119. return response_error("Unable to download file")
  120. @manage_templates_rest_blueprint.route('/manage/templates/delete/<report_id>', methods=['POST'])
  121. @ac_api_requires(Permissions.server_administrator)
  122. def delete_template(report_id):
  123. error = None
  124. report_template = CaseTemplateReport.query.filter(CaseTemplateReport.id == report_id).first()
  125. if report_template is None:
  126. return response_error('Template not found')
  127. report_name = report_template.name
  128. try:
  129. os.unlink(os.path.join(app.config['TEMPLATES_PATH'], report_template.internal_reference))
  130. except Exception as e:
  131. error = f"Template reference will be deleted but there has been some errors. {e}"
  132. finally:
  133. CaseTemplateReport.query.filter(CaseTemplateReport.id == report_id).delete()
  134. db.session.commit()
  135. if error:
  136. return response_error(error)
  137. track_activity(f"report template '{report_name}' deleted", ctx_less=True)
  138. return response_success("Deleted successfully", data=error)