def manage_group_policies_handler()

in modular_api_cli/modular_handler/group_handler.py [0:0]


    def manage_group_policies_handler(self, group: str, policies: list,
                                      action: str) -> CommandResponse:
        """
        Adds policies to existed group entity
        :param group: group name which will be updated
        :param policies: Policies list which will be attached/detached to/from group
        :param action: add or remove action
        :return: CommandResponse
        """

        policies = list(set(policies))

        group_item = self.group_service.describe_group(group_name=group)
        if not group_item:
            _LOG.error(f'Group with name \'{group}\' does not exist')
            raise ModularApiBadRequestException(
                f'Group with name \'{group}\' does not exist. Please check '
                f'group name spelling or add group via command:{line_sep}'
                f'modular group add --group {group} --policy $policy_name_1 '
                f'--policy $policy_name_2 --policy $policy_name_N')

        if group_item.state != ACTIVATED_STATE:
            _LOG.error(f'Group with name \'{group}\' is blocked or deleted')
            raise ModularApiBadRequestException(
                f'Group with name \'{group}\' is blocked or deleted. To get '
                f'more detailed information please execute command:{line_sep}'
                f'modular group describe --group {group}')

        if self.group_service.calculate_group_hash(group_item) != \
                group_item.hash:
            click.confirm(
                f'Group with name \'{group}\' is compromised. Command '
                f'execution leads to group entity hash sum recalculation. '
                f'Are you sure?', abort=True)

        retrieved_policies = self.policy_service.get_policies_by_name(
            policy_names=policies
        )
        if not retrieved_policies:
            not_existed_policy = set(policies).intersection(group_item.policies)
            if not_existed_policy and action == 'remove':
                click.confirm(
                    'Provided policy attached to group, but policy entity '
                    'does not exists. Possible reason is ModularPolicy '
                    f'collection compromised and the following policy entities'
                    f' dropped from DB: {not_existed_policy}. Are you about '
                    f'group hash recalculation?',
                    abort=True
                )
                for policy in not_existed_policy:
                    group_item.policies.remove(policy)
                group_hash_sum = self.group_service.calculate_group_hash(
                    group_item)
                group_item.hash = group_hash_sum
                self.group_service.save_group(group_item=group_item)
                return CommandResponse(
                    message='Group item hash successfully recalculated. '
                            'Please execute command again'
                )
            raise ModularApiBadRequestException(
                f'Not existed policy(ies) requested: {policies}')
        if len(policies) != len(retrieved_policies):
            retrieved_policy_names = [policy.policy_name
                                      for policy in retrieved_policies]
            not_existed_policies = [policy for policy in policies
                                    if policy not in retrieved_policy_names]
            not_existed_policy = set(not_existed_policies).intersection(
                group_item.policies)
            if not_existed_policy and action == 'remove':
                click.confirm(
                    'Provided policy attached to group, but policy entity '
                    'does not exists. Possible reason is ModularPolicy '
                    f'collection compromised and the following policy entities'
                    f' dropped from DB: {not_existed_policy}. Are you about '
                    f'group hash recalculation?',
                    abort=True
                )
                for policy in not_existed_policy:
                    group_item.policies.remove(policy)
                group_hash_sum = self.group_service.calculate_group_hash(
                    group_item)
                group_item.hash = group_hash_sum
                self.group_service.save_group(group_item=group_item)
                return CommandResponse(
                    message='Group item hash successfully recalculated. '
                            'Please execute command again'
                )

            if not_existed_policies:
                raise ModularApiBadRequestException(
                    f'Provided policies does not exist: '
                    f'{", ".join(not_existed_policies)}')

        invalid_policies = []
        for policy in retrieved_policies:
            if self.policy_service.calculate_policy_hash(policy) != policy.hash \
                    or policy.state != ACTIVATED_STATE:
                invalid_policies.append(policy.policy_name)

        if invalid_policies:
            _LOG.error('Provided policies compromised or deleted')
            raise ModularApiBadRequestException(
                f'Provided policies compromised or deleted: '
                f'{", ".join(invalid_policies)}{line_sep}To get more detailed'
                f' information please execute command:{line_sep}'
                f'modular policy describe')

        warnings_list = []
        existed_policies = group_item.policies
        if action == 'add':
            existed_policies_in_group = set(policies).intersection(
                existed_policies)
            if existed_policies_in_group:
                warnings_list.append(
                    f'The following policies already attached to \'{group}\' '
                    f'group:{line_sep}'
                    f'{", ".join(existed_policies_in_group)}')
            group_item.policies = list(set(existed_policies).union(set(policies)))

        elif action == 'remove':
            not_existed_group_in_user = set(policies).difference(existed_policies)
            if not_existed_group_in_user:
                warnings_list.append(
                    f'The following policies does not attached to \'{group}\' '
                    f'group:{line_sep}{", ".join(not_existed_group_in_user)}')
            group_item.policies = list(set(existed_policies) - set(policies))
        else:
            raise ModularApiBadRequestException('Invalid action requested')

        group_item.last_modification_date = utc_time_now().isoformat()
        group_hash_sum = self.group_service.calculate_group_hash(group_item)
        group_item.hash = group_hash_sum
        self.group_service.save_group(group_item=group_item)

        result = 'added' if action == 'add' else 'deleted'

        _LOG.info(f'Policies: {", ".join(policies)} successfully {result}. '
                  f'Updated group: \'{group}\'')
        return CommandResponse(
            message=f'Policies: {", ".join(policies)} successfully {result}. '
                    f'Updated group: \'{group}\'',
            warnings=warnings_list)