mirror of https://github.com/jumpserver/jumpserver
Test case added
parent
f45690b34f
commit
8e5e788bcd
|
@ -29,13 +29,12 @@ class UserUpdateForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = [
|
fields = [
|
||||||
'name', 'email', 'groups', 'wechat', 'avatar',
|
'name', 'email', 'groups', 'wechat',
|
||||||
'phone', 'enable_otp', 'role', 'date_expired', 'comment',
|
'phone', 'enable_otp', 'role', 'date_expired', 'comment',
|
||||||
]
|
]
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'username': '* required',
|
'username': '* required',
|
||||||
'name': '* required',
|
|
||||||
'email': '* required',
|
'email': '* required',
|
||||||
'groups': '* required'
|
'groups': '* required'
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ from django.contrib.auth.hashers import make_password
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import AbstractUser, Permission
|
from django.contrib.auth.models import AbstractUser, Permission
|
||||||
|
from django.db import OperationalError
|
||||||
|
|
||||||
|
|
||||||
class Role(models.Model):
|
class Role(models.Model):
|
||||||
|
@ -23,6 +24,12 @@ class Role(models.Model):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def delete(self, using=None, keep_parents=False):
|
||||||
|
if self.user_set.all().count() > 0:
|
||||||
|
raise OperationalError('Role %s has some member, should not be delete.' % self.name)
|
||||||
|
else:
|
||||||
|
return super(Role, self).delete(using=using, keep_parents=keep_parents)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'role'
|
db_table = 'role'
|
||||||
|
|
||||||
|
@ -56,7 +63,7 @@ class UserGroup(models.Model):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def initial(cls):
|
def initial(cls):
|
||||||
group_or_create = cls.objects.get_or_create(name='All', comment='Default user group for all user',
|
group_or_create = cls.objects.get_or_create(name='Default', comment='Default user group for all user',
|
||||||
created_by='System')
|
created_by='System')
|
||||||
return group_or_create[0]
|
return group_or_create[0]
|
||||||
|
|
||||||
|
@ -93,7 +100,7 @@ class User(AbstractUser):
|
||||||
phone = models.CharField(max_length=20, blank=True, verbose_name='手机号')
|
phone = models.CharField(max_length=20, blank=True, verbose_name='手机号')
|
||||||
enable_otp = models.BooleanField(default=False, verbose_name='启用二次验证')
|
enable_otp = models.BooleanField(default=False, verbose_name='启用二次验证')
|
||||||
secret_key_otp = models.CharField(max_length=16, blank=True)
|
secret_key_otp = models.CharField(max_length=16, blank=True)
|
||||||
role = models.ForeignKey(Role, on_delete=models.PROTECT, verbose_name='角色')
|
role = models.ForeignKey(Role, on_delete=models.SET('None'), verbose_name='角色')
|
||||||
private_key = models.CharField(max_length=5000, blank=True, verbose_name='ssh私钥') # ssh key max length 4096 bit
|
private_key = models.CharField(max_length=5000, blank=True, verbose_name='ssh私钥') # ssh key max length 4096 bit
|
||||||
public_key = models.CharField(max_length=1000, blank=True, verbose_name='公钥')
|
public_key = models.CharField(max_length=1000, blank=True, verbose_name='公钥')
|
||||||
comment = models.TextField(max_length=200, blank=True, verbose_name='描述')
|
comment = models.TextField(max_length=200, blank=True, verbose_name='描述')
|
||||||
|
@ -124,10 +131,12 @@ class User(AbstractUser):
|
||||||
if not self.name:
|
if not self.name:
|
||||||
self.name = self.username
|
self.name = self.username
|
||||||
super(User, self).save(args, **kwargs)
|
super(User, self).save(args, **kwargs)
|
||||||
|
|
||||||
# Set user default group 'All'
|
# Set user default group 'All'
|
||||||
|
# Todo: It's have bug
|
||||||
group = UserGroup.initial()
|
group = UserGroup.initial()
|
||||||
self.groups.add(group)
|
if group not in self.groups.all():
|
||||||
|
self.groups.add(group)
|
||||||
|
super(User, self).save(args, **kwargs)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'user'
|
db_table = 'user'
|
||||||
|
|
|
@ -41,13 +41,14 @@
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
<h3>角色安全</h3>
|
<h3>角色安全</h3>
|
||||||
{{ form.role|bootstrap_horizontal }}
|
{{ form.role|bootstrap_horizontal }}
|
||||||
<div class="form-group" id="date_5">
|
<div class="form-group {% if form.date_expired.errors %} has-error {% endif %}" id="date_5">
|
||||||
<label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label>
|
<label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group date">
|
<div class="input-group date">
|
||||||
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
||||||
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'m/d/Y' }}">
|
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'m/d/Y' }}">
|
||||||
</div>
|
</div>
|
||||||
|
<span class="help-block ">{{ form.date_expired.errors }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -4,26 +4,12 @@ from random import choice
|
||||||
import forgery_py
|
import forgery_py
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.shortcuts import reverse
|
||||||
from django.test import TestCase, Client, TransactionTestCase
|
from django.test import TestCase, Client, TransactionTestCase
|
||||||
from django.test.utils import setup_test_environment
|
from django.test.utils import setup_test_environment
|
||||||
from django.db import IntegrityError, transaction
|
from django.db import IntegrityError, transaction
|
||||||
from .models import User, UserGroup, Role, init_all_models
|
from .models import User, UserGroup, Role, init_all_models
|
||||||
|
from django.contrib.auth.models import Permission
|
||||||
|
|
||||||
setup_test_environment()
|
|
||||||
client = Client()
|
|
||||||
|
|
||||||
|
|
||||||
def create_usergroup(name):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def get_random_usergroup():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def create_user(username, name, email, groups):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def gen_username():
|
def gen_username():
|
||||||
|
@ -42,54 +28,113 @@ class UserModelTest(TransactionTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
init_all_models()
|
init_all_models()
|
||||||
|
|
||||||
def test_user_duplicate(self):
|
# 创建一个用户用于测试
|
||||||
# 创建一个基准测试用户
|
|
||||||
role = choice(Role.objects.all())
|
role = choice(Role.objects.all())
|
||||||
user = User(name='test', username='test', email='test@email.org', role=role)
|
user = User(name='test', username='test', email='test@email.org', role=role)
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
# 创建一个姓名一致的用户, 应该创建成功
|
def test_initial(self):
|
||||||
|
self.assertEqual(User.objects.all().count(), 2)
|
||||||
|
self.assertEqual(Role.objects.all().count(), 3)
|
||||||
|
self.assertEqual(UserGroup.objects.all().count(), 1)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def role(self):
|
||||||
|
return choice(Role.objects.all())
|
||||||
|
|
||||||
|
# 创建一个姓名一致的用户, 应该创建成功
|
||||||
|
def test_user_name_duplicate(self):
|
||||||
user1 = User(name='test', username=gen_username(), password_raw=gen_username(),
|
user1 = User(name='test', username=gen_username(), password_raw=gen_username(),
|
||||||
email=gen_email(), role=role)
|
email=gen_email(), role=self.role)
|
||||||
try:
|
try:
|
||||||
user1.save()
|
user1.save()
|
||||||
user1.delete()
|
user1.delete()
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
self.assertTrue(0, 'Duplicate <name> not allowed.')
|
self.assertTrue(0, 'Duplicate <name> not allowed.')
|
||||||
|
|
||||||
# 创建一个用户名一致的用户, 应该创建不成功
|
# 创建一个用户名一致的用户, 应该创建不成功
|
||||||
user2 = User(username='test', email=gen_email(), role=role)
|
def test_user_username_duplicate(self):
|
||||||
|
user2 = User(username='test', email=gen_email(), role=self.role)
|
||||||
try:
|
try:
|
||||||
user2.save()
|
user2.save()
|
||||||
self.assertTrue(0, 'Duplicate <username> allowed.')
|
self.assertTrue(0, 'Duplicate <username> allowed.')
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# 创建一个Email一致的用户,应该创建不成功
|
# 创建一个Email一致的用户,应该创建不成功
|
||||||
user3 = User(username=gen_username(), email='test@email.org', role=role)
|
def test_user_email_duplicate(self):
|
||||||
|
user3 = User(username=gen_username(), email='test@email.org', role=self.role)
|
||||||
try:
|
try:
|
||||||
user3.save()
|
user3.save()
|
||||||
self.assertTrue(0, 'Duplicate <email> allowed.')
|
self.assertTrue(0, 'Duplicate <email> allowed.')
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# 用户过期测试
|
||||||
def test_user_was_expired(self):
|
def test_user_was_expired(self):
|
||||||
role = choice(Role.objects.all())
|
|
||||||
date = timezone.now() - timezone.timedelta(days=1)
|
date = timezone.now() - timezone.timedelta(days=1)
|
||||||
user = User(name=gen_name(), username=gen_username(),
|
user = User(name=gen_name(), username=gen_username(),
|
||||||
email=gen_email(), role=role, date_expired=date)
|
email=gen_email(), role=self.role, date_expired=date)
|
||||||
|
|
||||||
self.assertTrue(user.is_expired())
|
self.assertTrue(user.is_expired())
|
||||||
|
|
||||||
|
# 测试用户默认会输入All用户组
|
||||||
def test_user_with_default_group(self):
|
def test_user_with_default_group(self):
|
||||||
role = choice(Role.objects.all())
|
role = choice(Role.objects.all())
|
||||||
user = User(username=gen_username(), email=gen_email(), role=role)
|
user = User(username=gen_username(), email=gen_email(), role=role)
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
self.assertEqual(user.groups.count(), 1)
|
self.assertEqual(user.groups.count(), 1)
|
||||||
self.assertEqual(user.groups.first().name, 'All')
|
self.assertEqual(user.groups.first().name, 'Default')
|
||||||
|
|
||||||
|
def test_user_password_authenticated(self):
|
||||||
|
password = gen_username() * 3
|
||||||
|
user = User(username=gen_username(), password_raw=password, role=self.role)
|
||||||
|
user.save()
|
||||||
|
self.assertTrue(user.check_password(password))
|
||||||
|
self.assertFalse(user.check_password(password*2))
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
User.objects.all().delete()
|
||||||
|
UserGroup.objects.all().delete()
|
||||||
|
Role.objects.all().delete()
|
||||||
|
|
||||||
|
|
||||||
|
class RoleModelTestCase(TransactionTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
Role.objects.all().delete()
|
||||||
|
Role.initial()
|
||||||
|
|
||||||
|
def test_role_initial(self):
|
||||||
|
self.assertEqual(Role.objects.all().count(), 3)
|
||||||
|
|
||||||
|
def test_create_new_role(self):
|
||||||
|
role = Role(name=gen_name(), comment=gen_name()*3)
|
||||||
|
role.save()
|
||||||
|
role.permissions = Permission.objects.all()
|
||||||
|
role.save()
|
||||||
|
|
||||||
|
self.assertEqual(Role.objects.count(), 4)
|
||||||
|
role = Role.objects.last()
|
||||||
|
self.assertEqual(role.permissions.all().count(), Permission.objects.all().count())
|
||||||
|
|
||||||
|
|
||||||
|
class UserGroupModelTestCase(TransactionTestCase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class UserListViewTests(TestCase):
|
class UserListViewTests(TestCase):
|
||||||
pass
|
def setUp(self):
|
||||||
|
init_all_models()
|
||||||
|
User.generate_fake()
|
||||||
|
|
||||||
|
def test_list_view_with_one_user(self):
|
||||||
|
response = self.client.get(reverse('users:user-list'))
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertContains(response, 'Admin')
|
||||||
|
self.assertQuerysetEqual(response.context['user_list'], [repr(user) for user in User.objects.all()])
|
||||||
|
|
||||||
|
def test_pagination(self):
|
||||||
|
response = self.client.get(reverse('users:user-list'))
|
||||||
|
self.assertContains(response.status_code, 200)
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,10 @@ class UserUpdateView(UpdateView):
|
||||||
user.set_password(password)
|
user.set_password(password)
|
||||||
return super(UserUpdateView, self).form_valid(form)
|
return super(UserUpdateView, self).form_valid(form)
|
||||||
|
|
||||||
|
def form_invalid(self, form):
|
||||||
|
print(form.errors)
|
||||||
|
return super(UserUpdateView, self).form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
class UserDeleteView(DeleteView):
|
class UserDeleteView(DeleteView):
|
||||||
model = User
|
model = User
|
||||||
|
|
Loading…
Reference in New Issue