import base64 from django.contrib.auth import get_user_model from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from .models import * # class WireGuardVPNPoolSerializer(serializers.ModelSerializer): # class Meta: # model = WireGuardVPNPool # fields = '__all__' # class WireGuardVPNSerializer(serializers.ModelSerializer): # class Meta: # model = VPNNetworkReservation # fields = '__all__' # class VPNNetworkSerializer(serializers.ModelSerializer): # class Meta: # model = VPNNetwork # fields = '__all__' # # This is required for finding the VPN pool, but does not # # exist in the model # network_size = serializers.IntegerField(min_value=0, # max_value=128, # write_only=True) # def validate_wireguard_public_key(self, value): # msg = _("Supplied key is not a valid wireguard public key") # """ FIXME: verify that this does not create broken wireguard config files, # i.e. contains \n or similar! # We might even need to be more strict to not break wireguard... # """ # try: # base64.standard_b64decode(value) # except Exception as e: # raise serializers.ValidationError(msg) # if '\n' in value: # raise serializers.ValidationError(msg) # return value # def validate(self, data): # # FIXME: filter for status = active or similar # all_pools = VPNPool.objects.all() # sizes = [ p.subnetwork_size for p in all_pools ] # pools = VPNPool.objects.filter(subnetwork_size=data['network_size']) # if len(pools) == 0: # msg = _("No pool available for networks with size = {}. Available are: {}".format(data['network_size'], sizes)) # raise serializers.ValidationError(msg) # return data # def create(self, validated_data): # """ # Creating a new vpnnetwork - there are a couple of race conditions, # especially when run in parallel. # What we should be doing: # - create a reservation race free # - map the reservation to a network (?) # """ # pools = VPNPool.objects.filter(subnetwork_size=validated_data['network_size']) # vpn_network = None # for pool in pools: # if pool.num_free_networks > 0: # next_address = pool.next_free_network # reservation, created = VPNNetworkReservation.objects.update_or_create( # vpnpool=pool, address=next_address, # defaults = { # 'status': 'used' # }) # vpn_network = VPNNetwork.objects.create( # owner=self.context['request'].user, # network=reservation, # wireguard_public_key=validated_data['wireguard_public_key'] # ) # break # if not vpn_network: # # FIXME: use correct exception # raise Exception("Did not find any free pool") # return vpn_network