diff --git a/seahub/api2/endpoints/admin/default_library.py b/seahub/api2/endpoints/admin/default_library.py new file mode 100644 index 0000000000..c9316e588b --- /dev/null +++ b/seahub/api2/endpoints/admin/default_library.py @@ -0,0 +1,136 @@ +# Copyright (c) 2012-2016 Seafile Ltd. +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 seahub.options.models import UserOptions +from seahub.api2.authentication import TokenAuthentication +from seahub.api2.throttling import UserRateThrottle +from seahub.api2.utils import api_error +from seahub.base.accounts import User +from seahub.views import get_system_default_repo_id + +try: + from seahub.settings import USER_DEFAULT_LIBRARY_NAME +except ImportError: + USER_DEFAULT_LIBRARY_NAME = "My Library" + +logger = logging.getLogger(__name__) + + +class AdminDefaultLibrary(APIView): + + authentication_classes = (TokenAuthentication, SessionAuthentication) + throttle_classes = (UserRateThrottle,) + permission_classes = (IsAdminUser,) + + def create_default_repo(self, username): + + default_repo_id = seafile_api.create_repo(name=USER_DEFAULT_LIBRARY_NAME, + desc=USER_DEFAULT_LIBRARY_NAME, username=username, passwd=None) + + sys_repo_id = get_system_default_repo_id() + if not sys_repo_id or not seafile_api.get_repo(sys_repo_id): + return None + + dirents = seafile_api.list_dir_by_path(sys_repo_id, '/') + for dirent in dirents: + obj_name = dirent.obj_name + seafile_api.copy_file(sys_repo_id, '/', obj_name, + default_repo_id, '/', obj_name, username, 0) + + UserOptions.objects.set_default_repo(username, default_repo_id) + + return default_repo_id + + def get(self, request): + """ Get info of common user's default library. + + Permission checking: + 1. only admin can perform this action. + """ + + # argument check + user_email = request.GET.get('user_email', None) + if not user_email: + error_msg = 'user_email invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + try: + User.objects.get(email=user_email) + except User.DoesNotExist: + error_msg = 'User %s not found.' % user_email + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + # get default library info + try: + default_repo_id = UserOptions.objects.get_default_repo(user_email) + except Exception as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + default_repo_info = {} + default_repo_info['user_email'] = user_email + if default_repo_id and seafile_api.get_repo(default_repo_id) is not None: + default_repo_info['exists'] = True + default_repo_info['repo_id'] = default_repo_id + else: + default_repo_info['exists'] = False + + return Response(default_repo_info) + + def post(self, request): + """ Create a default library for a common user. + + Permission checking: + 1. only admin can perform this action. + """ + + # argument check + user_email = request.POST.get('user_email', None) + if not user_email: + error_msg = 'user_email invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + try: + common_user = User.objects.get(email=user_email) + except User.DoesNotExist: + error_msg = 'User %s not found.' % user_email + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + # permission check + if not common_user.permissions.can_add_repo(): + error_msg = 'Permission denied, %s can not create library.' % user_email + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + # create default library for common use + try: + default_repo_id = UserOptions.objects.get_default_repo(user_email) + except Exception as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + default_repo_info = {} + default_repo_info['user_email'] = user_email + default_repo_info['exists'] = True + + try: + if default_repo_id and seafile_api.get_repo(default_repo_id) is not None: + default_repo_info['repo_id'] = default_repo_id + else: + new_default_repo_id = self.create_default_repo(user_email) + default_repo_info['repo_id'] = new_default_repo_id + except Exception as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + return Response(default_repo_info) diff --git a/seahub/urls.py b/seahub/urls.py index c799cc6803..70ea1646f9 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -45,6 +45,7 @@ from seahub.api2.endpoints.admin.device_errors import AdminDeviceErrors from seahub.api2.endpoints.admin.libraries import AdminLibraries, AdminLibrary from seahub.api2.endpoints.admin.library_dirents import AdminLibraryDirents, AdminLibraryDirent from seahub.api2.endpoints.admin.system_library import AdminSystemLibrary +from seahub.api2.endpoints.admin.default_library import AdminDefaultLibrary from seahub.api2.endpoints.admin.trash_libraries import AdminTrashLibraries, AdminTrashLibrary from seahub.api2.endpoints.admin.groups import AdminGroups, AdminGroup from seahub.api2.endpoints.admin.group_libraries import AdminGroupLibraries, AdminGroupLibrary @@ -220,6 +221,7 @@ urlpatterns = patterns( url(r'^api/v2.1/admin/groups/(?P\d+)/members/(?P[^/]+)/$', AdminGroupMember.as_view(), name='api-v2.1-admin-group-member'), url(r'^api/v2.1/admin/libraries/(?P[-0-9a-f]{36})/dirent/$', AdminLibraryDirent.as_view(), name='api-v2.1-admin-library-dirent'), url(r'^api/v2.1/admin/system-library/$', AdminSystemLibrary.as_view(), name='api-v2.1-admin-system-library'), + url(r'^api/v2.1/admin/default-library/$', AdminDefaultLibrary.as_view(), name='api-v2.1-admin-default-library'), url(r'^api/v2.1/admin/trash-libraries/$', AdminTrashLibraries.as_view(), name='api-v2.1-admin-trash-libraries'), url(r'^api/v2.1/admin/trash-libraries/(?P[-0-9a-f]{36})/$', AdminTrashLibrary.as_view(), name='api-v2.1-admin-trash-library'), url(r'^api/v2.1/admin/shares/$', AdminShares.as_view(), name='api-v2.1-admin-shares'), diff --git a/tests/api/endpoints/admin/test_default_library.py b/tests/api/endpoints/admin/test_default_library.py new file mode 100644 index 0000000000..fd4caef6c6 --- /dev/null +++ b/tests/api/endpoints/admin/test_default_library.py @@ -0,0 +1,57 @@ +import json + +from django.core.urlresolvers import reverse +from seahub.options.models import UserOptions +from seahub.test_utils import BaseTestCase + +class DefaultLibraryTest(BaseTestCase): + + def setUp(self): + self.user_name = self.user.username + self.admin_name = self.admin.username + self.group_id = self.group.id + self.repo_id = self.repo.id + + self.endpoint = reverse('api-v2.1-admin-default-library') + + def tearDown(self): + self.remove_group() + + def test_can_get(self): + self.login_as(self.admin) + + assert UserOptions.objects.get_default_repo(self.user_name) is None + + resp = self.client.get(self.endpoint + '?user_email=%s' % self.user_name) + json_resp = json.loads(resp.content) + + assert json_resp['user_email'] == self.user_name + assert json_resp['exists'] == False + + def test_can_create(self): + self.login_as(self.admin) + + assert UserOptions.objects.get_default_repo(self.user_name) is None + + data = {'user_email': self.user_name} + resp = self.client.post(self.endpoint, data) + json_resp = json.loads(resp.content) + + new_default_repo_id = UserOptions.objects.get_default_repo(self.user_name) + + assert json_resp['user_email'] == self.user_name + assert json_resp['exists'] == True + assert json_resp['repo_id'] == new_default_repo_id + + def test_can_not_get_if_not_admin(self): + self.login_as(self.user) + + resp = self.client.get(self.endpoint + '?user_email=%s' % self.user_name) + self.assertEqual(403, resp.status_code) + + def test_can_not_create_if_not_admin(self): + self.login_as(self.user) + + data = {'user_email': self.user_name} + resp = self.client.post(self.endpoint, data) + self.assertEqual(403, resp.status_code)