From 5940cec0e648f0a1d4c58f41d1640c269e30e341 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 1 Sep 2016 01:12:02 +0800 Subject: [PATCH] Add user and send mail --- apps/common/utils.py | 17 +++++++++++++-- apps/jumpserver/settings.py | 4 ++++ apps/jumpserver/views.py | 0 apps/templates/_left_side_bar.html | 6 ++++- apps/templates/_nav_user.html | 29 +++++++++++++++++++++++++ apps/templates/index.html | 0 apps/users/models.py | 1 + apps/users/urls.py | 4 ++-- apps/users/utils.py | 35 ++++++++++++++++++++++++++++++ apps/users/views.py | 34 ++++------------------------- config-example.py | 1 + 11 files changed, 96 insertions(+), 35 deletions(-) create mode 100644 apps/jumpserver/views.py create mode 100644 apps/templates/_nav_user.html create mode 100644 apps/templates/index.html diff --git a/apps/common/utils.py b/apps/common/utils.py index 3dd26ae97..f975d4bda 100644 --- a/apps/common/utils.py +++ b/apps/common/utils.py @@ -1,4 +1,17 @@ -#!/usr/bin/env python # -*- coding: utf-8 -*- -# +# + +from __future__ import unicode_literals + +from django.shortcuts import reverse as dj_reverse +from django.conf import settings + + +def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None, external=False): + url = dj_reverse(viewname, urlconf=urlconf, args=args, kwargs=kwargs, current_app=current_app) + + if external: + url = settings.SITE_URL.strip('/') + url + + return url diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 7d868f3e3..2244a0a79 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -39,6 +39,10 @@ SECRET_KEY = CONFIG.SECRET_KEY or '2vym+ky!997d5kkcc64mnz06y1mmui3lut#(^wd=%s_qj DEBUG = CONFIG.DEBUG or False +# Absolute url for some case, for example email link +SITE_URL = CONFIG.SITE_URL or 'http://localhost' + + # LOG LEVEL LOG_LEVEL = 'DEBUG' if DEBUG else CONFIG.LOG_LEVEL or 'WARNING' diff --git a/apps/jumpserver/views.py b/apps/jumpserver/views.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/templates/_left_side_bar.html b/apps/templates/_left_side_bar.html index 80a3825df..0d58e79a2 100644 --- a/apps/templates/_left_side_bar.html +++ b/apps/templates/_left_side_bar.html @@ -2,7 +2,11 @@ diff --git a/apps/templates/_nav_user.html b/apps/templates/_nav_user.html new file mode 100644 index 000000000..3c9f48f95 --- /dev/null +++ b/apps/templates/_nav_user.html @@ -0,0 +1,29 @@ +
  • + + 仪表盘 + +
  • +
  • + + 我的资产 + +
  • +
  • + + 上传下载 + + +
  • +
  • + + 用户信息 + +
  • + \ No newline at end of file diff --git a/apps/templates/index.html b/apps/templates/index.html new file mode 100644 index 000000000..e69de29bb diff --git a/apps/users/models.py b/apps/users/models.py index aead530ba..acd0ed182 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -115,6 +115,7 @@ class User(AbstractUser): 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='描述') + first_login = models.BooleanField(default=False) date_expired = models.DateTimeField(default=date_expired_default, blank=True, null=True, verbose_name='有效期') created_by = models.CharField(max_length=30, default='') diff --git a/apps/users/urls.py b/apps/users/urls.py index fdc55d35b..776ae1e89 100644 --- a/apps/users/urls.py +++ b/apps/users/urls.py @@ -9,8 +9,8 @@ app_name = 'users' urlpatterns = [ url(r'^login$', auth_views.login, {'template_name': 'users/login.html'}, name='login'), url(r'^logout$', auth_views.logout, {'template_name': 'users/login.html'}, name='logout'), - url(r'^password/forget-password$', views.UserForgetPasswordView.as_view(), name='forget-password'), - url(r'^password/reset-password$', views.UserRestPasswordView.as_view(), name='reset-password'), + url(r'^password/forget$', views.UserForgetPasswordView.as_view(), name='forget-password'), + url(r'^password/reset$', views.UserRestPasswordView.as_view(), name='reset-password'), url(r'^users$', views.UserListView.as_view(), name='user-list'), url(r'^users/(?P[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'), url(r'^users/add$', views.UserAddView.as_view(), name='user-add'), diff --git a/apps/users/utils.py b/apps/users/utils.py index 8c5b0e32e..99afd2c86 100644 --- a/apps/users/utils.py +++ b/apps/users/utils.py @@ -1,6 +1,7 @@ # ~*~ coding: utf-8 ~*~ # +from __future__ import unicode_literals import os import logging @@ -8,6 +9,10 @@ from paramiko.rsakey import RSAKey from django.contrib.auth.mixins import UserPassesTestMixin from django.urls import reverse_lazy +from common.tasks import send_mail_async +from common.utils import reverse +from users.models import User + try: import cStringIO as StringIO @@ -57,6 +62,36 @@ def ssh_key_gen(length=2048, password=None, username='root', hostname=None): raise IOError('These is error when generate ssh key.') +def user_add_success_next(user): + subject = '您的用户创建成功' + recipient_list = [user.email] + message = """ + 您好 %(name)s: +
    + 恭喜您,您的账号已经创建成功. +
    + 请点击这里设置密码 +
    + 这个链接有效期1小时, 超过时间您可以 重新申请 + +
    + --- + +
    + 直接登录 + +
    + """ % { + 'name': user.name, + 'rest_password_url': reverse('users:reset-password', external=True), + 'rest_password_token': User.generate_reset_token(user.email), + 'forget_password_url': reverse('users:forget-password', external=True), + 'email': user.email, + 'login_url': reverse('users:login', external=True), + } + + send_mail_async.delay(subject, message, recipient_list, html_message=message) + diff --git a/apps/users/views.py b/apps/users/views.py index 136957839..833563eec 100644 --- a/apps/users/views.py +++ b/apps/users/views.py @@ -14,43 +14,15 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView, Proces from django.views.generic.detail import DetailView from django.contrib.messages.views import SuccessMessageMixin from django.conf import settings -from django.contrib.auth import authenticate, login, logout from .models import User, UserGroup from .forms import UserAddForm, UserUpdateForm, UserGroupForm, UserLoginForm -from .utils import AdminUserRequiredMixin, ssh_key_gen +from .utils import AdminUserRequiredMixin, ssh_key_gen, user_add_success_next logger = logging.getLogger('jumpserver.users.views') -# class UserLoginView(FormView): -# template_name = 'users/login.html' -# form_class = UserLoginForm -# success_url = reverse_lazy('users:user-list') -# -# def get(self, request, *args, **kwargs): -# if self.request.user.is_staff: -# return HttpResponseRedirect(reverse('users:user-list')) -# return super(UserLoginView, self).get(request, *args, **kwargs) -# -# def form_valid(self, form): -# username = form.cleaned_data.get('username', '') -# password = form.cleaned_data.get('password', '') -# -# user = authenticate(username=username, password=password) -# if user is not None and user.is_staff: -# login(self.request, user) -# return HttpResponseRedirect(self.success_url) -# -# logger.warning('Login user [%(username)s] password error' % {'username': username}) -# return render(self.request, self.template_name, context={'form': form, 'error': '密码错误'}) -# -# def form_invalid(self, form): -# logger.warning('Login form commit invalid.') -# return super(UserLoginView, self).form_invalid(form) - - class UserListView(AdminUserRequiredMixin, ListView): model = User paginate_by = settings.CONFIG.DISPLAY_PER_PAGE @@ -92,7 +64,9 @@ class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): user = form.save(commit=False) user.created_by = self.request.user.username or 'System' user.save() - form.save_m2m() + + user_add_success_next(user) + return super(UserAddView, self).form_valid(form) def get_success_message(self, cleaned_data): diff --git a/config-example.py b/config-example.py index 874e36f09..f452e7464 100644 --- a/config-example.py +++ b/config-example.py @@ -15,6 +15,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__)) class Config: SECRET_KEY = os.environ.get('SECRET_KEY') or '2vym+ky!997d5kkcc64mnz06y1mmui3lut#(^wd=%s_qj$1%x' DISPLAY_PER_PAGE = 20 + SITE_URL = 'http://m' ALLOWED_HOSTS = ['*'] DEBUG = False LOG_LEVEL = 'DEBUG'