Keine Beschreibung

case_notes_db.py 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. # IRIS Source Code
  2. # Copyright (C) 2021 - Airbus CyberSecurity (SAS)
  3. # ir@cyberactionlab.net
  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. from flask_login import current_user
  19. from sqlalchemy import and_
  20. from app import db
  21. from app.datamgmt.manage.manage_attribute_db import get_default_custom_attributes
  22. from app.datamgmt.states import update_notes_state
  23. from app.models.models import Comments
  24. from app.models.models import NoteDirectory
  25. from app.models.models import NoteRevisions
  26. from app.models.models import Notes
  27. from app.models.models import NotesComments
  28. from app.models.models import NotesGroup
  29. from app.models.models import NotesGroupLink
  30. from app.models.authorization import User
  31. def get_note(note_id, caseid=None):
  32. note = Notes.query.filter(and_(
  33. Notes.note_id == note_id,
  34. Notes.note_case_id == caseid
  35. )).first()
  36. return note
  37. def get_directory(directory_id, caseid):
  38. directory = NoteDirectory.query.filter(and_(
  39. NoteDirectory.id == directory_id,
  40. NoteDirectory.case_id == caseid
  41. )).first()
  42. return directory
  43. def delete_directory(directory, caseid):
  44. # Proceed to delete directory, but remove all associated notes and subdirectories recursively
  45. if directory:
  46. # Delete all notes in the directory
  47. for note in directory.notes:
  48. delete_note(note.note_id, caseid)
  49. # Delete all subdirectories
  50. for subdirectory in directory.subdirectories:
  51. delete_directory(subdirectory, caseid)
  52. # Delete the directory
  53. db.session.delete(directory)
  54. db.session.commit()
  55. return True
  56. return False
  57. def get_note_raw(note_id, caseid):
  58. note = Notes.query.filter(
  59. Notes.note_case_id == caseid,
  60. Notes.note_id == note_id
  61. ).first()
  62. return note
  63. def delete_note(note_id, caseid):
  64. with db.session.begin_nested():
  65. NotesGroupLink.query.filter(and_(
  66. NotesGroupLink.note_id == note_id,
  67. NotesGroupLink.case_id == caseid
  68. )).delete()
  69. com_ids = NotesComments.query.with_entities(
  70. NotesComments.comment_id
  71. ).filter(
  72. NotesComments.comment_note_id == note_id
  73. ).all()
  74. com_ids = [c.comment_id for c in com_ids]
  75. NotesComments.query.filter(NotesComments.comment_id.in_(com_ids)).delete()
  76. NoteRevisions.query.filter(NoteRevisions.note_id == note_id).delete()
  77. Comments.query.filter(Comments.comment_id.in_(com_ids)).delete()
  78. Notes.query.filter(Notes.note_id == note_id).delete()
  79. update_notes_state(caseid=caseid)
  80. def update_note(note_content, note_title, update_date, user_id, note_id, caseid):
  81. note = get_note_raw(note_id, caseid=caseid)
  82. if note:
  83. note.note_content = note_content
  84. note.note_title = note_title
  85. note.note_lastupdate = update_date
  86. note.note_user = user_id
  87. db.session.commit()
  88. return note
  89. else:
  90. return None
  91. def add_note(note_title, creation_date, user_id, caseid, directory_id, note_content=""):
  92. note = Notes()
  93. note.note_title = note_title
  94. note.note_creationdate = note.note_lastupdate = creation_date
  95. note.note_content = note_content
  96. note.note_case_id = caseid
  97. note.note_user = user_id
  98. note.directory_id = directory_id
  99. note.custom_attributes = get_default_custom_attributes('note')
  100. db.session.add(note)
  101. update_notes_state(caseid=caseid, userid=user_id)
  102. db.session.commit()
  103. return note
  104. def get_groups_short(caseid):
  105. groups_short = NotesGroup.query.with_entities(
  106. NotesGroup.group_id,
  107. NotesGroup.group_uuid,
  108. NotesGroup.group_title
  109. ).filter(
  110. NotesGroup.group_case_id == caseid
  111. ).order_by(
  112. NotesGroup.group_id
  113. ).all()
  114. return groups_short
  115. def get_notes_from_group(caseid, group_id):
  116. notes = NotesGroupLink.query.with_entities(
  117. Notes.note_id,
  118. Notes.note_uuid,
  119. Notes.note_title,
  120. User.user,
  121. Notes.note_lastupdate
  122. ).filter(
  123. NotesGroupLink.case_id == caseid,
  124. NotesGroupLink.group_id == group_id,
  125. ).join(
  126. NotesGroupLink.note
  127. ).join(
  128. Notes.user
  129. ).order_by(
  130. Notes.note_id
  131. ).all()
  132. return notes
  133. def get_groups_detail(caseid):
  134. groups = NotesGroupLink.query.with_entities(
  135. NotesGroup.group_id,
  136. NotesGroup.group_uuid,
  137. NotesGroup.group_title,
  138. Notes.note_id,
  139. Notes.note_uuid,
  140. Notes.note_title,
  141. User.user,
  142. Notes.note_lastupdate
  143. ).filter(
  144. NotesGroupLink.case_id == caseid,
  145. ).join(
  146. NotesGroupLink.note
  147. ).join(
  148. NotesGroupLink.note_group
  149. ).join(
  150. Notes.user
  151. ).group_by(
  152. NotesGroup.group_id,
  153. Notes.note_id,
  154. User.user
  155. ).all()
  156. return groups
  157. def get_group_details(group_id, caseid):
  158. group_l = NotesGroup.query.with_entities(
  159. NotesGroup.group_id,
  160. NotesGroup.group_uuid,
  161. NotesGroup.group_title,
  162. NotesGroup.group_creationdate,
  163. NotesGroup.group_lastupdate
  164. ).filter(
  165. NotesGroup.group_case_id == caseid
  166. ).filter(
  167. NotesGroup.group_id == group_id
  168. ).first()
  169. group = None
  170. if group_l:
  171. group = group_l._asdict()
  172. group['notes'] = [note._asdict() for note in get_notes_from_group(caseid=caseid, group_id=group_id)]
  173. return group
  174. def add_note_group(group_title, caseid, userid, creationdate):
  175. ng = NotesGroup()
  176. ng.group_title = group_title
  177. ng.group_case_id = caseid
  178. ng.group_user = userid
  179. ng.group_creationdate = creationdate
  180. ng.group_lastupdate = creationdate
  181. db.session.add(ng)
  182. update_notes_state(caseid=caseid, userid=userid)
  183. db.session.commit()
  184. if group_title == '':
  185. ng.group_title = "New notes group"
  186. db.session.commit()
  187. return ng
  188. def delete_note_group(group_id, caseid):
  189. ngl = NotesGroupLink.query.with_entities(
  190. NotesGroupLink.note_id
  191. ).filter(
  192. NotesGroupLink.group_id == group_id,
  193. NotesGroupLink.case_id == caseid
  194. ).all()
  195. if not ngl:
  196. group = NotesGroup.query.filter(and_(
  197. NotesGroup.group_id == group_id,
  198. NotesGroup.group_case_id == caseid
  199. )).first()
  200. if not group:
  201. return False
  202. db.session.delete(group)
  203. update_notes_state(caseid=caseid)
  204. db.session.commit()
  205. return True
  206. to_delete = [row.note_id for row in ngl]
  207. NotesGroupLink.query.filter(
  208. NotesGroupLink.group_id == group_id,
  209. NotesGroupLink.case_id == caseid
  210. ).delete()
  211. db.session.commit()
  212. for nid in to_delete:
  213. Notes.query.filter(Notes.note_id == nid).delete()
  214. NotesGroup.query.filter(and_(
  215. NotesGroup.group_id == group_id,
  216. NotesGroup.group_case_id == caseid
  217. )).delete()
  218. update_notes_state(caseid=caseid)
  219. db.session.commit()
  220. return True
  221. def update_note_group(group_title, group_id, caseid):
  222. ng = NotesGroup.query.filter(and_(
  223. NotesGroup.group_id == group_id,
  224. NotesGroup.group_case_id == caseid
  225. )).first()
  226. if ng:
  227. ng.group_title = group_title
  228. update_notes_state(caseid=caseid)
  229. db.session.commit()
  230. return ng
  231. else:
  232. return None
  233. def find_pattern_in_notes(pattern, caseid):
  234. notes = Notes.query.filter(
  235. Notes.note_content.like(pattern),
  236. Notes.note_case_id == caseid
  237. ).with_entities(
  238. Notes.note_id,
  239. Notes.note_title
  240. ).all()
  241. return notes
  242. def get_case_note_comments(note_id):
  243. return Comments.query.filter(
  244. NotesComments.comment_note_id == note_id
  245. ).join(
  246. NotesComments,
  247. Comments.comment_id == NotesComments.comment_id
  248. ).order_by(
  249. Comments.comment_date.asc()
  250. ).all()
  251. def add_comment_to_note(note_id, comment_id):
  252. ec = NotesComments()
  253. ec.comment_note_id = note_id
  254. ec.comment_id = comment_id
  255. db.session.add(ec)
  256. db.session.commit()
  257. def get_case_notes_comments_count(notes_list):
  258. return NotesComments.query.filter(
  259. NotesComments.comment_note_id.in_(notes_list)
  260. ).with_entities(
  261. NotesComments.comment_note_id,
  262. NotesComments.comment_id
  263. ).group_by(
  264. NotesComments.comment_note_id,
  265. NotesComments.comment_id
  266. ).all()
  267. def get_case_note_comment(note_id, comment_id):
  268. return db.session.query(
  269. Comments.comment_id,
  270. Comments.comment_text,
  271. Comments.comment_date,
  272. Comments.comment_update_date,
  273. Comments.comment_uuid,
  274. User.name,
  275. User.user
  276. ).join(
  277. NotesComments,
  278. Comments.comment_id == NotesComments.comment_id
  279. ).join(
  280. User,
  281. User.id == Comments.comment_user_id
  282. ).filter(
  283. NotesComments.comment_note_id == note_id,
  284. NotesComments.comment_id == comment_id
  285. ).first()
  286. def delete_note_comment(note_id, comment_id):
  287. comment = Comments.query.filter(
  288. Comments.comment_id == comment_id,
  289. Comments.comment_user_id == current_user.id
  290. ).first()
  291. if not comment:
  292. return False, "You are not allowed to delete this comment"
  293. NotesComments.query.filter(
  294. NotesComments.comment_note_id == note_id,
  295. NotesComments.comment_id == comment_id
  296. ).delete()
  297. db.session.delete(comment)
  298. db.session.commit()
  299. return True, "Comment deleted"
  300. def get_directories_with_note_count(case_id):
  301. # Fetch all directories for the given case
  302. directories = NoteDirectory.query.filter_by(case_id=case_id).order_by(
  303. NoteDirectory.name.asc()
  304. ).all()
  305. # Create a list to store the directories with note counts
  306. directories_with_note_count = []
  307. # For each directory, fetch the subdirectories, note count, and note titles
  308. for directory in directories:
  309. directory_with_note_count = get_directory_with_note_count(directory)
  310. notes = [{'id': note.note_id, 'title': note.note_title} for note in directory.notes]
  311. # Order by note title
  312. notes = sorted(notes, key=lambda note: note['title'])
  313. directory_with_note_count['notes'] = notes
  314. directories_with_note_count.append(directory_with_note_count)
  315. return directories_with_note_count
  316. def get_directory_with_note_count(directory):
  317. note_count = Notes.query.filter_by(directory_id=directory.id).count()
  318. directory_dict = {
  319. 'id': directory.id,
  320. 'name': directory.name,
  321. 'note_count': note_count,
  322. 'subdirectories': []
  323. }
  324. if directory.subdirectories:
  325. for subdirectory in directory.subdirectories:
  326. directory_dict['subdirectories'].append(get_directory_with_note_count(subdirectory))
  327. return directory_dict