* fix: token 系统用户增加 protocol

* fix: 修复清除orphan session时同时清除对应的 session_task

* perf: 修改 connection token api

* fix: 修复无法获取系统角色绑定的问题

* perf: 增加 db terminal 及 magnus 组件

* perf: 修改 migrations

* fix: 修复AUTHENTICATION_BACKENDS相关的逻辑

* fix: 修改判断backend认证逻辑

* fix: 修复资产账号查看密码跳过mfa

* fix: 修复用户组授权权限错误

* feat: 支持COS对象存储

* feat: 升级依赖 jms_storage==0.0.42

* fix: 修复 koko api 问题

* feat: 修改存储翻译信息

* perf: 修改 ticket 权限

* fix: 修复获取资产授权系统用户 get_queryset

* perf: 抽取 ticket

* perf: 修改 cmd filter 的权限

* fix: 修改 ticket perm

* fix: 修复oidc依赖问题

Co-authored-by: Eric <xplzv@126.com>
Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: 小冯 <xiaofeng@xiaofengdeMacBook-Pro.local>
Co-authored-by: feng626 <1304903146@qq.com>
This commit is contained in:
Jiangjie.Bai
2022-02-28 19:28:58 +08:00
committed by GitHub
parent edfca5eb24
commit 03afa4f974
33 changed files with 294 additions and 205 deletions

View File

@@ -105,7 +105,7 @@ class ClientProtocolMixin:
width = self.request.query_params.get('width')
full_screen = is_true(self.request.query_params.get('full_screen'))
drives_redirect = is_true(self.request.query_params.get('drives_redirect'))
token = self.create_token(user, asset, application, system_user)
token, secret = self.create_token(user, asset, application, system_user)
# 设置磁盘挂载
if drives_redirect:
@@ -381,15 +381,15 @@ class UserConnectionTokenViewSet(
key = self.CACHE_KEY_PREFIX.format(token)
cache.set(key, value, timeout=ttl)
return token
return token, secret
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
asset, application, system_user, user = self.get_request_resource(serializer)
token = self.create_token(user, asset, application, system_user)
return Response({"token": token}, status=201)
token, secret = self.create_token(user, asset, application, system_user)
return Response({"id": token, 'secret': secret}, status=201)
def valid_token(self, token):
from users.models import User

View File

@@ -17,32 +17,35 @@ class JMSBaseAuthBackend:
def has_perm(self, user_obj, perm, obj=None):
return False
# can authenticate
def username_can_authenticate(self, username):
return self.allow_authenticate(username=username)
def user_can_authenticate(self, user):
if not self.allow_authenticate(user=user):
return False
"""
Reject users with is_valid=False. Custom user models that don't have
that attribute are allowed.
"""
is_valid = getattr(user, 'is_valid', None)
return is_valid or is_valid is None
@property
def backend_path(self):
return f'{self.__module__}.{self.__class__.__name__}'
# allow user to authenticate
def username_allow_authenticate(self, username):
return self.allow_authenticate(username=username)
def user_allow_authenticate(self, user):
return self.allow_authenticate(user=user)
def allow_authenticate(self, user=None, username=None):
if user:
allowed_backends = user.get_allowed_auth_backends()
allowed_backend_paths = user.get_allowed_auth_backend_paths()
else:
allowed_backends = User.get_user_allowed_auth_backends(username)
if allowed_backends is None:
allowed_backend_paths = User.get_user_allowed_auth_backend_paths(username)
if allowed_backend_paths is None:
# 特殊值 None 表示没有限制
return True
allow = self.backend_path in allowed_backends
backend_name = self.__class__.__name__
allowed_backend_names = [path.split('.')[-1] for path in allowed_backend_paths]
allow = backend_name in allowed_backend_names
if not allow:
info = 'User {} skip authentication backend {}, because it not in {}'
info = info.format(username, self.backend_path, ','.join(allowed_backends))
info = info.format(username, backend_name, ','.join(allowed_backend_names))
logger.debug(info)
return allow

View File

@@ -3,3 +3,4 @@
# 保证 utils 中的模块进行初始化
from . import utils
from .backends import *

View File

@@ -0,0 +1 @@
from .backends import *

View File

@@ -28,6 +28,8 @@ from .signals import (
logger = get_logger(__file__)
__all__ = ['OIDCAuthCodeBackend', 'OIDCAuthPasswordBackend']
class UserMixin:

View File

@@ -1,2 +1,4 @@
# -*- coding: utf-8 -*-
#
from .backends import *

View File

@@ -57,8 +57,8 @@ def authenticate(request=None, **credentials):
username = credentials.get('username')
for backend, backend_path in _get_backends(return_tuples=True):
# 预先检查,不浪费认证时间
if not backend.username_can_authenticate(username):
# 检查用户名是否允许认证 (预先检查,不浪费认证时间)
if not backend.username_allow_authenticate(username):
continue
# 原生
@@ -76,8 +76,8 @@ def authenticate(request=None, **credentials):
if user is None:
continue
# 再次检查遇检查中遗漏的用户
if not backend.user_can_authenticate(user):
# 检查用户是否允许认证
if not backend.user_allow_authenticate(user):
continue
# Annotate the user object with the path of the backend.

View File

@@ -169,7 +169,7 @@ class ConnectionTokenAssetSerializer(serializers.ModelSerializer):
class ConnectionTokenSystemUserSerializer(serializers.ModelSerializer):
class Meta:
model = SystemUser
fields = ['id', 'name', 'username', 'password', 'private_key', 'ad_domain', 'org_id']
fields = ['id', 'name', 'username', 'password', 'private_key', 'protocol', 'ad_domain', 'org_id']
class ConnectionTokenGatewaySerializer(serializers.ModelSerializer):

View File

@@ -184,9 +184,7 @@ class UserLoginView(mixins.AuthMixin, FormView):
@staticmethod
def get_forgot_password_url():
forgot_password_url = reverse('authentication:forgot-password')
has_other_auth_backend = settings.AUTHENTICATION_BACKENDS[1] != settings.AUTH_BACKEND_MODEL
if has_other_auth_backend and settings.FORGOT_PASSWORD_URL:
forgot_password_url = settings.FORGOT_PASSWORD_URL
forgot_password_url = settings.FORGOT_PASSWORD_URL or forgot_password_url
return forgot_password_url
def get_context_data(self, **kwargs):