mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-15 00:25:16 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eba7a7288a | ||
|
|
bd11018cef | ||
|
|
8a2b0a7845 | ||
|
|
b3dbdd5389 | ||
|
|
a4643fe4b4 | ||
|
|
dce9b50ac0 | ||
|
|
e2b7c902a5 | ||
|
|
4055306cf8 | ||
|
|
9e1c5bb64d | ||
|
|
32df722e9d | ||
|
|
22f6f5c34c | ||
|
|
6fb819ca53 | ||
|
|
043c4a7a0b |
@@ -113,7 +113,7 @@ class AuthMixin:
|
||||
if self.public_key:
|
||||
public_key = self.public_key
|
||||
elif self.private_key:
|
||||
public_key = ssh_pubkey_gen(self.private_key, self.password)
|
||||
public_key = ssh_pubkey_gen(private_key=self.private_key, password=self.password)
|
||||
else:
|
||||
return ''
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ reason_choices = {
|
||||
reason_user_invalid: _('Disabled or expired'),
|
||||
reason_user_inactive: _("This account is inactive."),
|
||||
reason_backend_not_match: _("Auth backend not match"),
|
||||
reason_acl_not_allow: _("ACL is not allowed")
|
||||
reason_acl_not_allow: _("Login IP is not allowed")
|
||||
}
|
||||
old_reason_choices = {
|
||||
'0': '-',
|
||||
|
||||
@@ -55,6 +55,9 @@ class UserLoginView(mixins.AuthMixin, FormView):
|
||||
def form_valid(self, form):
|
||||
if not self.request.session.test_cookie_worked():
|
||||
return HttpResponse(_("Please enable cookies and try again."))
|
||||
# https://docs.djangoproject.com/en/3.1/topics/http/sessions/#setting-test-cookies
|
||||
self.request.session.delete_test_cookie()
|
||||
|
||||
try:
|
||||
self.check_user_auth(decrypt_passwd=True)
|
||||
except errors.AuthFailedError as e:
|
||||
@@ -66,6 +69,7 @@ class UserLoginView(mixins.AuthMixin, FormView):
|
||||
new_form = form_cls(data=form.data)
|
||||
new_form._errors = form.errors
|
||||
context = self.get_context_data(form=new_form)
|
||||
self.request.session.set_test_cookie()
|
||||
return self.render_to_response(context)
|
||||
except (errors.PasswdTooSimple, errors.PasswordRequireResetError) as e:
|
||||
return redirect(e.url)
|
||||
|
||||
Binary file not shown.
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-19 14:34+0800\n"
|
||||
"POT-Creation-Date: 2021-03-22 14:42+0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||
@@ -428,7 +428,7 @@ msgstr "激活"
|
||||
|
||||
#: assets/models/asset.py:196 assets/models/cluster.py:19
|
||||
#: assets/models/user.py:66 templates/_nav.html:44
|
||||
#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers.py:138
|
||||
#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers.py:137
|
||||
msgid "Admin user"
|
||||
msgstr "管理用户"
|
||||
|
||||
@@ -693,7 +693,7 @@ msgstr "ssh私钥"
|
||||
#: users/templates/users/user_asset_permission.html:41
|
||||
#: users/templates/users/user_asset_permission.html:73
|
||||
#: users/templates/users/user_asset_permission.html:158
|
||||
#: xpack/plugins/cloud/models.py:89 xpack/plugins/cloud/serializers.py:139
|
||||
#: xpack/plugins/cloud/models.py:89 xpack/plugins/cloud/serializers.py:138
|
||||
msgid "Node"
|
||||
msgstr "节点"
|
||||
|
||||
@@ -1140,7 +1140,7 @@ msgstr "启用"
|
||||
msgid "-"
|
||||
msgstr ""
|
||||
|
||||
#: audits/models.py:96 xpack/plugins/cloud/const.py:24
|
||||
#: audits/models.py:96 xpack/plugins/cloud/const.py:23
|
||||
msgid "Failed"
|
||||
msgstr "失败"
|
||||
|
||||
@@ -1331,8 +1331,8 @@ msgid "Auth backend not match"
|
||||
msgstr "没有匹配到认证后端"
|
||||
|
||||
#: authentication/errors.py:34
|
||||
msgid "ACL is not allowed"
|
||||
msgstr "ACL 不被允许"
|
||||
msgid "Login IP is not allowed"
|
||||
msgstr "登录 IP 不被允许"
|
||||
|
||||
#: authentication/errors.py:44
|
||||
msgid "No session found, check your cookie"
|
||||
@@ -2249,7 +2249,7 @@ msgstr "全局启用 MFA 认证"
|
||||
|
||||
#: settings/serializers/settings.py:133
|
||||
msgid "All user enable MFA"
|
||||
msgstr "强制每个启用多因子认证"
|
||||
msgstr "强制所有用户启用多因子认证"
|
||||
|
||||
#: settings/serializers/settings.py:136
|
||||
msgid "Batch command execution"
|
||||
@@ -3784,7 +3784,7 @@ msgstr "安全令牌验证"
|
||||
|
||||
#: users/templates/users/_base_otp.html:14 users/templates/users/_user.html:13
|
||||
#: users/templates/users/user_profile_update.html:55
|
||||
#: xpack/plugins/cloud/models.py:78 xpack/plugins/cloud/serializers.py:137
|
||||
#: xpack/plugins/cloud/models.py:78 xpack/plugins/cloud/serializers.py:136
|
||||
msgid "Account"
|
||||
msgstr "账户"
|
||||
|
||||
@@ -4774,46 +4774,42 @@ msgid "Azure (China)"
|
||||
msgstr "Azure (中国)"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:12
|
||||
msgid "Azure (International)"
|
||||
msgstr "Azure (国际)"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:13
|
||||
msgid "Huawei Cloud"
|
||||
msgstr "华为云"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:14
|
||||
#: xpack/plugins/cloud/const.py:13
|
||||
msgid "Tencent Cloud"
|
||||
msgstr "腾讯云"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:15
|
||||
#: xpack/plugins/cloud/const.py:14
|
||||
msgid "VMware"
|
||||
msgstr ""
|
||||
|
||||
#: xpack/plugins/cloud/const.py:19
|
||||
#: xpack/plugins/cloud/const.py:18
|
||||
msgid "Instance name"
|
||||
msgstr "实例名称"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:20
|
||||
#: xpack/plugins/cloud/const.py:19
|
||||
msgid "Instance name and Partial IP"
|
||||
msgstr "实例名称和部分IP"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:25
|
||||
#: xpack/plugins/cloud/const.py:24
|
||||
msgid "Succeed"
|
||||
msgstr "成功"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:29
|
||||
#: xpack/plugins/cloud/const.py:28
|
||||
msgid "Unsync"
|
||||
msgstr "未同步"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:30
|
||||
#: xpack/plugins/cloud/const.py:29
|
||||
msgid "New Sync"
|
||||
msgstr "新同步"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:31
|
||||
#: xpack/plugins/cloud/const.py:30
|
||||
msgid "Synced"
|
||||
msgstr "已同步"
|
||||
|
||||
#: xpack/plugins/cloud/const.py:32
|
||||
#: xpack/plugins/cloud/const.py:31
|
||||
msgid "Released"
|
||||
msgstr "已释放"
|
||||
|
||||
@@ -4829,7 +4825,7 @@ msgstr "云服务商"
|
||||
msgid "Cloud account"
|
||||
msgstr "云账号"
|
||||
|
||||
#: xpack/plugins/cloud/models.py:81 xpack/plugins/cloud/serializers.py:118
|
||||
#: xpack/plugins/cloud/models.py:81 xpack/plugins/cloud/serializers.py:117
|
||||
msgid "Regions"
|
||||
msgstr "地域"
|
||||
|
||||
@@ -4837,7 +4833,7 @@ msgstr "地域"
|
||||
msgid "Hostname strategy"
|
||||
msgstr "主机名策略"
|
||||
|
||||
#: xpack/plugins/cloud/models.py:95 xpack/plugins/cloud/serializers.py:141
|
||||
#: xpack/plugins/cloud/models.py:95 xpack/plugins/cloud/serializers.py:140
|
||||
msgid "Always update"
|
||||
msgstr "总是更新"
|
||||
|
||||
@@ -5029,15 +5025,15 @@ msgstr ""
|
||||
msgid "Subscription ID"
|
||||
msgstr ""
|
||||
|
||||
#: xpack/plugins/cloud/serializers.py:116
|
||||
#: xpack/plugins/cloud/serializers.py:115
|
||||
msgid "History count"
|
||||
msgstr "执行次数"
|
||||
|
||||
#: xpack/plugins/cloud/serializers.py:117
|
||||
#: xpack/plugins/cloud/serializers.py:116
|
||||
msgid "Instance count"
|
||||
msgstr "实例个数"
|
||||
|
||||
#: xpack/plugins/cloud/serializers.py:140
|
||||
#: xpack/plugins/cloud/serializers.py:139
|
||||
#: xpack/plugins/gathered_user/serializers.py:20
|
||||
msgid "Periodic display"
|
||||
msgstr "定时执行"
|
||||
@@ -5130,6 +5126,9 @@ msgstr "旗舰版"
|
||||
msgid "Community edition"
|
||||
msgstr "社区版"
|
||||
|
||||
#~ msgid "Azure (International)"
|
||||
#~ msgstr "Azure (国际)"
|
||||
|
||||
#~ msgid "Root organization only allow view and delete"
|
||||
#~ msgstr "全局组织仅支持 查看和删除"
|
||||
|
||||
|
||||
@@ -90,6 +90,11 @@ class OrgMemberRelationBulkViewSet(JMSBulkRelationModelViewSet):
|
||||
filterset_class = OrgMemberRelationFilterSet
|
||||
search_fields = ('user__name', 'user__username', 'org__name')
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset()
|
||||
queryset = queryset.exclude(user__role=User.ROLE.APP)
|
||||
return queryset
|
||||
|
||||
def perform_bulk_destroy(self, queryset):
|
||||
objs = list(queryset.all().prefetch_related('user', 'org'))
|
||||
queryset.delete()
|
||||
|
||||
@@ -488,11 +488,12 @@ class UserGrantedAssetsQueryUtils(UserGrantedUtilsBase):
|
||||
|
||||
if granted_status == NodeFrom.granted:
|
||||
assets = Asset.objects.order_by().filter(nodes__id=node.id)
|
||||
return assets
|
||||
elif granted_status == NodeFrom.asset:
|
||||
return self._get_indirect_granted_node_assets(node.id)
|
||||
assets = self._get_indirect_granted_node_assets(node.id)
|
||||
else:
|
||||
return Asset.objects.none()
|
||||
assets = Asset.objects.none()
|
||||
assets = assets.order_by('hostname')
|
||||
return assets
|
||||
|
||||
def _get_indirect_granted_node_assets(self, id) -> AssetQuerySet:
|
||||
assets = Asset.objects.order_by().filter(nodes__id=id).distinct() & self.get_direct_granted_assets()
|
||||
@@ -538,6 +539,10 @@ class UserGrantedAssetsQueryUtils(UserGrantedUtilsBase):
|
||||
|
||||
|
||||
class UserGrantedNodesQueryUtils(UserGrantedUtilsBase):
|
||||
def sort(self, nodes):
|
||||
nodes = sorted(nodes, key=lambda x: x.value)
|
||||
return nodes
|
||||
|
||||
def get_node_children(self, key):
|
||||
if not key:
|
||||
return self.get_top_level_nodes()
|
||||
@@ -545,11 +550,13 @@ class UserGrantedNodesQueryUtils(UserGrantedUtilsBase):
|
||||
node = PermNode.objects.get(key=key)
|
||||
granted_status = node.get_granted_status(self.user)
|
||||
if granted_status == NodeFrom.granted:
|
||||
return PermNode.objects.filter(parent_key=key)
|
||||
nodes = PermNode.objects.filter(parent_key=key)
|
||||
elif granted_status in (NodeFrom.asset, NodeFrom.child):
|
||||
return self.get_indirect_granted_node_children(key)
|
||||
nodes = self.get_indirect_granted_node_children(key)
|
||||
else:
|
||||
return PermNode.objects.none()
|
||||
nodes = PermNode.objects.none()
|
||||
nodes = self.sort(nodes)
|
||||
return nodes
|
||||
|
||||
def get_indirect_granted_node_children(self, key):
|
||||
"""
|
||||
@@ -571,7 +578,8 @@ class UserGrantedNodesQueryUtils(UserGrantedUtilsBase):
|
||||
|
||||
def get_top_level_nodes(self):
|
||||
nodes = self.get_special_nodes()
|
||||
nodes.extend(self.get_indirect_granted_node_children(''))
|
||||
real_nodes = self.get_indirect_granted_node_children('')
|
||||
nodes.extend(self.sort(real_nodes))
|
||||
return nodes
|
||||
|
||||
def get_ungrouped_node(self):
|
||||
|
||||
18
apps/terminal/migrations/0033_auto_20210324_1008.py
Normal file
18
apps/terminal/migrations/0033_auto_20210324_1008.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.1 on 2021-03-24 02:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('terminal', '0032_auto_20210302_1853'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='session',
|
||||
name='login_from',
|
||||
field=models.CharField(choices=[('ST', 'SSH Terminal'), ('RT', 'RDP Terminal'), ('WT', 'Web Terminal')], default='ST', max_length=2, verbose_name='Login from'),
|
||||
),
|
||||
]
|
||||
@@ -20,6 +20,7 @@ from .terminal import Terminal
|
||||
class Session(OrgModelMixin):
|
||||
class LOGIN_FROM(ChoiceSet):
|
||||
ST = 'ST', 'SSH Terminal'
|
||||
RT = 'RT', 'RDP Terminal'
|
||||
WT = 'WT', 'Web Terminal'
|
||||
|
||||
class PROTOCOL(ChoiceSet):
|
||||
|
||||
@@ -182,7 +182,6 @@ class CommandStorageTypeESSerializer(serializers.Serializer):
|
||||
)
|
||||
DOC_TYPE = ReadableHiddenField(default='command', label=_('Doc type'), allow_null=True)
|
||||
|
||||
|
||||
# mapping
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user