mirror of https://github.com/jumpserver/jumpserver
修改 terminal上报接口和api
parent
3639b190e3
commit
7f9ce57318
|
@ -1,22 +1,23 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import copy
|
import copy
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets, serializers
|
||||||
from rest_framework.views import APIView, Response
|
from rest_framework.views import APIView, Response
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from .models import Terminal, TerminalHeatbeat
|
from .models import Terminal, TerminalStatus, TerminalSession, TerminalTask
|
||||||
from .serializers import TerminalSerializer, TerminalHeatbeatSerializer
|
from .serializers import TerminalSerializer, TerminalStatusSerializer, \
|
||||||
|
TerminalSessionSerializer, TerminalTaskSerializer
|
||||||
from .hands import IsSuperUserOrAppUser, IsAppUser, ProxyLog, \
|
from .hands import IsSuperUserOrAppUser, IsAppUser, ProxyLog, \
|
||||||
IsSuperUserOrAppUserOrUserReadonly
|
IsSuperUserOrAppUserOrUserReadonly
|
||||||
from common.utils import get_object_or_none
|
from common.utils import get_object_or_none
|
||||||
|
|
||||||
|
|
||||||
class TerminalViewSet(viewsets.ModelViewSet):
|
class TerminalViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Terminal.objects.all()
|
queryset = Terminal.objects.filter(is_deleted=False)
|
||||||
serializer_class = TerminalSerializer
|
serializer_class = TerminalSerializer
|
||||||
permission_classes = (IsSuperUserOrAppUserOrUserReadonly,)
|
permission_classes = (IsSuperUserOrAppUserOrUserReadonly,)
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ class TerminalViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
terminal = serializer.save()
|
terminal = serializer.save()
|
||||||
app_user, access_key = terminal.create_related_app_user()
|
app_user, access_key = terminal.create_app_user()
|
||||||
data = OrderedDict()
|
data = OrderedDict()
|
||||||
data['terminal'] = copy.deepcopy(serializer.data)
|
data['terminal'] = copy.deepcopy(serializer.data)
|
||||||
data['user'] = app_user.to_json()
|
data['user'] = app_user.to_json()
|
||||||
|
@ -51,44 +52,86 @@ class TerminalViewSet(viewsets.ModelViewSet):
|
||||||
def get_permissions(self):
|
def get_permissions(self):
|
||||||
if self.action == "create":
|
if self.action == "create":
|
||||||
self.permission_classes = (AllowAny,)
|
self.permission_classes = (AllowAny,)
|
||||||
|
|
||||||
return super().get_permissions()
|
return super().get_permissions()
|
||||||
|
|
||||||
|
|
||||||
tasks = OrderedDict()
|
class TerminalStatusViewSet(viewsets.ModelViewSet):
|
||||||
# tasks = {1: [{'name': 'kill_proxy', 'proxy_log_id': 23}]}
|
queryset = TerminalStatus.objects.all()
|
||||||
|
serializer_class = TerminalStatusSerializer
|
||||||
|
permission_classes = (IsSuperUserOrAppUser,)
|
||||||
class TerminalHeatbeatViewSet(viewsets.ModelViewSet):
|
session_serializer_class = TerminalSessionSerializer
|
||||||
queryset = TerminalHeatbeat.objects.all()
|
|
||||||
serializer_class = TerminalHeatbeatSerializer
|
|
||||||
permission_classes = (IsAppUser,)
|
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
terminal = request.user.terminal
|
sessions_active = []
|
||||||
TerminalHeatbeat.objects.create(terminal=terminal)
|
for session_data in request.data.get("sessions", []):
|
||||||
task = tasks.get(terminal.name)
|
session_data["terminal"] = self.request.user.terminal.id
|
||||||
tasks[terminal.name] = []
|
_id = session_data["id"]
|
||||||
return Response({'msg': 'Success',
|
session = get_object_or_none(TerminalSession, id=_id)
|
||||||
'tasks': task},
|
if session:
|
||||||
status=201)
|
serializer = TerminalSessionSerializer(data=session_data, instance=session)
|
||||||
|
|
||||||
|
|
||||||
class TerminateConnectionView(APIView):
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
if isinstance(request.data, dict):
|
|
||||||
data = [request.data]
|
|
||||||
else:
|
|
||||||
data = request.data
|
|
||||||
for d in data:
|
|
||||||
proxy_log_id = d.get('proxy_log_id')
|
|
||||||
proxy_log = get_object_or_404(ProxyLog, id=proxy_log_id)
|
|
||||||
terminal_id = proxy_log.terminal
|
|
||||||
if terminal_id in tasks:
|
|
||||||
tasks[terminal_id].append({'name': 'kill_proxy',
|
|
||||||
'proxy_log_id': proxy_log_id})
|
|
||||||
else:
|
else:
|
||||||
tasks[terminal_id] = [{'name': 'kill_proxy',
|
serializer = TerminalSessionSerializer(data=session_data)
|
||||||
'proxy_log_id': proxy_log_id}]
|
|
||||||
|
|
||||||
return Response({'msg': 'get it'})
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
|
||||||
|
if session_data["is_finished"]:
|
||||||
|
sessions_active.append(session_data["id"])
|
||||||
|
|
||||||
|
sessions_in_db_active = TerminalSession.objects.filter(
|
||||||
|
is_finished=False, terminal=self.request.user.terminal.id
|
||||||
|
)
|
||||||
|
|
||||||
|
for session in sessions_in_db_active:
|
||||||
|
if session.id not in sessions_active:
|
||||||
|
session.is_finished = True
|
||||||
|
session.date_end = timezone.now()
|
||||||
|
session.save()
|
||||||
|
|
||||||
|
return super().create(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
terminal_id = self.kwargs.get("terminal", None)
|
||||||
|
if terminal_id:
|
||||||
|
terminal = get_object_or_404(Terminal, id=terminal_id)
|
||||||
|
self.queryset = terminal.terminalstatus_set.all()
|
||||||
|
return self.queryset
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
serializer.validated_data["terminal"] = self.request.user.terminal
|
||||||
|
return super().perform_create(serializer)
|
||||||
|
|
||||||
|
def get_permissions(self):
|
||||||
|
if self.action == "create":
|
||||||
|
self.permission_classes = (IsAppUser,)
|
||||||
|
return super().get_permissions()
|
||||||
|
|
||||||
|
|
||||||
|
class TerminalSessionViewSet(viewsets.ModelViewSet):
|
||||||
|
queryset = TerminalSession.objects.all()
|
||||||
|
serializers_class = TerminalSessionSerializer
|
||||||
|
permission_classes = (IsSuperUserOrAppUser,)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
terminal_id = self.kwargs.get("terminal", None)
|
||||||
|
if terminal_id:
|
||||||
|
terminal = get_object_or_404(Terminal, id=terminal_id)
|
||||||
|
self.queryset = terminal.terminalstatus_set.all()
|
||||||
|
return self.queryset
|
||||||
|
|
||||||
|
|
||||||
|
class TerminalTaskViewSet(viewsets.ModelViewSet):
|
||||||
|
queryset = TerminalTask.objects.all()
|
||||||
|
serializer_class = TerminalTaskSerializer
|
||||||
|
permission_classes = (IsSuperUserOrAppUser,)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
terminal_id = self.kwargs.get("terminal", None)
|
||||||
|
if terminal_id:
|
||||||
|
terminal = get_object_or_404(Terminal, id=terminal_id)
|
||||||
|
self.queryset = terminal.terminalstatus_set.all()
|
||||||
|
|
||||||
|
if hasattr(self.request.user, "terminal"):
|
||||||
|
terminal = self.request.user.terminal
|
||||||
|
self.queryset = terminal.terminalstatus_set.all()
|
||||||
|
return self.queryset
|
||||||
|
|
|
@ -13,6 +13,7 @@ class Terminal(models.Model):
|
||||||
http_port = models.IntegerField(verbose_name=_('HTTP Port'), default=5000)
|
http_port = models.IntegerField(verbose_name=_('HTTP Port'), default=5000)
|
||||||
user = models.OneToOneField(User, related_name='terminal', verbose_name='Application User', null=True, on_delete=models.CASCADE)
|
user = models.OneToOneField(User, related_name='terminal', verbose_name='Application User', null=True, on_delete=models.CASCADE)
|
||||||
is_accepted = models.BooleanField(default=False, verbose_name='Is Accepted')
|
is_accepted = models.BooleanField(default=False, verbose_name='Is Accepted')
|
||||||
|
is_deleted = models.BooleanField(default=False)
|
||||||
date_created = models.DateTimeField(auto_now_add=True)
|
date_created = models.DateTimeField(auto_now_add=True)
|
||||||
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ class Terminal(models.Model):
|
||||||
self.user.is_active = active
|
self.user.is_active = active
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
|
||||||
def create_related_app_user(self):
|
def create_app_user(self):
|
||||||
user, access_key = User.create_app_user(name=self.name, comment=self.comment)
|
user, access_key = User.create_app_user(name=self.name, comment=self.comment)
|
||||||
self.user = user
|
self.user = user
|
||||||
self.save()
|
self.save()
|
||||||
|
@ -37,19 +38,71 @@ class Terminal(models.Model):
|
||||||
def delete(self, using=None, keep_parents=False):
|
def delete(self, using=None, keep_parents=False):
|
||||||
if self.user:
|
if self.user:
|
||||||
self.user.delete()
|
self.user.delete()
|
||||||
return super(Terminal, self).delete(using=using, keep_parents=keep_parents)
|
self.is_deleted = True
|
||||||
|
self.save()
|
||||||
|
return
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
active = 'Active' if self.user and self.user.is_active else 'Disabled'
|
status = "Active"
|
||||||
return '%s: %s' % (self.name, active)
|
if not self.is_accepted:
|
||||||
|
status = "NotAccept"
|
||||||
|
elif self.is_deleted:
|
||||||
|
status = "Deleted"
|
||||||
|
elif not self.is_active:
|
||||||
|
status = "Disable"
|
||||||
|
return '%s: %s' % (self.name, status)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('is_accepted',)
|
ordering = ('is_accepted',)
|
||||||
|
|
||||||
|
|
||||||
class TerminalHeatbeat(models.Model):
|
class TerminalStatus(models.Model):
|
||||||
terminal = models.ForeignKey(Terminal, on_delete=models.CASCADE)
|
session_online = models.IntegerField(verbose_name=_("Session Online"), default=0)
|
||||||
|
cpu_used = models.FloatField(verbose_name=_("CPU Usage"))
|
||||||
|
memory_used = models.FloatField(verbose_name=_("Memory Used"))
|
||||||
|
connections = models.IntegerField(verbose_name=_("Connections"))
|
||||||
|
threads = models.IntegerField(verbose_name=_("Threads"))
|
||||||
|
boot_time = models.FloatField(verbose_name=_("Boot Time"))
|
||||||
|
terminal = models.ForeignKey(Terminal, null=True, on_delete=models.CASCADE)
|
||||||
date_created = models.DateTimeField(auto_now_add=True)
|
date_created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'terminal_heatbeat'
|
db_table = 'terminal_status'
|
||||||
|
|
||||||
|
# def __str__(self):
|
||||||
|
# return "<{} status>".format(self.terminal.name)
|
||||||
|
|
||||||
|
|
||||||
|
class TerminalSession(models.Model):
|
||||||
|
LOGIN_FROM_CHOICES = (
|
||||||
|
('ST', 'SSH Terminal'),
|
||||||
|
('WT', 'Web Terminal'),
|
||||||
|
)
|
||||||
|
|
||||||
|
id = models.UUIDField(primary_key=True)
|
||||||
|
user = models.CharField(max_length=128, verbose_name=_("User"))
|
||||||
|
asset = models.CharField(max_length=1024, verbose_name=_("Asset"))
|
||||||
|
system_user = models.CharField(max_length=128, verbose_name=_("System User"))
|
||||||
|
login_from = models.CharField(max_length=2, choices=LOGIN_FROM_CHOICES, default="ST")
|
||||||
|
is_finished = models.BooleanField(default=False)
|
||||||
|
terminal = models.IntegerField(null=True, verbose_name=_("Terminal"))
|
||||||
|
date_start = models.DateTimeField(verbose_name=_("Date Start"))
|
||||||
|
date_end = models.DateTimeField(verbose_name=_("Date End"), null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "terminal_session"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "{0.id} of {0.user} to {0.asset}".format(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TerminalTask(models.Model):
|
||||||
|
name = models.CharField(max_length=128, verbose_name=_("Name"))
|
||||||
|
args = models.CharField(max_length=1024, verbose_name=_("Task Args"))
|
||||||
|
terminal = models.ForeignKey(Terminal, null=True, on_delete=models.CASCADE)
|
||||||
|
is_finished = models.BooleanField(default=False)
|
||||||
|
date_created = models.DateTimeField(auto_now_add=True)
|
||||||
|
date_finished = models.DateTimeField(null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "terminal_task"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from .models import Terminal, TerminalHeatbeat
|
from .models import Terminal, TerminalStatus, TerminalSession, TerminalTask
|
||||||
from .hands import ProxyLog
|
from .hands import ProxyLog
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,8 +15,7 @@ class TerminalSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Terminal
|
model = Terminal
|
||||||
fields = ['id', 'name', 'remote_addr', 'http_port', 'ssh_port',
|
fields = ['id', 'name', 'remote_addr', 'http_port', 'ssh_port',
|
||||||
'comment', 'is_accepted',
|
'comment', 'is_accepted', 'session_connected', 'is_alive']
|
||||||
'session_connected', 'is_alive']
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_session_connected(obj):
|
def get_session_connected(obj):
|
||||||
|
@ -31,12 +30,22 @@ class TerminalSerializer(serializers.ModelSerializer):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class TerminalHeatbeatSerializer(serializers.ModelSerializer):
|
class TerminalSessionSerializer(serializers.ModelSerializer):
|
||||||
date_start = serializers.DateTimeField
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TerminalHeatbeat
|
model = TerminalSession
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class TerminalStatusSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
fields = '__all__'
|
||||||
|
model = TerminalStatus
|
||||||
|
|
||||||
|
|
||||||
|
class TerminalTaskSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
fields = '__all__'
|
||||||
|
model = TerminalTask
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from celery import shared_task
|
||||||
|
|
||||||
|
|
||||||
|
# Todo: 定期清理上报history
|
||||||
|
@shared_task
|
||||||
|
def clean_terminal_history():
|
||||||
|
pass
|
||||||
|
|
|
@ -10,12 +10,13 @@ from .. import api
|
||||||
app_name = 'applications'
|
app_name = 'applications'
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.register(r'v1/terminal/heatbeat', api.TerminalHeatbeatViewSet, 'terminal-heatbeat')
|
router.register(r'v1/terminal/(?P<terminal>[0-9]+)?/?status', api.TerminalStatusViewSet, 'terminal-status')
|
||||||
router.register(r'v1/terminal', api.TerminalViewSet, 'terminal')
|
router.register(r'v1/terminal/(?P<terminal>[0-9]+)?/?sessions', api.TerminalSessionViewSet, 'terminal-sessions')
|
||||||
|
router.register(r'v1/terminal$', api.TerminalViewSet, 'terminal')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^v1/terminate/connection/$', api.TerminateConnectionView.as_view(),
|
# url(r'^v1/terminate/connection/$', api.TerminateConnectionView.as_view(),
|
||||||
name='terminate-connection')
|
# name='terminate-connection')
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns += router.urls
|
urlpatterns += router.urls
|
||||||
|
|
|
@ -65,9 +65,6 @@ class TerminalModelAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView)
|
||||||
form_class = TerminalForm
|
form_class = TerminalForm
|
||||||
template_name = 'applications/terminal_modal_test.html'
|
template_name = 'applications/terminal_modal_test.html'
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
return super(TerminalModelAccept, self).post(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
terminal = form.save()
|
terminal = form.save()
|
||||||
terminal.is_accepted = True
|
terminal.is_accepted = True
|
||||||
|
@ -80,7 +77,6 @@ class TerminalModelAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView)
|
||||||
return self.render_json_response(data)
|
return self.render_json_response(data)
|
||||||
|
|
||||||
def form_invalid(self, form):
|
def form_invalid(self, form):
|
||||||
print(form.data)
|
|
||||||
data = {
|
data = {
|
||||||
'success': False,
|
'success': False,
|
||||||
'msg': str(form.errors),
|
'msg': str(form.errors),
|
||||||
|
|
|
@ -199,8 +199,7 @@ class SystemUser(models.Model):
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
def get_assets(self):
|
def get_assets(self):
|
||||||
assets = set(self.assets.all()
|
assets = set(self.assets.all()) | self.get_assets_inherit_from_asset_groups()
|
||||||
) | self.get_assets_inherit_from_asset_groups()
|
|
||||||
return list(assets)
|
return list(assets)
|
||||||
|
|
||||||
def _to_secret_json(self):
|
def _to_secret_json(self):
|
||||||
|
|
|
@ -187,3 +187,16 @@ class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
fields.append('assets_amount')
|
fields.append('assets_amount')
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
|
||||||
|
class AssetGroupGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
|
assets_granted = AssetGrantedSerializer(many=True, read_only=True)
|
||||||
|
assets_amount = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = AssetGroup
|
||||||
|
list_serializer_class = BulkListSerializer
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_assets_amount(obj):
|
||||||
|
return len(obj.assets_granted)
|
||||||
|
|
|
@ -7,7 +7,6 @@ import uuid
|
||||||
import codecs
|
import codecs
|
||||||
import chardet
|
import chardet
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from collections import defaultdict
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
|
@ -31,6 +31,11 @@ app.conf.update(
|
||||||
'task': 'assets.tasks.test_admin_user_connective_period',
|
'task': 'assets.tasks.test_admin_user_connective_period',
|
||||||
'schedule': 60*60*60,
|
'schedule': 60*60*60,
|
||||||
'args': (),
|
'args': (),
|
||||||
|
},
|
||||||
|
'clean_terminal_history': {
|
||||||
|
'task': 'applications.tasks.clean_terminal_history',
|
||||||
|
'schedule': 60*60*60,
|
||||||
|
'args': (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,7 @@ from .utils import get_user_granted_assets, get_user_granted_asset_groups, \
|
||||||
get_user_group_granted_assets, get_user_group_granted_asset_groups
|
get_user_group_granted_assets, get_user_group_granted_asset_groups
|
||||||
from .models import AssetPermission
|
from .models import AssetPermission
|
||||||
from .hands import AssetGrantedSerializer, User, UserGroup, AssetGroup, Asset, \
|
from .hands import AssetGrantedSerializer, User, UserGroup, AssetGroup, Asset, \
|
||||||
AssetGroup, AssetGroupSerializer, SystemUser
|
AssetGroup, AssetGroupGrantedSerializer, SystemUser
|
||||||
from . import serializers
|
from . import serializers
|
||||||
from .utils import associate_system_users_and_assets
|
from .utils import associate_system_users_and_assets
|
||||||
|
|
||||||
|
@ -135,30 +135,24 @@ class UserGrantedAssetsApi(ListAPIView):
|
||||||
|
|
||||||
class UserGrantedAssetGroupsApi(ListAPIView):
|
class UserGrantedAssetGroupsApi(ListAPIView):
|
||||||
permission_classes = (IsSuperUserOrAppUser,)
|
permission_classes = (IsSuperUserOrAppUser,)
|
||||||
serializer_class = AssetGroupSerializer
|
serializer_class = AssetGroupGrantedSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
user_id = self.kwargs.get('pk', '')
|
user_id = self.kwargs.get('pk', '')
|
||||||
|
|
||||||
if not user_id:
|
if not user_id:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
user = get_object_or_404(User, id=user_id)
|
user = get_object_or_404(User, id=user_id)
|
||||||
if user:
|
asset_groups = get_user_granted_asset_groups(user)
|
||||||
asset_groups = {}
|
|
||||||
for asset, system_ in get_user_granted_assets(user).items():
|
|
||||||
for asset_group in asset.groups.all():
|
|
||||||
if asset_group.id in asset_groups:
|
|
||||||
asset_groups[asset_group.id]['assets_amount'] += 1
|
|
||||||
else:
|
|
||||||
asset_groups[asset_group.id] = {
|
|
||||||
'id': asset_group.id,
|
|
||||||
'name': asset_group.name,
|
|
||||||
'comment': asset_group.comment,
|
|
||||||
'assets_amount': 1
|
|
||||||
}
|
|
||||||
asset_groups_json = asset_groups.values()
|
|
||||||
|
|
||||||
|
queryset = []
|
||||||
|
for asset_group, assets_system_users in asset_groups.items():
|
||||||
|
assets = []
|
||||||
|
for asset, system_users in assets_system_users:
|
||||||
|
asset.system_users_granted = system_users
|
||||||
|
assets.append(asset)
|
||||||
|
asset_group.assets_granted = assets
|
||||||
|
queryset.append(asset_group)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,7 +271,7 @@ class UserGroupGrantedAssetsApi(ListAPIView):
|
||||||
|
|
||||||
class UserGroupGrantedAssetGroupsApi(ListAPIView):
|
class UserGroupGrantedAssetGroupsApi(ListAPIView):
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
serializer_class = AssetGroupSerializer
|
serializer_class = AssetGroupGrantedSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
user_group_id = self.kwargs.get('pk', '')
|
user_group_id = self.kwargs.get('pk', '')
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
from users.utils import AdminUserRequiredMixin
|
from users.utils import AdminUserRequiredMixin
|
||||||
from users.models import User, UserGroup
|
from users.models import User, UserGroup
|
||||||
from assets.models import Asset, AssetGroup, SystemUser
|
from assets.models import Asset, AssetGroup, SystemUser
|
||||||
from assets.serializers import AssetGrantedSerializer, AssetGroupSerializer
|
from assets.serializers import AssetGrantedSerializer, AssetGroupGrantedSerializer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
import collections
|
||||||
|
|
||||||
from common.utils import setattr_bulk, get_logger
|
from common.utils import setattr_bulk, get_logger
|
||||||
from .tasks import push_users
|
from .tasks import push_users
|
||||||
|
@ -52,77 +53,77 @@ def get_user_group_granted_assets(user_group):
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
|
|
||||||
def get_user_granted_asset_groups_direct(user):
|
# def get_user_granted_asset_groups_direct(user):
|
||||||
"""Return asset groups granted of the user direct nor inherit from user group
|
# """Return asset groups granted of the user direct nor inherit from user group
|
||||||
|
#
|
||||||
:param user: Instance of :class: ``User``
|
# :param user: Instance of :class: ``User``
|
||||||
:return: {asset_group: {system_user1, },
|
# :return: {asset_group: {system_user1, },
|
||||||
asset_group2: {system_user1, system_user2]}
|
# asset_group2: {system_user1, system_user2]}
|
||||||
"""
|
# """
|
||||||
asset_groups = {}
|
# asset_groups = {}
|
||||||
asset_permissions_direct = user.asset_permissions.all()
|
# asset_permissions_direct = user.asset_permissions.all()
|
||||||
|
#
|
||||||
for asset_permission in asset_permissions_direct:
|
# for asset_permission in asset_permissions_direct:
|
||||||
if not asset_permission.is_valid:
|
# if not asset_permission.is_valid:
|
||||||
continue
|
# continue
|
||||||
for asset_group in asset_permission.asset_groups.all():
|
# for asset_group in asset_permission.asset_groups.all():
|
||||||
if asset_group in asset_groups:
|
# if asset_group in asset_groups:
|
||||||
asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
# asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
||||||
else:
|
# else:
|
||||||
setattr(asset_group, 'inherited', False)
|
# setattr(asset_group, 'inherited', False)
|
||||||
asset_groups[asset_group] = set(asset_permission.system_users.all())
|
# asset_groups[asset_group] = set(asset_permission.system_users.all())
|
||||||
|
#
|
||||||
return asset_groups
|
# return asset_groups
|
||||||
|
|
||||||
|
|
||||||
def get_user_granted_asset_groups_inherit_from_user_groups(user):
|
# def get_user_granted_asset_groups_inherit_from_user_groups(user):
|
||||||
"""Return asset groups granted of the user and inherit from user group
|
# """Return asset groups granted of the user and inherit from user group
|
||||||
|
#
|
||||||
:param user: Instance of :class: ``User``
|
# :param user: Instance of :class: ``User``
|
||||||
:return: {asset_group: {system_user1, },
|
# :return: {asset_group: {system_user1, },
|
||||||
asset_group2: {system_user1, system_user2]}
|
# asset_group2: {system_user1, system_user2]}
|
||||||
"""
|
# """
|
||||||
asset_groups = {}
|
# asset_groups = {}
|
||||||
user_groups = user.groups.all()
|
# user_groups = user.groups.all()
|
||||||
asset_permissions = set()
|
# asset_permissions = set()
|
||||||
|
#
|
||||||
# Get asset permission list of user groups for this user
|
# # Get asset permission list of user groups for this user
|
||||||
for user_group in user_groups:
|
# for user_group in user_groups:
|
||||||
asset_permissions |= set(user_group.asset_permissions.all())
|
# asset_permissions |= set(user_group.asset_permissions.all())
|
||||||
|
#
|
||||||
# Get asset groups granted from user groups
|
# # Get asset groups granted from user groups
|
||||||
for asset_permission in asset_permissions:
|
# for asset_permission in asset_permissions:
|
||||||
if not asset_permission.is_valid:
|
# if not asset_permission.is_valid:
|
||||||
continue
|
# continue
|
||||||
for asset_group in asset_permission.asset_groups.all():
|
# for asset_group in asset_permission.asset_groups.all():
|
||||||
if asset_group in asset_groups:
|
# if asset_group in asset_groups:
|
||||||
asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
# asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
||||||
else:
|
# else:
|
||||||
setattr(asset_group, 'inherited', True)
|
# setattr(asset_group, 'inherited', True)
|
||||||
asset_groups[asset_group] = set(asset_permission.system_users.all())
|
# asset_groups[asset_group] = set(asset_permission.system_users.all())
|
||||||
|
#
|
||||||
return asset_groups
|
# return asset_groups
|
||||||
|
|
||||||
|
|
||||||
def get_user_granted_asset_groups(user):
|
# def get_user_granted_asset_groups(user):
|
||||||
"""Get user granted asset groups all, include direct and inherit from user group
|
# """Get user granted asset groups all, include direct and inherit from user group
|
||||||
|
#
|
||||||
:param user: Instance of :class: ``User``
|
# :param user: Instance of :class: ``User``
|
||||||
:return: {asset1: {system_user1, system_user2}, asset2: {...}}
|
# :return: {asset_group1: {system_user1, system_user2}, asset_group2: {...}}
|
||||||
"""
|
# """
|
||||||
|
#
|
||||||
asset_groups_inherit_from_user_groups = \
|
# asset_groups_inherit_from_user_groups = \
|
||||||
get_user_granted_asset_groups_inherit_from_user_groups(user)
|
# get_user_granted_asset_groups_inherit_from_user_groups(user)
|
||||||
asset_groups_direct = get_user_granted_asset_groups_direct(user)
|
# asset_groups_direct = get_user_granted_asset_groups_direct(user)
|
||||||
asset_groups = asset_groups_inherit_from_user_groups
|
# asset_groups = asset_groups_inherit_from_user_groups
|
||||||
|
#
|
||||||
# Merge direct granted and inherit from user group
|
# # Merge direct granted and inherit from user group
|
||||||
for asset_group, system_users in asset_groups_direct.items():
|
# for asset_group, system_users in asset_groups_direct.items():
|
||||||
if asset_group in asset_groups:
|
# if asset_group in asset_groups:
|
||||||
asset_groups[asset_group] |= asset_groups_direct[asset_group]
|
# asset_groups[asset_group] |= asset_groups_direct[asset_group]
|
||||||
else:
|
# else:
|
||||||
asset_groups[asset_group] = asset_groups_direct[asset_group]
|
# asset_groups[asset_group] = asset_groups_direct[asset_group]
|
||||||
return asset_groups
|
# return asset_groups
|
||||||
|
|
||||||
|
|
||||||
def get_user_granted_assets_direct(user):
|
def get_user_granted_assets_direct(user):
|
||||||
|
@ -191,8 +192,21 @@ def get_user_granted_assets(user):
|
||||||
|
|
||||||
|
|
||||||
def get_user_granted_asset_groups(user):
|
def get_user_granted_asset_groups(user):
|
||||||
pass
|
"""Return asset groups with assets and system users, it's not the asset
|
||||||
|
group direct permed in rules. We get all asset and then get it asset group
|
||||||
|
|
||||||
|
:param user: Instance of :class: ``User``
|
||||||
|
:return: {asset_group1: [asset1, asset2], asset_group2: []}
|
||||||
|
"""
|
||||||
|
asset_groups = collections.defaultdict(list)
|
||||||
|
ungroups = [AssetGroup(name="UnGrouped")]
|
||||||
|
for asset, system_users in get_user_granted_assets(user).items():
|
||||||
|
groups = asset.groups.all()
|
||||||
|
if not groups:
|
||||||
|
groups = ungroups
|
||||||
|
for asset_group in groups:
|
||||||
|
asset_groups[asset_group].append((asset, system_users))
|
||||||
|
return asset_groups
|
||||||
|
|
||||||
|
|
||||||
def get_user_group_asset_permissions(user_group):
|
def get_user_group_asset_permissions(user_group):
|
||||||
|
|
|
@ -153,16 +153,21 @@ class UserAuthApi(APIView):
|
||||||
login_ip = request.data.get('remote_addr', None)
|
login_ip = request.data.get('remote_addr', None)
|
||||||
user_agent = request.data.get('HTTP_USER_AGENT', '')
|
user_agent = request.data.get('HTTP_USER_AGENT', '')
|
||||||
|
|
||||||
|
if not login_ip:
|
||||||
|
login_ip = request.META.get("REMOTE_ADDR")
|
||||||
|
|
||||||
user, msg = check_user_valid(
|
user, msg = check_user_valid(
|
||||||
username=username, password=password,
|
username=username, password=password,
|
||||||
public_key=public_key)
|
public_key=public_key
|
||||||
|
)
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
token = generate_token(request, user)
|
token = generate_token(request, user)
|
||||||
write_login_log_async.delay(
|
write_login_log_async.delay(
|
||||||
user.username, name=user.name,
|
user.username, name=user.name,
|
||||||
user_agent=user_agent, login_ip=login_ip,
|
user_agent=user_agent, login_ip=login_ip,
|
||||||
login_type=login_type)
|
login_type=login_type
|
||||||
|
)
|
||||||
return Response({'token': token, 'user': user.to_json()})
|
return Response({'token': token, 'user': user.to_json()})
|
||||||
else:
|
else:
|
||||||
return Response({'msg': msg}, status=401)
|
return Response({'msg': msg}, status=401)
|
||||||
|
|
Loading…
Reference in New Issue