mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-14 16:12:34 +00:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32aecb79c4 | ||
|
|
5afc1c7889 | ||
|
|
4fe62f1c15 | ||
|
|
4af75ff584 | ||
|
|
91f6614711 | ||
|
|
e617245b26 | ||
|
|
9280884c1c | ||
|
|
f31994fdcd | ||
|
|
71766418bb | ||
|
|
a9399dd709 | ||
|
|
d0cb9e5432 | ||
|
|
558188da90 | ||
|
|
ad5460dab8 | ||
|
|
4d37dca0de | ||
|
|
2ca4002624 | ||
|
|
053d640e4c | ||
|
|
f3acc28ded | ||
|
|
25987545db | ||
|
|
6720ecc6e0 | ||
|
|
0b3a7bb020 | ||
|
|
56373e362b | ||
|
|
02fc045370 | ||
|
|
e4ac73896f | ||
|
|
1518f792d6 | ||
|
|
67277dd622 | ||
|
|
82e7f020ea | ||
|
|
f20b9e01ab | ||
|
|
8cf8a3701b | ||
|
|
7ba24293d1 | ||
|
|
f10114c9ed | ||
|
|
cf31cbfb07 | ||
|
|
0edad24d5d | ||
|
|
1f1c1a9157 | ||
|
|
6c9d271ae1 | ||
|
|
6ff852e225 | ||
|
|
baa75dc735 | ||
|
|
8a9f0436b8 | ||
|
|
a9620a3cbe | ||
|
|
769e7dc8a0 | ||
|
|
2a70449411 | ||
|
|
8df720f19e | ||
|
|
dabbb45f6e | ||
|
|
ce24c1c3fd | ||
|
|
3c54c82ce9 |
@@ -362,6 +362,7 @@ class ConnectionTokenViewSet(AuthFaceMixin, ExtraActionApiMixin, RootOrgViewMixi
|
||||
self.validate_serializer(serializer)
|
||||
return super().perform_create(serializer)
|
||||
|
||||
|
||||
def _insert_connect_options(self, data, user):
|
||||
connect_options = data.pop('connect_options', {})
|
||||
default_name_opts = {
|
||||
@@ -564,7 +565,9 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
|
||||
rbac_perms = {
|
||||
'create': 'authentication.add_superconnectiontoken',
|
||||
'renewal': 'authentication.add_superconnectiontoken',
|
||||
'list': 'authentication.view_superconnectiontoken',
|
||||
'check': 'authentication.view_superconnectiontoken',
|
||||
'retrieve': 'authentication.view_superconnectiontoken',
|
||||
'get_secret_detail': 'authentication.view_superconnectiontokensecret',
|
||||
'get_applet_info': 'authentication.view_superconnectiontoken',
|
||||
'release_applet_account': 'authentication.view_superconnectiontoken',
|
||||
@@ -572,7 +575,12 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
return ConnectionToken.objects.all()
|
||||
return ConnectionToken.objects.none()
|
||||
|
||||
def get_object(self):
|
||||
pk = self.kwargs.get(self.lookup_field)
|
||||
token = get_object_or_404(ConnectionToken, pk=pk)
|
||||
return token
|
||||
|
||||
def get_user(self, serializer):
|
||||
return serializer.validated_data.get('user')
|
||||
|
||||
@@ -18,7 +18,7 @@ urlpatterns = [
|
||||
path('login/guard/', views.UserLoginGuardView.as_view(), name='login-guard'),
|
||||
path('logout/', views.UserLogoutView.as_view(), name='logout'),
|
||||
|
||||
# 原来在users中的
|
||||
# 原来在 users 中的
|
||||
path('password/forget/previewing/', users_view.UserForgotPasswordPreviewingView.as_view(),
|
||||
name='forgot-previewing'),
|
||||
path('password/forgot/', users_view.UserForgotPasswordView.as_view(), name='forgot-password'),
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from django.conf import settings
|
||||
from typing import Callable
|
||||
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.throttling import UserRateThrottle
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
|
||||
@@ -14,8 +16,12 @@ from orgs.utils import current_org
|
||||
__all__ = ['SuggestionMixin', 'RenderToJsonMixin']
|
||||
|
||||
|
||||
class CustomUserRateThrottle(UserRateThrottle):
|
||||
rate = '60/m'
|
||||
|
||||
|
||||
class SuggestionMixin:
|
||||
suggestion_limit = 10
|
||||
suggestion_limit = settings.SUGGESTION_LIMIT
|
||||
|
||||
filter_queryset: Callable
|
||||
get_queryset: Callable
|
||||
@@ -35,6 +41,7 @@ class SuggestionMixin:
|
||||
queryset = queryset.none()
|
||||
|
||||
queryset = self.filter_queryset(queryset)
|
||||
|
||||
queryset = queryset[:self.suggestion_limit]
|
||||
page = self.paginate_queryset(queryset)
|
||||
|
||||
@@ -45,6 +52,11 @@ class SuggestionMixin:
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
def get_throttles(self):
|
||||
if self.action == 'match':
|
||||
return [CustomUserRateThrottle()]
|
||||
return super().get_throttles()
|
||||
|
||||
|
||||
class RenderToJsonMixin:
|
||||
@action(methods=[POST, PUT], detail=False, url_path='render-to-json')
|
||||
|
||||
@@ -729,6 +729,9 @@ class Config(dict):
|
||||
'LOKI_BASE_URL': 'http://loki:3100',
|
||||
|
||||
'TOOL_USER_ENABLED': False,
|
||||
|
||||
# Suggestion api
|
||||
'SUGGESTION_LIMIT': 10,
|
||||
}
|
||||
|
||||
old_config_map = {
|
||||
|
||||
@@ -266,3 +266,5 @@ LOKI_LOG_ENABLED = CONFIG.LOKI_LOG_ENABLED
|
||||
LOKI_BASE_URL = CONFIG.LOKI_BASE_URL
|
||||
|
||||
TOOL_USER_ENABLED = CONFIG.TOOL_USER_ENABLED
|
||||
|
||||
SUGGESTION_LIMIT = CONFIG.SUGGESTION_LIMIT
|
||||
@@ -24,5 +24,7 @@ class OrgMixin:
|
||||
|
||||
@sync_to_async
|
||||
def has_perms(self, user, perms):
|
||||
self.cookie = self.get_cookie()
|
||||
self.org = self.get_current_org()
|
||||
with tmp_to_org(self.org):
|
||||
return user.has_perms(perms)
|
||||
|
||||
@@ -56,8 +56,6 @@ class ToolsWebsocket(AsyncJsonWebsocketConsumer, OrgMixin):
|
||||
async def connect(self):
|
||||
user = self.scope["user"]
|
||||
if user.is_authenticated:
|
||||
self.cookie = self.get_cookie()
|
||||
self.org = self.get_current_org()
|
||||
has_perm = self.has_perms(user, ['rbac.view_systemtools'])
|
||||
if await self.is_superuser(user) or (settings.TOOL_USER_ENABLED and has_perm):
|
||||
await self.accept()
|
||||
@@ -128,14 +126,14 @@ class ToolsWebsocket(AsyncJsonWebsocketConsumer, OrgMixin):
|
||||
close_old_connections()
|
||||
|
||||
|
||||
class LdapWebsocket(AsyncJsonWebsocketConsumer):
|
||||
class LdapWebsocket(AsyncJsonWebsocketConsumer, OrgMixin):
|
||||
category: str
|
||||
|
||||
async def connect(self):
|
||||
user = self.scope["user"]
|
||||
query = parse_qs(self.scope['query_string'].decode())
|
||||
self.category = query.get('category', [User.Source.ldap.value])[0]
|
||||
if user.is_authenticated:
|
||||
if user.is_authenticated and await self.has_perms(user, ['settings.view_setting']):
|
||||
await self.accept()
|
||||
else:
|
||||
await self.close()
|
||||
@@ -166,8 +164,6 @@ class LdapWebsocket(AsyncJsonWebsocketConsumer):
|
||||
config = {
|
||||
'server_uri': serializer.validated_data.get(f"{prefix}SERVER_URI"),
|
||||
'bind_dn': serializer.validated_data.get(f"{prefix}BIND_DN"),
|
||||
'password': (serializer.validated_data.get(f"{prefix}BIND_PASSWORD") or
|
||||
getattr(settings, f"{prefix}BIND_PASSWORD")),
|
||||
'use_ssl': serializer.validated_data.get(f"{prefix}START_TLS", False),
|
||||
'search_ou': serializer.validated_data.get(f"{prefix}SEARCH_OU"),
|
||||
'search_filter': serializer.validated_data.get(f"{prefix}SEARCH_FILTER"),
|
||||
@@ -175,6 +171,12 @@ class LdapWebsocket(AsyncJsonWebsocketConsumer):
|
||||
'auth_ldap': serializer.validated_data.get(f"{prefix.rstrip('_')}", False)
|
||||
}
|
||||
|
||||
password = serializer.validated_data.get(f"{prefix}BIND_PASSWORD")
|
||||
if not password and config['server_uri'] == getattr(settings, f"{prefix}SERVER_URI"):
|
||||
# 只有在没有修改服务器地址的情况下,才使用原有的密码
|
||||
config['password'] = getattr(settings, f"{prefix}BIND_PASSWORD")
|
||||
else:
|
||||
config['password'] = password
|
||||
return config
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -41,8 +41,8 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, SuggestionMixin, BulkModelV
|
||||
permission_classes = [RBACPermission, UserObjectPermission]
|
||||
serializer_classes = {
|
||||
'default': UserSerializer,
|
||||
'suggestion': MiniUserSerializer,
|
||||
'invite': InviteSerializer,
|
||||
'match': MiniUserSerializer,
|
||||
'retrieve': UserRetrieveSerializer,
|
||||
}
|
||||
rbac_perms = {
|
||||
|
||||
Reference in New Issue
Block a user