Нет описания

utils.py 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. from flask import session
  2. from flask_login import current_user
  3. from sqlalchemy import and_
  4. import app
  5. from app import db
  6. from app.datamgmt.manage.manage_access_control_db import check_ua_case_client
  7. from app.models.cases import Cases
  8. from app.models.models import Client
  9. from app.models.authorization import CaseAccessLevel
  10. from app.models.authorization import UserClient
  11. from app.models.authorization import Group
  12. from app.models.authorization import GroupCaseAccess
  13. from app.models.authorization import Organisation
  14. from app.models.authorization import OrganisationCaseAccess
  15. from app.models.authorization import Permissions
  16. from app.models.authorization import User
  17. from app.models.authorization import UserCaseAccess
  18. from app.models.authorization import UserCaseEffectiveAccess
  19. from app.models.authorization import UserGroup
  20. from app.models.authorization import UserOrganisation
  21. log = app.app.logger
  22. def ac_flag_match_mask(flag, mask):
  23. return (flag & mask) == mask
  24. def ac_get_mask_full_permissions():
  25. """
  26. Return access mask for full permissions
  27. """
  28. am = 0
  29. for perm in Permissions._member_names_:
  30. am |= Permissions[perm].value
  31. return am
  32. def get_auto_follow_groups():
  33. return UserGroup.query.with_entities(
  34. Group.group_auto_follow_access_level,
  35. Group.group_id,
  36. User.id
  37. ).join(
  38. UserGroup.user
  39. ).join(
  40. UserGroup.group
  41. ).filter(
  42. Group.group_auto_follow == True
  43. ).all()
  44. def ac_combine_groups_access(groups_list):
  45. """
  46. Combine a list of group access masks
  47. """
  48. users = {}
  49. for group in groups_list:
  50. if group.id in users:
  51. if group.group_auto_follow_access_level > users[group.id]:
  52. users[group.id] = group.group_auto_follow_access_level
  53. else:
  54. users[group.id] = group.group_auto_follow_access_level
  55. return users
  56. def ac_get_mask_analyst():
  57. """
  58. Return a standard access mask for analysts
  59. """
  60. return Permissions.standard_user.value | Permissions.alerts_read.value \
  61. | Permissions.alerts_write.value | Permissions.search_across_cases.value | Permissions.customers_read.value \
  62. | Permissions.activities_read.value
  63. def ac_permission_to_list(permission):
  64. """
  65. Return a list of permissions from a permission mask
  66. """
  67. perms = []
  68. for perm in Permissions._member_names_:
  69. if permission & Permissions[perm].value:
  70. perms.append({
  71. 'name': perm,
  72. 'value': Permissions[perm].value
  73. })
  74. return perms
  75. def ac_mask_from_val_list(permissions):
  76. """
  77. Return a permission mask from a list of permissions
  78. """
  79. am = 0
  80. for perm in permissions:
  81. am |= int(perm)
  82. return am
  83. def ac_get_all_permissions():
  84. """
  85. Return a list of all permissions
  86. """
  87. perms = []
  88. for perm in Permissions._member_names_:
  89. perms.append({
  90. 'name': perm,
  91. 'value': Permissions[perm].value
  92. })
  93. return perms
  94. def ac_get_detailed_effective_permissions_from_groups(groups):
  95. """
  96. Return a list of permissions from a list of groups
  97. """
  98. perms = {}
  99. for group in groups:
  100. perm = group.group_permissions
  101. for std_perm in Permissions._member_names_:
  102. if perm & Permissions[std_perm].value:
  103. if Permissions[std_perm].value not in perms:
  104. perms[Permissions[std_perm].value] = {
  105. 'name': std_perm,
  106. 'value': Permissions[std_perm].value,
  107. 'inherited_from': [group.group_name]
  108. }
  109. else:
  110. if group.group_name not in perms[Permissions[std_perm].value]['inherited_from']:
  111. perms[Permissions[std_perm].value]['inherited_from'].append(group.group_name)
  112. return perms
  113. def ac_get_effective_permissions_from_groups(groups):
  114. """
  115. Return a permission mask from a list of groups
  116. """
  117. final_perm = 0
  118. for group in groups:
  119. final_perm &= group.group_permissions
  120. return final_perm
  121. def ac_get_effective_permissions_of_user(user):
  122. """
  123. Return a permission mask from a user
  124. """
  125. groups_perms = UserGroup.query.with_entities(
  126. Group.group_permissions,
  127. ).filter(
  128. UserGroup.user_id == user.id
  129. ).join(
  130. UserGroup.group
  131. ).all()
  132. final_perm = 0
  133. for group in groups_perms:
  134. final_perm |= group.group_permissions
  135. return final_perm
  136. def ac_ldp_group_removal(user_id, group_id):
  137. """
  138. Access control lockdown prevention on group removal
  139. """
  140. if current_user.id != user_id:
  141. return False
  142. groups_perms = UserGroup.query.with_entities(
  143. Group.group_permissions,
  144. Group.group_name,
  145. Group.group_id,
  146. Group.group_uuid
  147. ).filter(
  148. UserGroup.user_id == user_id
  149. ).join(
  150. UserGroup.group
  151. ).all()
  152. adm_access_count = []
  153. for group in groups_perms:
  154. perm = group.group_permissions
  155. if ac_flag_match_mask(perm,
  156. Permissions.server_administrator.value):
  157. adm_access_count.append(group.group_id)
  158. if len(adm_access_count) == 1 and adm_access_count[0] == group_id:
  159. return True
  160. return False
  161. def ac_ldp_group_update(user_id):
  162. """
  163. Access control lockdown prevention on group update
  164. """
  165. if current_user.id != user_id:
  166. return False
  167. groups_perms = UserGroup.query.with_entities(
  168. Group.group_permissions,
  169. Group.group_name,
  170. Group.group_id,
  171. Group.group_uuid
  172. ).filter(
  173. UserGroup.user_id == user_id
  174. ).join(
  175. UserGroup.group
  176. ).all()
  177. adm_access_count = []
  178. for group in groups_perms:
  179. perm = group.group_permissions
  180. if ac_flag_match_mask(perm,
  181. Permissions.server_administrator.value):
  182. adm_access_count.append(group.group_id)
  183. if len(adm_access_count) == 0:
  184. return True
  185. return False
  186. def ac_trace_effective_user_permissions(user_id):
  187. """
  188. Returns a detailed permission list from a user
  189. """
  190. groups_perms = UserGroup.query.with_entities(
  191. Group.group_permissions,
  192. Group.group_name,
  193. Group.group_id,
  194. Group.group_uuid
  195. ).filter(
  196. UserGroup.user_id == user_id
  197. ).join(
  198. UserGroup.group
  199. ).all()
  200. perms = {
  201. 'details': {},
  202. 'effective': 0,
  203. }
  204. for group in groups_perms:
  205. perm = group.group_permissions
  206. perms['effective'] |= group.group_permissions
  207. for std_perm in Permissions._member_names_:
  208. if ac_flag_match_mask(perm, Permissions[std_perm].value):
  209. if Permissions[std_perm].value not in perms['details']:
  210. perms['details'][Permissions[std_perm].value] = {
  211. 'name': std_perm,
  212. 'value': Permissions[std_perm].value,
  213. 'inherited_from': {
  214. group.group_id: {
  215. 'group_name': group.group_name,
  216. 'group_uuid': group.group_uuid
  217. }
  218. }
  219. }
  220. else:
  221. if group.group_name not in perms['details'][Permissions[std_perm].value]['inherited_from']:
  222. perms['details'][Permissions[std_perm].value]['inherited_from'].update({
  223. group.group_id: {
  224. 'group_name': group.group_name,
  225. 'group_uuid': group.group_uuid
  226. }
  227. })
  228. return perms
  229. def ac_fast_check_user_has_case_access(user_id, cid, access_level: list[CaseAccessLevel]):
  230. """
  231. Checks the user has access to the case with at least one of the access_level
  232. if the user has access, returns the access level of the user to the case
  233. Returns None otherwise
  234. """
  235. ucea = UserCaseEffectiveAccess.query.with_entities(
  236. UserCaseEffectiveAccess.access_level
  237. ).filter(
  238. UserCaseEffectiveAccess.user_id == user_id,
  239. UserCaseEffectiveAccess.case_id == cid
  240. ).first()
  241. if not ucea:
  242. # The user has no direct access, check if he is part of the client
  243. cuacu = check_ua_case_client(user_id, cid)
  244. if cuacu is None:
  245. return None
  246. ac_set_case_access_for_user(user_id, cid, cuacu.access_level)
  247. return cuacu.access_level
  248. if ac_flag_match_mask(ucea[0], CaseAccessLevel.deny_all.value):
  249. return None
  250. for acl in access_level:
  251. if ac_flag_match_mask(ucea[0], acl.value):
  252. return ucea[0]
  253. return None
  254. def ac_fast_check_current_user_has_case_access(cid, access_level):
  255. return ac_fast_check_user_has_case_access(current_user.id, cid, access_level)
  256. def ac_recompute_effective_ac_from_users_list(users_list):
  257. """
  258. Recompute all users effective access of users
  259. """
  260. for member in users_list:
  261. ac_auto_update_user_effective_access(user_id=member['id'])
  262. return
  263. def ac_recompute_all_users_effective_ac():
  264. """
  265. Recompute all users effective access
  266. """
  267. users = User.query.with_entities(
  268. User.id
  269. ).all()
  270. for user_id in users:
  271. ac_auto_update_user_effective_access(user_id[0])
  272. return
  273. def ac_recompute_effective_ac(user_id):
  274. """
  275. Recompute a users effective access
  276. """
  277. return ac_auto_update_user_effective_access(user_id)
  278. def ac_add_users_multi_effective_access(users_list, cases_list, access_level):
  279. """
  280. Add multiple users to multiple cases with a specific access level
  281. """
  282. for case_id in cases_list:
  283. ac_add_user_effective_access(users_list, case_id=case_id, access_level=access_level)
  284. return
  285. def ac_add_user_effective_access(users_list, case_id, access_level):
  286. """
  287. Directly add a set of effective user access
  288. """
  289. UserCaseEffectiveAccess.query.filter(
  290. UserCaseEffectiveAccess.case_id == case_id,
  291. UserCaseEffectiveAccess.user_id.in_(users_list)
  292. ).delete()
  293. access_to_add = []
  294. for user_id in users_list:
  295. ucea = UserCaseEffectiveAccess()
  296. ucea.user_id = user_id
  297. ucea.case_id = case_id
  298. ucea.access_level = access_level
  299. access_to_add.append(ucea)
  300. db.session.add_all(access_to_add)
  301. db.session.commit()
  302. def ac_add_user_effective_access_from_map(users_map, case_id):
  303. """
  304. Directly add a set of effective user access
  305. """
  306. UserCaseEffectiveAccess.query.filter(
  307. UserCaseEffectiveAccess.case_id == case_id,
  308. UserCaseEffectiveAccess.user_id.in_(users_map.keys())
  309. ).delete()
  310. access_to_add = []
  311. for user_id in users_map:
  312. ucea = UserCaseEffectiveAccess()
  313. ucea.user_id = user_id
  314. ucea.case_id = case_id
  315. ucea.access_level = users_map[user_id]
  316. access_to_add.append(ucea)
  317. db.session.add_all(access_to_add)
  318. db.session.commit()
  319. def ac_set_new_case_access(org_members, case_id, customer_id = None):
  320. """
  321. Set a new case access
  322. """
  323. users = ac_apply_autofollow_groups_access(case_id)
  324. if current_user.id in users.keys():
  325. del users[current_user.id]
  326. users_full = User.query.with_entities(User.id).all()
  327. users_full_access = list(set([u.id for u in users_full]) - set(users.keys()))
  328. # Default users case access - Full access
  329. ac_add_user_effective_access(users_full_access, case_id, CaseAccessLevel.deny_all.value)
  330. # Add specific right for the user creating the case
  331. UserCaseAccess.query.filter(
  332. UserCaseAccess.case_id == case_id,
  333. UserCaseAccess.user_id == current_user.id
  334. ).delete()
  335. db.session.commit()
  336. uca = UserCaseAccess()
  337. uca.case_id = case_id
  338. uca.user_id = current_user.id
  339. uca.access_level = CaseAccessLevel.full_access.value
  340. db.session.add(uca)
  341. db.session.commit()
  342. ac_add_user_effective_access([current_user.id], case_id, CaseAccessLevel.full_access.value)
  343. # Add customer permissions for all users belonging to the customer
  344. if customer_id:
  345. users_client = UserClient.query.filter(
  346. UserClient.client_id == customer_id
  347. ).with_entities(
  348. UserClient.user_id,
  349. UserClient.access_level
  350. ).all()
  351. users_map = { u.user_id: u.access_level for u in users_client }
  352. ac_add_user_effective_access_from_map(users_map, case_id)
  353. def ac_apply_autofollow_groups_access(case_id):
  354. """
  355. Apply a direct effective user access to users within a group
  356. """
  357. groups = get_auto_follow_groups()
  358. users = ac_combine_groups_access(groups)
  359. rows_to_push = []
  360. for user_id in users:
  361. ucea = UserCaseEffectiveAccess()
  362. ucea.user_id = user_id
  363. ucea.case_id = case_id
  364. ucea.access_level = users[user_id]
  365. rows_to_push.append(ucea)
  366. grps_to_add = {}
  367. for group in groups:
  368. if group.group_id not in grps_to_add:
  369. grps_to_add[group.group_id] = group.group_auto_follow_access_level
  370. for group_id in grps_to_add:
  371. gca = GroupCaseAccess()
  372. gca.case_id = case_id
  373. gca.group_id = group_id
  374. gca.access_level = grps_to_add[group_id]
  375. rows_to_push.append(gca)
  376. db.session.add_all(rows_to_push)
  377. db.session.commit()
  378. return users
  379. def ac_auto_update_user_effective_access(user_id):
  380. """
  381. Updates the effective access of a user given its ID
  382. """
  383. uceas = UserCaseEffectiveAccess.query.filter(
  384. UserCaseEffectiveAccess.user_id == user_id
  385. ).all()
  386. grouped_uca = {}
  387. for ucea in uceas:
  388. grouped_uca[ucea.case_id] = ucea.access_level
  389. target_ucas = ac_get_user_cases_access(user_id)
  390. ucea_to_add = {}
  391. cid_to_remove = []
  392. for case_id in target_ucas:
  393. if case_id not in grouped_uca:
  394. ucea_to_add.update({case_id: target_ucas[case_id]})
  395. else:
  396. if not ac_flag_match_mask(grouped_uca[case_id], target_ucas[case_id]):
  397. cid_to_remove.append(case_id)
  398. ucea_to_add.update({case_id: target_ucas[case_id]})
  399. for prev_case_id in grouped_uca:
  400. if prev_case_id not in target_ucas.keys():
  401. cid_to_remove.append(prev_case_id)
  402. UserCaseEffectiveAccess.query.where(and_(
  403. UserCaseEffectiveAccess.user_id == user_id,
  404. UserCaseEffectiveAccess.case_id.in_(cid_to_remove)
  405. )).delete()
  406. for case_id in ucea_to_add:
  407. ucea = UserCaseEffectiveAccess()
  408. ucea.user_id = user_id
  409. ucea.case_id = case_id
  410. ucea.access_level = ucea_to_add[case_id]
  411. db.session.add(ucea)
  412. db.session.commit()
  413. return
  414. def ac_remove_case_access_from_user(user_id, case_id):
  415. """
  416. Remove a case access from a user
  417. """
  418. uac = UserCaseEffectiveAccess.query.where(and_(
  419. UserCaseEffectiveAccess.user_id == user_id,
  420. UserCaseEffectiveAccess.case_id == case_id
  421. )).all()
  422. if len(uac) > 1:
  423. log.error(f'Multiple access found for user {user_id} and case {case_id}')
  424. for u in uac:
  425. db.session.delete(u)
  426. db.session.commit()
  427. uac = UserCaseEffectiveAccess()
  428. uac.user_id = user_id
  429. uac.case_id = case_id
  430. uac.access_level = CaseAccessLevel.deny_all.value
  431. db.session.add(uac)
  432. elif len(uac) == 1:
  433. uac = uac[0]
  434. uac.access_level = CaseAccessLevel.deny_all.value
  435. db.session.commit()
  436. return
  437. def ac_set_case_access_for_users(users, case_id, access_level):
  438. """
  439. Set a case access for a list of users
  440. """
  441. logs = "Access updated"
  442. for user in users:
  443. user_id = user.get('id')
  444. if user_id == current_user.id:
  445. logs = "It's done, but I excluded you from the list of users to update, Dave"
  446. ac_set_case_access_for_user(user.get('id'), case_id, access_level=CaseAccessLevel.full_access.value)
  447. continue
  448. ac_set_case_access_for_user(user.get('id'), case_id, access_level)
  449. db.session.commit()
  450. return True, logs
  451. def ac_set_case_access_for_user(user_id, case_id, access_level, commit=True):
  452. """
  453. Set a case access from a user
  454. """
  455. uac = UserCaseEffectiveAccess.query.where(and_(
  456. UserCaseEffectiveAccess.user_id == user_id,
  457. UserCaseEffectiveAccess.case_id == case_id
  458. )).all()
  459. if len(uac) > 1:
  460. log.error(f'Multiple access found for user {user_id} and case {case_id}')
  461. for u in uac:
  462. db.session.delete(u)
  463. db.session.commit()
  464. uac = UserCaseEffectiveAccess()
  465. uac.user_id = user_id
  466. uac.case_id = case_id
  467. uac.access_level = access_level
  468. db.session.add(uac)
  469. elif len(uac) == 1:
  470. uac = uac[0]
  471. uac.access_level = access_level
  472. if commit:
  473. db.session.commit()
  474. return
  475. def ac_get_fast_user_cases_access(user_id):
  476. ucea = UserCaseEffectiveAccess.query.with_entities(
  477. UserCaseEffectiveAccess.case_id
  478. ).filter(and_(
  479. UserCaseEffectiveAccess.user_id == user_id,
  480. UserCaseEffectiveAccess.access_level != CaseAccessLevel.deny_all.value
  481. )).all()
  482. return [e.case_id for e in ucea]
  483. def ac_get_user_case_counts(user_id):
  484. query = UserCaseEffectiveAccess.query.filter(
  485. UserCaseEffectiveAccess.user_id == user_id,
  486. UserCaseEffectiveAccess.access_level != CaseAccessLevel.deny_all.value
  487. )
  488. ucea_count = query.count()
  489. open_cases_count = query.join(Cases).filter(Cases.close_date == None).count()
  490. owned_cases_count = query.join(
  491. Cases, isouter=True
  492. ).filter(
  493. and_(
  494. Cases.owner_id == user_id,
  495. Cases.close_date == None
  496. )
  497. ).count()
  498. return ucea_count, open_cases_count, owned_cases_count
  499. def ac_get_user_cases_access(user_id):
  500. # ocas = OrganisationCaseAccess.query.with_entities(
  501. # Cases.case_id,
  502. # OrganisationCaseAccess.access_level
  503. # ).filter(
  504. # and_(UserOrganisation.user_id == user_id,
  505. # OrganisationCaseAccess.org_id == UserOrganisation.org_id)
  506. # ).join(
  507. # OrganisationCaseAccess.case,
  508. # ).all()
  509. cases = Cases.query.with_entities(
  510. Cases.case_id
  511. ).all()
  512. gcas = GroupCaseAccess.query.with_entities(
  513. Cases.case_id,
  514. GroupCaseAccess.access_level
  515. ).filter(
  516. and_(UserGroup.user_id == user_id,
  517. UserGroup.group_id == GroupCaseAccess.group_id)
  518. ).join(
  519. GroupCaseAccess.case
  520. ).all()
  521. ccas = UserClient.query.with_entities(
  522. UserClient.access_level,
  523. Cases.case_id,
  524. ).join(
  525. Cases, UserClient.client_id == Cases.client_id
  526. ).filter(
  527. UserClient.user_id == user_id
  528. ).all()
  529. ucas = UserCaseAccess.query.with_entities(
  530. Cases.case_id,
  531. UserCaseAccess.access_level
  532. ).filter(
  533. and_(UserCaseAccess.user_id == user_id)
  534. ).join(
  535. UserCaseAccess.case
  536. ).all()
  537. effective_cases_access = {}
  538. for oca in cases:
  539. effective_cases_access[oca.case_id] = CaseAccessLevel.deny_all.value
  540. for gca in gcas:
  541. effective_cases_access[gca.case_id] = gca.access_level
  542. for cca in ccas:
  543. effective_cases_access[cca.case_id] = cca.access_level
  544. for uca in ucas:
  545. effective_cases_access[uca.case_id] = uca.access_level
  546. return effective_cases_access
  547. def ac_trace_user_effective_cases_access_2(user_id):
  548. gcas = GroupCaseAccess.query.with_entities(
  549. Group.group_name,
  550. Group.group_id,
  551. Group.group_uuid,
  552. Cases.case_id,
  553. Cases.name,
  554. GroupCaseAccess.access_level
  555. ).filter(
  556. and_(UserGroup.user_id == user_id,
  557. UserGroup.group_id == GroupCaseAccess.group_id)
  558. ).join(
  559. GroupCaseAccess.case
  560. ).join(
  561. GroupCaseAccess.group
  562. ).all()
  563. ucas = UserCaseAccess.query.with_entities(
  564. User.name.label('user_name'),
  565. User.id.label('user_id'),
  566. User.uuid.label('user_uuid'),
  567. Cases.case_id,
  568. Cases.name,
  569. UserCaseAccess.access_level
  570. ).filter(
  571. and_(UserCaseAccess.user_id == user_id)
  572. ).join(
  573. UserCaseAccess.case
  574. ).join(
  575. UserCaseAccess.user
  576. ).all()
  577. effective_cases_access = {}
  578. cases = Cases.query.with_entities(
  579. Cases.case_id,
  580. Cases.name
  581. ).all()
  582. ccas = UserClient.query.with_entities(
  583. UserClient.access_level,
  584. Cases.case_id,
  585. Cases.name.label('case_name'),
  586. Client.name.label('client_name'),
  587. Client.client_id,
  588. Client.client_uuid
  589. ).join(
  590. Cases, UserClient.client_id == Cases.client_id
  591. ).join(
  592. Client, Client.client_id == Cases.client_id
  593. ).filter(
  594. UserClient.user_id == user_id
  595. ).all()
  596. # Organisation case access. Default access level
  597. for oca in cases:
  598. access = {
  599. 'state': 'Effective',
  600. 'access_list': CaseAccessLevel.deny_all.name,
  601. 'access_value': CaseAccessLevel.deny_all.value,
  602. 'inherited_from': {
  603. 'object_type': 'default_access_level',
  604. 'object_name': 'Default access level',
  605. 'object_id': '',
  606. 'object_uuid': ''
  607. }
  608. }
  609. effective_cases_access[oca.case_id] = {
  610. 'case_info': {
  611. 'case_name': oca.name,
  612. 'case_id': oca.case_id
  613. },
  614. 'user_access': [],
  615. 'user_effective_access': CaseAccessLevel.deny_all.value
  616. }
  617. effective_cases_access[oca.case_id]['user_access'].append(access)
  618. # Group case access
  619. for gca in gcas:
  620. access = {
  621. 'state': 'Effective',
  622. 'access_list': ac_access_level_to_list(gca.access_level),
  623. 'access_value': gca.access_level,
  624. 'inherited_from': {
  625. 'object_type': 'group_access_level',
  626. 'object_name': gca.group_name,
  627. 'object_id': gca.group_id,
  628. 'object_uuid': gca.group_uuid
  629. }
  630. }
  631. if gca.case_id in effective_cases_access:
  632. effective_cases_access[gca.case_id]['user_effective_access'] = gca.access_level
  633. for kec in effective_cases_access[gca.case_id]['user_access']:
  634. kec['state'] = f'Overwritten by group {gca.group_name}'
  635. else:
  636. effective_cases_access[gca.case_id] = {
  637. 'case_info': {
  638. 'case_name': gca.name,
  639. 'case_id': gca.case_id
  640. },
  641. 'user_access': [],
  642. 'user_effective_access': gca.access_level
  643. }
  644. effective_cases_access[gca.case_id]['user_access'].append(access)
  645. # Client case access:
  646. for cca in ccas:
  647. access = {
  648. 'state': 'Effective',
  649. 'access_list': ac_access_level_to_list(cca.access_level),
  650. 'access_value': cca.access_level,
  651. 'inherited_from': {
  652. 'object_type': 'customer_access_level',
  653. 'object_name': cca.client_name,
  654. 'object_id': cca.client_id,
  655. 'object_uuid': cca.client_uuid
  656. }
  657. }
  658. if cca.case_id in effective_cases_access:
  659. effective_cases_access[cca.case_id]['user_effective_access'] = cca.access_level
  660. for kec in effective_cases_access[cca.case_id]['user_access']:
  661. kec['state'] = f'Overwritten by customer {cca.client_name}'
  662. else:
  663. effective_cases_access[cca.case_id] = {
  664. 'case_info': {
  665. 'case_name': cca.case_name,
  666. 'case_id': cca.case_id
  667. },
  668. 'user_access': [],
  669. 'user_effective_access': cca.access_level
  670. }
  671. effective_cases_access[cca.case_id]['user_access'].append(access)
  672. # User case access
  673. for uca in ucas:
  674. access = {
  675. 'state': 'Effective',
  676. 'access_list': ac_access_level_to_list(uca.access_level),
  677. 'access_value': uca.access_level,
  678. 'inherited_from': {
  679. 'object_type': 'user_access_level',
  680. 'object_name': uca.user_name,
  681. 'object_id': uca.user_id,
  682. 'object_uuid': uca.user_uuid
  683. }
  684. }
  685. if uca.case_id in effective_cases_access:
  686. effective_cases_access[uca.case_id]['user_effective_access'] = uca.access_level
  687. for kec in effective_cases_access[uca.case_id]['user_access']:
  688. kec['state'] = 'Overwritten by self user access'
  689. else:
  690. effective_cases_access[uca.case_id] = {
  691. 'case_info': {
  692. 'case_name': uca.name,
  693. 'case_id': uca.case_id
  694. },
  695. 'user_access': [],
  696. 'user_effective_access': uca.access_level
  697. }
  698. effective_cases_access[uca.case_id]['user_access'].append(access)
  699. for case_id in effective_cases_access:
  700. effective_cases_access[case_id]['user_effective_access'] = ac_access_level_to_list(
  701. effective_cases_access[case_id]['user_effective_access'])
  702. return effective_cases_access
  703. def ac_trace_case_access(case_id):
  704. case = Cases.query.with_entities(
  705. Cases.case_id,
  706. Cases.name
  707. ).filter(
  708. Cases.case_id == case_id
  709. ).first()
  710. if not case:
  711. return {}
  712. ocas = OrganisationCaseAccess.query.with_entities(
  713. Organisation.org_name,
  714. Organisation.org_id,
  715. Organisation.org_uuid,
  716. OrganisationCaseAccess.access_level,
  717. User.id.label('user_id'),
  718. User.name.label('user_name'),
  719. User.email.label('user_email'),
  720. User.uuid.label('user_uuid')
  721. ).filter(
  722. and_(OrganisationCaseAccess.case_id == case.case_id,
  723. OrganisationCaseAccess.org_id == UserOrganisation.org_id)
  724. ).join(
  725. OrganisationCaseAccess.org,
  726. UserOrganisation.user
  727. ).all()
  728. gcas = GroupCaseAccess.query.with_entities(
  729. Group.group_name,
  730. Group.group_id,
  731. Group.group_uuid,
  732. GroupCaseAccess.access_level,
  733. User.id.label('user_id'),
  734. User.name.label('user_name'),
  735. User.email.label('user_email'),
  736. User.uuid.label('user_uuid')
  737. ).filter(
  738. and_(GroupCaseAccess.case_id == case.case_id,
  739. UserGroup.group_id == GroupCaseAccess.group_id)
  740. ).join(
  741. GroupCaseAccess.group,
  742. UserGroup.user
  743. ).all()
  744. ucas = UserCaseAccess.query.with_entities(
  745. User.id.label('user_id'),
  746. User.name.label('user_name'),
  747. User.uuid.label('user_uuid'),
  748. User.email.label('user_email'),
  749. UserCaseAccess.access_level
  750. ).filter(
  751. and_(UserCaseAccess.case_id == case.case_id)
  752. ).join(
  753. UserCaseAccess.user
  754. ).all()
  755. case_access = {}
  756. for uca in ucas:
  757. user = {
  758. 'access_trace': [],
  759. 'user_effective_access': 0,
  760. 'user_effective_access_list': [],
  761. 'user_info': {
  762. 'user_name': uca.user_name,
  763. 'user_uuid': uca.user_uuid,
  764. 'user_email': uca.user_email
  765. }
  766. }
  767. for ac_l in CaseAccessLevel:
  768. if uca:
  769. if ac_flag_match_mask(uca.access_level, ac_l.value):
  770. user['user_effective_access'] |= uca.access_level
  771. user['access_trace'].append({
  772. 'state': 'Effective',
  773. 'name': ac_l.name,
  774. 'value': ac_l.value,
  775. 'inherited_from': {
  776. 'object_type': 'user_access_level',
  777. 'object_name': 'self',
  778. 'object_id': 'self',
  779. 'object_uuid': 'self'
  780. }
  781. })
  782. user['user_effective_access_list'].append(ac_l.name)
  783. has_uca_overwritten = True
  784. if ac_l.value == CaseAccessLevel.deny_all.value:
  785. has_uca_deny_all = True
  786. if uca.user_id not in case_access:
  787. case_access.update({
  788. uca.user_id: user
  789. })
  790. for gca in gcas:
  791. if gca.user_id not in case_access:
  792. user = {
  793. 'access_trace': [],
  794. 'user_effective_access': 0,
  795. 'user_effective_access_list': [],
  796. 'user_info': {
  797. 'user_name': gca.user_name,
  798. 'user_uuid': gca.user_uuid,
  799. 'user_email': gca.user_email
  800. }
  801. }
  802. else:
  803. user = case_access[gca.user_id]
  804. for ac_l in CaseAccessLevel:
  805. if gca:
  806. if ac_flag_match_mask(gca.access_level, ac_l.value):
  807. if gca.user_id not in case_access:
  808. user['user_effective_access'] |= gca.access_level
  809. user['user_effective_access_list'].append(ac_l.name)
  810. state = 'Effective'
  811. else:
  812. state = 'Overwritten by user access'
  813. user['access_trace'].append({
  814. 'state': state,
  815. 'name': ac_l.name,
  816. 'value': ac_l.value,
  817. 'inherited_from': {
  818. 'object_type': 'group_access_level',
  819. 'object_name': gca.group_name,
  820. 'object_id': gca.group_id,
  821. 'object_uuid': gca.group_uuid
  822. }
  823. })
  824. if gca.user_id not in case_access:
  825. case_access.update({
  826. gca.user_id: user
  827. })
  828. for oca in ocas:
  829. if oca.user_id not in case_access:
  830. user = {
  831. 'access_trace': [],
  832. 'user_effective_access': 0,
  833. 'user_effective_access_list': [],
  834. 'user_info': {
  835. 'user_name': oca.user_name,
  836. 'user_uuid': oca.user_uuid,
  837. 'user_email': oca.user_email
  838. }
  839. }
  840. else:
  841. user = case_access[oca.user_id]
  842. for ac_l in CaseAccessLevel:
  843. if oca:
  844. if ac_flag_match_mask(oca.access_level, ac_l.value):
  845. if oca.user_id not in case_access:
  846. user['user_effective_access'] |= oca.access_level
  847. user['user_effective_access_list'].append(ac_l.name)
  848. state = 'Effective'
  849. else:
  850. state = 'Overwritten by user or group access'
  851. user['access_trace'].append({
  852. 'state': state,
  853. 'name': ac_l.name,
  854. 'value': ac_l.value,
  855. 'inherited_from': {
  856. 'object_type': 'organisation_access_level',
  857. 'object_name': oca.org_name,
  858. 'object_id': oca.org_id,
  859. 'object_uuid': oca.org_uuid
  860. }
  861. })
  862. if oca.user_id not in case_access:
  863. case_access.update({
  864. oca.user_id: user
  865. })
  866. return case_access
  867. def ac_get_mask_case_access_level_full():
  868. """
  869. Return a mask for full access level
  870. """
  871. am = 0
  872. for ac in CaseAccessLevel._member_names_:
  873. if CaseAccessLevel.deny_all.name == CaseAccessLevel[ac].name:
  874. continue
  875. am |= CaseAccessLevel[ac].value
  876. return am
  877. def ac_get_all_access_level():
  878. """
  879. Return a list of all access levels
  880. """
  881. ac_list = []
  882. for ac in CaseAccessLevel._member_names_:
  883. ac_list.append({
  884. 'name': ac,
  885. 'value': CaseAccessLevel[ac].value
  886. })
  887. return ac_list
  888. def ac_access_level_to_list(access_level):
  889. """
  890. Return a list of access level from an access level mask
  891. """
  892. access_levels = []
  893. for ac in CaseAccessLevel._member_names_:
  894. if ac_flag_match_mask(access_level, CaseAccessLevel[ac].value):
  895. access_levels.append({
  896. 'name': ac,
  897. 'value': CaseAccessLevel[ac].value
  898. })
  899. return access_levels
  900. def ac_access_level_mask_from_val_list(access_levels):
  901. """
  902. Return an access level mask from a list of access levels
  903. """
  904. am = 0
  905. for acc in access_levels:
  906. am |= int(acc)
  907. return am
  908. def ac_user_has_permission(user, permission):
  909. """
  910. Return True if user has permission
  911. """
  912. return ac_flag_match_mask(ac_get_effective_permissions_of_user(user), permission.value)
  913. def ac_current_user_has_permission(permission):
  914. """
  915. Return True if current user has permission
  916. """
  917. return ac_flag_match_mask(session['permissions'], permission.value)