Browse Source

Add validation to networks form

devel
bashmak 8 years ago
parent
commit
9894968e9b
  1. 12
      djing/lib/tln/tln.py
  2. 24
      ip_pool/forms.py
  3. 18
      ip_pool/models.py
  4. 8
      ip_pool/templates/ip_pool/net_add.html
  5. 8
      ip_pool/templates/ip_pool/net_edit.html
  6. 49
      static/js/cidr.js
  7. 22
      static/js/my.js
  8. 1
      templates/all_base.html

12
djing/lib/tln/tln.py

@ -29,21 +29,23 @@ class ValidationError(ValueError):
MAC_ADDR_REGEX = b'^([0-9A-Fa-f]{1,2}[:-]){5}([0-9A-Fa-f]{1,2})$' MAC_ADDR_REGEX = b'^([0-9A-Fa-f]{1,2}[:-]){5}([0-9A-Fa-f]{1,2})$'
IP_ADDR_REGEX = '^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
IP_ADDR_REGEX = (
'^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
)
ONU_SN_REGEX = b'^ZTEG[A-F\d]{8}$' ONU_SN_REGEX = b'^ZTEG[A-F\d]{8}$'
class TelnetApi(Telnet): class TelnetApi(Telnet):
config_level = []
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
timeout = kwargs.get('timeout') timeout = kwargs.get('timeout')
if timeout: if timeout:
self._timeout = timeout self._timeout = timeout
self._prompt_string = b'ZTE-C320-PKP#' self._prompt_string = b'ZTE-C320-PKP#'
self.config_level = []
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def write(self, buffer: bytes) -> None: def write(self, buffer: bytes) -> None:

24
ip_pool/forms.py

@ -1,4 +1,4 @@
from netaddr import IPNetwork, AddrFormatError, IPAddress
from netaddr import IPNetwork, AddrFormatError
from django import forms from django import forms
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@ -6,21 +6,29 @@ from ip_pool import models
class NetworkForm(forms.ModelForm): class NetworkForm(forms.ModelForm):
mask = forms.CharField(max_length=39, min_length=7, widget=forms.TextInput())
def clean_mask(self):
def clean_network(self):
netw = self.data.get('network')
mask = self.data.get('mask')
if netw is None:
return
try: try:
network = IPAddress(self.data.get('network'))
mask = self.data.get('mask')
net = IPNetwork('%s/%s' % (network, mask))
ip, new_mask = str(net.cidr).split('/')
return new_mask
if mask:
net = IPNetwork('%s/%s' % (netw, mask))
else:
net = IPNetwork(netw)
return str(net.ip)
except AddrFormatError as e: except AddrFormatError as e:
raise ValidationError(e, code='invalid') raise ValidationError(e, code='invalid')
class Meta: class Meta:
model = models.NetworkModel model = models.NetworkModel
fields = '__all__' fields = '__all__'
widgets = {
'mask': forms.TextInput(attrs={
'pattern': '^\d{1,3}$'
})
}
class EmployedIpForm(forms.ModelForm): class EmployedIpForm(forms.ModelForm):

18
ip_pool/models.py

@ -7,28 +7,18 @@ from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
IP_SUBNET_RE = (
'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/'
'(3[0-2]|2\d|1\d|\d))|(\/(3[0-2]|2\d|1\d|\d))$'
)
class NetworkModel(models.Model): class NetworkModel(models.Model):
_netw_cache = None _netw_cache = None
network = models.GenericIPAddressField( network = models.GenericIPAddressField(
verbose_name=_('IP network'), verbose_name=_('IP network'),
help_text=_('Dot separated ip address of network. For example: 192.168.1.0'),
help_text=_('Ip address of network. For example: 192.168.1.0 or fde8:6789:1234:1::'),
unique=True unique=True
) )
mask = models.PositiveSmallIntegerField( mask = models.PositiveSmallIntegerField(
_('Mask'), _('Mask'),
help_text=_('For example: 24, if network is 192.168.1.0/24'),
help_text=_('Net mask bits length for ipv4 or prefix length for ipv6'),
default=24, default=24,
validators=()
) )
work_range_start_ip = models.GenericIPAddressField( work_range_start_ip = models.GenericIPAddressField(
verbose_name=_('Work range start ip'), verbose_name=_('Work range start ip'),
@ -55,7 +45,9 @@ class NetworkModel(models.Model):
def get_network(self) -> IPNetwork: def get_network(self) -> IPNetwork:
if self._netw_cache is None: if self._netw_cache is None:
self._netw_cache = IPNetwork("%s/%s" % (self.network, self.mask or 32))
self._netw_cache = IPNetwork(self.network)
if self.mask:
self._netw_cache.prefixlen = self.mask
return self._netw_cache return self._netw_cache
def get_absolute_url(self): def get_absolute_url(self):

8
ip_pool/templates/ip_pool/net_add.html

@ -3,6 +3,10 @@
{% load bootstrap3 %} {% load bootstrap3 %}
{% load globaltags %} {% load globaltags %}
{% block additional_link %}
<script src="/static/js/cidr.js"></script>
{% endblock %}
{% block breadcrumb %} {% block breadcrumb %}
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <li><span class="glyphicon glyphicon-home"></span></li>
@ -15,9 +19,9 @@
{% block main %} {% block main %}
<form action="{% url 'ip_pool:net_add' %}" method="post">{% csrf_token %} <form action="{% url 'ip_pool:net_add' %}" method="post">{% csrf_token %}
<div class="panel panel-default">
<div class="panel panel-default cidr-contain">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title">{% trans 'Add network' %}</h3>
<h3 class="panel-title">{% trans 'Add network' %} <span></span></h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
{% bootstrap_form form %} {% bootstrap_form form %}

8
ip_pool/templates/ip_pool/net_edit.html

@ -3,6 +3,10 @@
{% load bootstrap3 %} {% load bootstrap3 %}
{% load globaltags %} {% load globaltags %}
{% block additional_link %}
<script src="/static/js/cidr.js"></script>
{% endblock %}
{% block breadcrumb %} {% block breadcrumb %}
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li> <li><span class="glyphicon glyphicon-home"></span></li>
@ -15,9 +19,9 @@
{% block main %} {% block main %}
<form action="{% url 'ip_pool:net_edit' object.pk %}" method="post">{% csrf_token %} <form action="{% url 'ip_pool:net_edit' object.pk %}" method="post">{% csrf_token %}
<div class="panel panel-default">
<div class="panel panel-default cidr-contain">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title">{% trans 'Edit network' %}</h3>
<h3 class="panel-title">{% trans 'Edit network' %} <span>{{ object.get_network }}</span></h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
{% bootstrap_form form %} {% bootstrap_form form %}

49
static/js/cidr.js

@ -0,0 +1,49 @@
(function ($){
$.fn.cidr_validator = function(opts){
var IP4_REG = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/s;
var IP6_REG = /^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?$/s;
var settings = $.extend( {
res_label: this.find('.panel-title>span')
}, opts);
var net_inp = this.find('#id_network');
var mask_inp = this.find('#id_mask');
/*var wrsi = this.children('#id_work_range_start_ip');
var wrei = this.children('#id_work_range_end_ip');*/
var validate_ip_by_key = function(){
var v = this.value;
var o = $(this).closest('.form-group-sm,.form-group');
o.removeClass('has-error has-success');
if(v.match(IP4_REG) !== null){
mask_inp.val('24');
o.addClass('has-success');
}else
if(v.match(IP6_REG) !== null){
mask_inp.val('64');
o.addClass('has-success');
}else
o.addClass('has-error');
};
var validate_ip_by_focus_lost = function(){
console.log('Lost');
var v = this.value;
if(v.includes('/')){
var chunks = v.split('/');
if(chunks[1] !== ""){
net_inp.val(chunks[0]);
mask_inp.val(chunks[1]);
settings.res_label.text(v);
}
}else {
settings.res_label.text(v + '/' + mask_inp.val());
}
};
net_inp.on('keyup', validate_ip_by_key).on('focusout', validate_ip_by_focus_lost);
};
})(jQuery);
$(document).ready(function () {
$('div.cidr-contain').cidr_validator();
});

22
static/js/my.js

@ -77,7 +77,7 @@ $(document).ajaxError(function (ev, jqXHR, ajaxSettings, thrownError) {
var def_play = function(e){ var def_play = function(e){
var audiotag = e.data['audiotag'][0]; var audiotag = e.data['audiotag'][0];
if(audiotag.readyState == 0){
if(audiotag.readyState === 0){
$(this).prop('disabled', true); $(this).prop('disabled', true);
return; return;
}else }else
@ -143,14 +143,14 @@ $(document).ajaxError(function (ev, jqXHR, ajaxSettings, thrownError) {
// Ajax form // Ajax form
(function ($){ (function ($){
$.fn.ajform = function(opt){ $.fn.ajform = function(opt){
var on_response_default = function(){
alert('You must assign callback function for response');
};
var settings = $.extend({ var settings = $.extend({
on_response : on_response_default on_response : on_response_default
}, opt); }, opt);
var on_response_default = function(r){
alert('You must assign callback function for response');
};
var on_submit = function(e){ var on_submit = function(e){
e.preventDefault(); e.preventDefault();
var formData = new FormData(this); var formData = new FormData(this);
@ -183,24 +183,24 @@ $(document).ajaxError(function (ev, jqXHR, ajaxSettings, thrownError) {
var notifShow = function(title, content){ var notifShow = function(title, content){
if(!settings.news_url) return; if(!settings.news_url) return;
var perm = Notification.permission.toLowerCase(); var perm = Notification.permission.toLowerCase();
if(perm == "granted"){
if(perm === "granted"){
curnotify = new Notification(title, { curnotify = new Notification(title, {
tag: 'djing-notify', tag: 'djing-notify',
body: content, body: content,
icon: '/static/img/noticon.png'} icon: '/static/img/noticon.png'}
); );
}else if(perm == "default"){
}else if(perm === "default"){
Notification.requestPermission(on_ask_perm); Notification.requestPermission(on_ask_perm);
} }
}
};
var on_ask_perm = function(r){ var on_ask_perm = function(r){
console.log("Thanks for letting notify you"); console.log("Thanks for letting notify you");
}
};
var check_news = function(){ var check_news = function(){
var perm = Notification.permission.toLowerCase(); var perm = Notification.permission.toLowerCase();
if(perm == "granted" && settings.news_url){
if("granted" === perm && settings.news_url){
$.getJSON(settings.news_url, function(r){ $.getJSON(settings.news_url, function(r){
if(r.auth){ if(r.auth){
if(r.exist){ if(r.exist){
@ -211,7 +211,7 @@ $(document).ajaxError(function (ev, jqXHR, ajaxSettings, thrownError) {
} }
}); });
} }
}
};
if(settings.news_url){ if(settings.news_url){
// once per minute check news // once per minute check news

1
templates/all_base.html

@ -8,6 +8,7 @@
<link rel="stylesheet" href="/static/css/all.min.css"> <link rel="stylesheet" href="/static/css/all.min.css">
<link rel="stylesheet" href="/static/css/custom.css"> <link rel="stylesheet" href="/static/css/custom.css">
<script src="/static/js/all.min.js"></script> <script src="/static/js/all.min.js"></script>
{% block additional_link %}{% endblock %}
<script src="/static/js/my.js"></script> <script src="/static/js/my.js"></script>
<link rel="shortcut icon" href="/static/img/favicon_m.ico"> <link rel="shortcut icon" href="/static/img/favicon_m.ico">
<meta name="author" content="Dmitry Novikov"> <meta name="author" content="Dmitry Novikov">

Loading…
Cancel
Save