Compare commits

...

61 Commits
2.0.0 ... v2.0

Author SHA1 Message Date
Bai
79fe39792d fix(common) 修复管理员未设置Email主题前缀导致发送邮件失败的问题 2020-09-02 10:23:18 +08:00
ibuler
514fee1c16 perf(config): 修改默认登录日志保存时间 2020-08-18 05:23:37 -05:00
xinwen
8cbc98f338 fix(csv): 修复JMSCSVParser调用serializer导致循环调用问题 2020-08-13 13:45:01 +08:00
老广
ffea2aef02 Revert "fix(cmd_filter): 命令过滤器唯一应该为 name + org_id (#4326)"
This reverts commit 550107c456.
2020-08-13 13:43:41 +08:00
ibuler
85f997b06f fix(auth): 修复radius decode error的问题 2020-08-03 10:32:26 +08:00
ibuler
1f215988f9 ci: 修改docker构建的问题 2020-07-29 19:50:16 +08:00
ibuler
12973fd5a1 ci(dockerfile): 修改dockerfile构建 2020-07-28 19:29:38 +08:00
Bai
82ee34f746 fix(perms): 修复perms api UserPermissionMixin 中 kwargs 参数传递(未发现引出其他问题) 2020-07-23 11:05:32 +08:00
github-actions
8f2fe13407 fix(cas): 修复cas校验不同的问题 2020-07-22 17:23:27 +08:00
ibuler
c01f94f22b fix(es): 修复es7数据结构引起的命令无法查询的问题
- 更新了 jms-storage版本依赖
2020-07-22 17:15:26 +08:00
github-actions
9ac7759a88 ci(github): 添加通用action 2020-07-21 14:31:35 +08:00
Bai
cfe321163e fix(authentication): 修复用户认证Radius认证中参数传递错误问题 *kwargs -> **kwargs 2020-07-21 10:30:53 +08:00
BaiJiangJie
f89df33601 fix(radius): 修复radius认证失败问题 (#4340)
* fix(radius): 修复radius认证失败问题,添加get_django_user方法参数(django-radius==1.4.0 中添加了额外参数)

* fix(radius): 修复radius认证失败问题,重写authenticate方法(django-radius 不接受public_key参数)
2020-07-16 17:08:06 +08:00
xinwen
550107c456 fix(cmd_filter): 命令过滤器唯一应该为 name + org_id (#4326) 2020-07-15 20:03:16 +08:00
xinwen
46ee7c4e04 fix(audits): 操作日志中的动作搜索条件,删除文件字段改成删除 (#4333) 2020-07-15 20:02:13 +08:00
Bai
148a7aa9ee fix(command): 修复命令记录没有根据sesion进行过滤的问题 2020-07-15 17:29:59 +08:00
Bai
dcf9de420e fix(gather_asset_users): 修复收集资产用户日志中用户名显示不完整的问题 2020-07-15 16:23:02 +08:00
xinwen
e94c5daca7 fix(terminal): 移除CommandQueryMixin.get_filter_fields 2020-07-14 19:35:39 +08:00
xinwen
e24abdffba fix(audits): 日志审计模块 Serializer 添加 org_id 字段 2020-07-14 18:05:45 +08:00
Bai
9541a99273 fix(assets): 修复用户name字段长度与资产created_by字段长度不一致导致创建资产失败的问题 2020-07-13 11:32:33 +08:00
ibuler
f0b2d2cdf7 ci(fix): 修改构建脚本 2020-07-09 17:19:21 +08:00
ibuler
ed932f6198 ci(build): 修改构建逻辑 2020-07-09 17:19:21 +08:00
ibuler
7c08582e7d Merge branch 'master' into v2.0 2020-07-08 16:14:19 +08:00
ibuler
3555fe1c20 Merge branch 'v2.0' of github.com:jumpserver/jumpserver into v2.0 2020-07-08 16:14:06 +08:00
ibuler
4a1045ba81 ci(build&release): 自动化构建发布 2020-07-08 15:58:57 +08:00
ibuler
7fc3218010 添加example api 2020-07-08 15:58:57 +08:00
ibuler
0dd4c8adc2 Merge branch 'v2.0' of github.com:jumpserver/jumpserver into v2.0 2020-07-08 15:48:05 +08:00
ibuler
ce7edc1612 ci(release): 修改 release 使用的tag,而不是自动生成的 2020-07-08 10:36:43 +08:00
ibuler
23ef185b7e fix(build): 修改调用action jumpserver/action-build-upload-asset的参数 2020-07-07 14:30:34 +08:00
ibuler
6b16aa6bc0 ci(build): 修改 构建脚本
- sed 在不同系统下表现不同
2020-07-07 13:52:50 +08:00
ibuler
43741dc9b2 ci(build): 修改 workflow
- 修改使用action jumpserver/action-build-upload-assets
2020-07-07 13:38:26 +08:00
ibuler
18174e2867 fix(build): 修稿构建 2020-07-07 13:28:59 +08:00
ibuler
3077d11483 ci(release&build): 添加 github workflows, 自动构建 release
- 添加 utils/build.sh 脚本,构建后放到 release 目录中
- 当 push tags时,自动创建 Release Draft
- 自动生成 Release Change Log
- 自动构建包,上传到 Release Assets
2020-07-07 13:03:48 +08:00
xinwen
a9626c2b39 Merge pull request #4223 from jumpserver/update-add-filter
[Update] assets/gathered_user 添加过滤字段
2020-07-01 17:32:58 +08:00
xinwen
b265fad50f [Update] assets/gathered_user 添加过滤字段 2020-07-01 17:21:00 +08:00
BaiJiangJie
f40b50dddd Merge pull request #4209 from jumpserver/ftp_log_order
fix:修改 ftp 日志按开始日期排序
2020-07-01 15:02:44 +08:00
xinwen
0d6255b07f Merge pull request #4218 from jumpserver/system-user-add-filter
System user add filter
2020-07-01 15:01:07 +08:00
xinwen
06b02cfcfd [Update] 系统用户添加过滤字段 2020-07-01 14:57:52 +08:00
jym503558564
a7e1ed6f03 fix:修改 ftp 日志按开始日期排序 2020-07-01 11:04:42 +08:00
xinwen
1c6f89519a Merge pull request #4201 from jumpserver/fix-i18n
Fix i18n
2020-06-30 14:21:44 +08:00
xinwen
24d093747f [Fix] X-Pack/云管中心 i18n 2020-06-30 14:18:21 +08:00
老广
8c4e9720d3 Merge pull request #4183 from jumpserver/fix_template
docs(github): 修改 github issue 模板
2020-06-28 15:22:41 +08:00
ibuler
d43709f584 docs(github): 修改 github issue 模板
更改版本号说明,1.4及之前不再提供支持
2020-06-28 15:17:15 +08:00
BaiJiangJie
89496baae5 Merge pull request #4148 from jumpserver/v2.0
V2.0
2020-06-28 10:47:56 +08:00
BaiJiangJie
ea6d995f55 Merge pull request #4147 from jumpserver/v2.0_bugfix_csv
[Update] 修改csv导出,最大限制条目数从100->10000条
2020-06-28 10:46:31 +08:00
Bai
cf6aba1f38 [Update] 修改csv导出,最大限制条目数从100->10000条 2020-06-28 10:43:47 +08:00
老广
2acc1dc875 Merge pull request #4134 from jumpserver/fix-mfa-1.5
Fix mfa 1.5
2020-06-22 19:05:15 +08:00
xinwen
32ed43ba7b Merge branch 'v2.0' into fix-mfa-1.5 2020-06-22 19:04:42 +08:00
xinwen
3e993fd044 [Update] 调整MFA绑定策略 V2 2020-06-22 19:02:14 +08:00
xinwen
005573b53b [Fix] 重新绑定 MFA 的漏洞 2020-06-22 18:03:45 +08:00
老广
e04e31eb30 Merge pull request #4129 from jumpserver/readme
feat: readme 添加docker pull
2020-06-22 12:08:28 +08:00
ibuler
ff747f9e42 feat: readme 添加docker pull 2020-06-22 12:06:42 +08:00
BaiJiangJie
c4bd093fd7 Merge pull request #4126 from jumpserver/v2.0
V2.0
2020-06-20 19:26:12 +08:00
BaiJiangJie
408b2d6dbd Merge pull request #4125 from jumpserver/v2.0_bugfix
v2.0 添加改密计划安全模式配置项
2020-06-20 19:24:17 +08:00
BaiJiangJie
ebc63b9410 Merge pull request #4123 from jumpserver/v1.5_bugfix
[Update] 添加改密计划安全模式配置项
2020-06-20 16:20:53 +08:00
Michael Bai
f1e5c7c2bb 添加改密计划安全模式配置项 2020-06-20 16:18:58 +08:00
Michael Bai
fcb0aefe3c 更改改密计划安全模式配置项名 2020-06-20 15:47:39 +08:00
Bai
29666cc8d3 [Update] 添加改密计划安全模式配置项 2020-06-19 20:41:51 +08:00
xinwen
1d640eccf6 [Fix] /opt/jumpserver/apps/jumpserver/views/index.py redirect(assets:user-asset-list) (#4121) 2020-06-19 18:28:43 +08:00
ibuler
7548bb8976 Merge branch 'dev' of github.com:jumpserver/jumpserver into dev 2020-06-17 11:33:57 +08:00
ibuler
8ffa5e0aec 添加example api 2020-06-16 20:11:50 +08:00
36 changed files with 502 additions and 219 deletions

View File

@@ -2,7 +2,7 @@
##### 使用版本 ##### 使用版本
[请提供你使用的Jumpserver版本 1.x.x 注: 0.3.x不再提供支持] [请提供你使用的JumpServer版本 如 2.0.1 注: 1.4及以下版本不再提供支持]
##### 问题复现步骤 ##### 问题复现步骤
1. [步骤1] 1. [步骤1]

44
.github/release-config.yml vendored Normal file
View File

@@ -0,0 +1,44 @@
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
categories:
- title: '🌱 新功能 Features'
labels:
- 'feature'
- 'enhancement'
- 'feat'
- '新功能'
- title: '🚀 性能优化 Optimization'
labels:
- 'perf'
- 'opt'
- 'refactor'
- 'Optimization'
- '优化'
- title: '🐛 Bug修复 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 其它 Maintenance'
labels:
- 'chore'
- 'docs'
exclude-labels:
- 'no'
- '无需处理'
- 'wontfix'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
version-resolver:
major:
labels:
- 'major'
minor:
labels:
- 'minor'
patch:
labels:
- 'patch'
default: patch
template: |
## 版本变化 Whats Changed
$CHANGES

View File

@@ -0,0 +1,12 @@
on: [push, pull_request, release]
name: JumpServer repos generic handler
jobs:
generic_handler:
name: Run generic handler
runs-on: ubuntu-latest
steps:
- uses: jumpserver/action-generic-handler@master
env:
GITHUB_TOKEN: ${{ secrets.PRIVATE_TOKEN }}

46
.github/workflows/release-drafter.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
name: Create Release And Upload assets
jobs:
create-realese:
name: Create Release
runs-on: ubuntu-latest
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Get version
id: get_version
run: |
TAG=$(basename ${GITHUB_REF})
VERSION=${TAG/v/}
echo "::set-output name=TAG::$TAG"
echo "::set-output name=VERSION::$VERSION"
- name: Create Release
id: create_release
uses: release-drafter/release-drafter@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
config-name: release-config.yml
version: ${{ steps.get_version.outputs.TAG }}
tag: ${{ steps.get_version.outputs.TAG }}
build-and-release:
needs: create-realese
name: Build and Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build it and upload
uses: jumpserver/action-build-upload-assets@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-realese.outputs.upload_url }}

2
.gitignore vendored
View File

@@ -36,3 +36,5 @@ xpack
logs/* logs/*
### Vagrant ### ### Vagrant ###
.vagrant/ .vagrant/
release/*
releashe

View File

@@ -1,19 +1,33 @@
FROM registry.fit2cloud.com/public/python:v3 FROM registry.fit2cloud.com/public/python:v3 as stage-build
MAINTAINER Jumpserver Team <ibuler@qq.com> MAINTAINER Jumpserver Team <ibuler@qq.com>
ARG VERSION
ENV VERSION=$VERSION
WORKDIR /opt/jumpserver WORKDIR /opt/jumpserver
ADD . .
RUN cd utils && bash -ixeu build.sh
FROM registry.fit2cloud.com/public/python:v3
ARG PIP_MIRROR=https://pypi.douban.com/simple
ENV PIP_MIRROR=$PIP_MIRROR
ARG MYSQL_MIRROR=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql57-community-el6/
ENV MYSQL_MIRROR=$MYSQL_MIRROR
WORKDIR /opt/jumpserver
COPY ./requirements ./requirements
RUN useradd jumpserver RUN useradd jumpserver
COPY ./requirements /tmp/requirements
RUN yum -y install epel-release && \ RUN yum -y install epel-release && \
echo -e "[mysql]\nname=mysql\nbaseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql57-community-el6/\ngpgcheck=0\nenabled=1" > /etc/yum.repos.d/mysql.repo echo -e "[mysql]\nname=mysql\nbaseurl=${MYSQL_MIRROR}\ngpgcheck=0\nenabled=1" > /etc/yum.repos.d/mysql.repo
RUN cd /tmp/requirements && yum -y install $(cat rpm_requirements.txt) RUN yum -y install $(cat requirements/rpm_requirements.txt)
RUN cd /tmp/requirements && pip install --upgrade pip setuptools && pip install wheel && \ RUN pip install --upgrade pip setuptools wheel -i ${PIP_MIRROR} && \
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt || pip install -r requirements.txt pip config set global.index-url ${PIP_MIRROR}
RUN pip install -r requirements/requirements.txt || pip install -r requirements/requirements.txt
COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver
RUN mkdir -p /root/.ssh/ && echo -e "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null" > /root/.ssh/config RUN mkdir -p /root/.ssh/ && echo -e "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null" > /root/.ssh/config
COPY . /opt/jumpserver
RUN echo > config.yml RUN echo > config.yml
VOLUME /opt/jumpserver/data VOLUME /opt/jumpserver/data
VOLUME /opt/jumpserver/logs VOLUME /opt/jumpserver/logs

View File

@@ -2,6 +2,7 @@
[![Python3](https://img.shields.io/badge/python-3.6-green.svg?style=plastic)](https://www.python.org/) [![Python3](https://img.shields.io/badge/python-3.6-green.svg?style=plastic)](https://www.python.org/)
[![Django](https://img.shields.io/badge/django-2.2-brightgreen.svg?style=plastic)](https://www.djangoproject.com/) [![Django](https://img.shields.io/badge/django-2.2-brightgreen.svg?style=plastic)](https://www.djangoproject.com/)
[![Docker Pulls](https://img.shields.io/docker/pulls/jumpserver/jms_all.svg)](https://hub.docker.com/u/jumpserver)
JumpServer 是全球首款开源的堡垒机,使用 GNU GPL v2.0 开源协议,是符合 4A 规范的运维安全审计系统。 JumpServer 是全球首款开源的堡垒机,使用 GNU GPL v2.0 开源协议,是符合 4A 规范的运维安全审计系统。

View File

@@ -18,5 +18,5 @@ class GatheredUserViewSet(OrgModelViewSet):
permission_classes = [IsOrgAdmin] permission_classes = [IsOrgAdmin]
extra_filter_backends = [AssetRelatedByNodeFilterBackend] extra_filter_backends = [AssetRelatedByNodeFilterBackend]
filter_fields = ['asset', 'username', 'present', 'asset__ip', 'asset__hostname'] filter_fields = ['asset', 'username', 'present', 'asset__ip', 'asset__hostname', 'asset_id']
search_fields = ['username', 'asset__ip', 'asset__hostname'] search_fields = ['username', 'asset__ip', 'asset__hostname']

View File

@@ -28,7 +28,7 @@ class SystemUserViewSet(OrgBulkModelViewSet):
System user api set, for add,delete,update,list,retrieve resource System user api set, for add,delete,update,list,retrieve resource
""" """
model = SystemUser model = SystemUser
filter_fields = ("name", "username") filter_fields = ("name", "username", "protocol")
search_fields = filter_fields search_fields = filter_fields
serializer_class = serializers.SystemUserSerializer serializer_class = serializers.SystemUserSerializer
serializer_classes = { serializer_classes = {

View File

@@ -0,0 +1,18 @@
# Generated by Django 2.2.10 on 2020-07-11 09:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assets', '0049_systemuser_sftp_root'),
]
operations = [
migrations.AlterField(
model_name='asset',
name='created_by',
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Created by'),
),
]

View File

@@ -221,7 +221,7 @@ class Asset(ProtocolsMixin, NodesRelationMixin, OrgModelMixin):
hostname_raw = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Hostname raw')) hostname_raw = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Hostname raw'))
labels = models.ManyToManyField('assets.Label', blank=True, related_name='assets', verbose_name=_("Labels")) labels = models.ManyToManyField('assets.Label', blank=True, related_name='assets', verbose_name=_("Labels"))
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by')) created_by = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Created by'))
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date created')) date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date created'))
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))

View File

@@ -64,7 +64,7 @@ GATHER_ASSET_USERS_TASKS = [
"action": { "action": {
"module": "shell", "module": "shell",
"args": "users=$(getent passwd | grep -v 'nologin' | " "args": "users=$(getent passwd | grep -v 'nologin' | "
"grep -v 'shudown' | awk -F: '{ print $1 }');for i in $users;do last -F $i -1 | " "grep -v 'shudown' | awk -F: '{ print $1 }');for i in $users;do last -w -F $i -1 | "
"head -1 | grep -v '^$' | awk '{ print $1\"@\"$3\"@\"$5,$6,$7,$8 }';done" "head -1 | grep -v '^$' | awk '{ print $1\"@\"$3\"@\"$5,$6,$7,$8 }';done"
} }
} }

View File

@@ -27,6 +27,7 @@ class FTPLogViewSet(CreateModelMixin,
] ]
filter_fields = ['user', 'asset', 'system_user', 'filename'] filter_fields = ['user', 'asset', 'system_user', 'filename']
search_fields = filter_fields search_fields = filter_fields
ordering = ['-date_start']
class UserLoginLogViewSet(ListModelMixin, CommonGenericViewSet): class UserLoginLogViewSet(ListModelMixin, CommonGenericViewSet):

View File

@@ -17,7 +17,7 @@ class FTPLogSerializer(serializers.ModelSerializer):
model = models.FTPLog model = models.FTPLog
fields = ( fields = (
'id', 'user', 'remote_addr', 'asset', 'system_user', 'id', 'user', 'remote_addr', 'asset', 'system_user',
'operate', 'filename', 'is_success', 'date_start' 'operate', 'filename', 'is_success', 'date_start', 'org_id'
) )
@@ -39,7 +39,7 @@ class OperateLogSerializer(serializers.ModelSerializer):
model = models.OperateLog model = models.OperateLog
fields = ( fields = (
'id', 'user', 'action', 'resource_type', 'resource', 'id', 'user', 'action', 'resource_type', 'resource',
'remote_addr', 'datetime' 'remote_addr', 'datetime', 'org_id'
) )
@@ -65,7 +65,7 @@ class CommandExecutionSerializer(serializers.ModelSerializer):
fields_mini = ['id'] fields_mini = ['id']
fields_small = fields_mini + [ fields_small = fields_mini + [
'run_as', 'command', 'user', 'is_finished', 'run_as', 'command', 'user', 'is_finished',
'date_start', 'result', 'is_success' 'date_start', 'result', 'is_success', 'org_id'
] ]
fields = fields_small + ['hosts', 'run_as_display', 'user_display'] fields = fields_small + ['hosts', 'run_as_display', 'user_display']
extra_kwargs = { extra_kwargs = {

View File

@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import traceback
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from radiusauth.backends import RADIUSBackend, RADIUSRealmBackend from radiusauth.backends import RADIUSBackend, RADIUSRealmBackend
from django.conf import settings from django.conf import settings
from pyrad.packet import AccessRequest
User = get_user_model() User = get_user_model()
class CreateUserMixin: class CreateUserMixin:
def get_django_user(self, username, password=None): def get_django_user(self, username, password=None, *args, **kwargs):
if isinstance(username, bytes): if isinstance(username, bytes):
username = username.decode() username = username.decode()
try: try:
@@ -27,6 +27,23 @@ class CreateUserMixin:
user.save() user.save()
return user return user
def _perform_radius_auth(self, client, packet):
# TODO: 等待官方库修复这个BUG
try:
return super()._perform_radius_auth(client, packet)
except UnicodeError as e:
import sys
tb = ''.join(traceback.format_exception(*sys.exc_info(), limit=2, chain=False))
if tb.find("cl.decode") != -1:
return [], False, False
return None
def authenticate(self, *args, **kwargs):
# 校验用户时会传入public_key参数父类authentication中不接受public_key参数所以要pop掉
# TODO:需要优化各backend的authenticate方法django进行调用前会检测各authenticate的参数
kwargs.pop('public_key', None)
return super().authenticate(*args, **kwargs)
class RadiusBackend(CreateUserMixin, RADIUSBackend): class RadiusBackend(CreateUserMixin, RADIUSBackend):
pass pass

View File

@@ -38,9 +38,9 @@ class JMSCSVParser(BaseParser):
yield row yield row
@staticmethod @staticmethod
def _get_fields_map(serializer): def _get_fields_map(serializer_cls):
fields_map = {} fields_map = {}
fields = serializer.fields fields = serializer_cls().fields
fields_map.update({v.label: k for k, v in fields.items()}) fields_map.update({v.label: k for k, v in fields.items()})
fields_map.update({k: k for k, _ in fields.items()}) fields_map.update({k: k for k, _ in fields.items()})
return fields_map return fields_map
@@ -82,7 +82,8 @@ class JMSCSVParser(BaseParser):
def parse(self, stream, media_type=None, parser_context=None): def parse(self, stream, media_type=None, parser_context=None):
parser_context = parser_context or {} parser_context = parser_context or {}
try: try:
serializer = parser_context["view"].get_serializer() view = parser_context['view']
serializer_cls = view.get_serializer_class()
except Exception as e: except Exception as e:
logger.debug(e, exc_info=True) logger.debug(e, exc_info=True)
raise ParseError('The resource does not support imports!') raise ParseError('The resource does not support imports!')
@@ -96,7 +97,7 @@ class JMSCSVParser(BaseParser):
rows = self._gen_rows(binary, charset=encoding) rows = self._gen_rows(binary, charset=encoding)
header = next(rows) header = next(rows)
fields_map = self._get_fields_map(serializer) fields_map = self._get_fields_map(serializer_cls)
header = [fields_map.get(name.strip('*'), '') for name in header] header = [fields_map.get(name.strip('*'), '') for name in header]
data = [] data = []

View File

@@ -30,7 +30,7 @@ class JMSCSVRender(BaseRenderer):
@staticmethod @staticmethod
def _gen_table(data, fields): def _gen_table(data, fields):
data = data[:100] data = data[:10000]
yield ['*{}'.format(f.label) if f.required else f.label for f in fields] yield ['*{}'.format(f.label) if f.required else f.label for f in fields]
for item in data: for item in data:

View File

@@ -10,3 +10,7 @@ class HttpResponseTemporaryRedirect(HttpResponse):
def __init__(self, redirect_to): def __init__(self, redirect_to):
HttpResponse.__init__(self) HttpResponse.__init__(self)
self['Location'] = iri_to_uri(redirect_to) self['Location'] = iri_to_uri(redirect_to)
def get_remote_addr(request):
return request.META.get("HTTP_X_FORWARDED_HOST") or request.META.get("REMOTE_ADDR")

View File

@@ -24,7 +24,7 @@ def send_mail_async(*args, **kwargs):
""" """
if len(args) == 3: if len(args) == 3:
args = list(args) args = list(args)
args[0] = settings.EMAIL_SUBJECT_PREFIX + args[0] args[0] = (settings.EMAIL_SUBJECT_PREFIX or '') + args[0]
email_from = settings.EMAIL_FROM or settings.EMAIL_HOST_USER email_from = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
args.insert(2, email_from) args.insert(2, email_from)
args = tuple(args) args = tuple(args)

View File

@@ -241,7 +241,7 @@ class Config(dict):
'HTTP_BIND_HOST': '0.0.0.0', 'HTTP_BIND_HOST': '0.0.0.0',
'HTTP_LISTEN_PORT': 8080, 'HTTP_LISTEN_PORT': 8080,
'WS_LISTEN_PORT': 8070, 'WS_LISTEN_PORT': 8070,
'LOGIN_LOG_KEEP_DAYS': 90, 'LOGIN_LOG_KEEP_DAYS': 9999,
'TASK_LOG_KEEP_DAYS': 10, 'TASK_LOG_KEEP_DAYS': 10,
'ASSETS_PERM_CACHE_TIME': 3600 * 24, 'ASSETS_PERM_CACHE_TIME': 3600 * 24,
'SECURITY_MFA_VERIFY_TTL': 3600, 'SECURITY_MFA_VERIFY_TTL': 3600,
@@ -259,7 +259,8 @@ class Config(dict):
'WINDOWS_SKIP_ALL_MANUAL_PASSWORD': False, 'WINDOWS_SKIP_ALL_MANUAL_PASSWORD': False,
'ORG_CHANGE_TO_URL': '', 'ORG_CHANGE_TO_URL': '',
'LANGUAGE_CODE': 'zh', 'LANGUAGE_CODE': 'zh',
'TIME_ZONE': 'Asia/Shanghai' 'TIME_ZONE': 'Asia/Shanghai',
'CHANGE_AUTH_PLAN_SECURE_MODE_ENABLED': True
} }
def compatible_auth_openid_of_key(self): def compatible_auth_openid_of_key(self):

View File

@@ -92,6 +92,7 @@ CAS_LOGGED_MSG = None
CAS_LOGOUT_COMPLETELY = CONFIG.CAS_LOGOUT_COMPLETELY CAS_LOGOUT_COMPLETELY = CONFIG.CAS_LOGOUT_COMPLETELY
CAS_VERSION = CONFIG.CAS_VERSION CAS_VERSION = CONFIG.CAS_VERSION
CAS_ROOT_PROXIED_AS = CONFIG.CAS_ROOT_PROXIED_AS CAS_ROOT_PROXIED_AS = CONFIG.CAS_ROOT_PROXIED_AS
CAS_CHECK_NEXT = lambda: lambda _next_page: True
# Other setting # Other setting

View File

@@ -86,7 +86,11 @@ TASK_LOG_KEEP_DAYS = CONFIG.TASK_LOG_KEEP_DAYS
ORG_CHANGE_TO_URL = CONFIG.ORG_CHANGE_TO_URL ORG_CHANGE_TO_URL = CONFIG.ORG_CHANGE_TO_URL
WINDOWS_SKIP_ALL_MANUAL_PASSWORD = CONFIG.WINDOWS_SKIP_ALL_MANUAL_PASSWORD WINDOWS_SKIP_ALL_MANUAL_PASSWORD = CONFIG.WINDOWS_SKIP_ALL_MANUAL_PASSWORD
AUTH_EXPIRED_SECONDS = 60 * 5
# XPACK # XPACK
XPACK_LICENSE_IS_VALID = DYNAMIC.XPACK_LICENSE_IS_VALID XPACK_LICENSE_IS_VALID = DYNAMIC.XPACK_LICENSE_IS_VALID
LOGO_URLS = DYNAMIC.LOGO_URLS LOGO_URLS = DYNAMIC.LOGO_URLS
CHANGE_AUTH_PLAN_SECURE_MODE_ENABLED = CONFIG.CHANGE_AUTH_PLAN_SECURE_MODE_ENABLED

View File

@@ -1,5 +1,4 @@
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import redirect from django.shortcuts import redirect
from common.permissions import PermissionsMixin, IsValidUser from common.permissions import PermissionsMixin, IsValidUser
@@ -12,17 +11,3 @@ class IndexView(PermissionsMixin, TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
return redirect('/ui/') return redirect('/ui/')
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return self.handle_no_permission()
if request.user.is_common_user:
return redirect('assets:user-asset-list')
return super(IndexView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'app': _("Dashboard"),
})
return context

Binary file not shown.

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n" "Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-16 11:02+0800\n" "POT-Creation-Date: 2020-07-15 17:03+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n" "Language-Team: JumpServer team<ibuler@qq.com>\n"
@@ -28,7 +28,7 @@ msgstr "自定义"
#: assets/models/label.py:18 ops/mixin.py:24 orgs/models.py:12 #: assets/models/label.py:18 ops/mixin.py:24 orgs/models.py:12
#: perms/models/base.py:48 settings/models.py:27 terminal/models.py:26 #: perms/models/base.py:48 settings/models.py:27 terminal/models.py:26
#: terminal/models.py:342 terminal/models.py:374 terminal/models.py:411 #: terminal/models.py:342 terminal/models.py:374 terminal/models.py:411
#: users/forms/profile.py:20 users/models/group.py:15 users/models/user.py:466 #: users/forms/profile.py:20 users/models/group.py:15 users/models/user.py:467
#: users/templates/users/_select_user_modal.html:13 #: users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_asset_permission.html:37 #: users/templates/users/user_asset_permission.html:37
#: users/templates/users/user_asset_permission.html:154 #: users/templates/users/user_asset_permission.html:154
@@ -77,15 +77,15 @@ msgstr "数据库"
#: assets/models/group.py:23 assets/models/label.py:23 ops/models/adhoc.py:37 #: assets/models/group.py:23 assets/models/label.py:23 ops/models/adhoc.py:37
#: orgs/models.py:18 perms/models/base.py:56 settings/models.py:32 #: orgs/models.py:18 perms/models/base.py:56 settings/models.py:32
#: terminal/models.py:36 terminal/models.py:381 terminal/models.py:418 #: terminal/models.py:36 terminal/models.py:381 terminal/models.py:418
#: users/models/group.py:16 users/models/user.py:499 #: users/models/group.py:16 users/models/user.py:500
#: users/templates/users/user_detail.html:115 #: users/templates/users/user_detail.html:115
#: users/templates/users/user_granted_database_app.html:38 #: users/templates/users/user_granted_database_app.html:38
#: users/templates/users/user_granted_remote_app.html:37 #: users/templates/users/user_granted_remote_app.html:37
#: users/templates/users/user_group_detail.html:62 #: users/templates/users/user_group_detail.html:62
#: users/templates/users/user_group_list.html:16 #: users/templates/users/user_group_list.html:16
#: users/templates/users/user_profile.html:138 #: users/templates/users/user_profile.html:138
#: xpack/plugins/change_auth_plan/models.py:76 xpack/plugins/cloud/models.py:53 #: xpack/plugins/change_auth_plan/models.py:77 xpack/plugins/cloud/models.py:53
#: xpack/plugins/cloud/models.py:139 xpack/plugins/gathered_user/models.py:26 #: xpack/plugins/cloud/models.py:140 xpack/plugins/gathered_user/models.py:26
msgid "Comment" msgid "Comment"
msgstr "备注" msgstr "备注"
@@ -106,11 +106,12 @@ msgstr "数据库应用"
#: assets/serializers/system_user.py:176 audits/models.py:20 #: assets/serializers/system_user.py:176 audits/models.py:20
#: perms/forms/asset_permission.py:89 perms/models/asset_permission.py:80 #: perms/forms/asset_permission.py:89 perms/models/asset_permission.py:80
#: templates/index.html:82 terminal/backends/command/models.py:19 #: templates/index.html:82 terminal/backends/command/models.py:19
#: terminal/models.py:187 users/templates/users/user_asset_permission.html:40 #: terminal/backends/command/serializers.py:13 terminal/models.py:187
#: users/templates/users/user_asset_permission.html:40
#: users/templates/users/user_asset_permission.html:70 #: users/templates/users/user_asset_permission.html:70
#: users/templates/users/user_granted_remote_app.html:36 #: users/templates/users/user_granted_remote_app.html:36
#: xpack/plugins/change_auth_plan/models.py:282 #: xpack/plugins/change_auth_plan/models.py:283
#: xpack/plugins/cloud/models.py:269 #: xpack/plugins/cloud/models.py:266
msgid "Asset" msgid "Asset"
msgstr "资产" msgstr "资产"
@@ -131,10 +132,10 @@ msgstr "参数"
#: assets/models/base.py:240 assets/models/cluster.py:28 #: assets/models/base.py:240 assets/models/cluster.py:28
#: assets/models/cmd_filter.py:26 assets/models/cmd_filter.py:59 #: assets/models/cmd_filter.py:26 assets/models/cmd_filter.py:59
#: assets/models/group.py:21 common/mixins/models.py:49 orgs/models.py:16 #: assets/models/group.py:21 common/mixins/models.py:49 orgs/models.py:16
#: perms/models/base.py:54 users/models/user.py:507 #: perms/models/base.py:54 users/models/user.py:508
#: users/serializers/group.py:35 users/templates/users/user_detail.html:97 #: users/serializers/group.py:35 users/templates/users/user_detail.html:97
#: xpack/plugins/change_auth_plan/models.py:80 xpack/plugins/cloud/models.py:56 #: xpack/plugins/change_auth_plan/models.py:81 xpack/plugins/cloud/models.py:56
#: xpack/plugins/cloud/models.py:145 xpack/plugins/gathered_user/models.py:30 #: xpack/plugins/cloud/models.py:146 xpack/plugins/gathered_user/models.py:30
msgid "Created by" msgid "Created by"
msgstr "创建者" msgstr "创建者"
@@ -147,7 +148,7 @@ msgstr "创建者"
#: common/mixins/models.py:50 ops/models/adhoc.py:38 ops/models/command.py:27 #: common/mixins/models.py:50 ops/models/adhoc.py:38 ops/models/command.py:27
#: orgs/models.py:17 perms/models/base.py:55 users/models/group.py:18 #: orgs/models.py:17 perms/models/base.py:55 users/models/group.py:18
#: users/templates/users/user_group_detail.html:58 #: users/templates/users/user_group_detail.html:58
#: xpack/plugins/cloud/models.py:59 xpack/plugins/cloud/models.py:148 #: xpack/plugins/cloud/models.py:59 xpack/plugins/cloud/models.py:149
msgid "Date created" msgid "Date created"
msgstr "创建日期" msgstr "创建日期"
@@ -232,7 +233,7 @@ msgstr "网域"
#: assets/models/asset.py:195 assets/models/user.py:109 #: assets/models/asset.py:195 assets/models/user.py:109
#: perms/models/asset_permission.py:81 #: perms/models/asset_permission.py:81
#: xpack/plugins/change_auth_plan/models.py:55 #: xpack/plugins/change_auth_plan/models.py:56
#: xpack/plugins/gathered_user/models.py:24 #: xpack/plugins/gathered_user/models.py:24
msgid "Nodes" msgid "Nodes"
msgstr "节点" msgstr "节点"
@@ -245,7 +246,7 @@ msgstr "激活"
#: assets/models/asset.py:199 assets/models/cluster.py:19 #: assets/models/asset.py:199 assets/models/cluster.py:19
#: assets/models/user.py:65 templates/_nav.html:44 #: assets/models/user.py:65 templates/_nav.html:44
#: xpack/plugins/cloud/models.py:133 #: xpack/plugins/cloud/models.py:133 xpack/plugins/cloud/serializers.py:83
msgid "Admin user" msgid "Admin user"
msgstr "管理用户" msgstr "管理用户"
@@ -337,13 +338,13 @@ msgstr ""
#: audits/models.py:81 authentication/forms.py:10 #: audits/models.py:81 authentication/forms.py:10
#: authentication/templates/authentication/login.html:21 #: authentication/templates/authentication/login.html:21
#: authentication/templates/authentication/xpack_login.html:93 #: authentication/templates/authentication/xpack_login.html:93
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:464 #: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:465
#: users/templates/users/_select_user_modal.html:14 #: users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:53 #: users/templates/users/user_detail.html:53
#: users/templates/users/user_list.html:15 #: users/templates/users/user_list.html:15
#: users/templates/users/user_profile.html:47 #: users/templates/users/user_profile.html:47
#: xpack/plugins/change_auth_plan/models.py:46 #: xpack/plugins/change_auth_plan/models.py:47
#: xpack/plugins/change_auth_plan/models.py:278 #: xpack/plugins/change_auth_plan/models.py:279
msgid "Username" msgid "Username"
msgstr "用户名" msgstr "用户名"
@@ -358,21 +359,21 @@ msgstr "用户名"
#: users/templates/users/user_profile_update.html:41 #: users/templates/users/user_profile_update.html:41
#: users/templates/users/user_pubkey_update.html:41 #: users/templates/users/user_pubkey_update.html:41
#: users/templates/users/user_update.html:20 #: users/templates/users/user_update.html:20
#: xpack/plugins/change_auth_plan/models.py:67 #: xpack/plugins/change_auth_plan/models.py:68
#: xpack/plugins/change_auth_plan/models.py:190 #: xpack/plugins/change_auth_plan/models.py:191
#: xpack/plugins/change_auth_plan/models.py:285 #: xpack/plugins/change_auth_plan/models.py:286
msgid "Password" msgid "Password"
msgstr "密码" msgstr "密码"
#: assets/models/base.py:235 xpack/plugins/change_auth_plan/models.py:71 #: assets/models/base.py:235 xpack/plugins/change_auth_plan/models.py:72
#: xpack/plugins/change_auth_plan/models.py:197 #: xpack/plugins/change_auth_plan/models.py:198
#: xpack/plugins/change_auth_plan/models.py:292 #: xpack/plugins/change_auth_plan/models.py:293
msgid "SSH private key" msgid "SSH private key"
msgstr "SSH密钥" msgstr "SSH密钥"
#: assets/models/base.py:236 xpack/plugins/change_auth_plan/models.py:74 #: assets/models/base.py:236 xpack/plugins/change_auth_plan/models.py:75
#: xpack/plugins/change_auth_plan/models.py:193 #: xpack/plugins/change_auth_plan/models.py:194
#: xpack/plugins/change_auth_plan/models.py:288 #: xpack/plugins/change_auth_plan/models.py:289
msgid "SSH public key" msgid "SSH public key"
msgstr "SSH公钥" msgstr "SSH公钥"
@@ -389,7 +390,7 @@ msgstr "带宽"
msgid "Contact" msgid "Contact"
msgstr "联系人" msgstr "联系人"
#: assets/models/cluster.py:22 users/models/user.py:485 #: assets/models/cluster.py:22 users/models/user.py:486
#: users/templates/users/user_detail.html:62 #: users/templates/users/user_detail.html:62
msgid "Phone" msgid "Phone"
msgstr "手机" msgstr "手机"
@@ -415,7 +416,7 @@ msgid "Default"
msgstr "默认" msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14 #: assets/models/cluster.py:36 assets/models/label.py:14
#: users/models/user.py:626 #: users/models/user.py:627
msgid "System" msgid "System"
msgstr "系统" msgstr "系统"
@@ -448,7 +449,7 @@ msgid "Regex"
msgstr "正则表达式" msgstr "正则表达式"
#: assets/models/cmd_filter.py:40 ops/models/command.py:23 #: assets/models/cmd_filter.py:40 ops/models/command.py:23
#: terminal/models.py:196 #: terminal/backends/command/serializers.py:15 terminal/models.py:196
msgid "Command" msgid "Command"
msgstr "命令" msgstr "命令"
@@ -534,9 +535,10 @@ msgstr "默认资产组"
#: perms/forms/asset_permission.py:83 perms/forms/database_app_permission.py:38 #: perms/forms/asset_permission.py:83 perms/forms/database_app_permission.py:38
#: perms/forms/remote_app_permission.py:40 perms/models/base.py:49 #: perms/forms/remote_app_permission.py:40 perms/models/base.py:49
#: templates/index.html:78 terminal/backends/command/models.py:18 #: templates/index.html:78 terminal/backends/command/models.py:18
#: terminal/models.py:185 tickets/models/ticket.py:33 #: terminal/backends/command/serializers.py:12 terminal/models.py:185
#: tickets/models/ticket.py:128 users/forms/group.py:15 #: tickets/models/ticket.py:33 tickets/models/ticket.py:128
#: users/models/user.py:159 users/models/user.py:175 users/models/user.py:614 #: tickets/serializers/ticket.py:27 users/forms/group.py:15
#: users/models/user.py:160 users/models/user.py:176 users/models/user.py:615
#: users/serializers/group.py:20 #: users/serializers/group.py:20
#: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:38
#: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_asset_permission.html:64
@@ -584,7 +586,7 @@ msgstr "键"
#: users/templates/users/user_asset_permission.html:41 #: users/templates/users/user_asset_permission.html:41
#: users/templates/users/user_asset_permission.html:73 #: users/templates/users/user_asset_permission.html:73
#: users/templates/users/user_asset_permission.html:158 #: users/templates/users/user_asset_permission.html:158
#: xpack/plugins/cloud/models.py:129 #: xpack/plugins/cloud/models.py:129 xpack/plugins/cloud/serializers.py:84
msgid "Node" msgid "Node"
msgstr "节点" msgstr "节点"
@@ -601,12 +603,12 @@ msgid "Username same with user"
msgstr "用户名与用户相同" msgstr "用户名与用户相同"
#: assets/models/user.py:110 templates/_nav.html:39 #: assets/models/user.py:110 templates/_nav.html:39
#: xpack/plugins/change_auth_plan/models.py:51 #: xpack/plugins/change_auth_plan/models.py:52
msgid "Assets" msgid "Assets"
msgstr "资产管理" msgstr "资产管理"
#: assets/models/user.py:111 templates/_nav.html:17 #: assets/models/user.py:111 templates/_nav.html:17
#: users/views/profile/password.py:40 users/views/profile/pubkey.py:36 #: users/views/profile/password.py:42 users/views/profile/pubkey.py:36
msgid "Users" msgid "Users"
msgstr "用户管理" msgstr "用户管理"
@@ -640,7 +642,8 @@ msgstr "SFTP根路径"
#: perms/models/asset_permission.py:82 #: perms/models/asset_permission.py:82
#: perms/models/database_app_permission.py:22 #: perms/models/database_app_permission.py:22
#: perms/models/remote_app_permission.py:16 templates/_nav.html:45 #: perms/models/remote_app_permission.py:16 templates/_nav.html:45
#: terminal/backends/command/models.py:20 terminal/models.py:189 #: terminal/backends/command/models.py:20
#: terminal/backends/command/serializers.py:14 terminal/models.py:189
#: users/templates/users/_granted_assets.html:27 #: users/templates/users/_granted_assets.html:27
#: users/templates/users/user_asset_permission.html:42 #: users/templates/users/user_asset_permission.html:42
#: users/templates/users/user_asset_permission.html:76 #: users/templates/users/user_asset_permission.html:76
@@ -685,7 +688,7 @@ msgstr "硬件信息"
msgid "Org name" msgid "Org name"
msgstr "组织名称" msgstr "组织名称"
#: assets/serializers/asset.py:144 assets/serializers/asset.py:181 #: assets/serializers/asset.py:144 assets/serializers/asset.py:175
msgid "Connectivity" msgid "Connectivity"
msgstr "连接" msgstr "连接"
@@ -699,14 +702,14 @@ msgid "Backend"
msgstr "后端" msgstr "后端"
#: assets/serializers/asset_user.py:75 users/forms/profile.py:148 #: assets/serializers/asset_user.py:75 users/forms/profile.py:148
#: users/models/user.py:496 users/templates/users/user_password_update.html:48 #: users/models/user.py:497 users/templates/users/user_password_update.html:48
#: users/templates/users/user_profile.html:69 #: users/templates/users/user_profile.html:69
#: users/templates/users/user_profile_update.html:46 #: users/templates/users/user_profile_update.html:46
#: users/templates/users/user_pubkey_update.html:46 #: users/templates/users/user_pubkey_update.html:46
msgid "Public key" msgid "Public key"
msgstr "SSH公钥" msgstr "SSH公钥"
#: assets/serializers/asset_user.py:79 users/models/user.py:493 #: assets/serializers/asset_user.py:79 users/models/user.py:494
msgid "Private key" msgid "Private key"
msgstr "ssh私钥" msgstr "ssh私钥"
@@ -874,8 +877,8 @@ msgid "Success"
msgstr "成功" msgstr "成功"
#: audits/models.py:25 ops/models/command.py:28 perms/models/base.py:52 #: audits/models.py:25 ops/models/command.py:28 perms/models/base.py:52
#: terminal/models.py:199 xpack/plugins/change_auth_plan/models.py:176 #: terminal/models.py:199 xpack/plugins/change_auth_plan/models.py:177
#: xpack/plugins/change_auth_plan/models.py:307 #: xpack/plugins/change_auth_plan/models.py:308
#: xpack/plugins/gathered_user/models.py:76 #: xpack/plugins/gathered_user/models.py:76
msgid "Date start" msgid "Date start"
msgstr "开始日期" msgstr "开始日期"
@@ -943,7 +946,7 @@ msgstr "启用"
msgid "-" msgid "-"
msgstr "" msgstr ""
#: audits/models.py:78 xpack/plugins/cloud/models.py:204 #: audits/models.py:78 xpack/plugins/cloud/models.py:201
msgid "Failed" msgid "Failed"
msgstr "失败" msgstr "失败"
@@ -966,19 +969,19 @@ msgstr "Agent"
#: audits/models.py:86 #: audits/models.py:86
#: authentication/templates/authentication/_mfa_confirm_modal.html:14 #: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: authentication/templates/authentication/login_otp.html:6 #: authentication/templates/authentication/login_otp.html:6
#: users/forms/profile.py:52 users/models/user.py:488 #: users/forms/profile.py:52 users/models/user.py:489
#: users/serializers/user.py:216 users/templates/users/user_detail.html:77 #: users/serializers/user.py:216 users/templates/users/user_detail.html:77
#: users/templates/users/user_profile.html:87 #: users/templates/users/user_profile.html:87
msgid "MFA" msgid "MFA"
msgstr "多因子认证" msgstr "多因子认证"
#: audits/models.py:87 xpack/plugins/change_auth_plan/models.py:303 #: audits/models.py:87 xpack/plugins/change_auth_plan/models.py:304
#: xpack/plugins/cloud/models.py:217 #: xpack/plugins/cloud/models.py:214
msgid "Reason" msgid "Reason"
msgstr "原因" msgstr "原因"
#: audits/models.py:88 tickets/serializers/ticket.py:25 #: audits/models.py:88 tickets/serializers/ticket.py:25
#: xpack/plugins/cloud/models.py:214 xpack/plugins/cloud/models.py:272 #: xpack/plugins/cloud/models.py:211 xpack/plugins/cloud/models.py:269
msgid "Status" msgid "Status"
msgstr "状态" msgstr "状态"
@@ -991,7 +994,7 @@ msgid "Is success"
msgstr "是否成功" msgstr "是否成功"
#: audits/serializers.py:72 ops/models/command.py:24 #: audits/serializers.py:72 ops/models/command.py:24
#: xpack/plugins/cloud/models.py:212 #: xpack/plugins/cloud/models.py:209
msgid "Result" msgid "Result"
msgstr "结果" msgstr "结果"
@@ -1106,8 +1109,8 @@ msgid ""
"after {} minutes)" "after {} minutes)"
msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)" msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)"
#: authentication/errors.py:48 users/views/profile/otp.py:63 #: authentication/errors.py:48 users/views/profile/otp.py:107
#: users/views/profile/otp.py:102 users/views/profile/otp.py:121 #: users/views/profile/otp.py:146 users/views/profile/otp.py:166
msgid "MFA code invalid, or ntp sync server time" msgid "MFA code invalid, or ntp sync server time"
msgstr "MFA验证码不正确或者服务器端时间不对" msgstr "MFA验证码不正确或者服务器端时间不对"
@@ -1186,7 +1189,7 @@ msgid "Show"
msgstr "显示" msgstr "显示"
#: authentication/templates/authentication/_access_key_modal.html:66 #: authentication/templates/authentication/_access_key_modal.html:66
#: users/models/user.py:386 users/serializers/user.py:213 #: users/models/user.py:387 users/serializers/user.py:213
#: users/templates/users/user_profile.html:94 #: users/templates/users/user_profile.html:94
#: users/templates/users/user_profile.html:163 #: users/templates/users/user_profile.html:163
#: users/templates/users/user_profile.html:166 #: users/templates/users/user_profile.html:166
@@ -1195,7 +1198,7 @@ msgid "Disable"
msgstr "禁用" msgstr "禁用"
#: authentication/templates/authentication/_access_key_modal.html:67 #: authentication/templates/authentication/_access_key_modal.html:67
#: users/models/user.py:387 users/serializers/user.py:214 #: users/models/user.py:388 users/serializers/user.py:214
#: users/templates/users/user_profile.html:92 #: users/templates/users/user_profile.html:92
#: users/templates/users/user_profile.html:170 #: users/templates/users/user_profile.html:170
msgid "Enable" msgid "Enable"
@@ -1397,10 +1400,6 @@ msgstr "字段必须唯一"
msgid "<h1>Flow service unavailable, check it</h1>" msgid "<h1>Flow service unavailable, check it</h1>"
msgstr "" msgstr ""
#: jumpserver/views/index.py:26 templates/_nav.html:7
msgid "Dashboard"
msgstr "仪表盘"
#: jumpserver/views/other.py:26 #: jumpserver/views/other.py:26
msgid "" msgid ""
"<div>Luna is a separately deployed program, you need to deploy Luna, koko, " "<div>Luna is a separately deployed program, you need to deploy Luna, koko, "
@@ -1520,8 +1519,8 @@ msgstr "开始时间"
msgid "End time" msgid "End time"
msgstr "完成时间" msgstr "完成时间"
#: ops/models/adhoc.py:242 xpack/plugins/change_auth_plan/models.py:179 #: ops/models/adhoc.py:242 xpack/plugins/change_auth_plan/models.py:180
#: xpack/plugins/change_auth_plan/models.py:310 #: xpack/plugins/change_auth_plan/models.py:311
#: xpack/plugins/gathered_user/models.py:79 #: xpack/plugins/gathered_user/models.py:79
msgid "Time" msgid "Time"
msgstr "时间" msgstr "时间"
@@ -1604,7 +1603,7 @@ msgstr "提示RDP 协议不支持单独控制上传或下载文件"
#: perms/forms/asset_permission.py:86 perms/forms/database_app_permission.py:41 #: perms/forms/asset_permission.py:86 perms/forms/database_app_permission.py:41
#: perms/forms/remote_app_permission.py:43 perms/models/base.py:50 #: perms/forms/remote_app_permission.py:43 perms/models/base.py:50
#: templates/_nav.html:21 users/forms/user.py:168 users/models/group.py:31 #: templates/_nav.html:21 users/forms/user.py:168 users/models/group.py:31
#: users/models/user.py:472 users/templates/users/_select_user_modal.html:16 #: users/models/user.py:473 users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_asset_permission.html:39 #: users/templates/users/user_asset_permission.html:39
#: users/templates/users/user_asset_permission.html:67 #: users/templates/users/user_asset_permission.html:67
#: users/templates/users/user_database_app_permission.html:38 #: users/templates/users/user_database_app_permission.html:38
@@ -1657,7 +1656,7 @@ msgstr "动作"
msgid "Asset permission" msgid "Asset permission"
msgstr "资产授权" msgstr "资产授权"
#: perms/models/base.py:53 users/models/user.py:504 #: perms/models/base.py:53 users/models/user.py:505
#: users/templates/users/user_detail.html:93 #: users/templates/users/user_detail.html:93
#: users/templates/users/user_profile.html:120 #: users/templates/users/user_profile.html:120
msgid "Date expired" msgid "Date expired"
@@ -1976,6 +1975,10 @@ msgstr ""
"\"%(user_pubkey_update)s\"> 链接 </a> 更新\n" "\"%(user_pubkey_update)s\"> 链接 </a> 更新\n"
" " " "
#: templates/_nav.html:7
msgid "Dashboard"
msgstr "仪表盘"
#: templates/_nav.html:20 #: templates/_nav.html:20
msgid "User list" msgid "User list"
msgstr "用户列表" msgstr "用户列表"
@@ -2320,14 +2323,17 @@ msgid "Input"
msgstr "输入" msgstr "输入"
#: terminal/backends/command/models.py:22 #: terminal/backends/command/models.py:22
#: terminal/backends/command/serializers.py:16
msgid "Output" msgid "Output"
msgstr "输出" msgstr "输出"
#: terminal/backends/command/models.py:23 #: terminal/backends/command/models.py:23
#: terminal/backends/command/serializers.py:17
msgid "Session" msgid "Session"
msgstr "会话" msgstr "会话"
#: terminal/backends/command/models.py:24 #: terminal/backends/command/models.py:24
#: terminal/backends/command/serializers.py:18
msgid "Risk level" msgid "Risk level"
msgstr "风险等级" msgstr "风险等级"
@@ -2553,7 +2559,7 @@ msgstr "确认密码"
msgid "Password does not match" msgid "Password does not match"
msgstr "密码不一致" msgstr "密码不一致"
#: users/forms/profile.py:89 users/models/user.py:468 #: users/forms/profile.py:89 users/models/user.py:469
#: users/templates/users/user_detail.html:57 #: users/templates/users/user_detail.html:57
#: users/templates/users/user_profile.html:59 #: users/templates/users/user_profile.html:59
msgid "Email" msgid "Email"
@@ -2594,7 +2600,7 @@ msgstr "不能和原来的密钥相同"
msgid "Not a valid ssh public key" msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法" msgstr "SSH密钥不合法"
#: users/forms/user.py:27 users/models/user.py:476 #: users/forms/user.py:27 users/models/user.py:477
#: users/templates/users/_select_user_modal.html:15 #: users/templates/users/_select_user_modal.html:15
#: users/templates/users/user_detail.html:73 #: users/templates/users/user_detail.html:73
#: users/templates/users/user_list.html:16 #: users/templates/users/user_list.html:16
@@ -2602,7 +2608,7 @@ msgstr "SSH密钥不合法"
msgid "Role" msgid "Role"
msgstr "角色" msgstr "角色"
#: users/forms/user.py:31 users/models/user.py:511 #: users/forms/user.py:31 users/models/user.py:512
#: users/templates/users/user_detail.html:89 #: users/templates/users/user_detail.html:89
#: users/templates/users/user_list.html:18 #: users/templates/users/user_list.html:18
#: users/templates/users/user_profile.html:102 #: users/templates/users/user_profile.html:102
@@ -2617,7 +2623,7 @@ msgstr "复制用户公钥到这里"
msgid "Join user groups" msgid "Join user groups"
msgstr "添加到用户组" msgstr "添加到用户组"
#: users/forms/user.py:103 users/views/profile/password.py:57 #: users/forms/user.py:103 users/views/profile/password.py:59
#: users/views/profile/reset.py:123 #: users/views/profile/reset.py:123
msgid "* Your password does not meet the requirements" msgid "* Your password does not meet the requirements"
msgstr "* 您的密码不符合要求" msgstr "* 您的密码不符合要求"
@@ -2631,52 +2637,52 @@ msgid "Set password"
msgstr "设置密码" msgstr "设置密码"
#: users/forms/user.py:132 users/serializers/user.py:38 #: users/forms/user.py:132 users/serializers/user.py:38
#: xpack/plugins/change_auth_plan/models.py:60 #: xpack/plugins/change_auth_plan/models.py:61
#: xpack/plugins/change_auth_plan/serializers.py:30 #: xpack/plugins/change_auth_plan/serializers.py:30
msgid "Password strategy" msgid "Password strategy"
msgstr "密码策略" msgstr "密码策略"
#: users/models/user.py:158 users/models/user.py:622 #: users/models/user.py:159 users/models/user.py:623
msgid "Administrator" msgid "Administrator"
msgstr "管理员" msgstr "管理员"
#: users/models/user.py:160 #: users/models/user.py:161
msgid "Application" msgid "Application"
msgstr "应用程序" msgstr "应用程序"
#: users/models/user.py:161 #: users/models/user.py:162
msgid "Auditor" msgid "Auditor"
msgstr "审计员" msgstr "审计员"
#: users/models/user.py:171 #: users/models/user.py:172
msgid "Org admin" msgid "Org admin"
msgstr "组织管理员" msgstr "组织管理员"
#: users/models/user.py:173 #: users/models/user.py:174
msgid "Org auditor" msgid "Org auditor"
msgstr "组织审计员" msgstr "组织审计员"
#: users/models/user.py:388 users/templates/users/user_profile.html:90 #: users/models/user.py:389 users/templates/users/user_profile.html:90
msgid "Force enable" msgid "Force enable"
msgstr "强制启用" msgstr "强制启用"
#: users/models/user.py:455 #: users/models/user.py:456
msgid "Local" msgid "Local"
msgstr "数据库" msgstr "数据库"
#: users/models/user.py:479 #: users/models/user.py:480
msgid "Avatar" msgid "Avatar"
msgstr "头像" msgstr "头像"
#: users/models/user.py:482 users/templates/users/user_detail.html:68 #: users/models/user.py:483 users/templates/users/user_detail.html:68
msgid "Wechat" msgid "Wechat"
msgstr "微信" msgstr "微信"
#: users/models/user.py:515 #: users/models/user.py:516
msgid "Date password last updated" msgid "Date password last updated"
msgstr "最后更新密码日期" msgstr "最后更新密码日期"
#: users/models/user.py:625 #: users/models/user.py:626
msgid "Administrator is the super user of system" msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员" msgstr "Administrator是初始的超级管理员"
@@ -2738,7 +2744,7 @@ msgstr "安全令牌验证"
#: users/templates/users/_base_otp.html:14 users/templates/users/_user.html:13 #: users/templates/users/_base_otp.html:14 users/templates/users/_user.html:13
#: users/templates/users/user_profile_update.html:55 #: users/templates/users/user_profile_update.html:55
#: xpack/plugins/cloud/models.py:119 #: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/serializers.py:82
msgid "Account" msgid "Account"
msgstr "账户" msgstr "账户"
@@ -2902,7 +2908,7 @@ msgstr "很强"
#: users/templates/users/user_database_app_permission.html:41 #: users/templates/users/user_database_app_permission.html:41
#: users/templates/users/user_list.html:19 #: users/templates/users/user_list.html:19
#: users/templates/users/user_remote_app_permission.html:41 #: users/templates/users/user_remote_app_permission.html:41
#: xpack/plugins/cloud/models.py:50 xpack/plugins/cloud/serializers.py:32 #: xpack/plugins/cloud/models.py:50
msgid "Validity" msgid "Validity"
msgstr "有效" msgstr "有效"
@@ -3453,27 +3459,27 @@ msgstr ""
" <br>\n" " <br>\n"
" " " "
#: users/views/profile/otp.py:145 #: users/views/profile/otp.py:190
msgid "MFA enable success" msgid "MFA enable success"
msgstr "多因子认证启用成功" msgstr "多因子认证启用成功"
#: users/views/profile/otp.py:146 #: users/views/profile/otp.py:191
msgid "MFA enable success, return login page" msgid "MFA enable success, return login page"
msgstr "多因子认证启用成功,返回到登录页面" msgstr "多因子认证启用成功,返回到登录页面"
#: users/views/profile/otp.py:148 #: users/views/profile/otp.py:193
msgid "MFA disable success" msgid "MFA disable success"
msgstr "多因子认证禁用成功" msgstr "多因子认证禁用成功"
#: users/views/profile/otp.py:149 #: users/views/profile/otp.py:194
msgid "MFA disable success, return login page" msgid "MFA disable success, return login page"
msgstr "多因子认证禁用成功,返回登录页面" msgstr "多因子认证禁用成功,返回登录页面"
#: users/views/profile/password.py:41 #: users/views/profile/password.py:43
msgid "Password update" msgid "Password update"
msgstr "密码更新" msgstr "密码更新"
#: users/views/profile/password.py:72 #: users/views/profile/password.py:74
msgid "Password invalid" msgid "Password invalid"
msgstr "用户名或密码无效" msgstr "用户名或密码无效"
@@ -3507,65 +3513,65 @@ msgid "Token invalid or expired"
msgstr "Token错误或失效" msgstr "Token错误或失效"
#: xpack/plugins/change_auth_plan/meta.py:9 #: xpack/plugins/change_auth_plan/meta.py:9
#: xpack/plugins/change_auth_plan/models.py:88 #: xpack/plugins/change_auth_plan/models.py:89
#: xpack/plugins/change_auth_plan/models.py:183 #: xpack/plugins/change_auth_plan/models.py:184
msgid "Change auth plan" msgid "Change auth plan"
msgstr "改密计划" msgstr "改密计划"
#: xpack/plugins/change_auth_plan/models.py:40 #: xpack/plugins/change_auth_plan/models.py:41
msgid "Custom password" msgid "Custom password"
msgstr "自定义密码" msgstr "自定义密码"
#: xpack/plugins/change_auth_plan/models.py:41 #: xpack/plugins/change_auth_plan/models.py:42
msgid "All assets use the same random password" msgid "All assets use the same random password"
msgstr "所有资产使用相同的随机密码" msgstr "所有资产使用相同的随机密码"
#: xpack/plugins/change_auth_plan/models.py:42 #: xpack/plugins/change_auth_plan/models.py:43
msgid "All assets use different random password" msgid "All assets use different random password"
msgstr "所有资产使用不同的随机密码" msgstr "所有资产使用不同的随机密码"
#: xpack/plugins/change_auth_plan/models.py:64 #: xpack/plugins/change_auth_plan/models.py:65
msgid "Password rules" msgid "Password rules"
msgstr "密码规则" msgstr "密码规则"
#: xpack/plugins/change_auth_plan/models.py:187 #: xpack/plugins/change_auth_plan/models.py:188
msgid "Change auth plan snapshot" msgid "Change auth plan snapshot"
msgstr "改密计划快照" msgstr "改密计划快照"
#: xpack/plugins/change_auth_plan/models.py:202 #: xpack/plugins/change_auth_plan/models.py:203
#: xpack/plugins/change_auth_plan/models.py:296 #: xpack/plugins/change_auth_plan/models.py:297
msgid "Change auth plan execution" msgid "Change auth plan execution"
msgstr "改密计划执行" msgstr "改密计划执行"
#: xpack/plugins/change_auth_plan/models.py:269 #: xpack/plugins/change_auth_plan/models.py:270
msgid "Ready" msgid "Ready"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:270 #: xpack/plugins/change_auth_plan/models.py:271
msgid "Preflight check" msgid "Preflight check"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:271 #: xpack/plugins/change_auth_plan/models.py:272
msgid "Change auth" msgid "Change auth"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:272 #: xpack/plugins/change_auth_plan/models.py:273
msgid "Verify auth" msgid "Verify auth"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:273 #: xpack/plugins/change_auth_plan/models.py:274
msgid "Keep auth" msgid "Keep auth"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:274 #: xpack/plugins/change_auth_plan/models.py:275
msgid "Finished" msgid "Finished"
msgstr "结束" msgstr "结束"
#: xpack/plugins/change_auth_plan/models.py:300 #: xpack/plugins/change_auth_plan/models.py:301
msgid "Step" msgid "Step"
msgstr "步骤" msgstr "步骤"
#: xpack/plugins/change_auth_plan/models.py:317 #: xpack/plugins/change_auth_plan/models.py:318
msgid "Change auth plan task" msgid "Change auth plan task"
msgstr "改密计划任务" msgstr "改密计划任务"
@@ -3609,7 +3615,7 @@ msgstr "有效"
msgid "Unavailable" msgid "Unavailable"
msgstr "无效" msgstr "无效"
#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/serializers.py:31 #: xpack/plugins/cloud/models.py:39
msgid "Provider" msgid "Provider"
msgstr "云服务商" msgstr "云服务商"
@@ -3625,7 +3631,7 @@ msgstr ""
msgid "Cloud account" msgid "Cloud account"
msgstr "云账号" msgstr "云账号"
#: xpack/plugins/cloud/models.py:122 xpack/plugins/cloud/serializers.py:55 #: xpack/plugins/cloud/models.py:122 xpack/plugins/cloud/serializers.py:59
msgid "Regions" msgid "Regions"
msgstr "地域" msgstr "地域"
@@ -3633,59 +3639,59 @@ msgstr "地域"
msgid "Instances" msgid "Instances"
msgstr "实例" msgstr "实例"
#: xpack/plugins/cloud/models.py:136 xpack/plugins/cloud/serializers.py:77 #: xpack/plugins/cloud/models.py:137 xpack/plugins/cloud/serializers.py:86
msgid "Covered always" msgid "Always update"
msgstr "总是被覆盖" msgstr "总是更新"
#: xpack/plugins/cloud/models.py:142 #: xpack/plugins/cloud/models.py:143
msgid "Date last sync" msgid "Date last sync"
msgstr "最后同步日期" msgstr "最后同步日期"
#: xpack/plugins/cloud/models.py:153 xpack/plugins/cloud/models.py:210 #: xpack/plugins/cloud/models.py:154 xpack/plugins/cloud/models.py:207
msgid "Sync instance task" msgid "Sync instance task"
msgstr "同步实例任务" msgstr "同步实例任务"
#: xpack/plugins/cloud/models.py:205 #: xpack/plugins/cloud/models.py:202
msgid "Succeed" msgid "Succeed"
msgstr "成功" msgstr "成功"
#: xpack/plugins/cloud/models.py:220 xpack/plugins/cloud/models.py:275 #: xpack/plugins/cloud/models.py:217 xpack/plugins/cloud/models.py:272
msgid "Date sync" msgid "Date sync"
msgstr "同步日期" msgstr "同步日期"
#: xpack/plugins/cloud/models.py:248 #: xpack/plugins/cloud/models.py:245
msgid "Unsync" msgid "Unsync"
msgstr "未同步" msgstr "未同步"
#: xpack/plugins/cloud/models.py:249 xpack/plugins/cloud/models.py:250 #: xpack/plugins/cloud/models.py:246 xpack/plugins/cloud/models.py:247
msgid "Synced" msgid "Synced"
msgstr "已同步" msgstr "已同步"
#: xpack/plugins/cloud/models.py:251 #: xpack/plugins/cloud/models.py:248
msgid "Released" msgid "Released"
msgstr "已释放" msgstr "已释放"
#: xpack/plugins/cloud/models.py:256 #: xpack/plugins/cloud/models.py:253
msgid "Sync task" msgid "Sync task"
msgstr "同步任务" msgstr "同步任务"
#: xpack/plugins/cloud/models.py:260 #: xpack/plugins/cloud/models.py:257
msgid "Sync instance task history" msgid "Sync instance task history"
msgstr "同步实例任务历史" msgstr "同步实例任务历史"
#: xpack/plugins/cloud/models.py:263 #: xpack/plugins/cloud/models.py:260
msgid "Instance" msgid "Instance"
msgstr "实例" msgstr "实例"
#: xpack/plugins/cloud/models.py:266 #: xpack/plugins/cloud/models.py:263
msgid "Region" msgid "Region"
msgstr "地域" msgstr "地域"
#: xpack/plugins/cloud/providers/aliyun.py:19 #: xpack/plugins/cloud/providers/aliyun.py:22
msgid "Alibaba Cloud" msgid "Alibaba Cloud"
msgstr "阿里云" msgstr "阿里云"
#: xpack/plugins/cloud/providers/aws.py:15 #: xpack/plugins/cloud/providers/aws.py:18
msgid "AWS (International)" msgid "AWS (International)"
msgstr "AWS (国际)" msgstr "AWS (国际)"
@@ -3693,79 +3699,75 @@ msgstr "AWS (国际)"
msgid "AWS (China)" msgid "AWS (China)"
msgstr "AWS (中国)" msgstr "AWS (中国)"
#: xpack/plugins/cloud/providers/huaweicloud.py:17 #: xpack/plugins/cloud/providers/huaweicloud.py:20
msgid "Huawei Cloud" msgid "Huawei Cloud"
msgstr "华为云" msgstr "华为云"
#: xpack/plugins/cloud/providers/huaweicloud.py:20 #: xpack/plugins/cloud/providers/huaweicloud.py:23
msgid "AF-Johannesburg" msgid "AF-Johannesburg"
msgstr "非洲-约翰内斯堡" msgstr "非洲-约翰内斯堡"
#: xpack/plugins/cloud/providers/huaweicloud.py:21 #: xpack/plugins/cloud/providers/huaweicloud.py:24
msgid "AP-Bangkok" msgid "AP-Bangkok"
msgstr "亚太-曼谷" msgstr "亚太-曼谷"
#: xpack/plugins/cloud/providers/huaweicloud.py:22 #: xpack/plugins/cloud/providers/huaweicloud.py:25
msgid "AP-Hong Kong" msgid "AP-Hong Kong"
msgstr "亚太-香港" msgstr "亚太-香港"
#: xpack/plugins/cloud/providers/huaweicloud.py:23 #: xpack/plugins/cloud/providers/huaweicloud.py:26
msgid "AP-Singapore" msgid "AP-Singapore"
msgstr "亚太-新加坡" msgstr "亚太-新加坡"
#: xpack/plugins/cloud/providers/huaweicloud.py:24 #: xpack/plugins/cloud/providers/huaweicloud.py:27
msgid "CN East-Shanghai1" msgid "CN East-Shanghai1"
msgstr "华东-上海1" msgstr "华东-上海1"
#: xpack/plugins/cloud/providers/huaweicloud.py:25 #: xpack/plugins/cloud/providers/huaweicloud.py:28
msgid "CN East-Shanghai2" msgid "CN East-Shanghai2"
msgstr "华东-上海2" msgstr "华东-上海2"
#: xpack/plugins/cloud/providers/huaweicloud.py:26 #: xpack/plugins/cloud/providers/huaweicloud.py:29
msgid "CN North-Beijing1" msgid "CN North-Beijing1"
msgstr "华北-北京1" msgstr "华北-北京1"
#: xpack/plugins/cloud/providers/huaweicloud.py:27 #: xpack/plugins/cloud/providers/huaweicloud.py:30
msgid "CN North-Beijing4" msgid "CN North-Beijing4"
msgstr "华北-北京4" msgstr "华北-北京4"
#: xpack/plugins/cloud/providers/huaweicloud.py:28 #: xpack/plugins/cloud/providers/huaweicloud.py:31
msgid "CN Northeast-Dalian" msgid "CN Northeast-Dalian"
msgstr "华北-大连" msgstr "华北-大连"
#: xpack/plugins/cloud/providers/huaweicloud.py:29 #: xpack/plugins/cloud/providers/huaweicloud.py:32
msgid "CN South-Guangzhou" msgid "CN South-Guangzhou"
msgstr "华南-广州" msgstr "华南-广州"
#: xpack/plugins/cloud/providers/huaweicloud.py:30 #: xpack/plugins/cloud/providers/huaweicloud.py:33
msgid "CN Southwest-Guiyang1" msgid "CN Southwest-Guiyang1"
msgstr "西南-贵阳1" msgstr "西南-贵阳1"
#: xpack/plugins/cloud/providers/huaweicloud.py:31 #: xpack/plugins/cloud/providers/huaweicloud.py:34
msgid "EU-Paris" msgid "EU-Paris"
msgstr "欧洲-巴黎" msgstr "欧洲-巴黎"
#: xpack/plugins/cloud/providers/huaweicloud.py:32 #: xpack/plugins/cloud/providers/huaweicloud.py:35
msgid "LA-Santiago" msgid "LA-Santiago"
msgstr "拉美-圣地亚哥" msgstr "拉美-圣地亚哥"
#: xpack/plugins/cloud/providers/qcloud.py:17 #: xpack/plugins/cloud/providers/qcloud.py:20
msgid "Tencent Cloud" msgid "Tencent Cloud"
msgstr "腾讯云" msgstr "腾讯云"
#: xpack/plugins/cloud/serializers.py:53 #: xpack/plugins/cloud/serializers.py:57
msgid "History count" msgid "History count"
msgstr "用户数量" msgstr "执行次数"
#: xpack/plugins/cloud/serializers.py:54 #: xpack/plugins/cloud/serializers.py:58
msgid "Instance count" msgid "Instance count"
msgstr "实例个数" msgstr "实例个数"
#: xpack/plugins/cloud/serializers.py:75 #: xpack/plugins/cloud/serializers.py:85
msgid "Account name"
msgstr "账户名称"
#: xpack/plugins/cloud/serializers.py:76
#: xpack/plugins/gathered_user/serializers.py:20 #: xpack/plugins/gathered_user/serializers.py:20
msgid "Periodic display" msgid "Periodic display"
msgstr "定时执行" msgstr "定时执行"
@@ -3854,6 +3856,30 @@ msgstr "企业版"
msgid "Ultimate edition" msgid "Ultimate edition"
msgstr "旗舰版" msgstr "旗舰版"
#~ msgid "Upload"
#~ msgstr "上传文件"
#~ msgid "Download"
#~ msgstr "下载文件"
#~ msgid "Rmdir"
#~ msgstr "删除目录"
#~ msgid "Rename"
#~ msgstr "重命名"
#~ msgid "Mkdir"
#~ msgstr "创建目录"
#~ msgid "Symlink"
#~ msgstr "建立软链接"
#~ msgid "Covered always"
#~ msgstr "总是被覆盖"
#~ msgid "Account name"
#~ msgstr "账户名称"
#~ msgid "Target URL" #~ msgid "Target URL"
#~ msgstr "目标URL" #~ msgstr "目标URL"
@@ -5020,9 +5046,6 @@ msgstr "旗舰版"
#~ msgid "Download replay" #~ msgid "Download replay"
#~ msgstr "下载录像" #~ msgstr "下载录像"
#~ msgid "Download"
#~ msgstr "下载"
#~ msgid "Monitor session" #~ msgid "Monitor session"
#~ msgstr "监控" #~ msgstr "监控"
@@ -5032,9 +5055,6 @@ msgstr "旗舰版"
#~ msgid "Terminate success" #~ msgid "Terminate success"
#~ msgstr "终断成功" #~ msgstr "终断成功"
#~ msgid "Duration"
#~ msgstr "时长"
#~ msgid "Terminate selected" #~ msgid "Terminate selected"
#~ msgstr "终断所选" #~ msgstr "终断所选"
@@ -5809,9 +5829,6 @@ msgstr "旗舰版"
#~ msgid "Gather user plan" #~ msgid "Gather user plan"
#~ msgstr "收集用户计划" #~ msgstr "收集用户计划"
#~ msgid "Task update"
#~ msgstr "更新"
#~ msgid "Task create" #~ msgid "Task create"
#~ msgstr "创建" #~ msgstr "创建"

View File

@@ -21,7 +21,7 @@ class UserPermissionMixin:
obj = None obj = None
def initial(self, *args, **kwargs): def initial(self, *args, **kwargs):
super().initial(*args, *kwargs) super().initial(*args, **kwargs)
self.obj = self.get_obj() self.obj = self.get_obj()
def get_obj(self): def get_obj(self):

View File

@@ -55,21 +55,17 @@ class CommandQueryMixin:
q = self.request.query_params q = self.request.query_params
multi_command_storage = get_multi_command_storage() multi_command_storage = get_multi_command_storage()
queryset = multi_command_storage.filter( queryset = multi_command_storage.filter(
date_from=date_from, date_to=date_to, input=q.get("input"), date_from=date_from, date_to=date_to,
user=q.get("user"), asset=q.get("asset"), user=q.get("user"), asset=q.get("asset"), system_user=q.get("system_user"),
system_user=q.get("system_user"), input=q.get("input"), session=q.get("session_id"),
risk_level=self.get_query_risk_level(), org_id=self.get_org_id(), risk_level=self.get_query_risk_level(), org_id=self.get_org_id(),
) )
return queryset return queryset
def filter_queryset(self, queryset): def filter_queryset(self, queryset):
# 解决es存储命令时父类根据filter_fields过滤出现异常的问题返回的queryset类型list
return queryset return queryset
def get_filter_fields(self, request):
fields = self.filter_fields
fields.extend(["date_from", "date_to"])
return fields
def get_date_range(self): def get_date_range(self):
now = timezone.now() now = timezone.now()
days_ago = now - timezone.timedelta(days=self.default_days_ago) days_ago = now - timezone.timedelta(days=self.default_days_ago)

View File

@@ -16,7 +16,7 @@ class CommandBase(object):
@abc.abstractmethod @abc.abstractmethod
def filter(self, date_from=None, date_to=None, def filter(self, date_from=None, date_to=None,
user=None, asset=None, system_user=None, user=None, asset=None, system_user=None,
input=None, session=None): input=None, session=None, risk_level=None, org_id=None):
pass pass
@abc.abstractmethod @abc.abstractmethod

View File

@@ -5,8 +5,8 @@ import re
import pyotp import pyotp
import base64 import base64
import logging import logging
import time
from django.http import Http404
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.core.cache import cache from django.core.cache import cache
@@ -333,3 +333,15 @@ def get_source_choices():
if settings.AUTH_CAS: if settings.AUTH_CAS:
choices.append((User.SOURCE_CAS, choices_all[User.SOURCE_CAS])) choices.append((User.SOURCE_CAS, choices_all[User.SOURCE_CAS]))
return choices return choices
def is_auth_time_valid(session, key):
return True if session.get(key, 0) > time.time() else False
def is_auth_password_time_valid(session):
return is_auth_time_valid(session, 'auth_password_expired_at')
def is_auth_otp_time_valid(session):
return is_auth_time_valid(session, 'auth_opt_expired_at')

View File

@@ -1,4 +1,5 @@
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
import time
from django.urls import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
@@ -6,13 +7,17 @@ from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from django.contrib.auth import logout as auth_logout from django.contrib.auth import logout as auth_logout
from django.conf import settings from django.conf import settings
from django.http.response import HttpResponseForbidden
from common.utils import get_logger from authentication.mixins import AuthMixin
from users.models import User
from common.utils import get_logger, get_object_or_none
from common.permissions import IsValidUser from common.permissions import IsValidUser
from ... import forms from ... import forms
from .password import UserVerifyPasswordView from .password import UserVerifyPasswordView
from ...utils import ( from ...utils import (
generate_otp_uri, check_otp_code, get_user_or_pre_auth_user, generate_otp_uri, check_otp_code, get_user_or_pre_auth_user,
is_auth_password_time_valid, is_auth_otp_time_valid
) )
__all__ = [ __all__ = [
@@ -46,11 +51,50 @@ class UserOtpEnableInstallAppView(TemplateView):
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
class UserOtpEnableBindView(TemplateView, FormView): class UserOtpEnableBindView(AuthMixin, TemplateView, FormView):
template_name = 'users/user_otp_enable_bind.html' template_name = 'users/user_otp_enable_bind.html'
form_class = forms.UserCheckOtpCodeForm form_class = forms.UserCheckOtpCodeForm
success_url = reverse_lazy('authentication:user-otp-settings-success') success_url = reverse_lazy('authentication:user-otp-settings-success')
def get(self, request, *args, **kwargs):
if self._check_can_bind():
return super().get(request, *args, **kwargs)
return HttpResponseForbidden()
def post(self, request, *args, **kwargs):
if self._check_can_bind():
return super().post(request, *args, **kwargs)
return HttpResponseForbidden()
def _check_authenticated_user_can_bind(self):
user = self.request.user
session = self.request.session
if not user.mfa_enabled:
return is_auth_password_time_valid(session)
if not user.otp_secret_key:
return is_auth_password_time_valid(session)
return is_auth_otp_time_valid(session)
def _check_unauthenticated_user_can_bind(self):
session_user = None
if not self.request.session.is_empty():
user_id = self.request.session.get('user_id')
session_user = get_object_or_none(User, pk=user_id)
if session_user:
if all((is_auth_password_time_valid(self.request.session), session_user.mfa_enabled, not session_user.otp_secret_key)):
return True
return False
def _check_can_bind(self):
if self.request.user.is_authenticated:
return self._check_authenticated_user_can_bind()
else:
return self._check_unauthenticated_user_can_bind()
def form_valid(self, form): def form_valid(self, form):
otp_code = form.cleaned_data.get('otp_code') otp_code = form.cleaned_data.get('otp_code')
otp_secret_key = self.request.session.get('otp_secret_key', '') otp_secret_key = self.request.session.get('otp_secret_key', '')
@@ -116,6 +160,7 @@ class UserOtpUpdateView(FormView):
valid = user.check_mfa(otp_code) valid = user.check_mfa(otp_code)
if valid: if valid:
self.request.session['auth_opt_expired_at'] = time.time() + settings.AUTH_EXPIRED_SECONDS
return super().form_valid(form) return super().form_valid(form)
else: else:
error = _('MFA code invalid, or ntp sync server time') error = _('MFA code invalid, or ntp sync server time')

View File

@@ -1,8 +1,10 @@
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
import time
from django.conf import settings
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.shortcuts import redirect from django.shortcuts import redirect
from django.urls import reverse_lazy, reverse from django.urls import reverse_lazy
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.generic.edit import UpdateView, FormView from django.views.generic.edit import UpdateView, FormView
from django.contrib.auth import logout as auth_logout from django.contrib.auth import logout as auth_logout
@@ -76,6 +78,7 @@ class UserVerifyPasswordView(FormView):
user.save() user.save()
self.request.session['user_id'] = str(user.id) self.request.session['user_id'] = str(user.id)
self.request.session['auth_password'] = 1 self.request.session['auth_password'] = 1
self.request.session['auth_password_expired_at'] = time.time() + settings.AUTH_EXPIRED_SECONDS
return redirect(self.get_success_url()) return redirect(self.get_success_url())
def get_success_url(self): def get_success_url(self):

View File

@@ -1,11 +0,0 @@
#!/bin/bash
#
version=$1
if [ -z "$version" ];then
echo "Usage: sh build version"
exit
fi
docker build -t jumpserver/jumpserver:$version .

View File

@@ -61,7 +61,7 @@ pytz==2018.3
PyYAML==5.1 PyYAML==5.1
redis==3.2.0 redis==3.2.0
requests==2.22.0 requests==2.22.0
jms-storage==0.0.29 jms-storage==0.0.31
s3transfer==0.3.3 s3transfer==0.3.3
simplejson==3.13.2 simplejson==3.13.2
six==1.11.0 six==1.11.0

32
utils/build.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
#
# 该build基于registry.fit2cloud.com/public/python:3
utils_dir=$(pwd)
project_dir=$(dirname "$utils_dir")
release_dir=${project_dir}/release
# 打包
cd "${project_dir}" || exit 3
rm -rf "${release_dir:?}"/*
to_dir="${release_dir}/jumpserver"
mkdir -p "${to_dir}"
if [[ -d '.git' ]];then
command -v git || yum -y install git
git archive --format tar HEAD | tar x -C "${to_dir}"
else
cp -R . /tmp/jumpserver
mv /tmp/jumpserver/* "${to_dir}"
fi
if [[ $(uname) == 'Darwin' ]];then
alias sedi="sed -i ''"
else
alias sedi='sed -i'
fi
# 修改版本号文件
if [[ -n ${VERSION} ]]; then
sedi "s@VERSION = .*@VERSION = \"${VERSION}\"@g" "${to_dir}/apps/jumpserver/const.py"
fi

12
utils/build_docker.sh Normal file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
#
utils_dir=$(dirname "$0")
project_dir=$(dirname "${utils_dir}")
version=$1
if [ -z "$version" ]; then
echo "Usage: sh build version"
exit
fi
cd "${project_dir}" && docker build -t "jumpserver/jumpserver:${version}" .

26
utils/example_api.py Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env python
import requests
# 私有token页面上目前不允许创建只能后台生成见 https://docs.jumpserver.org/zh/master/dev/rest_api/
private_token = '10659d70a223235b8f76d45a3023eca1147488d7'
def do_request(url, data=None, method='get', params=None, org_id=''):
authorization = 'Token {}'.format(private_token)
headers = {'Authorization': authorization, 'Content-Type': 'application/json'}
if org_id:
headers['X-JMS-ORG'] = org_id
resp = requests.request(method=method, url=url, data=data, params=params, headers=headers)
return resp
def get_assets_list():
url = 'http://localhost:8080/api/v1/assets/assets/?limit=10'
resp = do_request(url)
print(resp.status_code)
print(resp.json())
print(resp)
if __name__ == '__main__':
get_assets_list()