group.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
  2. # Copyright: (c) <spug.dev@gmail.com>
  3. # Released under the AGPL-3.0 License.
  4. from django.views.generic import View
  5. from django.db.models import F
  6. from libs import json_response, JsonParser, Argument
  7. from apps.host.models import Group
  8. from apps.account.models import Role
  9. def fetch_children(data, with_hosts):
  10. if data:
  11. sub_data = dict()
  12. for item in Group.objects.filter(parent_id__in=data.keys()):
  13. tmp = item.to_view(with_hosts)
  14. sub_data[item.id] = tmp
  15. data[item.parent_id]['children'].append(tmp)
  16. return fetch_children(sub_data, with_hosts)
  17. def merge_children(data, prefix, childes):
  18. prefix = f'{prefix}/' if prefix else ''
  19. for item in childes:
  20. name = f'{prefix}{item["title"]}'
  21. item['name'] = name
  22. if item.get('children'):
  23. merge_children(data, name, item['children'])
  24. else:
  25. data[item['key']] = name
  26. def filter_by_perm(data, result, ids):
  27. for item in data:
  28. if 'children' in item:
  29. if item['key'] in ids:
  30. result.append(item)
  31. elif item['children']:
  32. filter_by_perm(item['children'], result, ids)
  33. class GroupView(View):
  34. def get(self, request):
  35. with_hosts = request.GET.get('with_hosts')
  36. data, data2 = dict(), dict()
  37. for item in Group.objects.filter(parent_id=0):
  38. data[item.id] = item.to_view(with_hosts)
  39. fetch_children(data, with_hosts)
  40. if not data:
  41. grp = Group.objects.create(name='Default', sort_id=1)
  42. data[grp.id] = grp.to_view()
  43. if request.user.is_supper:
  44. tree_data = list(data.values())
  45. else:
  46. tree_data, ids = [], request.user.group_perms
  47. filter_by_perm(data.values(), tree_data, ids)
  48. merge_children(data2, '', tree_data)
  49. return json_response({'treeData': tree_data, 'groups': data2})
  50. def post(self, request):
  51. form, error = JsonParser(
  52. Argument('id', type=int, required=False),
  53. Argument('parent_id', type=int, default=0),
  54. Argument('name', help='请输入分组名称')
  55. ).parse(request.body)
  56. if error is None:
  57. if form.id:
  58. Group.objects.filter(pk=form.id).update(name=form.name)
  59. else:
  60. group = Group.objects.create(**form)
  61. group.sort_id = group.id
  62. group.save()
  63. return json_response(error=error)
  64. def patch(self, request):
  65. form, error = JsonParser(
  66. Argument('s_id', type=int, help='参数错误'),
  67. Argument('d_id', type=int, help='参数错误'),
  68. Argument('action', type=int, help='参数错误')
  69. ).parse(request.body)
  70. if error is None:
  71. src = Group.objects.get(pk=form.s_id)
  72. dst = Group.objects.get(pk=form.d_id)
  73. if form.action == 0:
  74. src.parent_id = dst.id
  75. dst = Group.objects.filter(parent_id=dst.id).first()
  76. if not dst:
  77. src.save()
  78. return json_response()
  79. form.action = -1
  80. src.parent_id = dst.parent_id
  81. if src.sort_id > dst.sort_id:
  82. if form.action == -1:
  83. dst = Group.objects.filter(sort_id__gt=dst.sort_id).last()
  84. Group.objects.filter(sort_id__lt=src.sort_id, sort_id__gte=dst.sort_id).update(sort_id=F('sort_id') + 1)
  85. else:
  86. if form.action == 1:
  87. dst = Group.objects.filter(sort_id__lt=dst.sort_id).first()
  88. Group.objects.filter(sort_id__lte=dst.sort_id, sort_id__gt=src.sort_id).update(sort_id=F('sort_id') - 1)
  89. src.sort_id = dst.sort_id
  90. src.save()
  91. return json_response(error=error)
  92. def delete(self, request):
  93. form, error = JsonParser(
  94. Argument('id', type=int, help='参数错误')
  95. ).parse(request.GET)
  96. if error is None:
  97. group = Group.objects.filter(pk=form.id).first()
  98. if not group:
  99. return json_response(error='未找到指定分组')
  100. if Group.objects.filter(parent_id=group.id).exists():
  101. return json_response(error='请移除子分组后再尝试删除')
  102. if group.hosts.exists():
  103. return json_response(error='请移除分组下的主机后再尝试删除')
  104. if not Group.objects.exclude(pk=form.id).exists():
  105. return json_response(error='请至少保留一个分组')
  106. role = Role.objects.filter(group_perms__regex=fr'[^0-9]{form.id}[^0-9]').first()
  107. if role:
  108. return json_response(error=f'账户角色【{role.name}】的主机权限关联该分组,请解除关联后再尝试删除')
  109. group.delete()
  110. return json_response(error=error)