mirror of https://github.com/jumpserver/jumpserver
Add user and send mail
parent
5359da3ce2
commit
5940cec0e6
|
@ -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
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
<div class="sidebar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
{% include '_user_profile.html' %}
|
||||
{% include '_nav.html' %}
|
||||
{% if request.user.is_superuser %}
|
||||
{% include '_nav.html' %}
|
||||
{% else %}
|
||||
{% include '_nav_user.html' %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<li id="index">
|
||||
<a href="">
|
||||
<i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="">
|
||||
<a href="">
|
||||
<i class="fa fa-files-o"></i><span class="nav-label">我的资产</span><span class="label label-info pull-right"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li id="">
|
||||
<a href="#">
|
||||
<i class="fa fa-download"></i> <span class="nav-label">上传下载</span><span class="fa arrow"></span>
|
||||
</a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li class="upload"><a href="">文件上传</a></li>
|
||||
<li class="download"><a href="">文件下载</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li id="">
|
||||
<a href="">
|
||||
<i class="fa fa-gears"></i> <span class="nav-label">用户信息</span><span class="label label-info pull-right"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="special_link">
|
||||
<a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i>
|
||||
<span class="nav-label">访问官网</span>
|
||||
</a>
|
||||
</li>
|
|
@ -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='')
|
||||
|
||||
|
|
|
@ -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<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
|
||||
url(r'^users/add$', views.UserAddView.as_view(), name='user-add'),
|
||||
|
|
|
@ -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:
|
||||
</br>
|
||||
恭喜您,您的账号已经创建成功.
|
||||
</br>
|
||||
<a href="%(rest_password_url)s?token=%(rest_password_token)s">请点击这里设置密码</a>
|
||||
</br>
|
||||
这个链接有效期1小时, 超过时间您可以 <a href="%(forget_password_url)s?email=%(email)s">重新申请</a>
|
||||
|
||||
</br>
|
||||
---
|
||||
|
||||
</br>
|
||||
<a href="%(login_url)s">直接登录</a>
|
||||
|
||||
</br>
|
||||
""" % {
|
||||
'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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Reference in New Issue