Commit f2746844 authored by ibuler's avatar ibuler

Add translation for support i18n

parent ba3f46fb
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
} }
} }
{% if auto_redirect %} {% if auto_redirect %}
window.onload = redirect_page window.onload = redirect_page;
{% endif %} {% endif %}
</script> </script>
</html> </html>
...@@ -215,7 +215,7 @@ LOGGING = { ...@@ -215,7 +215,7 @@ LOGGING = {
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/ # https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'en_US'
TIME_ZONE = 'Asia/Shanghai' TIME_ZONE = 'Asia/Shanghai'
...@@ -225,6 +225,9 @@ USE_L10N = True ...@@ -225,6 +225,9 @@ USE_L10N = True
USE_TZ = True USE_TZ = True
# I18N translation
LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale'),]
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/ # https://docs.djangoproject.com/en/1.10/howto/static-files/
...@@ -246,7 +249,6 @@ BOOTSTRAP_COLUMN_COUNT = 11 ...@@ -246,7 +249,6 @@ BOOTSTRAP_COLUMN_COUNT = 11
# Init data or generate fake data source for development # Init data or generate fake data source for development
FIXTURE_DIRS = [os.path.join(BASE_DIR, 'fixtures'), ] FIXTURE_DIRS = [os.path.join(BASE_DIR, 'fixtures'), ]
# Email config # Email config
EMAIL_HOST = CONFIG.EMAIL_HOST EMAIL_HOST = CONFIG.EMAIL_HOST
EMAIL_PORT = CONFIG.EMAIL_PORT EMAIL_PORT = CONFIG.EMAIL_PORT
......
This diff is collapsed.
{% load i18n %}
<div class="row border-bottom"> <div class="row border-bottom">
<nav class="navbar navbar-static-top white-bg" role="navigation" style="margin-bottom: 0"> <nav class="navbar navbar-static-top white-bg" role="navigation" style="margin-bottom: 0">
<div class="navbar-header"> <div class="navbar-header">
<a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="#"><i class="fa fa-bars"></i> </a> <a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="#"><i class="fa fa-bars"></i> </a>
<form role="search" class="navbar-form-custom" method="get" action=""> <form role="search" class="navbar-form-custom" method="get" action="">
<div class="form-group"> <div class="form-group">
<input type="text" placeholder="输入搜索..." class="form-control" name="search" id="top-search"> <input type="text" placeholder="{% trans 'Search' %}..." class="form-control" name="search" id="top-search">
</div> </div>
</form> </form>
</div> </div>
<ul class="nav navbar-top-links navbar-right"> <ul class="nav navbar-top-links navbar-right">
<li> <li>
<span class="m-r-sm text-muted welcome-message">欢迎使用Jumpserver开源跳板机系统</span> <span class="m-r-sm text-muted welcome-message">{% trans 'Welcome use Jumpserver system' %}</span>
</li> </li>
<li class="dropdown"> <li class="dropdown">
<a class="dropdown-toggle count-info" data-toggle="dropdown" href="#"> <a class="dropdown-toggle count-info" data-toggle="dropdown" href="#">
<span class="m-r-sm text-muted welcome-message">帮助</span> <span class="m-r-sm text-muted welcome-message">{% trans 'Help' %}</span>
</a> </a>
</li> </li>
<li> <li>
...@@ -31,7 +32,7 @@ ...@@ -31,7 +32,7 @@
<h2></h2> <h2></h2>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li> <li>
<a href="">仪表盘</a> <a href="">{% trans 'Home' %}</a>
</li> </li>
<li> <li>
{% if app %} {% if app %}
......
{% load i18n %}
<li id="index"> <li id="index">
<a href=""> <a href="">
<i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span> <i class="fa fa-dashboard"></i> <span class="nav-label">{% trans 'Home' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li id="users"> <li id="users">
<a href="#"> <a href="#">
<i class="fa fa-group"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span> <i class="fa fa-group"></i> <span class="nav-label">{% trans 'Users' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level active"> <ul class="nav nav-second-level active">
<li class="users"><a href="{% url 'users:user-list' %}">用户列表</a></li> <li class="users"><a href="{% url 'users:user-list' %}">{% trans 'User' %}</a></li>
<li class="usergroups"><a href="{% url 'users:usergroup-list' %}">用户组列表</a></li> <li class="usergroups"><a href="{% url 'users:usergroup-list' %}">{% trans 'Usergroup' %}</a></li>
</ul> </ul>
</li> </li>
<li id=""> <li id="">
<a> <a>
<i class="fa fa-inbox"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span> <i class="fa fa-inbox"></i> <span class="nav-label">{% trans 'Assets' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class=""><a href="">资产列表</a></li> <li class=""><a href="">{% trans 'Asset' %}</a></li>
<li class=""><a href="">资产组列表</a></li> <li class=""><a href="">{% trans 'Assetgroup' %}</a></li>
<li class=""><a href="">机房列表</a></li> <li class=""><a href="">{% trans 'IDC' %}</a></li>
<li class=""><a href="">管理用户</a></li> <li class=""><a href="">{% trans 'Opsuser' %}</a></li>
<li class=""><a href="">系统用户</a></li> <li class=""><a href="">{% trans 'Sysuser' %}</a></li>
<li class=""><a href="">标签列表</a></li> <li class=""><a href="">{% trans 'Label' %}</a></li>
</ul> </ul>
</li> </li>
<li id=""> <li id="">
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">授权管理</span><span class="fa arrow"></span></a> <a href="#"><i class="fa fa-edit"></i> <span class="nav-label">{% trans 'Perms' %}</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="sudo"> <li class="sudo">
<a class="sudo" href="">授权列表</a> <a class="sudo" href="">{% trans 'Perm' %}</a>
</li> </li>
<li class="role"> <li class="role">
<a href="">添加授权</a> <a href="">{% trans 'Create perm' %}</a>
</li> </li>
</ul> </ul>
</li> </li>
<li id=""> <li id="">
<a href=""> <a href="">
<i class="fa fa-files-o"></i><span class="nav-label">审计管理</span><span class="label label-info pull-right"></span> <i class="fa fa-files-o"></i><span class="nav-label">{% trans 'Audit' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li id=""> <li id="">
<a href="#"> <a href="#">
<i class="fa fa-download"></i> <span class="nav-label">上传下载</span><span class="fa arrow"></span> <i class="fa fa-download"></i> <span class="nav-label">{% trans 'File' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="upload"><a href="">文件上传</a></li> <li class="upload"><a href="">{% trans 'File upload' %}</a></li>
<li class="download"><a href="">文件下载</a></li> <li class="download"><a href="">{% trans 'File download' %}</a></li>
</ul> </ul>
</li> </li>
<li id=""> <li id="">
<a href=""> <a href="">
<i class="fa fa-gears"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span> <i class="fa fa-gears"></i> <span class="nav-label">{% trans 'Settings' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li class="special_link"> <li class="special_link">
<a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i> <a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i>
<span class="nav-label">访问官网</span> <span class="nav-label">{% trans 'Visit us' %}</span>
</a> </a>
</li> </li>
\ No newline at end of file
...@@ -34,10 +34,10 @@ ...@@ -34,10 +34,10 @@
</div> </div>
{% endif %} {% endif %}
<script> <script>
function sleep(n) { //n表示的毫秒数 {# function sleep(n) { //n表示的毫秒数#}
var start = new Date().getTime(); {# var start = new Date().getTime();#}
while (true) if (new Date().getTime() - start > n) break; {# while (true) if (new Date().getTime() - start > n) break;#}
} {# }#}
$(document).ready(function () { $(document).ready(function () {
$('.page').click(function () { $('.page').click(function () {
......
{% load static %} {% load static %}
{% load i18n %}
<li class="nav-header"> <li class="nav-header">
<div class="dropdown profile-element"> <div class="dropdown profile-element">
<span> <span>
...@@ -10,15 +11,14 @@ ...@@ -10,15 +11,14 @@
<strong class="font-bold"> {{ request.user.name }}<span style="color: #8095a8"></span></strong> <strong class="font-bold"> {{ request.user.name }}<span style="color: #8095a8"></span></strong>
</span> </span>
<span class="text-muted text-xs block"> <span class="text-muted text-xs block">
{{ request.user.get_role_display | default:'普通用户' }}<b class="caret"></b> {{ request.user.get_role_display | default:"{% trans 'User' %}" }}<b class="caret"></b>
</span> </span>
</span> </span>
</a> </a>
<ul class="dropdown-menu animated fadeInRight m-t-xs"> <ul class="dropdown-menu animated fadeInRight m-t-xs">
<li><a value="">个人信息</a></li> <li><a value="">{% trans 'Profile' %}</a></li>
<li><a href="">修改信息</a></li>
<li class="divider"></li> <li class="divider"></li>
<li><a href="">注销</a></li> <li><a href="">{% trans 'Logout' %}</a></li>
</ul> </ul>
</div> </div>
<div class="logo-element"> <div class="logo-element">
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<title>Jumpserver | 开源跳板机系统</title> <title>Jumpserver</title>
<link rel="shortcut icon" href={% static "img/facio.ico" %} type="image/x-icon"> <link rel="shortcut icon" href={% static "img/facio.ico" %} type="image/x-icon">
{% include '_head_css_js.html' %} {% include '_head_css_js.html' %}
......
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
from django.forms import ModelForm from django.forms import ModelForm
from django import forms from django import forms
from captcha.fields import CaptchaField from captcha.fields import CaptchaField
from django.utils.translation import gettext_lazy as _
from .models import User, UserGroup from .models import User, UserGroup
class UserLoginForm(forms.Form): class UserLoginForm(forms.Form):
username = forms.CharField(label='用户名', max_length=100) username = forms.CharField(label=_('Username'), max_length=100)
password = forms.CharField(label='密码', widget=forms.PasswordInput, max_length=100) password = forms.CharField(label=_('Password'), widget=forms.PasswordInput, max_length=100)
captcha = CaptchaField() captcha = CaptchaField()
...@@ -27,7 +28,7 @@ class UserAddForm(ModelForm): ...@@ -27,7 +28,7 @@ class UserAddForm(ModelForm):
} }
widgets = { widgets = {
'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': '请选择用户组'}), 'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Join usergroups')}),
} }
...@@ -46,7 +47,7 @@ class UserUpdateForm(ModelForm): ...@@ -46,7 +47,7 @@ class UserUpdateForm(ModelForm):
} }
widgets = { widgets = {
'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': '请选择用户组'}), 'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Join usergroups')}),
} }
......
...@@ -12,6 +12,7 @@ from django.contrib.auth.models import AbstractUser, Permission ...@@ -12,6 +12,7 @@ from django.contrib.auth.models import AbstractUser, Permission
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.db import IntegrityError from django.db import IntegrityError
from django.utils.translation import ugettext_lazy as _
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
from django.core import signing from django.core import signing
...@@ -56,8 +57,8 @@ from django.core import signing ...@@ -56,8 +57,8 @@ from django.core import signing
class UserGroup(models.Model): class UserGroup(models.Model):
name = models.CharField(max_length=100, unique=True, verbose_name='组名称') name = models.CharField(max_length=100, unique=True, verbose_name=_('Name'))
comment = models.TextField(blank=True, verbose_name='描述') comment = models.TextField(blank=True, verbose_name=_('Comment'))
date_added = models.DateTimeField(auto_now_add=True) date_added = models.DateTimeField(auto_now_add=True)
created_by = models.CharField(max_length=100) created_by = models.CharField(max_length=100)
...@@ -98,25 +99,26 @@ def date_expired_default(): ...@@ -98,25 +99,26 @@ def date_expired_default():
class User(AbstractUser): class User(AbstractUser):
ROLE_CHOICES = ( ROLE_CHOICES = (
('Admin', '管理员'), ('Admin', _('Administrator')),
('User', '用户'), ('User', _('User')),
) )
username = models.CharField(max_length=20, unique=True, verbose_name='用户名') username = models.CharField(max_length=20, unique=True, verbose_name=_('Username'))
name = models.CharField(max_length=20, blank=True, verbose_name='姓名') name = models.CharField(max_length=20, blank=True, verbose_name=_('Name'))
email = models.EmailField(max_length=30, unique=True, verbose_name='邮件') email = models.EmailField(max_length=30, unique=True, verbose_name=_('Email'))
groups = models.ManyToManyField(UserGroup, related_name='users', blank=True, verbose_name='用户组') groups = models.ManyToManyField(UserGroup, related_name='users', blank=True, verbose_name=_('Usergroup'))
role = models.CharField(choices=ROLE_CHOICES, default='User', max_length=10, blank=True, verbose_name='角色') role = models.CharField(choices=ROLE_CHOICES, default='User', max_length=10, blank=True, verbose_name=_('Role'))
avatar = models.ImageField(upload_to="avatar", verbose_name='头像') avatar = models.ImageField(upload_to="avatar", verbose_name=_('Avatar'))
wechat = models.CharField(max_length=30, blank=True, verbose_name='微信') wechat = models.CharField(max_length=30, blank=True, verbose_name=_('Wechat'))
phone = models.CharField(max_length=20, blank=True, verbose_name='手机号') phone = models.CharField(max_length=20, blank=True, verbose_name=_('Phone'))
enable_otp = models.BooleanField(default=False, verbose_name='启用二次验证') enable_otp = models.BooleanField(default=False, verbose_name=_('Enable OTP'))
secret_key_otp = models.CharField(max_length=16, blank=True) secret_key_otp = models.CharField(max_length=16, blank=True)
private_key = models.CharField(max_length=5000, blank=True, verbose_name='ssh私钥') # ssh key max length 4096 bit 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='公钥') 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 = models.TextField(max_length=200, blank=True, verbose_name=_('Comment'))
is_first_login = models.BooleanField(default=False) is_first_login = models.BooleanField(default=False)
date_expired = models.DateTimeField(default=date_expired_default, blank=True, null=True, verbose_name='有效期') date_expired = models.DateTimeField(default=date_expired_default, blank=True, null=True,
verbose_name=_('Date expired'))
created_by = models.CharField(max_length=30, default='') created_by = models.CharField(max_length=30, default='')
@property @property
...@@ -204,7 +206,7 @@ class User(AbstractUser): ...@@ -204,7 +206,7 @@ class User(AbstractUser):
user_email = data.get('email', '') user_email = data.get('email', '')
user = cls.objects.get(id=user_id, email=user_email) user = cls.objects.get(id=user_id, email=user_email)
except signing.BadSignature, cls.DoesNotExist: except (signing.BadSignature, cls.DoesNotExist):
user = None user = None
return user return user
...@@ -220,11 +222,11 @@ class User(AbstractUser): ...@@ -220,11 +222,11 @@ class User(AbstractUser):
def initial(cls): def initial(cls):
user = cls(username='admin', user = cls(username='admin',
email='admin@jumpserver.org', email='admin@jumpserver.org',
name='Administrator', name=_('Administrator'),
password_raw='admin', password_raw='admin',
role='Admin', role='Admin',
comment='Administrator is the super user of system', comment=_('Administrator is the super user of system'),
created_by='System') created_by=_('System'))
user.save() user.save()
user.groups.add(UserGroup.initial()) user.groups.add(UserGroup.initial())
......
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %}
{% load static %} {% load static %}
{% load bootstrap %} {% load bootstrap %}
{% block custom_head_css_js %} {% block custom_head_css_js %}
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>填写用户信息</h5> <h5>{% trans 'Create user' %}</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
...@@ -29,7 +30,7 @@ ...@@ -29,7 +30,7 @@
<div class="ibox-content"> <div class="ibox-content">
<form method="post" id="userForm" class="form-horizontal" action="" enctype="multipart/form-data"> <form method="post" id="userForm" class="form-horizontal" action="" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<h3>账户</h3> <h3>{% trans 'Account' %}</h3>
{% block username %} {% endblock %} {% block username %} {% endblock %}
{{ form.email|bootstrap_horizontal }} {{ form.email|bootstrap_horizontal }}
{{ form.name|bootstrap_horizontal }} {{ form.name|bootstrap_horizontal }}
...@@ -39,7 +40,7 @@ ...@@ -39,7 +40,7 @@
{% block password %} {% endblock %} {% block password %} {% endblock %}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<h3>角色安全</h3> <h3>{% trans 'Security and Role' %}</h3>
{{ form.role|bootstrap_horizontal }} {{ form.role|bootstrap_horizontal }}
<div class="form-group {% if form.date_expired.errors %} has-error {% endif %}" id="date_5"> <div class="form-group {% if form.date_expired.errors %} has-error {% endif %}" id="date_5">
<label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label> <label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label>
...@@ -52,21 +53,21 @@ ...@@ -52,21 +53,21 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">二次验证</label> <label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label>
<div class="col-sm-8"> <div class="col-sm-8">
{{ form.enable_otp }} {{ form.enable_otp }}
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<h3>信息</h3> <h3>{% trans 'Profile' %}</h3>
{{ form.phone|bootstrap_horizontal }} {{ form.phone|bootstrap_horizontal }}
{{ form.wechat|bootstrap_horizontal }} {{ form.wechat|bootstrap_horizontal }}
{{ form.comment|bootstrap_horizontal }} {{ form.comment|bootstrap_horizontal }}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">取消</button> <button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认保存</button> <button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Commit' %}</button>
</div> </div>
</div> </div>
</form> </form>
......
{% load static %} {% load static %}
{% load i18n %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
...@@ -22,14 +23,14 @@ ...@@ -22,14 +23,14 @@
<div class="ibox-content"> <div class="ibox-content">
<img src="{% static 'img/logo.png' %}" style="margin: auto" width="82" height="82"> <img src="{% static 'img/logo.png' %}" style="margin: auto" width="82" height="82">
<h2 class="font-bold" style="display: inline">忘记密码 ?</h2> <h2 class="font-bold" style="display: inline">{% trans 'Forget password' %} ?</h2>
<h1></h1> <h1></h1>
{% if errors %} {% if errors %}
<p class="red-fonts">{{ errors }}</p> <p class="red-fonts">{{ errors }}</p>
{% endif %} {% endif %}
<p> <p>
输入您的邮箱, 将会发一封重置短信邮件到您的邮箱中 {% trans 'Input your email, that will send a mail to your' %}
</p> </p>
<div class="row"> <div class="row">
...@@ -40,7 +41,7 @@ ...@@ -40,7 +41,7 @@
<input type="email" name="email" class="form-control" placeholder="Email address" required=""> <input type="email" name="email" class="form-control" placeholder="Email address" required="">
</div> </div>
<button type="submit" class="btn btn-primary block full-width m-b">重置密码</button> <button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Commit' %}</button>
</form> </form>
</div> </div>
......
{% load static %} {% load static %}
{% load i18n %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
...@@ -23,23 +24,17 @@ ...@@ -23,23 +24,17 @@
<body class="gray-bg"> <body class="gray-bg">
<div class="loginColumns animated fadeInDown"> <div class="loginColumns animated fadeInDown">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<h2 class="font-bold">欢迎使用Jumpserver开源跳板机</h2> <h2 class="font-bold">欢迎使用Jumpserver开源跳板机</h2>
<p> <p>
Jumpserver是一款使用Python, Django开发的开源跳板机系统, 助力互联网企业高效 用户、资产、权限、审计 管理 Jumpserver是一款使用Python, Django开发的开源跳板机系统, 助力互联网企业高效 用户、资产、权限、审计 管理
</p> </p>
<p> <p>
我们自五湖四海,我们对开源精神无比敬仰和崇拜,我们对完美、整洁、优雅 无止境的追求 我们自五湖四海,我们对开源精神无比敬仰和崇拜,我们对完美、整洁、优雅 无止境的追求
</p> </p>
<p> <p>
专注自动化运维,努力打造 易用、稳定、安全、自动化 的跳板机, 这是我们的不懈的追求和动力 专注自动化运维,努力打造 易用、稳定、安全、自动化 的跳板机, 这是我们的不懈的追求和动力
</p> </p>
<p> <p>
<small>永远年轻,永远热泪盈眶 stay foolish stay hungry</small> <small>永远年轻,永远热泪盈眶 stay foolish stay hungry</small>
</p> </p>
...@@ -47,27 +42,27 @@ ...@@ -47,27 +42,27 @@
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="ibox-content"> <div class="ibox-content">
<div><img src="{% static 'img/logo.png' %}" width="82" height="82"> <span class="font-bold text-center" style="font-size: 32px; font-family: inherit">登录</span></div> <div><img src="{% static 'img/logo.png' %}" width="82" height="82"> <span class="font-bold text-center" style="font-size: 32px; font-family: inherit">{% trans 'Login' %}</span></div>
<form class="m-t" role="form" method="post" action="{% url 'users:login' %}"> <form class="m-t" role="form" method="post" action="{% url 'users:login' %}">
{% csrf_token %} {% csrf_token %}
{% if form.errors %} {% if form.errors %}
{% if 'captcha' in form.errors %} {% if 'captcha' in form.errors %}
<p class="red-fonts">验证码错误</p> <p class="red-fonts">{% trans 'Captcha invalid' %}</p>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if errors %} {% if errors %}
<p class="red-fonts">{{ errors }}</p> <p class="red-fonts">{{ errors }}</p>
{% endif %} {% endif %}
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control" name="{{ form.username.html_name }}" placeholder="Username" required=""> <input type="text" class="form-control" name="{{ form.username.html_name }}" placeholder="{% trans 'Username' %}" required="">
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" name="{{ form.password.html_name }}" placeholder="Password" required=""> <input type="password" class="form-control" name="{{ form.password.html_name }}" placeholder="{% trans 'Password' %}" required="">
</div> </div>
<div> <div>
{{ form.captcha }} {{ form.captcha }}
</div> </div>
<button type="submit" class="btn btn-primary block full-width m-b">Login</button> <button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Login' %}</button>
<a href="{% url 'users:forget-password' %}"> <a href="{% url 'users:forget-password' %}">
<small>Forgot password?</small> <small>Forgot password?</small>
......
{% load static %} {% load static %}
{% load i18n %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
...@@ -41,31 +42,28 @@ ...@@ -41,31 +42,28 @@
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="ibox-content"> <div class="ibox-content">
<div><img src="{% static 'img/logo.png' %}" width="82" height="82"> <span class="font-bold text-center" style="font-size: 32px; font-family: inherit">重设密码</span></div> <div><img src="{% static 'img/logo.png' %}" width="82" height="82"> <span class="font-bold text-center" style="font-size: 32px; font-family: inherit">{% trans 'Reset password' %}</span></div>
<form class="m-t" role="form" method="post" action=""> <form class="m-t" role="form" method="post" action="">
{% csrf_token %} {% csrf_token %}
{% if errors %} {% if errors %}
<p class="red-fonts">{{ errors }}</p> <p class="red-fonts">{{ errors }}</p>
{% endif %} {% endif %}
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" name="password" placeholder="Password" required=""> <input type="password" class="form-control" name="password" placeholder="{% trans 'Password' %}" required="">
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" name="password-confirm" placeholder="Password again" required=""> <input type="password" class="form-control" name="password-confirm" placeholder="{% trans 'Password again' %}" required="">
</div> </div>
<button type="submit" class="btn btn-primary block full-width m-b">Setting</button> <button type="submit" class="btn btn-primary block full-width m-b">{% trans "Setting" %}</button>
<a href="#"> <a href="#">
<small>Forgot password?</small> <small>Forgot password?</small>
</a> </a>
<p class="text-muted text-center"> <p class="text-muted text-center">
{# <small>Do not have an account?</small>#}
</p> </p>
{# <a class="btn btn-sm btn-white btn-block" href="register.html">Create an account</a>#}
</form> </form>
<p class="m-t"> <p class="m-t">
{# <small>Inspinia we app framework base on Bootstrap 3 &copy; 2014</small>#}
</p> </p>
</div> </div>
</div> </div>
......
{% extends 'users/_user.html' %} {% extends 'users/_user.html' %}
{% load i18n %}
{% load bootstrap %} {% load bootstrap %}
{% block username %} {% block username %}
{{ form.username|bootstrap_horizontal }} {{ form.username|bootstrap_horizontal }}
{% endblock %} {% endblock %}
{% block password %} {% block password %}
<h3>密码</h3> <h3>{% trans 'Password' %}</h3>
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">密码</label> <label class="col-sm-2 control-label">{% trans 'Password' %}</label>
<div class="col-sm-8 controls" > <div class="col-sm-8 controls" >
生成重置密码连接,通过邮件发送给用户 {% trans 'Reset link will be generated and sent to the user. ' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
\ No newline at end of file
{% load i18n %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>确认删除</title> <title>{% trans 'Confirm delete' %}</title>
</head> </head>
<body> <body>
<form action="" method="post"> <form action="" method="post">
......
This diff is collapsed.
{% extends 'users/_user.html' %} {% extends 'users/_user.html' %}
{% load i18n %}
{% block username %} {% block username %}
<div class="form-group"> <div class="form-group">
<label for="{{ form.username.id_for_label }}" class="col-sm-2 control-label">用户名</label> <label for="{{ form.username.id_for_label }}" class="col-sm-2 control-label">{% trans 'Username' %}</label>
<div class="col-sm-9 controls" > <div class="col-sm-9 controls" >
<input id="{{ form.username.id_for_label }}" name="{{ form.username.html_name }}" type="text" value="{{ user.username }}" readonly class="form-control"> <input id="{{ form.username.id_for_label }}" name="{{ form.username.html_name }}" type="text" value="{{ user.username }}" readonly class="form-control">
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block password %} {% block password %}
<h3>密码</h3> <h3>{% trans 'Password' %}</h3>
<div class="form-group"> <div class="form-group">
<label for="password" class="col-sm-2 control-label">密码</label> <label for="password" class="col-sm-2 control-label">{% trans 'Password' %}</label>
<div class="col-sm-9 controls" > <div class="col-sm-9 controls" >
<input id="password" name="password" type="password" class="form-control"> <input id="password" name="password" type="password" class="form-control">
</div> </div>
......
{% extends '_list_base.html' %}
{% load common_tags %}
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5> 查看用户 </h5>
<div class="ibox-tools">
<a class="collapise-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="">
<a href="{% url 'users:user-add' %}" class="btn btn-sm btn-primary "> 添加用户 </a>
<a id="del_btn" class="btn btn-sm btn-danger "> 删除所选 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="用户名或姓名" value="{{ keyword }}">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
搜索
</button>
</div>
</div>
</form>
</div>
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
</th>
<th class="text-center"><a href="{% url 'users:user-list' %}?sort=name">姓名</a></th>
<th class="text-center"><a href="{% url 'users:user-list' %}?sort=username">用户名</a></th>
<th class="text-center">角色</th>
<th class="text-center">用户组</th>
<th class="text-center">资产数量</th>
<th class="text-center"><a href="{% url 'users:user-list' %}?sort=date_expired">有效</a></th>
<th class="text-center"></th>
</tr>
</thead>
<tbody>
{% for user in user_list %}
<tr class="gradeX">
<td class="text-center">
<input type="checkbox" name="checked" value="{{ user.id }}">
</td>
<td class="text-center">
<a href="{% url 'users:user-detail' pk=user.id %}">
{{ user.name }}
</a>
</td>
<td class="text-center">{{ user.username }}</td>
<td class="text-center">{{ user.role.name }}</td>
<td class="text-center" title="{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"> {{ user.groups.all|join_queryset_attr:"name" }} </td>
<th class="text-center">{{ user.name }}</th>
<td class="text-center">
{% if user.is_expired %}
<i class="fa fa-times text-danger"></i>
{% else %}
<i class="fa fa-check text-navy"></i>
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'users:user-edit' pk=user.id %}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'users:user-delete' pk=user.id %}" class="btn btn-xs btn-danger del {% if user.username == 'admin' %} disabled {% endif %}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
</div>
{% include '_pagination.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% extends '_list_base.html' %} {% extends '_list_base.html' %}
{% load i18n %}
{% load common_tags %} {% load common_tags %}
{% block content_left_head %} {% block content_left_head %}
<a href="{% url 'users:user-add' %}" class="btn btn-sm btn-primary "> 添加用户 </a> <a href="{% url 'users:user-add' %}" class="btn btn-sm btn-primary "> {% trans "Create user" %} </a>
{# <a id="del_btn" class="btn btn-sm btn-danger "> 删除所选 </a>#}
{% endblock %} {% endblock %}
{% block table_head %} {% block table_head %}
<th class="text-center"> <th class="text-center">
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')"> <input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
</th> </th>
<th class="text-center"><a href="{% url 'users:user-list' %}?sort=name">姓名</a></th> <th class="text-center"><a href="{% url 'users:user-list' %}?sort=name">{% trans 'Name' %}</a></th>
<th class="text-center"><a href="{% url 'users:user-list' %}?sort=username">用户名</a></th> <th class="text-center"><a href="{% url 'users:user-list' %}?sort=username">{% trans 'Username' %}</a></th>
<th class="text-center">角色</th> <th class="text-center">{% trans 'Role' %}</th>
<th class="text-center">用户组</th> <th class="text-center">{% trans 'Usergroup' %}</th>
<th class="text-center">资产数量</th> <th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center"><a href="{% url 'users:user-list' %}?sort=date_expired">有效</a></th> <th class="text-center"><a href="{% url 'users:user-list' %}?sort=date_expired">{% trans 'Active' %}</a></th>
<th class="text-center"></th> <th class="text-center"></th>
{% endblock %} {% endblock %}
...@@ -41,8 +41,8 @@ ...@@ -41,8 +41,8 @@
{% endif %} {% endif %}
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'users:user-edit' pk=user.id %}" class="btn btn-xs btn-info">编辑</a> <a href="{% url 'users:user-edit' pk=user.id %}" class="btn btn-xs btn-info">{% trans 'Edit' %}</a>
<a href="{% url 'users:user-delete' pk=user.id %}" class="btn btn-xs btn-danger del {% if user.id == request.user.id or user.username == 'admin' %} disabled {% endif %}">删除</a> <a href="{% url 'users:user-delete' pk=user.id %}" class="btn btn-xs btn-danger del {% if user.id == request.user.id or user.username == 'admin' %} disabled {% endif %}">{% trans 'Delete' %}</a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
...@@ -52,15 +52,15 @@ ...@@ -52,15 +52,15 @@
<form id="" method="get" action="" class=" mail-search"> <form id="" method="get" action="" class=" mail-search">
<div class="input-group"> <div class="input-group">
<select class="form-control m-b" style="width: auto"> <select class="form-control m-b" style="width: auto">
<option>批量删除</option> <option>{% trans 'Delete selected' %}</option>
<option>批量更新</option> <option>{% trans 'Update selected' %}</option>
<option>批量禁用</option> <option>{% trans 'Deactive selected' %}</option>
<option>批量导出</option> <option>{% trans 'Export selected' %}</option>
</select> </select>
<div class="input-group-btn pull-left" style="padding-left: 5px;"> <div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary"> <button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">
确认 {% trans 'Commit' %}
</button> </button>
</div> </div>
......
...@@ -8,6 +8,7 @@ import logging ...@@ -8,6 +8,7 @@ import logging
from paramiko.rsakey import RSAKey from paramiko.rsakey import RSAKey
from django.contrib.auth.mixins import UserPassesTestMixin from django.contrib.auth.mixins import UserPassesTestMixin
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import ugettext as _
from common.tasks import send_mail_async from common.tasks import send_mail_async
from common.utils import reverse from common.utils import reverse
...@@ -43,7 +44,7 @@ def ssh_key_gen(length=2048, password=None, username='root', hostname=None): ...@@ -43,7 +44,7 @@ def ssh_key_gen(length=2048, password=None, username='root', hostname=None):
f = StringIO.StringIO() f = StringIO.StringIO()
try: try:
logger.debug('Begin to generate ssh private key ...') logger.debug(_('Begin to generate ssh private key ...'))
private_key_obj = RSAKey.generate(length) private_key_obj = RSAKey.generate(length)
private_key_obj.write_private_key(f, password=password) private_key_obj.write_private_key(f, password=password)
private_key = f.getvalue() private_key = f.getvalue()
...@@ -55,33 +56,33 @@ def ssh_key_gen(length=2048, password=None, username='root', hostname=None): ...@@ -55,33 +56,33 @@ def ssh_key_gen(length=2048, password=None, username='root', hostname=None):
'hostname': hostname, 'hostname': hostname,
} }
logger.debug('Finish to generate ssh private key ...') logger.debug(_('Finish to generate ssh private key ...'))
return private_key, public_key return private_key, public_key
except IOError: except IOError:
raise IOError('These is error when generate ssh key.') raise IOError(_('These is error when generate ssh key.'))
def user_add_success_next(user): def user_add_success_next(user):
subject = '您的用户创建成功' subject = _('Create account successfully')
recipient_list = [user.email] recipient_list = [user.email]
message = """ message = _("""
您好 %(name)s: Hello %(name)s:
</br> </br>
恭喜您,您的账号已经创建成功. Your account has been created successfully
</br> </br>
<a href="%(rest_password_url)s?token=%(rest_password_token)s">请点击这里设置密码</a> <a href="%(rest_password_url)s?token=%(rest_password_token)s">click here to set your password</a>
</br> </br>
这个链接有效期1小时, 超过时间您可以 <a href="%(forget_password_url)s?email=%(email)s">重新申请</a> This link is valid for 1 hour. After it expires, <a href="%(forget_password_url)s?email=%(email)s">request new one</a>
</br> </br>
--- ---
</br> </br>
<a href="%(login_url)s">直接登录</a> <a href="%(login_url)s">Login direct</a>
</br> </br>
""" % { """) % {
'name': user.name, 'name': user.name,
'rest_password_url': reverse('users:reset-password', external=True), 'rest_password_url': reverse('users:reset-password', external=True),
'rest_password_token': user.generate_reset_token(), 'rest_password_token': user.generate_reset_token(),
...@@ -94,25 +95,25 @@ def user_add_success_next(user): ...@@ -94,25 +95,25 @@ def user_add_success_next(user):
def send_reset_password_mail(user): def send_reset_password_mail(user):
subject = '重设密码' subject = _('Reset password')
recipient_list = [user.email] recipient_list = [user.email]
message = """ message = _("""
您好 %(name)s: Hello %(name)s:
</br> </br>
您好,请点击下面链接重置密码, 如果不是您申请的, 请关注账号安全 Please click the link below to reset your password, if not your request, concern your account security
</br> </br>
<a href="%(rest_password_url)s?token=%(rest_password_token)s">请点击这里设置密码</a> <a href="%(rest_password_url)s?token=%(rest_password_token)s">Click here reset password</a>
</br> </br>
这个链接有效期1小时, 超过时间您可以 <a href="%(forget_password_url)s?email=%(email)s">重新申请</a> This link is valid for 1 hour. After it expires, <a href="%(forget_password_url)s?email=%(email)s">request new one<</a>
</br> </br>
--- ---
</br> </br>
<a href="%(login_url)s">直接登录</a> <a href="%(login_url)s">Login direct</a>
</br> </br>
""" % { """) % {
'name': user.name, 'name': user.name,
'rest_password_url': reverse('users:reset-password', external=True), 'rest_password_url': reverse('users:reset-password', external=True),
'rest_password_token': user.generate_reset_token(), 'rest_password_token': user.generate_reset_token(),
......
...@@ -5,7 +5,6 @@ from __future__ import unicode_literals ...@@ -5,7 +5,6 @@ from __future__ import unicode_literals
import logging import logging
from django.shortcuts import get_object_or_404, reverse, render, Http404, redirect from django.shortcuts import get_object_or_404, reverse, render, Http404, redirect
from django.http import HttpResponseRedirect
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.db.models import Q from django.db.models import Q
...@@ -68,8 +67,8 @@ class UserLogoutView(TemplateView): ...@@ -68,8 +67,8 @@ class UserLogoutView(TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'title': '退出登录成功', 'title': _('Logout success'),
'messages': '退出登录成功, 返回登录页面', 'messages': _('Logout success, return login page'),
'redirect_url': reverse('users:login'), 'redirect_url': reverse('users:login'),
'auto_redirect': True, 'auto_redirect': True,
} }
...@@ -98,7 +97,7 @@ class UserListView(AdminUserRequiredMixin, ListView): ...@@ -98,7 +97,7 @@ class UserListView(AdminUserRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserListView, self).get_context_data(**kwargs) context = super(UserListView, self).get_context_data(**kwargs)
context.update({'app': '用户管理', 'action': '用户列表', 'keyword': self.keyword}) context.update({'app': _('Users'), 'action': _('User list'), 'keyword': self.keyword})
return context return context
...@@ -107,11 +106,11 @@ class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): ...@@ -107,11 +106,11 @@ class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
form_class = UserAddForm form_class = UserAddForm
template_name = 'users/user_add.html' template_name = 'users/user_add.html'
success_url = reverse_lazy('users:user-list') success_url = reverse_lazy('users:user-list')
success_message = '添加用户 <a href="%s">%s</a> 成功 .' success_message = _('Create user<a href="%s">%s</a> success.')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserAddView, self).get_context_data(**kwargs) context = super(UserAddView, self).get_context_data(**kwargs)
context.update({'app': '用户管理', 'action': '用户添加'}) context.update({'app': _('Users'), 'action': _('Create user')})
return context return context
def form_valid(self, form): def form_valid(self, form):
...@@ -153,7 +152,7 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView): ...@@ -153,7 +152,7 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserUpdateView, self).get_context_data(**kwargs) context = super(UserUpdateView, self).get_context_data(**kwargs)
context.update({'app': '用户管理', 'action': '用户编辑'}) context.update({'app': _('Users'), 'action': _('Edit user')})
return context return context
...@@ -171,7 +170,7 @@ class UserDetailView(AdminUserRequiredMixin, DetailView): ...@@ -171,7 +170,7 @@ class UserDetailView(AdminUserRequiredMixin, DetailView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserDetailView, self).get_context_data(**kwargs) context = super(UserDetailView, self).get_context_data(**kwargs)
groups = [group for group in UserGroup.objects.iterator() if group not in self.object.groups.iterator()] groups = [group for group in UserGroup.objects.iterator() if group not in self.object.groups.iterator()]
context.update({'app': '用户管理', 'action': '用户详情', 'groups': groups}) context.update({'app': _('Users'), 'action': _('User detail'), 'groups': groups})
return context return context
...@@ -195,7 +194,7 @@ class UserGroupListView(AdminUserRequiredMixin, ListView): ...@@ -195,7 +194,7 @@ class UserGroupListView(AdminUserRequiredMixin, ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserGroupListView, self).get_context_data(**kwargs) context = super(UserGroupListView, self).get_context_data(**kwargs)
context.update({'app': '用户管理', 'action': '用户组列表', 'keyword': self.keyword}) context.update({'app': _('Users'), 'action': _('Usergroup list'), 'keyword': self.keyword})
return context return context
...@@ -208,7 +207,7 @@ class UserGroupAddView(AdminUserRequiredMixin, CreateView): ...@@ -208,7 +207,7 @@ class UserGroupAddView(AdminUserRequiredMixin, CreateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserGroupAddView, self).get_context_data(**kwargs) context = super(UserGroupAddView, self).get_context_data(**kwargs)
users = User.objects.all() users = User.objects.all()
context.update({'app': '用户管理', 'action': '用户组添加', 'users': users}) context.update({'app': _('Users'), 'action': _('Create usergroup'), 'users': users})
return context return context
def form_valid(self, form): def form_valid(self, form):
...@@ -240,7 +239,7 @@ class UserForgetPasswordView(TemplateView): ...@@ -240,7 +239,7 @@ class UserForgetPasswordView(TemplateView):
email = request.POST.get('email') email = request.POST.get('email')
user = get_object_or_none(User, email=email) user = get_object_or_none(User, email=email)
if not user: if not user:
return self.get(request, errors='邮件地址错误,请重新输入') return self.get(request, errors=_('Email address invalid, input again'))
else: else:
send_reset_password_mail(user) send_reset_password_mail(user)
return HttpResponseRedirect(reverse('users:forget-password-sendmail-success')) return HttpResponseRedirect(reverse('users:forget-password-sendmail-success'))
...@@ -251,8 +250,8 @@ class UserForgetPasswordSendmailSuccessView(TemplateView): ...@@ -251,8 +250,8 @@ class UserForgetPasswordSendmailSuccessView(TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'title': '发送重置邮件', 'title': _('Send reset password message'),
'messages': '发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)', 'messages': _('Send reset password mail success, login your mail box and follow it '),
'redirect_url': reverse('users:login'), 'redirect_url': reverse('users:login'),
} }
kwargs.update(context) kwargs.update(context)
...@@ -264,8 +263,8 @@ class UserResetPasswordSuccessView(TemplateView): ...@@ -264,8 +263,8 @@ class UserResetPasswordSuccessView(TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'title': '重设密码成功', 'title': _('Reset password success'),
'messages': '密码重置成功, 返回登录页面 ', 'messages': _('Reset password success, return to login page'),
'redirect_url': reverse('users:login'), 'redirect_url': reverse('users:login'),
'auto_redirect': True, 'auto_redirect': True,
} }
...@@ -281,7 +280,7 @@ class UserResetPasswordView(TemplateView): ...@@ -281,7 +280,7 @@ class UserResetPasswordView(TemplateView):
user = User.validate_reset_token(token) user = User.validate_reset_token(token)
if not user: if not user:
kwargs.update({'errors': 'Token不正确或已过期'}) kwargs.update({'errors': _('Token invalid or expired')})
return super(UserResetPasswordView, self).get(request, *args, **kwargs) return super(UserResetPasswordView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
...@@ -290,11 +289,11 @@ class UserResetPasswordView(TemplateView): ...@@ -290,11 +289,11 @@ class UserResetPasswordView(TemplateView):
token = request.GET.get('token') token = request.GET.get('token')
if password != password_confirm: if password != password_confirm:
return self.get(request, errors='两次密码不一致') return self.get(request, errors=_('Password not same'))
user = User.validate_reset_token(token) user = User.validate_reset_token(token)
if not user: if not user:
return self.get(request, errors='Token不正确或已过期') return self.get(request, errors=_('Token invalid or expired'))
user.reset_password(password) user.reset_password(password)
return HttpResponseRedirect(reverse('users:reset-password-success')) return HttpResponseRedirect(reverse('users:reset-password-success'))
...@@ -23,6 +23,7 @@ class Config: ...@@ -23,6 +23,7 @@ class Config:
# It's used to identify your site, When we send a create mail to user, we only know login url is /login/ # It's used to identify your site, When we send a create mail to user, we only know login url is /login/
# But we should know the absolute url like: http://jms.jumpserver.org/login/, so SITE_URL is # But we should know the absolute url like: http://jms.jumpserver.org/login/, so SITE_URL is
# HTTP_PROTOCOL://HOST[:PORT] # HTTP_PROTOCOL://HOST[:PORT]
# Todo: May be use :method: get_current_site more grace, bug restful api unknown ok or not
SITE_URL = 'http://localhost' SITE_URL = 'http://localhost'
# Django security setting, if your disable debug model, you should setting that # Django security setting, if your disable debug model, you should setting that
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment