Add form validate

pull/530/head
ibuler 8 years ago
parent 072da114db
commit a75e1db970

@ -1,8 +1,9 @@
# coding:utf-8
from django import forms
from django.utils.translation import gettext_lazy as _
from .models import IDC, Asset, AssetGroup, AdminUser, SystemUser, Tag
from django.utils.translation import gettext_lazy as _
from common.utils import validate_ssh_private_key, ssh_pubkey_gen
# class AssetForm(forms.ModelForm):
@ -141,7 +142,6 @@ class AdminUserForm(forms.ModelForm):
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
)
auto_generate_key = forms.BooleanField(required=True, initial=True)
# Form field name can not start with `_`, so redefine it,
password = forms.CharField(widget=forms.PasswordInput, max_length=100, min_length=8, strip=True,
help_text=_('If also set private key, use that first'), required=False)
@ -166,21 +166,36 @@ class AdminUserForm(forms.ModelForm):
# Because we define custom field, so we need rewrite :method: `save`
admin_user = super(AdminUserForm, self).save(commit=commit)
password = self.cleaned_data['password']
private_key_file = self.cleaned_data['private_key_file']
private_key = self.cleaned_data['private_key_file']
public_key = ssh_pubkey_gen(private_key)
if password:
admin_user.password = password
print(password)
# Todo: Validate private key file, and generate public key
# Todo: Auto generate private key and public key
if private_key_file:
admin_user.private_key = private_key_file.read()
if private_key:
admin_user.private_key = private_key
admin_user.public_key = public_key
admin_user.save()
return self.instance
return admin_user
def clean_private_key_file(self):
private_key_file = self.cleaned_data['private_key_file']
if private_key_file:
private_key = private_key_file.read()
if not validate_ssh_private_key(private_key):
raise forms.ValidationError(_('Invalid private key'))
return private_key
return private_key_file
def clean(self):
password = self.cleaned_data['password']
private_key_file = self.cleaned_data.get('private_key_file', '')
if not (password or private_key_file):
raise forms.ValidationError(_('Password and private key file must be input one'))
class Meta:
model = AdminUser
fields = ['name', 'username', 'auto_generate_key', 'password', 'private_key_file', 'as_default', 'comment']
fields = ['name', 'username', 'password', 'private_key_file', 'comment']
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'username': forms.TextInput(attrs={'placeholder': _('Username')}),

@ -6,8 +6,9 @@ from django.db import models
from django.core import serializers
import logging
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError
from common.utils import signer
from common.utils import signer, validate_ssh_private_key
logger = logging.getLogger(__name__)
@ -91,13 +92,21 @@ class AssetExtend(models.Model):
unique_together = ('key', 'value')
def private_key_validator(value):
if not validate_ssh_private_key(value):
raise ValidationError(
_('%(value)s is not an even number'),
params={'value': value},
)
class AdminUser(models.Model):
name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
username = models.CharField(max_length=16, verbose_name=_('Username'))
_password = models.CharField(max_length=256, blank=True, verbose_name=_('Password'))
_private_key = models.CharField(max_length=4096, blank=True, verbose_name=_('SSH private key'))
_password = models.CharField(max_length=256, blank=True, null=True, verbose_name=_('Password'))
_private_key = models.CharField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'),
validators=[private_key_validator,])
_public_key = models.CharField(max_length=4096, blank=True, verbose_name=_('SSH public key'))
as_default = models.BooleanField(default=False, verbose_name=_('As default'))
comment = models.TextField(blank=True, verbose_name=_('Comment'))
date_created = models.DateTimeField(auto_now_add=True, null=True)
created_by = models.CharField(max_length=32, null=True, verbose_name=_('Created by'))

@ -31,20 +31,8 @@
{% csrf_token %}
{{ form.name|bootstrap_horizontal }}
{{ form.username|bootstrap_horizontal }}
<div class="form-group">
<label for="{{ form.auto_generate_key.id_for_label }}" class="col-sm-2 control-label">{% trans 'Auto generate key' %}</label>
<div class="col-sm-8">
{{ form.auto_generate_key}}
</div>
</div>
{{ form.password|bootstrap_horizontal }}
{{ form.private_key_file|bootstrap_horizontal }}
<div class="form-group">
<label for="{{ form.as_default.id_for_label }}" class="col-sm-2 control-label">{% trans 'As default' %}</label>
<div class="col-sm-8">
{{ form.as_default}}
</div>
</div>
{{ form.assets|bootstrap_horizontal }}
{{ form.comment|bootstrap_horizontal }}

@ -1,22 +1,10 @@
{% extends '_base_list.html' %}
{% load i18n static %}
{% block custom_head_css_js %}
{{ block.super }}
<style>
div.dataTables_wrapper div.dataTables_filter,
.dataTables_length {
float: right !important;
}
div.dataTables_wrapper div.dataTables_filter {
margin-left: 15px;
}
</style>
{% block table_search %}
{% endblock %}
{% block table_search %}{% endblock %}
{% block table_container %}
<div class="uc pull-left m-l-5 m-r-5">
<a href="{% url "assets:idc-create" %}" class="btn btn-sm btn-primary"> {% trans "Create IDC" %} </a>
<a href="{% url "assets:admin-user-create" %}" class="btn btn-sm btn-primary"> {% trans "Create admin user" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="admin_user_list_table" >
<thead>
@ -29,7 +17,7 @@
<th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center">{% trans 'Lost connection' %}</th>
<th class="text-center">{% trans 'Comment' %}</th>
<th class="text-center"></th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
@ -59,9 +47,10 @@ $(document).ready(function(){
{# }#}
{# }},#}
{targets: 6, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var script_btn = '<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'.replace('99991937', cellData);
var update_btn = '<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn)
$(td).html(script_btn + update_btn + del_btn)
}}],
ajax_url: '{% url "assets:api-admin-user-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} },

@ -483,6 +483,9 @@ class AdminUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVie
))
return success_message
def form_invalid(self, form):
return super(AdminUserCreateView, self).form_invalid(form)
class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView):
model = AdminUser

@ -3,11 +3,14 @@
from __future__ import unicode_literals
from six import string_types
import os
from itertools import chain
import string
import logging
import datetime
import paramiko
import paramiko
from itsdangerous import TimedJSONWebSignatureSerializer, JSONWebSignatureSerializer, \
BadSignature, SignatureExpired
from django.shortcuts import reverse as dj_reverse
@ -15,6 +18,11 @@ from django.conf import settings
from django.core import signing
from django.utils import timezone
try:
import cStringIO as StringIO
except ImportError:
import StringIO
SECRET_KEY = settings.SECRET_KEY
@ -162,4 +170,70 @@ def timesince(dt, since='', default="just now"):
return default
def ssh_key_string_to_obj(text):
key_f = StringIO.StringIO(text)
key = None
try:
key = paramiko.RSAKey.from_private_key(key_f)
except paramiko.SSHException:
pass
try:
key = paramiko.DSSKey.from_private_key(key_f)
except paramiko.SSHException:
pass
return key
def ssh_pubkey_gen(private_key=None, username='jumpserver', hostname='localhost'):
if isinstance(private_key, string_types):
private_key = ssh_key_string_to_obj(private_key)
if not isinstance(private_key, (paramiko.RSAKey, paramiko.DSSKey)):
raise IOError('Invalid private key')
public_key = "%(key_type)s %(key_content)s %(username)s@%(hostname)s" % {
'key_type': private_key.get_name(),
'key_content': private_key.get_base64(),
'username': username,
'hostname': hostname,
}
return public_key
def ssh_key_gen(length=2048, type='rsa', password=None, username='jumpserver', hostname=None):
"""Generate user ssh private and public key
Use paramiko RSAKey generate it.
:return private key str and public key str
"""
if hostname is None:
hostname = os.uname()[1]
f = StringIO.StringIO()
try:
if type == 'rsa':
private_key_obj = paramiko.RSAKey.generate(length)
elif type == 'dsa':
private_key_obj = paramiko.DSSKey.generate(length)
else:
raise IOError('SSH private key must be `rsa` or `dsa`')
private_key_obj.write_private_key(f, password=password)
private_key = f.getvalue()
public_key = ssh_pubkey_gen(private_key_obj, username=username, hostname=hostname)
return private_key, public_key
except IOError:
raise IOError('These is error when generate ssh key.')
def validate_ssh_private_key(text):
key = ssh_key_string_to_obj(text)
if key is None:
return False
else:
return True
signer = Signer()

@ -34,36 +34,7 @@ class AdminUserRequiredMixin(UserPassesTestMixin):
return self.request.user.is_staff
def ssh_key_gen(length=2048, password=None, username='root', hostname=None):
"""Generate user ssh private and public key
Use paramiko RSAKey generate it.
"""
if hostname is None:
hostname = os.uname()[1]
f = StringIO.StringIO()
try:
logger.debug(_('Begin to generate ssh private key ...'))
private_key_obj = RSAKey.generate(length)
private_key_obj.write_private_key(f, password=password)
private_key = f.getvalue()
public_key = "%(key_type)s %(key_content)s %(username)s@%(hostname)s" % {
'key_type': private_key_obj.get_name(),
'key_content': private_key_obj.get_base64(),
'username': username,
'hostname': hostname,
}
logger.debug(_('Finish to generate ssh private key ...'))
return private_key, public_key
except IOError:
raise IOError(_('These is error when generate ssh key.'))
def user_add_success_next(user):

@ -11,3 +11,4 @@ django-simple-captcha==0.5.2
django-formtools==1.0
sshpubkeys==2.2.0
djangorestframework-bulk==0.2.1
paramiko==2.0.2

Loading…
Cancel
Save