diff --git a/apps/common/__init__.py b/apps/common/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/common/apps.py b/apps/common/apps.py new file mode 100644 index 000000000..6664a6438 --- /dev/null +++ b/apps/common/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class CommonConfig(AppConfig): + name = 'common' diff --git a/apps/common/migrations/__init__.py b/apps/common/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/common/models.py b/apps/common/models.py new file mode 100644 index 000000000..bd4b2abe9 --- /dev/null +++ b/apps/common/models.py @@ -0,0 +1,5 @@ +from __future__ import unicode_literals + +from django.db import models + +# Create your models here. diff --git a/apps/common/templatetags/__init__.py b/apps/common/templatetags/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/common/templatetags/common_tags.py b/apps/common/templatetags/common_tags.py new file mode 100644 index 000000000..a6ec3c2ba --- /dev/null +++ b/apps/common/templatetags/common_tags.py @@ -0,0 +1,20 @@ +# ~*~ coding: utf-8 ~*~ + +from django import template +from django.utils import timezone + + +register = template.Library() + + +@register.filter +def join_queryset_attr(queryset, attr, delimiter=', '): + return delimiter.join([getattr(obj, attr, '') for obj in queryset]) + + +@register.filter +def is_expired(datetime): + if datetime > timezone.now(): + return False + else: + return True diff --git a/apps/common/tests.py b/apps/common/tests.py new file mode 100644 index 000000000..7ce503c2d --- /dev/null +++ b/apps/common/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/common/views.py b/apps/common/views.py new file mode 100644 index 000000000..91ea44a21 --- /dev/null +++ b/apps/common/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 395edd221..0399343c6 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -36,6 +36,7 @@ INSTALLED_APPS = [ 'perms.apps.PermsConfig', 'ops.apps.OpsConfig', 'audits.apps.AuditsConfig', + 'common.apps.CommonConfig', 'bootstrapform', # 'django.contrib.admin', 'django.contrib.auth', diff --git a/apps/templates/_nav.html b/apps/templates/_nav.html index 4076efa8e..41a81b173 100644 --- a/apps/templates/_nav.html +++ b/apps/templates/_nav.html @@ -8,7 +8,7 @@ 用户管理 diff --git a/apps/users/forms.py b/apps/users/forms.py index 7bbdb6180..5b9f5b6e3 100644 --- a/apps/users/forms.py +++ b/apps/users/forms.py @@ -9,7 +9,6 @@ class UserForm(ModelForm): class Meta: model = User fields = [ - 'username', 'name', 'email', 'groups', 'wechat', + 'username', 'password', 'name', 'email', 'groups', 'wechat', 'phone', 'enable_2FA', 'role', 'date_expired', 'comment', ] - diff --git a/apps/users/migrations/0004_auto_20160815_2257.py b/apps/users/migrations/0004_auto_20160815_2257.py new file mode 100644 index 000000000..41e8fb85b --- /dev/null +++ b/apps/users/migrations/0004_auto_20160815_2257.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10 on 2016-08-15 14:57 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0003_auto_20160814_1758'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='date_expired', + field=models.DateTimeField(default=datetime.datetime(9999, 12, 31, 23, 59, 59, 999999), verbose_name='\u6709\u6548\u671f'), + ), + migrations.AlterField( + model_name='user', + name='email', + field=models.EmailField(help_text='* required', max_length=30, unique=True, verbose_name='\u90ae\u4ef6'), + ), + migrations.AlterField( + model_name='user', + name='groups', + field=models.ManyToManyField(to='users.UserGroup', verbose_name='\u7528\u6237\u7ec4'), + ), + migrations.AlterField( + model_name='user', + name='name', + field=models.CharField(help_text='* required', max_length=20, verbose_name='\u59d3\u540d'), + ), + migrations.AlterField( + model_name='user', + name='username', + field=models.CharField(help_text='* required', max_length=20, unique=True, verbose_name='\u7528\u6237\u540d'), + ), + ] diff --git a/apps/users/models.py b/apps/users/models.py index a79f273e3..d77c3a8f1 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -49,6 +49,12 @@ class UserGroup(models.Model): class Meta: db_table = 'usergroup' + @classmethod + def init(cls): + if not cls.objects.all(): + group = cls(name='所有人', comment='所有人默认都在用户组', created_by='System') + group.save() + class User(AbstractUser): username = models.CharField(max_length=20, unique=True, verbose_name='用户名', help_text='* required') @@ -63,7 +69,7 @@ class User(AbstractUser): role = models.ForeignKey(Role, on_delete=models.PROTECT, verbose_name='角色') 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='公钥') - comment = models.CharField(max_length=200, blank=True, verbose_name='描述') + comment = models.TextField(max_length=200, blank=True, verbose_name='描述') created_by = models.CharField(max_length=30, default='') date_expired = models.DateTimeField(default=datetime.datetime.max, verbose_name='有效期') diff --git a/apps/users/templates/users/_user.html b/apps/users/templates/users/_user.html new file mode 100644 index 000000000..e7581bc76 --- /dev/null +++ b/apps/users/templates/users/_user.html @@ -0,0 +1,109 @@ +{% extends 'base.html' %} +{% load bootstrap %} + +{% block content %} +
+
+
+
+
+
填写用户信息
+ +
+
+
+ {% csrf_token %} +

账户

+ {{ form.username|bootstrap_horizontal }} + {{ form.name|bootstrap_horizontal }} + {{ form.email|bootstrap_horizontal }} + {{ form.groups|bootstrap_horizontal }} + +
+ {% block password %} {% endblock %} + +
+

角色安全

+ {{ form.role|bootstrap_horizontal }} + {{ form.date_expired|bootstrap_horizontal }} +
+ +
+ {{ form.enable_2FA }} +
+
+
+

信息

+ {{ form.phone|bootstrap_horizontal }} + {{ form.wechat|bootstrap_horizontal }} + {{ form.comment|bootstrap_horizontal }} +
+
+
+ + +
+
+
+
+
+
+
+
+{% endblock %} +{% block self_footer_js %} + + +{% endblock %} \ No newline at end of file diff --git a/apps/users/templates/users/user_add.html b/apps/users/templates/users/user_add.html index d61642564..501df1baa 100644 --- a/apps/users/templates/users/user_add.html +++ b/apps/users/templates/users/user_add.html @@ -1,115 +1,10 @@ -{% extends 'base.html' %} -{% load bootstrap %} - -{% block content %} -
-
-
-
-
-
填写用户信息
- -
-
-
- {% csrf_token %} -

账户

- {{ form.username|bootstrap_horizontal }} - {{ form.name|bootstrap_horizontal }} - {{ form.email|bootstrap_horizontal }} - {{ form.groups|bootstrap_horizontal }} - -
-

密码

-
- -
- 生成重置密码连接,通过邮件发送给用户 -
-
- -
-

角色安全

- {{ form.role|bootstrap_horizontal }} - {{ form.date_expired|bootstrap_horizontal }} -
- -
- {{ form.enable_2FA }} -
-
-
-

信息

- {{ form.phone|bootstrap_horizontal }} - {{ form.wechat|bootstrap_horizontal }} - {{ form.comment|bootstrap_horizontal }} -
-
-
- - -
-
-
-
-
-
+{% extends 'users/_user.html' %} +{% block password %} +

密码

+
+ +
+ 生成重置密码连接,通过邮件发送给用户
-{% endblock %} -{% block self_footer_js %} - - {% endblock %} \ No newline at end of file diff --git a/apps/users/templates/users/user_edit.html b/apps/users/templates/users/user_edit.html new file mode 100644 index 000000000..636720450 --- /dev/null +++ b/apps/users/templates/users/user_edit.html @@ -0,0 +1,10 @@ +{% extends 'users/_user.html' %} +{% block password %} +

密码

+
+ +
+ +
+
+{% endblock %} \ No newline at end of file diff --git a/apps/users/templates/users/user_list.html b/apps/users/templates/users/user_list.html index 6c6ecaa6d..06d8ed225 100644 --- a/apps/users/templates/users/user_list.html +++ b/apps/users/templates/users/user_list.html @@ -1,4 +1,5 @@ {% extends 'base.html' %} +{% load common_tags %} {% block content %}
@@ -63,9 +64,9 @@ {{ user.username }} {{ user.role.name }} - {{ user.group.all }} + {{ user.groups.all|join_queryset_attr:"name" }} {{ user.name }} - {{ user.name }} + {{ user.date_expired|is_expired|yesno:"过期, 有效, 分不清楚" }} 编辑 删除 diff --git a/apps/users/urls.py b/apps/users/urls.py index 91e674bd3..24f7a24a6 100644 --- a/apps/users/urls.py +++ b/apps/users/urls.py @@ -1,6 +1,6 @@ from django.conf.urls import url -from .views import UserListView, UserAddView +from .views import UserListView, UserAddView, UserUpdateView app_name = 'users' @@ -8,6 +8,6 @@ urlpatterns = [ url(r'^$', UserListView.as_view(), name='user-list'), url(r'^(?P[0-9]+)/$', UserListView.as_view(), name='user-detail'), url(r'^add/$', UserAddView.as_view(), name='user-add'), - url(r'^(?P[0-9]+)/edit/$', UserListView.as_view(), name='user-edit'), + url(r'^(?P[0-9]+)/edit/$', UserUpdateView.as_view(), name='user-edit'), url(r'^(?P[0-9]+)/delete/$', UserListView.as_view(), name='user-delete'), ] diff --git a/apps/users/views.py b/apps/users/views.py index 98eceb290..1739d7833 100644 --- a/apps/users/views.py +++ b/apps/users/views.py @@ -3,9 +3,9 @@ from django.urls import reverse_lazy from django.db.models import Q from django.views.generic.list import ListView -from django.views.generic.edit import CreateView +from django.views.generic.edit import CreateView, DeleteView, UpdateView -from .models import User, UserGroup +from .models import User, UserGroup, Role from .forms import UserForm @@ -33,6 +33,7 @@ class UserListView(ListView): class UserAddView(CreateView): model = User form_class = UserForm + initial = {'role': Role.objects.get(name='User')} template_name = 'users/user_add.html' success_url = reverse_lazy('users:user-list') @@ -41,3 +42,22 @@ class UserAddView(CreateView): context.update({'path1': '用户管理', 'path2': '用户添加', 'title': '用户添加'}) return context + def form_valid(self, form): + user = form.save() + password = form['password'].value() + user.set_password(password) + return super(UserAddView, self).form_valid(form) + + +class UserUpdateView(UpdateView): + model = User + form_class = UserForm + template_name = 'users/user_edit.html' + success_url = reverse_lazy('users:user-list') + + def form_valid(self, form): + user = form.save() + password = form['password'].value() + if password: + user.set_password(password) + return super(UserUpdateView, self).form_valid(form)