diff --git a/seahub/api2/endpoints/admin/device_errors.py b/seahub/api2/endpoints/admin/device_errors.py new file mode 100644 index 0000000000..76000e0907 --- /dev/null +++ b/seahub/api2/endpoints/admin/device_errors.py @@ -0,0 +1,63 @@ +import logging + +from rest_framework.authentication import SessionAuthentication +from rest_framework.permissions import IsAdminUser +from rest_framework.response import Response +from rest_framework.views import APIView +from rest_framework import status + +from seaserv import seafile_api +from pysearpc import SearpcError + +from seahub.api2.authentication import TokenAuthentication +from seahub.api2.throttling import UserRateThrottle +from seahub.api2.utils import api_error +from seahub.api2.models import TokenV2 + +from seahub.utils.timeutils import timestamp_to_isoformat_timestr +from seahub.utils import is_pro_version + +logger = logging.getLogger(__name__) + +class AdminDeviceErrors(APIView): + authentication_classes = (TokenAuthentication, SessionAuthentication) + throttle_classes = (UserRateThrottle, ) + permission_classes = (IsAdminUser,) + + def get(self, request, format=None): + if not is_pro_version(): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + return_results = [] + try: + device_errors = seafile_api.list_repo_sync_errors() + except SearpcError as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + for error in device_errors: + result = {} + result['email'] = error.email if error.email else '' + result['device_ip'] = error.peer_ip if error.peer_ip else '' + result['repo_name'] = error.repo_name if error.repo_name else '' + result['repo_id'] = error.repo_id if error.repo_id else '' + result['error_msg'] = error.error_con if error.error_con else '' + + tokens = TokenV2.objects.filter(device_id = error.peer_id) + if tokens: + result['device_name'] = tokens[0].device_name + result['client_version'] = tokens[0].client_version + else: + result['device_name'] = '' + result['client_version'] = '' + + if error.error_time: + result['error_time'] = timestamp_to_isoformat_timestr(error.error_time) + else: + result['error_time'] = '' + + return_results.append(result) + + return Response(return_results) diff --git a/seahub/api2/endpoints/admin/devices.py b/seahub/api2/endpoints/admin/devices.py new file mode 100644 index 0000000000..735600a3bb --- /dev/null +++ b/seahub/api2/endpoints/admin/devices.py @@ -0,0 +1,88 @@ +import logging + +from rest_framework.authentication import SessionAuthentication +from rest_framework.permissions import IsAdminUser +from rest_framework.response import Response +from rest_framework.views import APIView +from rest_framework import status + +from pysearpc import SearpcError + +from seahub.utils.devices import do_unlink_device +from seahub.utils.timeutils import datetime_to_isoformat_timestr +from seahub.views import is_registered_user + +from seahub.api2.authentication import TokenAuthentication +from seahub.api2.throttling import UserRateThrottle +from seahub.api2.utils import api_error +from seahub.api2.models import TokenV2 + +logger = logging.getLogger(__name__) + +class AdminDevices(APIView): + authentication_classes = (TokenAuthentication, SessionAuthentication) + throttle_classes = (UserRateThrottle,) + permission_classes = (IsAdminUser,) + + def get(self, request, format=None): + + try: + current_page = int(request.GET.get('page', '1')) + per_page = int(request.GET.get('per_page', '50')) + except ValueError: + current_page = 1 + per_page = 50 + + platform = request.GET.get('platform', None) + + start = (current_page - 1) * per_page + end = current_page * per_page + 1 + devices = TokenV2.objects.get_devices(platform, start, end) + + if len(devices) == end - start: + devices = devices[:per_page] + has_next_page = True + else: + has_next_page = False + + return_results = [] + for device in devices: + result = {} + result['client_version'] = device.client_version + result['device_id'] = device.device_id + result['device_name'] = device.device_name + result['last_accessed'] = datetime_to_isoformat_timestr(device.last_accessed) + result['last_login_ip'] = device.last_login_ip + result['user'] = device.user + result['platform'] = device.platform + return_results.append(result) + + return Response(({'has_next_page': has_next_page}, return_results)) + + def delete(self, request, format=None): + + platform = request.data.get('platform', '') + device_id = request.data.get('device_id', '') + user = request.data.get('user', '') + + if not platform: + error_msg = 'platform invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if not device_id: + error_msg = 'device_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if not user or not is_registered_user(user): + error_msg = 'user invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + try: + do_unlink_device(user, platform, device_id) + except SearpcError as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + return Response({'success': True}) + diff --git a/seahub/api2/models.py b/seahub/api2/models.py index 3cee5a514b..688f9d837b 100644 --- a/seahub/api2/models.py +++ b/seahub/api2/models.py @@ -6,6 +6,7 @@ from django.db import models from seahub.base.fields import LowerCaseCharField DESKTOP_PLATFORMS = ('windows', 'linux', 'mac') +MOBILE_PLATFORMS = ('ios', 'android') class Token(models.Model): """ @@ -28,10 +29,20 @@ class Token(models.Model): return self.key class TokenV2Manager(models.Manager): + + def get_devices(self, platform, start, end): + if platform == 'desktop': + devices = super(TokenV2Manager, self).filter(platform__in=DESKTOP_PLATFORMS).order_by('-last_accessed')[start : end] + elif platform == 'mobile': + devices = super(TokenV2Manager, self).filter(platform__in=MOBILE_PLATFORMS).order_by('-last_accessed')[start : end] + else: + devices = super(TokenV2Manager, self).all().order_by('-last_accessed')[start : end] + + return devices + def get_user_devices(self, username): '''List user devices, most recently used first''' devices = super(TokenV2Manager, self).filter(user=username) - platform_priorities = { 'windows': 0, 'linux': 0, diff --git a/seahub/templates/js/sysadmin-templates.html b/seahub/templates/js/sysadmin-templates.html index 48c9754ef3..43cb0632d8 100644 --- a/seahub/templates/js/sysadmin-templates.html +++ b/seahub/templates/js/sysadmin-templates.html @@ -3,9 +3,11 @@ - + + + + + + + + + + diff --git a/seahub/templates/sysadmin/base.html b/seahub/templates/sysadmin/base.html index 47b95b6b89..1809df959d 100644 --- a/seahub/templates/sysadmin/base.html +++ b/seahub/templates/sysadmin/base.html @@ -6,7 +6,10 @@