diff --git a/netbox/templates/users/api_tokens.html b/netbox/templates/users/api_tokens.html
index 53839b38e..36b0143e7 100644
--- a/netbox/templates/users/api_tokens.html
+++ b/netbox/templates/users/api_tokens.html
@@ -45,7 +45,7 @@
Allowed Source IPs
{% if token.allowed_ips %}
- {{ token.allowed_ips }}
+ {{ token.allowed_ips|join:', ' }}
{% else %}
Any
{% endif %}
diff --git a/netbox/users/admin/__init__.py b/netbox/users/admin/__init__.py
index 3fb5d93bb..b9e9ca898 100644
--- a/netbox/users/admin/__init__.py
+++ b/netbox/users/admin/__init__.py
@@ -59,9 +59,14 @@ class UserAdmin(UserAdmin_):
class TokenAdmin(admin.ModelAdmin, DynamicArrayMixin):
form = forms.TokenAdminForm
list_display = [
- 'key', 'user', 'created', 'expires', 'write_enabled', 'description', 'allowed_ips'
+ 'key', 'user', 'created', 'expires', 'write_enabled', 'description', 'list_allowed_ips'
]
+ def list_allowed_ips(self, obj):
+ return obj.allowed_ips
+ list_allowed_ips.empty_value_display = 'Any'
+ list_allowed_ips.short_description = "Allowed IPs"
+
#
# Permissions
diff --git a/netbox/users/forms.py b/netbox/users/forms.py
index 4d2de2661..ebfecafff 100644
--- a/netbox/users/forms.py
+++ b/netbox/users/forms.py
@@ -1,8 +1,10 @@
from django import forms
from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm as DjangoPasswordChangeForm
+from django.contrib.postgres.forms import SimpleArrayField
from utilities.forms import BootstrapMixin, DateTimePicker
from .models import Token
+from ipam.formfields import IPNetworkFormField
class LoginForm(BootstrapMixin, AuthenticationForm):
@@ -18,6 +20,11 @@ class TokenForm(BootstrapMixin, forms.ModelForm):
required=False,
help_text="If no key is provided, one will be generated automatically."
)
+ allowed_ips = SimpleArrayField(
+ base_field=IPNetworkFormField(),
+ required=False,
+ help_text='Allowed IPv4/IPv6 networks from where the token can be used. Leave blank for no restrictions. Ex: "10.1.1.0/24, 192.168.10.16/32, 2001:DB8:1::/64"',
+ )
class Meta:
model = Token