From 0427d406b9b7f8344b74dadc64861bea926569fa Mon Sep 17 00:00:00 2001 From: ibuler Date: Sun, 21 Aug 2016 01:16:30 +0800 Subject: [PATCH] Add init data file --- apps/common/templatetags/common_tags.py | 8 --- apps/common/utils.py | 4 ++ apps/jumpserver/settings.py | 15 +++- apps/users/apps.py | 1 + apps/users/fixtures/users | 1 + apps/users/fixtures/users.json | 1 + apps/users/forms.py | 4 +- apps/users/migrations/0001_initial.py | 41 ++++++----- .../migrations/0002_auto_20160821_0051.py | 28 ++++++++ .../migrations/0010_auto_20160820_2243.py | 26 +++++++ .../migrations/0011_auto_20160820_2312.py | 30 ++++++++ .../migrations/0012_auto_20160820_2313.py | 22 ++++++ .../migrations/0013_auto_20160820_2313.py | 22 ++++++ apps/users/models.py | 69 +++++++++++++------ apps/users/templates/users/_user.html | 4 +- apps/users/templates/users/user_list.html | 2 +- 16 files changed, 223 insertions(+), 55 deletions(-) create mode 100644 apps/common/utils.py create mode 100644 apps/users/fixtures/users create mode 100644 apps/users/fixtures/users.json create mode 100644 apps/users/migrations/0002_auto_20160821_0051.py create mode 100644 apps/users/migrations/0010_auto_20160820_2243.py create mode 100644 apps/users/migrations/0011_auto_20160820_2312.py create mode 100644 apps/users/migrations/0012_auto_20160820_2313.py create mode 100644 apps/users/migrations/0013_auto_20160820_2313.py diff --git a/apps/common/templatetags/common_tags.py b/apps/common/templatetags/common_tags.py index 6dbebdf77..b9a822c8e 100644 --- a/apps/common/templatetags/common_tags.py +++ b/apps/common/templatetags/common_tags.py @@ -13,14 +13,6 @@ 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 - - @register.filter def pagination_range(total_page, current_num=1, display=5): """Return Page range diff --git a/apps/common/utils.py b/apps/common/utils.py new file mode 100644 index 000000000..3dd26ae97 --- /dev/null +++ b/apps/common/utils.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# + diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index d226a41c7..cf1fbc3dc 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -148,13 +148,22 @@ USE_TZ = True # https://docs.djangoproject.com/en/1.10/howto/static-files/ STATIC_URL = '/static/' -MEDIA_URL = '/media/' + STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"), ) -AUTH_USER_MODEL = 'users.User' -BOOTSTRAP_COLUMN_COUNT = 11 +# Media files (File, ImageField) will be save these + +MEDIA_URL = '/media/' + MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\', '/') + '/' +# Custom User Auth model +AUTH_USER_MODEL = 'users.User' + +# Use django-bootstrap-form to format template, input max width arg +BOOTSTRAP_COLUMN_COUNT = 11 + + diff --git a/apps/users/apps.py b/apps/users/apps.py index 55ad5ba92..af3dddf8e 100644 --- a/apps/users/apps.py +++ b/apps/users/apps.py @@ -5,3 +5,4 @@ from django.apps import AppConfig class UsersConfig(AppConfig): name = 'users' + diff --git a/apps/users/fixtures/users b/apps/users/fixtures/users new file mode 100644 index 000000000..d93ca343a --- /dev/null +++ b/apps/users/fixtures/users @@ -0,0 +1 @@ +[{"model": "users.role", "pk": 1, "fields": {"name": "Administrator", "date_added": "2016-08-20T17:03:42.631Z", "created_by": "System", "comment": "\u7ba1\u7406\u5458", "permissions": [16, 17, 18, 19, 20, 21, 10, 11, 12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"model": "users.role", "pk": 2, "fields": {"name": "User", "date_added": "2016-08-20T17:03:42.671Z", "created_by": "System", "comment": "\u7528\u6237", "permissions": []}}, {"model": "users.role", "pk": 3, "fields": {"name": "Auditor", "date_added": "2016-08-20T17:03:42.683Z", "created_by": "System", "comment": "\u5ba1\u8ba1\u5458", "permissions": []}}, {"model": "users.usergroup", "pk": 1, "fields": {"name": "ALL", "comment": "Default usergroup for all user", "date_added": "2016-08-20T17:03:42.693Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$xZUhPadgI8rs$n2rm5futcOv7Ww4b4BflN8K90Vk3u7ozfnOS7GQq0ns=", "last_login": null, "is_superuser": false, "first_name": "", "last_name": "", "is_staff": false, "is_active": true, "date_joined": "2016-08-20T17:03:42.752Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "role": 1, "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "date_expired": "2086-08-03T17:03:42.753Z", "created_by": "System", "user_permissions": [], "groups": [1]}}] \ No newline at end of file diff --git a/apps/users/fixtures/users.json b/apps/users/fixtures/users.json new file mode 100644 index 000000000..d93ca343a --- /dev/null +++ b/apps/users/fixtures/users.json @@ -0,0 +1 @@ +[{"model": "users.role", "pk": 1, "fields": {"name": "Administrator", "date_added": "2016-08-20T17:03:42.631Z", "created_by": "System", "comment": "\u7ba1\u7406\u5458", "permissions": [16, 17, 18, 19, 20, 21, 10, 11, 12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"model": "users.role", "pk": 2, "fields": {"name": "User", "date_added": "2016-08-20T17:03:42.671Z", "created_by": "System", "comment": "\u7528\u6237", "permissions": []}}, {"model": "users.role", "pk": 3, "fields": {"name": "Auditor", "date_added": "2016-08-20T17:03:42.683Z", "created_by": "System", "comment": "\u5ba1\u8ba1\u5458", "permissions": []}}, {"model": "users.usergroup", "pk": 1, "fields": {"name": "ALL", "comment": "Default usergroup for all user", "date_added": "2016-08-20T17:03:42.693Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$xZUhPadgI8rs$n2rm5futcOv7Ww4b4BflN8K90Vk3u7ozfnOS7GQq0ns=", "last_login": null, "is_superuser": false, "first_name": "", "last_name": "", "is_staff": false, "is_active": true, "date_joined": "2016-08-20T17:03:42.752Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "role": 1, "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "date_expired": "2086-08-03T17:03:42.753Z", "created_by": "System", "user_permissions": [], "groups": [1]}}] \ No newline at end of file diff --git a/apps/users/forms.py b/apps/users/forms.py index 06791d61e..54be3d9b4 100644 --- a/apps/users/forms.py +++ b/apps/users/forms.py @@ -11,7 +11,7 @@ class UserAddForm(ModelForm): model = User fields = [ 'username', 'name', 'email', 'groups', 'wechat', - 'phone', 'enable_2FA', 'role', 'date_expired', 'comment', + 'phone', 'enable_otp', 'role', 'date_expired', 'comment', ] help_texts = { @@ -31,7 +31,7 @@ class UserUpdateForm(ModelForm): model = User fields = [ 'name', 'email', 'groups', 'wechat', 'avatar', - 'phone', 'enable_2FA', 'role', 'date_expired', 'comment', + 'phone', 'enable_otp', 'role', 'date_expired', 'comment', ] help_texts = { diff --git a/apps/users/migrations/0001_initial.py b/apps/users/migrations/0001_initial.py index b399a3d5e..ed177a22b 100644 --- a/apps/users/migrations/0001_initial.py +++ b/apps/users/migrations/0001_initial.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.10 on 2016-08-13 16:36 +# Generated by Django 1.10 on 2016-08-20 16:21 from __future__ import unicode_literals import django.contrib.auth.models -import django.contrib.auth.validators from django.db import migrations, models import django.db.models.deletion import django.utils.timezone +import users.models class Migration(migrations.Migration): @@ -25,22 +25,24 @@ class Migration(migrations.Migration): ('password', models.CharField(max_length=128, verbose_name='password')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.ASCIIUsernameValidator()], verbose_name='username')), ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), ('last_name', models.CharField(blank=True, max_length=30, verbose_name='last name')), - ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('avatar', models.ImageField(default='', upload_to=b'', verbose_name='\u5934\u50cf')), - ('wechat', models.CharField(max_length=30, verbose_name='\u5fae\u4fe1')), - ('phone', models.CharField(max_length=20, verbose_name='\u624b\u673a')), - ('enable_2FA', models.BooleanField(default=False, verbose_name='\u542f\u7528\u4e8c\u6b21\u9a8c\u8bc1')), - ('secret_key_2FA', models.CharField(max_length=16)), - ('private_key', models.CharField(max_length=5000)), - ('public_key', models.CharField(max_length=1000)), - ('created_by', models.CharField(max_length=30)), - ('date_expired', models.DateTimeField()), + ('username', models.CharField(max_length=20, unique=True, verbose_name='\u7528\u6237\u540d')), + ('name', models.CharField(help_text='* required', max_length=20, verbose_name='\u59d3\u540d')), + ('email', models.EmailField(help_text='* required', max_length=30, unique=True, verbose_name='\u90ae\u4ef6')), + ('avatar', models.ImageField(upload_to='avatar', verbose_name='\u5934\u50cf')), + ('wechat', models.CharField(blank=True, max_length=30, verbose_name='\u5fae\u4fe1')), + ('phone', models.CharField(blank=True, max_length=20, verbose_name='\u624b\u673a\u53f7')), + ('enable_otp', models.BooleanField(default=False, verbose_name='\u542f\u7528\u4e8c\u6b21\u9a8c\u8bc1')), + ('secret_key_otp', models.CharField(blank=True, max_length=16)), + ('private_key', models.CharField(blank=True, max_length=5000, verbose_name='ssh\u79c1\u94a5')), + ('public_key', models.CharField(blank=True, max_length=1000, verbose_name='\u516c\u94a5')), + ('comment', models.TextField(blank=True, max_length=200, verbose_name='\u63cf\u8ff0')), + ('date_expired', models.DateTimeField(default=users.models.date_expired_default, verbose_name='\u6709\u6548\u671f')), + ('created_by', models.CharField(default='', max_length=30)), ], options={ 'db_table': 'user', @@ -52,20 +54,21 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Role', fields=[ - ('group_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='auth.Group')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=80, unique=True, verbose_name='name')), ('comment', models.CharField(blank=True, max_length=80)), + ('permissions', models.ManyToManyField(blank=True, to='auth.Permission', verbose_name='permissions')), ], options={ 'db_table': 'role', }, - bases=('auth.group',), ), migrations.CreateModel( name='UserGroup', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='\u8bf7\u8f93\u5165\u7ec4\u540d\u79f0', max_length=100, unique=True, verbose_name='\u7ec4\u540d\u79f0')), - ('comment', models.TextField(blank=True, help_text='\u8bf7\u8f93\u5165\u7528\u6237\u7ec4\u63cf\u8ff0', verbose_name='\u63cf\u8ff0')), + ('name', models.CharField(max_length=100, unique=True, verbose_name='\u7ec4\u540d\u79f0')), + ('comment', models.TextField(blank=True, verbose_name='\u63cf\u8ff0')), ('date_added', models.DateTimeField(auto_now_add=True)), ('created_by', models.CharField(max_length=100)), ], @@ -76,12 +79,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='user', name='groups', - field=models.ManyToManyField(to='users.UserGroup'), + field=models.ManyToManyField(help_text='* required', to='users.UserGroup', verbose_name='\u7528\u6237\u7ec4'), ), migrations.AddField( model_name='user', name='role', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='users.Role'), + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='users.Role', verbose_name='\u89d2\u8272'), ), migrations.AddField( model_name='user', diff --git a/apps/users/migrations/0002_auto_20160821_0051.py b/apps/users/migrations/0002_auto_20160821_0051.py new file mode 100644 index 000000000..244b2b707 --- /dev/null +++ b/apps/users/migrations/0002_auto_20160821_0051.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10 on 2016-08-20 16:51 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='role', + name='created_by', + field=models.CharField(default='System', max_length=100), + preserve_default=False, + ), + migrations.AddField( + model_name='role', + name='date_added', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + preserve_default=False, + ), + ] diff --git a/apps/users/migrations/0010_auto_20160820_2243.py b/apps/users/migrations/0010_auto_20160820_2243.py new file mode 100644 index 000000000..f4862701b --- /dev/null +++ b/apps/users/migrations/0010_auto_20160820_2243.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10 on 2016-08-20 22:43 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0009_auto_20160818_1444'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='date_expired', + field=models.DateTimeField(default=datetime.datetime(2086, 8, 3, 22, 43, 39, 338972), verbose_name='\u6709\u6548\u671f'), + ), + migrations.AlterField( + model_name='user', + name='username', + field=models.CharField(max_length=20, unique=True, verbose_name='\u7528\u6237\u540d'), + ), + ] diff --git a/apps/users/migrations/0011_auto_20160820_2312.py b/apps/users/migrations/0011_auto_20160820_2312.py new file mode 100644 index 000000000..27548699c --- /dev/null +++ b/apps/users/migrations/0011_auto_20160820_2312.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10 on 2016-08-20 15:12 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0010_auto_20160820_2243'), + ] + + operations = [ + migrations.RenameField( + model_name='user', + old_name='enable_2FA', + new_name='enable_otp', + ), + migrations.RenameField( + model_name='user', + old_name='secret_key_2FA', + new_name='secret_key_otp', + ), + migrations.AlterField( + model_name='user', + name='date_expired', + field=models.DateTimeField(verbose_name='\u6709\u6548\u671f'), + ), + ] diff --git a/apps/users/migrations/0012_auto_20160820_2313.py b/apps/users/migrations/0012_auto_20160820_2313.py new file mode 100644 index 000000000..4adcac5a9 --- /dev/null +++ b/apps/users/migrations/0012_auto_20160820_2313.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10 on 2016-08-20 15:13 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0011_auto_20160820_2312'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='date_expired', + field=models.DateTimeField(default=datetime.datetime(2086, 8, 3, 15, 13, 28, 819421, tzinfo=utc), verbose_name='\u6709\u6548\u671f'), + ), + ] diff --git a/apps/users/migrations/0013_auto_20160820_2313.py b/apps/users/migrations/0013_auto_20160820_2313.py new file mode 100644 index 000000000..950c70831 --- /dev/null +++ b/apps/users/migrations/0013_auto_20160820_2313.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10 on 2016-08-20 15:13 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0012_auto_20160820_2313'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='date_expired', + field=models.DateTimeField(default=datetime.datetime(2086, 8, 3, 15, 13, 45, 910700, tzinfo=utc), verbose_name='\u6709\u6548\u671f'), + ), + ] diff --git a/apps/users/models.py b/apps/users/models.py index eb31f3483..6262a77c3 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -4,15 +4,21 @@ from __future__ import unicode_literals import datetime -from django.db.models.signals import post_migrate -from django.dispatch import receiver +from django.contrib.auth.hashers import make_password from django.utils import timezone from django.db import models from django.contrib.auth.models import AbstractUser, Permission -from django.contrib.auth.models import Group as AbstractGroup -class Role(AbstractGroup): +class Role(models.Model): + name = models.CharField('name', max_length=80, unique=True) + permissions = models.ManyToManyField( + Permission, + verbose_name='permissions', + blank=True, + ) + date_added = models.DateTimeField(auto_now_add=True) + created_by = models.CharField(max_length=100) comment = models.CharField(max_length=80, blank=True) def __unicode__(self): @@ -21,9 +27,6 @@ class Role(AbstractGroup): class Meta: db_table = 'role' - def init(self): - pass - @classmethod def init(cls): roles = { @@ -33,14 +36,11 @@ class Role(AbstractGroup): 'comment': '审计员'}, } - for role in cls.objects.all(): - role.permissions.clear() - - cls.objects.all().delete() - for role_name, props in roles.items(): - role = cls.objects.create(name=role_name, comment=props.get('comment', '')) - role.permissions = props.get('permissions', []) + if not cls.objects.filter(name=role_name): + role = cls.objects.create(name=role_name, comment=props.get('comment', ''), created_by='System') + if props.get('permissions'): + role.permissions = props.get('permissions') class UserGroup(models.Model): @@ -58,7 +58,7 @@ class UserGroup(models.Model): @classmethod def init(cls): if not cls.objects.all(): - group = cls(name='所有人', comment='所有人默认都在用户组', created_by='System') + group = cls(name='ALL', comment='Default usergroup for all user', created_by='System') group.save() @classmethod @@ -80,6 +80,10 @@ class UserGroup(models.Model): continue +def date_expired_default(): + return timezone.now() + timezone.timedelta(days=365 * 70) + + class User(AbstractUser): username = models.CharField(max_length=20, unique=True, verbose_name='用户名') name = models.CharField(max_length=20, verbose_name='姓名', help_text='* required') @@ -88,23 +92,40 @@ class User(AbstractUser): avatar = models.ImageField(upload_to="avatar", verbose_name='头像') wechat = models.CharField(max_length=30, blank=True, verbose_name='微信') phone = models.CharField(max_length=20, blank=True, verbose_name='手机号') - enable_2FA = models.BooleanField(default=False, verbose_name='启用二次验证') - secret_key_2FA = models.CharField(max_length=16, blank=True) + enable_otp = models.BooleanField(default=False, verbose_name='启用二次验证') + secret_key_otp = models.CharField(max_length=16, blank=True) 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.TextField(max_length=200, blank=True, verbose_name='描述') + date_expired = models.DateTimeField(default=date_expired_default, verbose_name='有效期') created_by = models.CharField(max_length=30, default='') - date_expired = models.DateTimeField(default=timezone.now()+timezone.timedelta(days=365*70), verbose_name='有效期') class Meta: db_table = 'user' + def is_expired(self): + if self.date_expired > timezone.now(): + return False + else: + return True + + @classmethod + def init(cls): + user = cls(username='admin', + email='admin@jumpserver.org', + name='Administrator', + password=make_password('admin'), + role=Role.objects.get(name='Administrator'), + comment='Administrator is the super user of system', + created_by='System') + user.save() + user.groups.add(UserGroup.objects.get(name='ALL')) + @classmethod def generate_fake(cls, count=100): - from random import seed, randint, choice + from random import seed, choice import forgery_py - from django.contrib.auth.hashers import make_password from django.db import IntegrityError seed() @@ -127,5 +148,13 @@ class User(AbstractUser): user.save() +def init_all_models(): + for model in (Role, UserGroup, User): + if hasattr(model, 'init'): + model.init() +def generate_fake(): + for model in (Role, UserGroup, User): + if hasattr(model, 'generate_fake'): + model.generate_fake() diff --git a/apps/users/templates/users/_user.html b/apps/users/templates/users/_user.html index 74d493a39..8c25db3b4 100644 --- a/apps/users/templates/users/_user.html +++ b/apps/users/templates/users/_user.html @@ -42,9 +42,9 @@ {{ form.role|bootstrap_horizontal }} {{ form.date_expired|bootstrap_horizontal }}
- +
- {{ form.enable_2FA }} + {{ form.enable_otp }}
diff --git a/apps/users/templates/users/user_list.html b/apps/users/templates/users/user_list.html index 5701e322a..313de5eff 100644 --- a/apps/users/templates/users/user_list.html +++ b/apps/users/templates/users/user_list.html @@ -67,7 +67,7 @@ {{ user.groups.all|join_queryset_attr:"name" }} {{ user.name }} - {% if user.date_expired|is_expired %} + {% if user.is_expired %} {% else %}