From d8fe59debb015a7cff0fa406eda596ade2d666c3 Mon Sep 17 00:00:00 2001 From: "xiaokong1937@gmail.com" <763691951@qq.com> Date: Thu, 8 Sep 2016 21:51:44 +0800 Subject: [PATCH] temp save for issue 8 --- .gitignore | 1 + apps/users/forms.py | 12 +++ apps/users/models.py | 22 +++--- apps/users/templates/users/first_login.html | 68 ++++++++++++++++ .../templates/users/first_login.old.html | 77 +++++++++++++++++++ apps/users/urls.py | 1 + apps/users/views.py | 25 +++++- requirements.txt | 1 + 8 files changed, 192 insertions(+), 15 deletions(-) create mode 100644 apps/users/templates/users/first_login.html create mode 100644 apps/users/templates/users/first_login.old.html diff --git a/.gitignore b/.gitignore index 658ea27ac..959682445 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store *.pyc *.pyo +*.swp env env* dist diff --git a/apps/users/forms.py b/apps/users/forms.py index 8eb8ebcf8..c7f2a96e8 100644 --- a/apps/users/forms.py +++ b/apps/users/forms.py @@ -18,6 +18,7 @@ class UserLoginForm(AuthenticationForm): class UserCreateForm(forms.ModelForm): + class Meta: model = User fields = [ @@ -67,3 +68,14 @@ class UserGroupForm(forms.ModelForm): help_texts = { 'name': '* required' } + + +class UserInfoForm(forms.Form): + name = forms.CharField(max_length=20) + wechat = forms.CharField(max_length=30) + phone = forms.CharField(max_length=20) + enable_otp = forms.BooleanField() + + +class UserKeyForm(forms.Form): + private_key = forms.CharField(max_length=5000, widget=forms.Textarea) diff --git a/apps/users/models.py b/apps/users/models.py index f78c6082d..fba66a8d8 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -2,19 +2,17 @@ from __future__ import unicode_literals -import datetime - from django.conf import settings 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 AbstractUser +from django.core import signing +from django.db import models, IntegrityError from django.db.models.signals import post_save from django.dispatch import receiver -from django.db import IntegrityError +from django.utils import timezone from django.utils.translation import ugettext_lazy as _ + from rest_framework.authtoken.models import Token -from django.core import signing from common.utils import encrypt, decrypt @@ -44,16 +42,15 @@ class UserGroup(models.Model): @classmethod def generate_fake(cls, count=100): - from random import seed, randint, choice + from random import seed, choice import forgery_py - from django.db import IntegrityError seed() for i in range(count): group = cls(name=forgery_py.name.full_name(), comment=forgery_py.lorem_ipsum.sentence(), created_by=choice(User.objects.all()).username - ) + ) try: group.save() except IntegrityError: @@ -84,7 +81,7 @@ class User(AbstractUser): _private_key = models.CharField(max_length=5000, blank=True, verbose_name=_('ssh private key')) _public_key = models.CharField(max_length=1000, blank=True, verbose_name=_('ssh public key')) comment = models.TextField(max_length=200, blank=True, verbose_name=_('Comment')) - is_first_login = models.BooleanField(default=False) + is_first_login = models.BooleanField(default=True) date_expired = models.DateTimeField(default=date_expired_default, blank=True, null=True, verbose_name=_('Date expired')) created_by = models.CharField(max_length=30, default='', verbose_name=_('Created by')) @@ -235,7 +232,7 @@ class User(AbstractUser): wechat=forgery_py.internet.user_name(True), comment=forgery_py.lorem_ipsum.sentence(), created_by=choice(cls.objects.all()).username, - ) + ) try: user.save() except IntegrityError: @@ -264,4 +261,3 @@ def create_auth_token(sender, instance=None, created=False, **kwargs): Token.objects.create(user=instance) except IntegrityError: pass - diff --git a/apps/users/templates/users/first_login.html b/apps/users/templates/users/first_login.html new file mode 100644 index 000000000..6d51ca435 --- /dev/null +++ b/apps/users/templates/users/first_login.html @@ -0,0 +1,68 @@ +{% extends 'base.html' %} +{% load static %} +{% load i18n %} +{% load bootstrap %} + +{% block custom_head_css_js %} +{{ wizard.form.media }} + +{% endblock %} +{% block content %} +
+
+
+
+
+
Basic Wizzard
+ +
+
+
+
+ +
+
+
+ {% csrf_token %} + {{ wizard.management_form }} + {% if wizard.form.forms %} + {{ wizard.form.management_form }} + {% for form in wizard.form.forms %} + {{ form|bootstrap }} + {% endfor %} + {% else %} + {{ wizard.form|bootstrap }} + {% endif %} +
+
+ +
+ {% if wizard.steps.prev %} + + + {% endif %} + +
+
+
+
+ + +{% endblock %} diff --git a/apps/users/templates/users/first_login.old.html b/apps/users/templates/users/first_login.old.html new file mode 100644 index 000000000..b6b1cf838 --- /dev/null +++ b/apps/users/templates/users/first_login.old.html @@ -0,0 +1,77 @@ +{% extends 'base.html' %} +{% load static %} +{% load i18n %} + +{% block custom_head_css_js %} + + +{% endblock %} +{% block content %} +
+
+
+
+
+
Basic Wizzard
+ +
+
+

+ This is basic example of Step +

+
+

First Step

+
+
+

Hello in Step 1

+

+ This is the first content. +

+
+
+ +

Second Step

+
+
+

This is step 2

+

+ This content is diferent than the first one. +

+
+
+ +

Third Step

+
+
+

This is step 3

+

+ This is last content. +

+
+
+
+ +
+
+
+
+
+{% endblock %} +{% block custom_foot_js %} + +{% endblock %} + diff --git a/apps/users/urls.py b/apps/users/urls.py index a89958a2a..179827216 100644 --- a/apps/users/urls.py +++ b/apps/users/urls.py @@ -16,6 +16,7 @@ urlpatterns = [ name='reset-password-success'), url(r'^user$', views.UserListView.as_view(), name='user-list'), url(r'^user/(?P[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'), + url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'), url(r'^user/(?P[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'), url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'), url(r'^user/(?P[0-9]+)/update$', views.UserUpdateView.as_view(), name='user-update'), diff --git a/apps/users/views.py b/apps/users/views.py index bc967cb1e..c34d5fcf8 100644 --- a/apps/users/views.py +++ b/apps/users/views.py @@ -7,9 +7,10 @@ import logging from django.conf import settings from django.contrib.auth import login as auth_login, logout as auth_logout from django.contrib.messages.views import SuccessMessageMixin +from django.core.files.storage import default_storage from django.db.models import Q from django.http import HttpResponseRedirect -from django.shortcuts import get_object_or_404, reverse, redirect +from django.shortcuts import get_object_or_404, reverse, redirect, render from django.utils.decorators import method_decorator from django.utils.translation import ugettext as _ from django.urls import reverse_lazy @@ -21,10 +22,12 @@ from django.views.generic.list import ListView from django.views.generic.edit import CreateView, DeleteView, UpdateView, FormView from django.views.generic.detail import DetailView +from formtools.wizard.views import SessionWizardView + from common.utils import get_object_or_none from .models import User, UserGroup -from .forms import UserCreateForm, UserUpdateForm, UserGroupForm, UserLoginForm +from .forms import (UserCreateForm, UserUpdateForm, UserGroupForm, UserLoginForm, UserInfoForm, UserKeyForm) from .utils import AdminUserRequiredMixin, user_add_success_next, send_reset_password_mail @@ -49,6 +52,9 @@ class UserLoginView(FormView): return redirect(self.get_success_url()) def get_success_url(self): + if self.request.user.is_first_login: + return '/firstlogin' + return self.request.POST.get( self.redirect_field_name, self.request.GET.get(self.redirect_field_name, reverse('index'))) @@ -292,3 +298,18 @@ class UserResetPasswordView(TemplateView): user.reset_password(password) return HttpResponseRedirect(reverse('users:reset-password-success')) + + +class UserFirstLoginView(SessionWizardView): + template_name = 'users/first_login.html' + form_list = [UserInfoForm, UserKeyForm] + file_storage = default_storage + + def done(self, form_list, form_dict, **kwargs): + print form_list + return redirect(reverse('index')) + + def get_context_data(self, **kwargs): + context = super(UserFirstLoginView, self).get_context_data(**kwargs) + context.update({'app': _('Users'), 'action': _('First Login')}) + return context diff --git a/requirements.txt b/requirements.txt index 1b3476a53..ffc458d20 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,4 @@ paramiko==2.0.2 celery==3.1.23 ansible==2.1.1.0 django-simple-captcha==0.5.2 +django-formtools==1.0