mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
Introduce IPNetworkSerializer to serialize allowed token IPs
This commit is contained in:
parent
e3b7bba84f
commit
3c15419bd0
@ -13,6 +13,8 @@
|
||||
|
||||
#### PoE Interface Attributes ([#1099](https://github.com/netbox-community/netbox/issues/1099))
|
||||
|
||||
#### Restrict API Tokens by Client IP ([#8233](https://github.com/netbox-community/netbox/issues/8233))
|
||||
|
||||
### Enhancements
|
||||
|
||||
* [#1202](https://github.com/netbox-community/netbox/issues/1202) - Support overlapping assignment of NAT IP addresses
|
||||
@ -21,7 +23,6 @@
|
||||
* [#7120](https://github.com/netbox-community/netbox/issues/7120) - Add `termination_date` field to Circuit
|
||||
* [#7744](https://github.com/netbox-community/netbox/issues/7744) - Add `status` field to Location
|
||||
* [#8222](https://github.com/netbox-community/netbox/issues/8222) - Enable the assignment of a VM to a specific host device within a cluster
|
||||
* [#8233](https://github.com/netbox-community/netbox/issues/8233) - Restrict API token access by source IP
|
||||
* [#8471](https://github.com/netbox-community/netbox/issues/8471) - Add `status` field to Cluster
|
||||
* [#8495](https://github.com/netbox-community/netbox/issues/8495) - Enable custom field grouping
|
||||
* [#8995](https://github.com/netbox-community/netbox/issues/8995) - Enable arbitrary ordering of REST API results
|
||||
|
@ -1,4 +1,4 @@
|
||||
from .fields import ChoiceField, ContentTypeField, SerializedPKRelatedField
|
||||
from .fields import *
|
||||
from .routers import NetBoxRouter
|
||||
from .serializers import BulkOperationSerializer, ValidatedModelSerializer, WritableNestedSerializer
|
||||
|
||||
@ -7,6 +7,7 @@ __all__ = (
|
||||
'BulkOperationSerializer',
|
||||
'ChoiceField',
|
||||
'ContentTypeField',
|
||||
'IPNetworkSerializer',
|
||||
'NetBoxRouter',
|
||||
'SerializedPKRelatedField',
|
||||
'ValidatedModelSerializer',
|
||||
|
@ -1,12 +1,18 @@
|
||||
from collections import OrderedDict
|
||||
|
||||
import pytz
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from netaddr import IPNetwork
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.relations import PrimaryKeyRelatedField, RelatedField
|
||||
|
||||
__all__ = (
|
||||
'ChoiceField',
|
||||
'ContentTypeField',
|
||||
'IPNetworkSerializer',
|
||||
'SerializedPKRelatedField',
|
||||
)
|
||||
|
||||
|
||||
class ChoiceField(serializers.Field):
|
||||
"""
|
||||
@ -104,6 +110,17 @@ class ContentTypeField(RelatedField):
|
||||
return f"{obj.app_label}.{obj.model}"
|
||||
|
||||
|
||||
class IPNetworkSerializer(serializers.Serializer):
|
||||
"""
|
||||
Representation of an IP network value (e.g. 192.0.2.0/24).
|
||||
"""
|
||||
def to_representation(self, instance):
|
||||
return str(instance)
|
||||
|
||||
def to_internal_value(self, value):
|
||||
return IPNetwork(value)
|
||||
|
||||
|
||||
class SerializedPKRelatedField(PrimaryKeyRelatedField):
|
||||
"""
|
||||
Extends PrimaryKeyRelatedField to return a serialized object on read. This is useful for representing related
|
||||
|
@ -2,7 +2,7 @@ from django.contrib.auth.models import Group, User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from rest_framework import serializers
|
||||
|
||||
from netbox.api import ContentTypeField, SerializedPKRelatedField, ValidatedModelSerializer
|
||||
from netbox.api import ContentTypeField, IPNetworkSerializer, SerializedPKRelatedField, ValidatedModelSerializer
|
||||
from users.models import ObjectPermission, Token
|
||||
from .nested_serializers import *
|
||||
|
||||
@ -64,6 +64,7 @@ class TokenSerializer(ValidatedModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='users-api:token-detail')
|
||||
key = serializers.CharField(min_length=40, max_length=40, allow_blank=True, required=False)
|
||||
user = NestedUserSerializer()
|
||||
allowed_ips = serializers.ListField(child=IPNetworkSerializer())
|
||||
|
||||
class Meta:
|
||||
model = Token
|
||||
|
@ -4,12 +4,12 @@ import os
|
||||
from django.contrib.auth.models import Group, User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import MinLengthValidator
|
||||
from django.db import models
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from django.utils import timezone
|
||||
from netaddr import IPNetwork
|
||||
|
||||
from ipam.fields import IPNetworkField
|
||||
from netbox.config import get_config
|
||||
@ -17,8 +17,6 @@ from utilities.querysets import RestrictedQuerySet
|
||||
from utilities.utils import flatten_dict
|
||||
from .constants import *
|
||||
|
||||
import ipaddress
|
||||
|
||||
__all__ = (
|
||||
'ObjectPermission',
|
||||
'Token',
|
||||
@ -259,7 +257,7 @@ class Token(models.Model):
|
||||
return True
|
||||
|
||||
for ip_network in self.allowed_ips:
|
||||
if client_ip in ipaddress.ip_network(ip_network):
|
||||
if client_ip in IPNetwork(ip_network):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
@ -1,4 +1,4 @@
|
||||
import ipaddress
|
||||
from netaddr import IPAddress
|
||||
|
||||
__all__ = (
|
||||
'get_client_ip',
|
||||
@ -19,7 +19,7 @@ def get_client_ip(request, additional_headers=()):
|
||||
if header in request.META:
|
||||
client_ip = request.META[header].split(',')[0]
|
||||
try:
|
||||
return ipaddress.ip_address(client_ip)
|
||||
return IPAddress(client_ip)
|
||||
except ValueError:
|
||||
raise ValueError(f"Invalid IP address set for {header}: {client_ip}")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user