import json import logging from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.models import User, Permission, Group from django.http import JsonResponse from django.shortcuts import get_object_or_404 from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from console import conslog from console.serializers import AllPermsSerializer, GroupNameSerializer from core.decorators import log_url from perms.models import Perm from perms.services.get_permissions import get_all_linked_permissions, get_linked_permissions_name from users.serializers import UserSerializers _log = logging.getLogger(__name__) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) def all_perms(requset): """ API for getting list of all console permissions :param requset: request object :return: JSON with all console groups """ if requset.method == 'GET': permissions = Permission.objects.all().exclude( name='Can view vulnerabilities') serializer = AllPermsSerializer(permissions, many=True) return JsonResponse(serializer.data, safe=False) else: return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) @log_url @login_required def get_linked_permissions(request): permissions = request.GET.getlist('permissions[]', []) data = get_linked_permissions_name(permissions) return JsonResponse(data) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) def user_perms(request, pk): """ API for getting user permissions :param request: request object :param pk: target user primaty key :return: JSON with target user permissions """ if request.method == 'GET': user_by_id = get_object_or_404(User, pk=pk) user_perms = Permission.objects.filter(user=user_by_id) serializer = AllPermsSerializer(user_perms, many=True) return JsonResponse(serializer.data, safe=False) else: return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) def all_groups(requset): """ API for getting all console groups :param requset: request object :return: JSON with all console groups """ if requset.method == 'GET': groups = Group.objects.all() serializer = GroupNameSerializer(groups, many=True) return JsonResponse(serializer.data, safe=False) else: return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) def group_perms(request, g_name): """ API for getting target group permissions :param request: request object :param g_name: target group name :return: JSON with target group permissions """ if request.method == 'GET': target_group = Group.objects.filter(name=g_name) g_perms = Permission.objects.filter(content_type__app_label="perms", group__in=target_group).exclude( name='Can view vulnerabilities') serializer = AllPermsSerializer(g_perms, many=True) return JsonResponse(serializer.data, safe=False) else: return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) def all_perms_wo_group(request, g_name): """ API for getting permissions, which target group dont have :param request: request object :param g_name: target group name :return: JSON with permissions, whic target group dont have """ if request.method == 'GET': target_group = Group.objects.filter(name=g_name) perm_codenames = [] g_perms = Permission.objects.filter(content_type__app_label="perms", group__in=target_group) perms_count = g_perms.count() for perm in g_perms: perm_codenames.append(perm.codename) exc_perms = Permission.objects.filter(content_type__app_label="perms").exclude( codename__in=perm_codenames ).exclude(name='Can view vulnerabilities') serializer = AllPermsSerializer(exc_perms, many=True) return JsonResponse(serializer.data, safe=False) else: return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) def group_users(request, g_name): """ API for getting users, which assigned to target group :param request: request object :param g_name: target group name :return: JSON with target group users """ if request.method == 'GET': users = User.objects.filter(groups__name=g_name).exclude(username__startswith='deleted_') serializer = UserSerializers(users, many=True) return JsonResponse(serializer.data, safe=False) else: return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) def group_users_excluded(request, g_name): """ API for getting users, which are not assigned to the target group :param request: request object :param g_name: target group name :return: JSON with serialized user data """ group_users = User.objects.filter(groups__name=g_name) group_users_usernames = [] for user in group_users: group_users_usernames.append(user.username) available_users = User.objects.exclude(username__in=group_users_usernames).filter(is_active=True) serializer = UserSerializers(available_users, many=True) return JsonResponse(serializer.data, safe=False) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) @api_view(['POST']) def update_group_permission(request, g_name): """ API for updating target group permissions with the information, that user provided :param request: request object :param g_name: target group name :return: JSON with serialized permissions data """ # Recieving JSON with perms from top right table on 'manage_rights' page table_data = json.loads(request.POST.get('perms')) # perms_all = [] # for item in table_data: # perms_all.append(item['codename']) # perms_from_table = Permission.objects.filter(codename__in=perms_all).exclude( # name='Can view vulnerabilities') # serializer = AllPermsSerializer(perms_from_table, many=True) # Method for setting new permissions from permission list, provided by user perm_codenames = [] # Getting list of codenames, that users chose to apply to target group for item in table_data: perm_codenames.append(item.get('codename')) # Gettimg current perms of target group target_group = Group.objects.get(name=g_name) # Clearing all permissions from group target_group.permissions.clear() # Adding permissions, chosen by user to target group perm_codenames = get_all_linked_permissions(perm_codenames) permissions = Permission.objects.filter(codename__in=perm_codenames) target_group.permissions.set(permissions) serializer = AllPermsSerializer(permissions, many=True) log_message = f"User [{request.user}] updated the [[{g_name}]] group permissions. New group permissions: {perm_codenames}" conslog.add_info_log(log_message, _log) return JsonResponse(serializer.data, safe=False) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) @api_view(['POST']) def update_group_users(request, g_name): """ API for updating the group users set :param request: request object :param g_name: target group name from the user :return: JSON with serialized users data """ users = User.objects.filter(groups__name=g_name) target_group = Group.objects.get(name=g_name) # Gettimg list of usernames form bottom right table in JSON format users_new = json.loads(request.POST.get('users')) usernames_after = [] for user in users_new: usernames_after.append(user.get('username')) # Getting usernames, which are assigned to the target group before any changes users_before = User.objects.filter(groups__name=g_name) usernames_before = [] for user in users_before: usernames_before.append(user.username) # Removing all users from group target_group.user_set.clear() users_before_1 = User.objects.filter(groups__name=g_name) # Adding users to group, provided by operator for username in usernames_after: target_group.user_set.add(User.objects.get(username=username)) users_before_2 = User.objects.filter(groups__name=g_name) serializer = UserSerializers(users, many=True) log_message = f"User [{request.user}] updated the [[{g_name}]] group users. New group users: {usernames_after}" conslog.add_info_log(log_message, _log) return JsonResponse(serializer.data, safe=False) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) @api_view(['POST']) def delete_group_api(request, g_name): """ API for deleting the group :param request: request object :param g_name: target group name :return: JSON with serialized groups data """ target_group = Group.objects.get(name=g_name) serializer = GroupNameSerializer(target_group) Group.objects.get(name=g_name).delete() log_message = f"User [{request.user}] deleted [[{g_name}]] group" conslog.add_info_log(log_message, _log) return JsonResponse(serializer.data) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) @api_view(['POST']) def add_new_group(request, g_name): """ API for adding new group :param request: request object :param g_name: target group name :return: JSON with serialized groups data """ # Prepearing data for serializer (needs to be dict value, revieving a string from request dict_name = {'name': g_name} serializer = GroupNameSerializer(data=dict_name) if serializer.is_valid(): serializer.save() # serializer.add_new_group(validated_info=serializer.data) log_message = f"User [{request.user}] created a [[{g_name}]] group" conslog.add_info_log(log_message, _log) return Response(serializer.data) else: log_message = f"User [{request.user}] failed to create a new group [[{g_name}]] due to the error: {serializer.errors}" conslog.add_error_log(log_message, _log) return JsonResponse(serializer.errors, status=400) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) @api_view(['POST']) def rename_group(request, g_name, new_g_name): """ API for renaming the target group :param request: request object :param g_name: target group name :param new_g_name: new target group name """ # Prepearing data for serializer (needs to be dict value, revieving a string from request dict_name = {'name': new_g_name} serializer = GroupNameSerializer(data=dict_name) if serializer.is_valid(): upd_group = Group.objects.get(name=g_name) upd_group.name = serializer.data['name'] upd_group.save() log_message = f"User [{request.user}] renamed [[{g_name}]] group with the name: [[{new_g_name}]]" conslog.add_info_log(log_message, _log) return Response(serializer.data) else: log_message = f"User [{request.user}] failed to rename [[{g_name}]], due to the error: {serializer.errors}" conslog.add_error_log(log_message, _log) return JsonResponse(serializer.errors, status=400) @log_url @login_required @permission_required(Perm.perm_req(Perm.can_add_group), raise_exception=True) @api_view(['POST']) def copy_group(request, g_name, new_g_name): """ API for copying the target group :param request: request object :param g_name: target group name :param new_g_name: new target group name """ # Preparing data for serializer (needs to be dict value, revieving a string from request dict_name = {'name': new_g_name} serializer = GroupNameSerializer(data=dict_name) if serializer.is_valid(): master_group = Group.objects.get(name=g_name) slave_group = Group.objects.create(name=serializer.data['name']) for perm in master_group.permissions.all(): slave_group.permissions.add(Permission.objects.get(codename=perm.codename)) log_message = f"User [{request.user}] created a copy of the [[{g_name}]] group with the name: [[{new_g_name}]]" conslog.add_info_log(log_message, _log) return Response(serializer.data) else: log_message = f"User [{request.user}] failed to create copy of the [[{g_name}]], due to the error: {serializer.errors}" conslog.add_error_log(log_message, _log) return JsonResponse(serializer.errors, status=400)