diff --git a/dev-requirements.txt b/dev-requirements.txt index a63453d2b6..4f357df201 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -3,3 +3,5 @@ fabric transifex-client mysqlclient==1.3.12 + +raven==5.0.0 diff --git a/media/css/seahub.css b/media/css/seahub.css index 0c15661fa4..6708e6df24 100644 --- a/media/css/seahub.css +++ b/media/css/seahub.css @@ -197,6 +197,7 @@ .sf2-icon-more:before { content: "\e032"; } .sf2-icon-plus2:before { content: "\e033"; } .sf2-icon-upload:before { content: "\e034"; } +.sf2-icon-x3:before { content: "\e035"; } /******* tags **********/ html, body { @@ -3292,6 +3293,11 @@ button.sf-dropdown-toggle:focus { border-bottom:1px dotted #ddd; margin-bottom:3px; } +.search-time-range { + border-top:1px dotted #ddd; + margin-top:3px; + padding-top:3px; +} .custom-ftype-options { font-size:13px; padding:2px 0; diff --git a/media/css/sf_font2/seafile-font2.eot b/media/css/sf_font2/seafile-font2.eot index 48a9fe2c21..766a7e180a 100644 Binary files a/media/css/sf_font2/seafile-font2.eot and b/media/css/sf_font2/seafile-font2.eot differ diff --git a/media/css/sf_font2/seafile-font2.svg b/media/css/sf_font2/seafile-font2.svg index cbf012acd0..cbf6166c02 100644 --- a/media/css/sf_font2/seafile-font2.svg +++ b/media/css/sf_font2/seafile-font2.svg @@ -60,4 +60,5 @@ + diff --git a/media/css/sf_font2/seafile-font2.ttf b/media/css/sf_font2/seafile-font2.ttf index 76085179f9..c0e5748d7f 100644 Binary files a/media/css/sf_font2/seafile-font2.ttf and b/media/css/sf_font2/seafile-font2.ttf differ diff --git a/media/css/sf_font2/seafile-font2.woff b/media/css/sf_font2/seafile-font2.woff index cba87f8def..ba90fc93de 100644 Binary files a/media/css/sf_font2/seafile-font2.woff and b/media/css/sf_font2/seafile-font2.woff differ diff --git a/media/js/base.js b/media/js/base.js index b03c95f872..d240ea823d 100644 --- a/media/js/base.js +++ b/media/js/base.js @@ -265,7 +265,7 @@ function feedback(con, type, time) { hide_pos_top = '-' + ($el.outerHeight() + parseInt(show_pos_top)) + 'px'; // add transition: from 'hide' to 'show'. the transition effect is offered by CSS. - $el.css({'left':($(window).width() - $el.width())/2, 'top': hide_pos_top}); + $el.css({'left':($(window).width() - $el.width())/2, 'top': hide_pos_top}).removeClass('hide'); setTimeout(function() { $el.css({'top': show_pos_top}); }, 10); setTimeout(function() { $el.css({'top': hide_pos_top}); }, 5000); diff --git a/seahub/api2/endpoints/admin/libraries.py b/seahub/api2/endpoints/admin/libraries.py index 697f074f0f..b44c3b67ad 100644 --- a/seahub/api2/endpoints/admin/libraries.py +++ b/seahub/api2/endpoints/admin/libraries.py @@ -41,7 +41,7 @@ def get_repo_info(repo): except Exception: org_repo_owner = None - owner = repo_owner or org_repo_owner + owner = repo_owner or org_repo_owner or '' result = {} result['id'] = repo.repo_id diff --git a/seahub/api2/endpoints/admin/organizations.py b/seahub/api2/endpoints/admin/organizations.py new file mode 100644 index 0000000000..fc3efdb663 --- /dev/null +++ b/seahub/api2/endpoints/admin/organizations.py @@ -0,0 +1,222 @@ +# 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 ccnet_api, seafile_api + +from seaserv import seafserv_threaded_rpc + +from seahub.utils.file_size import get_file_size_unit +from seahub.utils.timeutils import timestamp_to_isoformat_timestr +from seahub.base.templatetags.seahub_tags import email2nickname, \ + email2contact_email +from seahub.api2.authentication import TokenAuthentication +from seahub.api2.throttling import UserRateThrottle +from seahub.api2.utils import api_error +from seahub.api2.permissions import IsProVersion + +try: + from seahub.settings import ORG_MEMBER_QUOTA_ENABLED +except ImportError: + ORG_MEMBER_QUOTA_ENABLED= False + +if ORG_MEMBER_QUOTA_ENABLED: + from seahub_extra.organizations.models import OrgMemberQuota + +try: + from seahub.settings import CLOUD_MODE +except ImportError: + CLOUD_MODE = False + +try: + from seahub.settings import MULTI_TENANCY +except ImportError: + MULTI_TENANCY = False + +logger = logging.getLogger(__name__) + +def get_org_info(org_id): + + org_info = {} + + org = ccnet_api.get_org_by_id(org_id) + + org_info['org_id'] = org_id + org_info['org_name'] = org.org_name + org_info['ctime'] = timestamp_to_isoformat_timestr(org.ctime) + org_info['org_url_prefix'] = org.url_prefix + + creator = org.creator + org_info['creator_email'] = creator + org_info['creator_name'] = email2nickname(creator) + org_info['creator_contact_email'] = email2contact_email(creator) + + org_info['quota'] = seafile_api.get_org_quota(org_id) + + if ORG_MEMBER_QUOTA_ENABLED: + org_info['max_user_number'] = OrgMemberQuota.objects.get_quota(org_id) + + return org_info + + +class AdminOrganization(APIView): + + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAdminUser, IsProVersion) + throttle_classes = (UserRateThrottle,) + + def get(self, request, org_id): + """ Get base info of a organization + + Permission checking: + 1. only admin can perform this action. + """ + + if not (CLOUD_MODE and MULTI_TENANCY): + error_msg = 'Feature is not enabled.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + org_id = int(org_id) + if org_id == 0: + error_msg = 'org_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + org = ccnet_api.get_org_by_id(org_id) + if not org: + error_msg = 'Organization %s not found.' % org_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + try: + org_info = get_org_info(org_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(org_info) + + def put(self, request, org_id): + """ Update base info of a organization + + Permission checking: + 1. only admin can perform this action. + """ + + if not (CLOUD_MODE and MULTI_TENANCY): + error_msg = 'Feature is not enabled.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + org_id = int(org_id) + if org_id == 0: + error_msg = 'org_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + org = ccnet_api.get_org_by_id(org_id) + if not org: + error_msg = 'Organization %s not found.' % org_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + # update org name + new_name = request.data.get('org_name', None) + if new_name: + try: + ccnet_api.set_org_name(org_id, new_name) + except Exception as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + # update org max user number + max_user_number = request.data.get('max_user_number', None) + if max_user_number and ORG_MEMBER_QUOTA_ENABLED: + + try: + max_user_number = int(max_user_number) + except ValueError: + error_msg = 'max_user_number invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if max_user_number <= 0: + error_msg = 'max_user_number invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + try: + OrgMemberQuota.objects.set_quota(org_id, max_user_number) + except Exception as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + quota_mb = request.data.get('quota', None) + if quota_mb: + + try: + quota_mb = int(quota_mb) + except ValueError: + error_msg = 'quota invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if quota_mb < 0: + error_msg = 'quota invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + + quota = quota_mb * get_file_size_unit('MB') + try: + seafile_api.set_org_quota(org_id, quota) + except Exception as e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + org_info = get_org_info(org_id) + return Response(org_info) + + def delete(self, request, org_id): + """ Delete an organization + + Permission checking: + 1. only admin can perform this action. + """ + + if not (CLOUD_MODE and MULTI_TENANCY): + error_msg = 'Feature is not enabled.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + org_id = int(org_id) + if org_id == 0: + error_msg = 'org_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + org = ccnet_api.get_org_by_id(org_id) + if not org: + error_msg = 'Organization %s not found.' % org_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + try: + # remove org users + users = ccnet_api.get_org_emailusers(org.url_prefix, -1, -1) + for u in users: + ccnet_api.remove_org_user(org_id, u.email) + + # remove org groups + groups = ccnet_api.get_org_groups(org_id, -1, -1) + for g in groups: + ccnet_api.remove_org_group(org_id, g.gid) + + # remove org repos + seafile_api.remove_org_repo_by_org_id(org_id) + + # remove org + ccnet_api.remove_org(org_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({'success': True}) diff --git a/seahub/api2/endpoints/file.py b/seahub/api2/endpoints/file.py index 59296f520e..107ef072ba 100644 --- a/seahub/api2/endpoints/file.py +++ b/seahub/api2/endpoints/file.py @@ -21,7 +21,7 @@ from seahub.utils import check_filename_with_rename, is_pro_version, \ normalize_dir_path from seahub.utils.timeutils import timestamp_to_isoformat_timestr from seahub.views import check_folder_permission -from seahub.utils.file_op import check_file_lock +from seahub.utils.file_op import check_file_lock, if_locked_by_online_office from seahub.settings import MAX_UPLOAD_FILE_NAME_LEN, \ FILE_LOCK_EXPIRATION_DAYS, OFFICE_TEMPLATE_ROOT @@ -464,7 +464,7 @@ class FileView(APIView): return Response({'success': True}) def put(self, request, repo_id, format=None): - """ Currently only for lock and unlock file operation. + """ Currently only support lock, unlock, refresh-lock file. Permission checking: 1. user with 'rw' permission for current file; @@ -487,8 +487,8 @@ class FileView(APIView): return api_error(status.HTTP_400_BAD_REQUEST, error_msg) operation = operation.lower() - if operation not in ('lock', 'unlock'): - error_msg = "operation can only be 'lock', or 'unlock'." + if operation not in ('lock', 'unlock', 'refresh-lock'): + error_msg = "operation can only be 'lock', 'unlock' or 'refresh-lock'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check @@ -516,34 +516,62 @@ class FileView(APIView): error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + # check if is locked by online office + locked_by_online_office = if_locked_by_online_office(repo_id, path) + if operation == 'lock': + + if is_locked: + error_msg = _("File is locked") + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + # lock file + expire = request.data.get('expire', FILE_LOCK_EXPIRATION_DAYS) + try: + seafile_api.lock_file(repo_id, path, username, expire) + except SearpcError, e: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + if operation == 'unlock': + if not is_locked: - # lock file - expire = request.data.get('expire', FILE_LOCK_EXPIRATION_DAYS) + error_msg = _("File is not locked.") + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + # file can only be locked by normal user or OnlineOffice + is_repo_owner = seafile_api.is_repo_owner(username, repo_id) + if locked_by_me or \ + (locked_by_online_office and is_repo_owner): + # unlock file try: - seafile_api.lock_file(repo_id, path.lstrip('/'), username, expire) + seafile_api.unlock_file(repo_id, path) except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) else: - if not locked_by_me: - error_msg = _("File is locked") - return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + error_msg = 'You can not unlock this file.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) - if operation == 'unlock': - if is_locked: - if not locked_by_me: - error_msg = 'You can not unlock this file.' - return api_error(status.HTTP_403_FORBIDDEN, error_msg) + if operation == 'refresh-lock': - # unlock file + if not is_locked: + error_msg = _("File is not locked.") + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if locked_by_me or locked_by_online_office: + # refresh lock file try: - seafile_api.unlock_file(repo_id, path.lstrip('/')) + seafile_api.refresh_file_lock(repo_id, path) except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + else: + error_msg = _("You can not refresh this file's lock.") + return api_error(status.HTTP_403_FORBIDDEN, error_msg) file_info = self.get_file_info(username, repo_id, path) return Response(file_info) diff --git a/seahub/api2/endpoints/move_folder_merge.py b/seahub/api2/endpoints/move_folder_merge.py new file mode 100644 index 0000000000..97f15c7bad --- /dev/null +++ b/seahub/api2/endpoints/move_folder_merge.py @@ -0,0 +1,181 @@ +# Copyright (c) 2012-2018 Seafile Ltd. + +import stat +import logging +import posixpath + +from rest_framework.authentication import SessionAuthentication +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework.views import APIView +from rest_framework import status +from django.utils.translation import ugettext as _ + +from seahub.api2.throttling import UserRateThrottle +from seahub.api2.authentication import TokenAuthentication +from seahub.api2.utils import api_error +from seahub.api2.views import HTTP_443_ABOVE_QUOTA + +from seahub.views import check_folder_permission +from seahub.utils.repo import get_repo_owner +from seahub.settings import MAX_PATH + +from seaserv import seafile_api + +logger = logging.getLogger(__name__) + +def get_dirent_name_list(username, repo_id, parent_path): + + file_name_list = [] + folder_name_list = [] + + path_id = seafile_api.get_dir_id_by_path(repo_id, parent_path) + dirs = seafile_api.list_dir_with_perm(repo_id, parent_path, + path_id, username, -1, -1) + + for dirent in dirs: + if stat.S_ISDIR(dirent.mode): + folder_name_list.append(dirent.obj_name) + else: + file_name_list.append(dirent.obj_name) + + return folder_name_list, file_name_list + +def folder_name_duplicate(username, src_folder_name, dst_repo_id, dst_parent_dir): + + dst_folder_name_list, dst_file_name_list = get_dirent_name_list(username, + dst_repo_id, dst_parent_dir) + + if src_folder_name in dst_folder_name_list: + return True + else: + return False + +def move_folder_with_merge(username, + src_repo_id, src_parent_dir, src_dirent_name, + dst_repo_id, dst_parent_dir, dst_dirent_name): + + if folder_name_duplicate(username, src_dirent_name, + dst_repo_id, dst_parent_dir): + + src_folder_path = posixpath.join(src_parent_dir, src_dirent_name) + dst_folder_path = posixpath.join(dst_parent_dir, dst_dirent_name) + src_sub_folder_name_list, src_sub_file_name_list = get_dirent_name_list(username, + src_repo_id, src_folder_path) + + # for sub file, copy it directly + for src_sub_file_name in src_sub_file_name_list: + seafile_api.move_file( + src_repo_id, src_folder_path, src_sub_file_name, + dst_repo_id, dst_folder_path, src_sub_file_name, + replace=False, username=username, need_progress=0) + + for src_sub_folder_name in src_sub_folder_name_list: + move_folder_with_merge(username, + src_repo_id, src_folder_path, src_sub_folder_name, + dst_repo_id, dst_folder_path, src_sub_folder_name) + else: + seafile_api.move_file( + src_repo_id, src_parent_dir, src_dirent_name, + dst_repo_id, dst_parent_dir, dst_dirent_name, + replace=False, username=username, need_progress=0) + + +class MoveFolderMergeView(APIView): + + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated,) + throttle_classes = (UserRateThrottle,) + + def post(self, request): + """ Only support move folder. + + Permission checking: + + User with 'rw' permission for src/dst folder. + """ + src_repo_id = request.data.get('src_repo_id', None) + src_parent_dir = request.data.get('src_parent_dir', None) + src_folder_name = request.data.get('src_dirent_name', None) + dst_repo_id = request.data.get('dst_repo_id', None) + dst_parent_dir = request.data.get('dst_parent_dir', None) + + # argument check + if not src_repo_id: + error_msg = 'src_repo_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if not src_parent_dir: + error_msg = 'src_parent_dir invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if not src_folder_name: + error_msg = 'src_dirent_name invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if not dst_repo_id: + error_msg = 'dst_repo_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if not dst_parent_dir: + error_msg = 'dst_parent_dir invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if src_repo_id == dst_repo_id and src_parent_dir == dst_parent_dir: + error_msg = _('Invalid destination path') + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if len(dst_parent_dir + src_folder_name) > MAX_PATH: + error_msg = _('Destination path is too long.') + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + # src resource check + src_repo = seafile_api.get_repo(src_repo_id) + if not src_repo: + error_msg = 'Library %s not found.' % src_repo_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + src_folder_path = posixpath.join(src_parent_dir, src_folder_name) + dir_id = seafile_api.get_dir_id_by_path(src_repo_id, src_folder_path) + if not dir_id: + error_msg = 'Folder %s not found.' % src_folder_path + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + # dst resource check + dst_repo = seafile_api.get_repo(dst_repo_id) + if not dst_repo: + error_msg = 'Library %s not found.' % dst_repo_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_parent_dir): + error_msg = 'Folder %s not found.' % dst_parent_dir + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + # permission check for src folder + if check_folder_permission(request, src_repo_id, src_folder_path) != 'rw': + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + # permission check for dst parent dir + if check_folder_permission(request, dst_repo_id, dst_parent_dir) != 'rw': + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + ## check if above quota for dst repo + if get_repo_owner(request, src_repo_id) != get_repo_owner(request, dst_repo_id): + + current_size = 0 + current_size = seafile_api.get_dir_size(src_repo.store_id, + src_repo.version, dir_id) + + if seafile_api.check_quota(dst_repo_id, current_size) < 0: + return api_error(HTTP_443_ABOVE_QUOTA, _(u"Out of quota.")) + + username = request.user.username + move_folder_with_merge(username, + src_repo_id, src_parent_dir, src_folder_name, + dst_repo_id, dst_parent_dir, src_folder_name) + + seafile_api.del_file(src_repo_id, src_parent_dir, src_folder_name, username) + + return Response({'success': True}) diff --git a/seahub/api2/endpoints/repo_set_password.py b/seahub/api2/endpoints/repo_set_password.py index 8ea42dbf74..3ebd30c0cc 100644 --- a/seahub/api2/endpoints/repo_set_password.py +++ b/seahub/api2/endpoints/repo_set_password.py @@ -14,8 +14,11 @@ 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.utils.repo import is_repo_owner, add_encrypted_repo_secret_key_to_database +from seahub.base.models import RepoSecretKey +from seahub.views import check_folder_permission -from seahub.utils import is_org_context +from seahub.settings import ENABLE_RESET_ENCRYPTED_REPO_PASSWORD logger = logging.getLogger(__name__) @@ -26,20 +29,36 @@ class RepoSetPassword(APIView): throttle_classes = (UserRateThrottle,) def post(self, request, repo_id): + """ Check if repo password is correct. - repo = seafile_api.get_repo(repo_id) - if not repo: - error_msg = 'Library %s not found.' % repo_id - return api_error(status.HTTP_404_NOT_FOUND, error_msg) + Permission checking: + 1. User can access current repo. + """ + # argument check password = request.POST.get('password', None) if not password: error_msg = 'password invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + # resource check + repo = seafile_api.get_repo(repo_id) + if not repo: + error_msg = 'Library %s not found.' % repo_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + if not repo.encrypted: + error_msg = 'Library %s is not encrypted.' % repo_id + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + # permission check + if not check_folder_permission(request, repo_id, '/'): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + # check the password is correct try: seafile_api.set_passwd(repo_id, request.user.username, password) - return Response({'success': True}) except SearpcError as e: if e.msg == 'Bad arguments': error_msg = 'Bad arguments' @@ -54,22 +73,23 @@ class RepoSetPassword(APIView): error_msg = _(u'Decrypt library error') return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + if ENABLE_RESET_ENCRYPTED_REPO_PASSWORD: + add_encrypted_repo_secret_key_to_database(repo_id, password) + + return Response({'success': True}) + def put(self, request, repo_id): - """ Change repo password. + """ Change/Init repo password. Permission checking: 1. repo owner """ # argument check - old_password = request.POST.get('old_password', None) - if not old_password: - error_msg = 'old_password invalid.' - return api_error(status.HTTP_400_BAD_REQUEST, error_msg) - - new_password = request.POST.get('new_password', None) - if not new_password: - error_msg = 'new_password invalid.' + operation = request.POST.get('operation', 'change-password') + operation = operation.lower() + if operation not in ('change-password', 'reset-password', 'can-reset-password'): + error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check @@ -78,25 +98,71 @@ class RepoSetPassword(APIView): error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) - # permission check - if is_org_context(request): - repo_owner = seafile_api.get_org_repo_owner(repo.id) - else: - repo_owner = seafile_api.get_repo_owner(repo.id) + if not repo.encrypted: + error_msg = 'Library %s is not encrypted.' % repo_id + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + # permission check username = request.user.username - if username != repo_owner: + if not is_repo_owner(request, repo_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) - # change password - try: - seafile_api.change_repo_passwd(repo_id, old_password, new_password, username) - except SearpcError as e: - if e.msg == 'Incorrect password': - error_msg = _(u'Wrong old password') + if operation == 'change-password': + + old_password = request.POST.get('old_password', None) + if not old_password: + error_msg = 'old_password invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + new_password = request.POST.get('new_password', None) + if not new_password: + error_msg = 'new_password invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + try: + seafile_api.change_repo_passwd(repo_id, old_password, new_password, username) + except Exception as e: + if e.msg == 'Incorrect password': + error_msg = _(u'Wrong old password') + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + else: + logger.error(e) + error_msg = 'Internal Server Error' + return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) + + if ENABLE_RESET_ENCRYPTED_REPO_PASSWORD: + add_encrypted_repo_secret_key_to_database(repo_id, new_password) + + if operation == 'can-reset-password': + if not ENABLE_RESET_ENCRYPTED_REPO_PASSWORD: + error_msg = 'Feature disabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + if not RepoSecretKey.objects.get_secret_key(repo_id): + return Response({'allowed': False}) else: + return Response({'allowed': True}) + + if operation == 'reset-password': + + if not ENABLE_RESET_ENCRYPTED_REPO_PASSWORD: + error_msg = 'Feature disabled.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + new_password = request.POST.get('new_password', None) + if not new_password: + error_msg = 'new_password invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + secret_key = RepoSecretKey.objects.get_secret_key(repo_id) + if not secret_key: + error_msg = 'repo_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + try: + seafile_api.reset_repo_passwd(repo_id, username, secret_key, new_password) + except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) diff --git a/seahub/api2/endpoints/repos_batch.py b/seahub/api2/endpoints/repos_batch.py index 27172d22a4..9a9308a22d 100644 --- a/seahub/api2/endpoints/repos_batch.py +++ b/seahub/api2/endpoints/repos_batch.py @@ -20,12 +20,20 @@ from seahub.api2.views import HTTP_443_ABOVE_QUOTA from seahub.group.utils import is_group_member from seahub.base.accounts import User +from seahub.share.utils import is_repo_admin, \ + check_user_share_out_permission, check_group_share_out_permission +from seahub.share.models import ExtraSharePermission, ExtraGroupsSharePermission from seahub.share.signals import share_repo_to_user_successful, \ share_repo_to_group_successful from seahub.utils import is_org_context, send_perm_audit_msg, \ - normalize_dir_path, get_folder_permission_recursively + normalize_dir_path, get_folder_permission_recursively, \ + normalize_file_path, check_filename_with_rename +from seahub.utils.repo import get_repo_owner + from seahub.views import check_folder_permission from seahub.settings import MAX_PATH +from seahub.constants import PERMISSION_READ, PERMISSION_READ_WRITE, \ + PERMISSION_ADMIN logger = logging.getLogger(__name__) @@ -87,14 +95,17 @@ class ReposBatchView(APIView): def post(self, request): # argument check - operation = request.data.get('operation') - - # operation could be `share`, `delete`, `transfer` - # we now only use `share` - if not operation or operation not in ('share'): + operation = request.data.get('operation', None) + if not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + # operation could be `share`, `unshare`, `delete`, `transfer` + # we now only use `share`, `unshare` + if operation not in ('share', 'unshare'): + error_msg = 'operation can only be "share", "unshare".' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + result = {} result['failed'] = [] result['success'] = [] @@ -113,35 +124,30 @@ class ReposBatchView(APIView): }) continue - if is_org_context(request): - org_id = request.user.org.org_id - org_repo_owner = seafile_api.get_org_repo_owner(repo_id) - if not username == org_repo_owner: - result['failed'].append({ - 'repo_id': repo_id, - 'error_msg': 'Permission denied.' - }) - continue - else: - if not seafile_api.is_repo_owner(username, repo_id): - result['failed'].append({ - 'repo_id': repo_id, - 'error_msg': 'Permission denied.' - }) - continue + repo_owner = get_repo_owner(request, repo_id) + if repo_owner != username and not is_repo_admin(username, repo_id): + result['failed'].append({ + 'repo_id': repo_id, + 'error_msg': 'Permission denied.' + }) + continue valid_repo_id_list.append(repo_id) # share repo if operation == 'share': - share_type = request.data.get('share_type') - if share_type != 'user' and share_type != 'group': + share_type = request.data.get('share_type', None) + if not share_type: error_msg = 'share_type invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + if share_type not in ('user', 'group'): + error_msg = 'share_type can only be "user", "group".' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + permission = request.data.get('permission', 'rw') - if permission not in ('r', 'rw'): + if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN]: error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) @@ -162,7 +168,7 @@ class ReposBatchView(APIView): try: org_of_to_user = ccnet_api.get_orgs_by_user(to_username) except Exception as e: - logger.debug(e) + logger.error(e) org_of_to_user = [] if is_org_context(request): @@ -285,6 +291,123 @@ class ReposBatchView(APIView): 'error_msg': 'Internal Server Error' }) + # unshare repo + if operation == 'unshare': + + share_type = request.data.get('share_type', None) + if not share_type: + error_msg = 'share_type invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if share_type not in ('user', 'group'): + error_msg = 'share_type can only be "user", "group".' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + # unshare repo from user + if share_type == 'user': + to_username = request.data.get('username', None) + if not to_username: + error_msg = 'username invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + for repo_id in valid_repo_id_list: + + if not self.has_shared_to_user(request, repo_id, to_username): + result['failed'].append({ + 'repo_id': repo_id, + 'error_msg': 'This item has not been shared to %s.' % to_username + }) + continue + + repo_owner = get_repo_owner(request, repo_id) + try: + # get share permission before unshare operation + permission = check_user_share_out_permission(repo_id, + '/', to_username, is_org_context(request)) + + if is_org_context(request): + # when calling seafile API to share authority related functions, change the uesrname to repo owner. + org_id = request.user.org.org_id + seafile_api.org_remove_share(org_id, repo_id, repo_owner, to_username) + else: + seafile_api.remove_share(repo_id, repo_owner, to_username) + + # Delete share permission at ExtraSharePermission table. + ExtraSharePermission.objects.delete_share_permission(repo_id, + to_username) + + # send message + send_perm_audit_msg('delete-repo-perm', username, + to_username, repo_id, '/', permission) + + result['success'].append({ + "repo_id": repo_id, + "username": to_username, + }) + except Exception as e: + logger.error(e) + result['failed'].append({ + 'repo_id': repo_id, + 'error_msg': 'Internal Server Error' + }) + + # unshare repo from group + if share_type == 'group': + to_group_id = request.data.get('group_id', None) + if not to_group_id: + error_msg = 'group_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + try: + to_group_id = int(to_group_id) + except ValueError: + error_msg = 'group_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + group = ccnet_api.get_group(to_group_id) + group_name = group.group_name if group else '' + + for repo_id in valid_repo_id_list: + if not self.has_shared_to_group(request, repo_id, to_group_id): + result['failed'].append({ + 'repo_id': repo_id, + 'error_msg': 'This item has not been shared to %s.' % group_name + }) + continue + + try: + # get share permission before unshare operation + permission = check_group_share_out_permission(repo_id, + '/', to_group_id, is_org_context(request)) + + org_id = None + if is_org_context(request): + org_id = request.user.org.org_id + seafile_api.del_org_group_repo(repo_id, org_id, to_group_id) + else: + seafile_api.unset_group_repo( + repo_id, to_group_id, username) + + # Delete share permission at ExtraSharePermission table. + ExtraGroupsSharePermission.objects.delete_share_permission(repo_id, + to_group_id) + + # send message + send_perm_audit_msg('delete-repo-perm', username, + to_group_id, repo_id, '/', permission) + + result['success'].append({ + "repo_id": repo_id, + "group_id": to_group_id, + "group_name": group_name, + }) + except SearpcError as e: + logger.error(e) + result['failed'].append({ + 'repo_id': repo_id, + 'error_msg': 'Internal Server Error' + }) + return Response(result) @@ -581,8 +704,6 @@ class ReposBatchCreateDirView(APIView): continue try: - # TODO - # move seafile_api.mkdir_with_parents() to CE version # rename obj name if name is existed seafile_api.mkdir_with_parents(repo_id, '/', path.strip('/'), username) except Exception as e: @@ -597,3 +718,348 @@ class ReposBatchCreateDirView(APIView): result['success'].append(common_dict) return Response(result) + + +class ReposBatchCopyItemView(APIView): + + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated, ) + throttle_classes = (UserRateThrottle, ) + + def post(self, request): + """ Multi copy files/folders. + Permission checking: + 1. User must has `r/rw` permission for src folder. + 2. User must has `rw` permission for dst folder. + Parameter: + { + "src_repo_id":"7460f7ac-a0ff-4585-8906-bb5a57d2e118", + "dst_repo_id":"a3fa768d-0f00-4343-8b8d-07b4077881db", + "paths":[ + {"src_path":"/1/2/3/","dst_path":"/4/5/6/"}, + {"src_path":"/a/b/c/","dst_path":"/d/e/f/"}, + ] + } + """ + + # argument check + path_list = request.data.get('paths', None) + if not path_list: + error_msg = 'paths invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + src_repo_id = request.data.get('src_repo_id', None) + if not src_repo_id: + error_msg = 'src_repo_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + dst_repo_id = request.data.get('dst_repo_id', None) + if not dst_repo_id: + error_msg = 'dst_repo_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + # resource check + src_repo = seafile_api.get_repo(src_repo_id) + if not src_repo: + error_msg = 'Library %s not found.' % src_repo_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + dst_repo = seafile_api.get_repo(dst_repo_id) + if not dst_repo: + error_msg = 'Library %s not found.' % dst_repo_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + # permission check + if check_folder_permission(request, src_repo_id, '/') is None: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + if check_folder_permission(request, dst_repo_id, '/') is None: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + result = {} + result['failed'] = [] + result['success'] = [] + username = request.user.username + + for path_item in path_list: + + src_path = path_item['src_path'] + src_path = normalize_dir_path(src_path) + src_parent_dir = os.path.dirname(src_path.rstrip('/')) + src_parent_dir = normalize_dir_path(src_parent_dir) + src_obj_name = os.path.basename(src_path.rstrip('/')) + + dst_path = path_item['dst_path'] + dst_path = normalize_dir_path(dst_path) + dst_parent_dir = dst_path + dst_obj_name = src_obj_name + + common_dict = { + 'src_repo_id': src_repo_id, + 'src_path': src_path, + 'dst_repo_id': dst_repo_id, + 'dst_path': dst_path, + } + + # src/dst parameter check + if src_repo_id == dst_repo_id and \ + dst_path.startswith(src_path): + error_dict = { + 'error_msg': "The destination directory is the same as the source, or is it's subfolder." + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + if src_path == '/': + error_dict = { + 'error_msg': "The source path can not be '/'." + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + if len(dst_parent_dir + dst_obj_name) > MAX_PATH: + error_dict = { + 'error_msg': "'Destination path is too long." + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + # src resource check + ## as we don't know if `src_path` stands for a file or a folder, + ## so we check both + src_dir_id = seafile_api.get_dir_id_by_path(src_repo_id, src_path) + src_file_id = seafile_api.get_file_id_by_path(src_repo_id, + normalize_file_path(src_path)) + + if not src_dir_id and not src_file_id: + error_dict = { + 'error_msg': '%s not found.' % src_path + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + # dst resource check + if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_path): + error_dict = { + 'error_msg': 'Folder %s not found.' % dst_path + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + # src path permission check, user must has `r/rw` permission for src folder. + if check_folder_permission(request, src_repo_id, src_parent_dir) is None: + error_dict = { + 'error_msg': 'Permission denied.' + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + # dst path permission check, user must has `rw` permission for dst folder. + if check_folder_permission(request, dst_repo_id, dst_path) != 'rw': + error_dict = { + 'error_msg': 'Permission denied.' + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + try: + dst_obj_name = check_filename_with_rename(dst_repo_id, + dst_parent_dir, dst_obj_name) + # need_progress=0, synchronous=1 + seafile_api.copy_file(src_repo_id, src_parent_dir, src_obj_name, + dst_repo_id, dst_parent_dir, dst_obj_name, username, 0, 1) + except Exception as e: + logger.error(e) + error_dict = { + 'error_msg': 'Internal Server Error' + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + common_dict['dst_obj_name'] = dst_obj_name + result['success'].append(common_dict) + + return Response(result) + + +class ReposBatchMoveItemView(APIView): + + authentication_classes = (TokenAuthentication, SessionAuthentication) + permission_classes = (IsAuthenticated, ) + throttle_classes = (UserRateThrottle, ) + + def post(self, request): + """ Multi move files/folders. + Permission checking: + 1. User must has `rw` permission for src folder. + 2. User must has `rw` permission for dst folder. + Parameter: + { + "src_repo_id":"7460f7ac-a0ff-4585-8906-bb5a57d2e118", + "dst_repo_id":"a3fa768d-0f00-4343-8b8d-07b4077881db", + "paths":[ + {"src_path":"/1/2/3/","dst_path":"/4/5/6/"}, + {"src_path":"/a/b/c/","dst_path":"/d/e/f/"}, + ] + } + """ + + # argument check + path_list = request.data.get('paths', None) + if not path_list: + error_msg = 'paths invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + src_repo_id = request.data.get('src_repo_id', None) + if not src_repo_id: + error_msg = 'src_repo_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + dst_repo_id = request.data.get('dst_repo_id', None) + if not dst_repo_id: + error_msg = 'dst_repo_id invalid.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + # resource check + src_repo = seafile_api.get_repo(src_repo_id) + if not src_repo: + error_msg = 'Library %s not found.' % src_repo_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + dst_repo = seafile_api.get_repo(dst_repo_id) + if not dst_repo: + error_msg = 'Library %s not found.' % dst_repo_id + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + # permission check + if check_folder_permission(request, src_repo_id, '/') is None: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + if check_folder_permission(request, dst_repo_id, '/') is None: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + result = {} + result['failed'] = [] + result['success'] = [] + username = request.user.username + + for path_item in path_list: + + src_path = path_item['src_path'] + src_path = normalize_dir_path(src_path) + src_parent_dir = os.path.dirname(src_path.rstrip('/')) + src_parent_dir = normalize_dir_path(src_parent_dir) + src_obj_name = os.path.basename(src_path.rstrip('/')) + + dst_path = path_item['dst_path'] + dst_path = normalize_dir_path(dst_path) + dst_parent_dir = dst_path + dst_obj_name = src_obj_name + + common_dict = { + 'src_repo_id': src_repo_id, + 'src_path': src_path, + 'dst_repo_id': dst_repo_id, + 'dst_path': dst_path, + } + + # src/dst parameter check + if src_repo_id == dst_repo_id and \ + dst_path.startswith(src_path): + error_dict = { + 'error_msg': "The destination directory is the same as the source, or is it's subfolder." + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + if src_path == '/': + error_dict = { + 'error_msg': "The source path can not be '/'." + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + if len(dst_parent_dir + dst_obj_name) > MAX_PATH: + error_dict = { + 'error_msg': "'Destination path is too long." + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + # src resource check + ## as we don't know if `src_path` stands for a file or a folder, + ## so we check both + src_dir_id = seafile_api.get_dir_id_by_path(src_repo_id, src_path) + src_file_id = seafile_api.get_file_id_by_path(src_repo_id, + normalize_file_path(src_path)) + + if not src_dir_id and not src_file_id: + error_dict = { + 'error_msg': '%s not found.' % src_path + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + # dst resource check + if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_path): + error_dict = { + 'error_msg': 'Folder %s not found.' % dst_path + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + # src path permission check, user must has `rw` permission for src folder. + if check_folder_permission(request, src_repo_id, src_parent_dir) != 'rw': + error_dict = { + 'error_msg': 'Permission denied.' + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + # dst path permission check, user must has `rw` permission for dst folder. + if check_folder_permission(request, dst_repo_id, dst_path) != 'rw': + error_dict = { + 'error_msg': 'Permission denied.' + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + try: + dst_obj_name = check_filename_with_rename(dst_repo_id, + dst_parent_dir, dst_obj_name) + # replace=False, username=username, need_progress=0, synchronous=1 + seafile_api.move_file(src_repo_id, src_parent_dir, src_obj_name, + dst_repo_id, dst_parent_dir, dst_obj_name, + False, username, 0, 1) + except Exception as e: + logger.error(e) + error_dict = { + 'error_msg': 'Internal Server Error' + } + common_dict.update(error_dict) + result['failed'].append(common_dict) + continue + + common_dict['dst_obj_name'] = dst_obj_name + result['success'].append(common_dict) + + return Response(result) diff --git a/seahub/api2/views.py b/seahub/api2/views.py index 7be5021c14..38c1191958 100644 --- a/seahub/api2/views.py +++ b/seahub/api2/views.py @@ -44,7 +44,7 @@ from seahub.avatar.templatetags.avatar_tags import api_avatar_url, avatar from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, \ grp_avatar from seahub.base.accounts import User -from seahub.base.models import UserStarredFiles, DeviceToken +from seahub.base.models import UserStarredFiles, DeviceToken, RepoSecretKey from seahub.share.models import ExtraSharePermission, ExtraGroupsSharePermission from seahub.share.utils import is_repo_admin, check_group_share_in_permission from seahub.base.templatetags.seahub_tags import email2nickname, \ @@ -74,7 +74,8 @@ from seahub.utils.file_revisions import get_file_revisions_after_renamed from seahub.utils.devices import do_unlink_device from seahub.utils.repo import get_repo_owner, get_library_storages, \ get_locked_files_by_dir, get_related_users_by_repo, \ - is_valid_repo_id_format, can_set_folder_perm_by_user + is_valid_repo_id_format, can_set_folder_perm_by_user, \ + add_encrypted_repo_secret_key_to_database from seahub.utils.star import star_file, unstar_file from seahub.utils.file_types import DOCUMENT from seahub.utils.file_size import get_file_size_unit @@ -92,7 +93,8 @@ if HAS_OFFICE_CONVERTER: import seahub.settings as settings from seahub.settings import THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, \ FILE_LOCK_EXPIRATION_DAYS, ENABLE_STORAGE_CLASSES, \ - ENABLE_THUMBNAIL, ENABLE_FOLDER_PERM, STORAGE_CLASS_MAPPING_POLICY + ENABLE_THUMBNAIL, ENABLE_FOLDER_PERM, STORAGE_CLASS_MAPPING_POLICY, \ + ENABLE_RESET_ENCRYPTED_REPO_PASSWORD try: from seahub.settings import CLOUD_MODE except ImportError: @@ -904,6 +906,9 @@ class Repos(APIView): repo_id = seafile_api.create_repo(repo_name, repo_desc, username, passwd) + if passwd and ENABLE_RESET_ENCRYPTED_REPO_PASSWORD: + add_encrypted_repo_secret_key_to_database(repo_id, passwd) + return repo_id, None def _create_enc_repo(self, request, repo_id, repo_name, repo_desc, username, org_id): @@ -1054,8 +1059,13 @@ class PubRepos(APIView): def set_repo_password(request, repo, password): assert password, 'password must not be none' + repo_id = repo.id try: - seafile_api.set_passwd(repo.id, request.user.username, password) + seafile_api.set_passwd(repo_id, request.user.username, password) + + if ENABLE_RESET_ENCRYPTED_REPO_PASSWORD: + add_encrypted_repo_secret_key_to_database(repo_id, password) + except SearpcError, e: if e.msg == 'Bad arguments': return api_error(status.HTTP_400_BAD_REQUEST, e.msg) @@ -1068,6 +1078,7 @@ def set_repo_password(request, repo, password): else: return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, e.msg) + def check_set_repo_password(request, repo): if not check_permission(repo.id, request.user.username): return api_error(status.HTTP_403_FORBIDDEN, @@ -2894,6 +2905,10 @@ class FileDetailView(APIView): except UserStarredFiles.DoesNotExist: entry["starred"] = False + entry["last_modifier_email"] = latest_contributor + entry["last_modifier_name"] = email2nickname(latest_contributor) + entry["last_modifier_contact_email"] = email2contact_email(latest_contributor) + return HttpResponse(json.dumps(entry), status=200, content_type=json_content_type) @@ -3245,10 +3260,6 @@ class DirView(APIView): return api_error(HTTP_520_OPERATION_FAILED, 'Failed to make directory.') else: - if not is_seafile_pro(): - return api_error(status.HTTP_400_BAD_REQUEST, - 'Feature not supported.') - if check_folder_permission(request, repo_id, '/') != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) @@ -4727,7 +4738,8 @@ class OrganizationView(APIView): def post(self, request, format=None): if not CLOUD_MODE or not MULTI_TENANCY: - return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied') + error_msg = 'Feature is not enabled.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) username = request.POST.get('username', None) password = request.POST.get('password', None) diff --git a/seahub/base/context_processors.py b/seahub/base/context_processors.py index 42b41670de..7814c254eb 100644 --- a/seahub/base/context_processors.py +++ b/seahub/base/context_processors.py @@ -16,7 +16,7 @@ from django.utils.functional import lazy from constance import config from seahub.settings import SEAFILE_VERSION, SITE_TITLE, SITE_NAME, \ - MAX_FILE_NAME, LOGO_PATH, LOGO_WIDTH, LOGO_HEIGHT,\ + MAX_FILE_NAME, LOGO_PATH, BRANDING_CSS, LOGO_WIDTH, LOGO_HEIGHT,\ SHOW_REPO_DOWNLOAD_BUTTON, SITE_ROOT, ENABLE_GUEST_INVITATION, \ FAVICON_PATH, ENABLE_THUMBNAIL, THUMBNAIL_SIZE_FOR_ORIGINAL, \ MEDIA_ROOT, SHOW_LOGOUT_ICON, CUSTOM_LOGO_PATH, CUSTOM_FAVICON_PATH @@ -84,6 +84,7 @@ def base(request): result = { 'seafile_version': SEAFILE_VERSION, 'site_title': config.SITE_TITLE, + 'branding_css': BRANDING_CSS, 'enable_branding_css': config.ENABLE_BRANDING_CSS, 'favicon_path': favicon_path, 'logo_path': logo_path, diff --git a/seahub/base/models.py b/seahub/base/models.py index 10ad6fa9aa..9f6dc8ce8e 100644 --- a/seahub/base/models.py +++ b/seahub/base/models.py @@ -315,3 +315,30 @@ class ClientLoginToken(models.Model): def __unicode__(self): return "/".join(self.username, self.token) + + +class RepoSecretKeyManager(models.Manager): + + def get_secret_key(self, repo_id): + try: + repo_secret_key = self.get(repo_id=repo_id) + except RepoSecretKey.DoesNotExist: + return None + + return repo_secret_key.secret_key + + def add_secret_key(self, repo_id, secret_key): + + repo_secret_key = self.model(repo_id=repo_id, secret_key=secret_key) + repo_secret_key.save(using=self._db) + + return repo_secret_key + + +class RepoSecretKey(models.Model): + """ + """ + repo_id = models.CharField(unique=True, max_length=36, db_index=True) + secret_key = models.CharField(max_length=44) + + objects = RepoSecretKeyManager() diff --git a/seahub/oauth/views.py b/seahub/oauth/views.py index 85b6bb84d7..ef196aef56 100644 --- a/seahub/oauth/views.py +++ b/seahub/oauth/views.py @@ -34,6 +34,7 @@ if ENABLE_OAUTH: TOKEN_URL = getattr(settings, 'OAUTH_TOKEN_URL', '') USER_INFO_URL = getattr(settings, 'OAUTH_USER_INFO_URL', '') SCOPE = getattr(settings, 'OAUTH_SCOPE', '') + ACCESS_TOKEN_IN_URI = getattr(settings, 'OAUTH_ACCESS_TOKEN_IN_URI', False) # Used for init an user for Seahub. PROVIDER_DOMAIN = getattr(settings, 'OAUTH_PROVIDER_DOMAIN', '') @@ -112,7 +113,7 @@ def oauth_callback(request): redirect_uri=REDIRECT_URL) try: - session.fetch_token(TOKEN_URL, client_secret=CLIENT_SECRET, + token = session.fetch_token(TOKEN_URL, client_secret=CLIENT_SECRET, authorization_response=request.get_full_path()) if session._client.__dict__['token'].has_key('user_id'): @@ -121,7 +122,11 @@ def oauth_callback(request): user_id = session._client.__dict__['token']['user_id'] user_info_resp = session.get(USER_INFO_URL + '?user_id=%s' % user_id) else: - user_info_resp = session.get(USER_INFO_URL) + user_info_url = USER_INFO_URL + if ACCESS_TOKEN_IN_URI: + code = request.GET.get('code') + user_info_url = USER_INFO_URL + '?access_token=%s&code=%s' % (token['access_token'], code) + user_info_resp = session.get(user_info_url) except Exception as e: logger.error(e) @@ -130,7 +135,7 @@ def oauth_callback(request): }) def format_user_info(user_info_resp): - + logger.info('user info resp: %s' % user_info_resp.text) error = False user_info = {} user_info_json = user_info_resp.json() diff --git a/seahub/profile/templates/profile/set_profile.html b/seahub/profile/templates/profile/set_profile.html index a4c64badec..f7b258dbb3 100644 --- a/seahub/profile/templates/profile/set_profile.html +++ b/seahub/profile/templates/profile/set_profile.html @@ -19,10 +19,6 @@
  • {% trans "Language" %}
  • - {% if user.permissions.can_add_repo %} -
  • {% trans "Default Library" %}
  • - {% endif %} - {% if two_factor_auth_enabled %}
  • {% trans "Two-Factor Authentication" %}
  • {% endif %} @@ -64,12 +60,7 @@
    {% endif %} - {% if form.department and form.telephone %} - - {% for error in form.department.errors %} - {{ error|escape }} - {% endfor %} -
    + {% if form.telephone %} {% for error in form.telephone.errors %} {{ error|escape }} @@ -114,27 +105,6 @@ -{% if user.permissions.can_add_repo %} -
    -

    {% trans "Default Library Setting" %}

    - {% if default_repo %} -

    {% trans "Your default library:" %} {{default_repo.name}}.

    - {% endif %} -

    {% trans "Default library is the default place to store your personal documents and pictures." %}

    - -
    -
    {% csrf_token %} -

    {% trans "Choose default library:" %}

    -
    -
    -
    - -

    {% trans "Please click and choose a library."%}

    - - -
    -{% endif %} - {% if two_factor_auth_enabled %}

    {% trans "Two-Factor Authentication" %}

    @@ -237,30 +207,6 @@ $('#account-delete-btn').on('click', function () { }); }); - -{% if user.permissions.can_add_repo %} -var all_repos = []; -{% for a_repo in owned_repos %} - all_repos.push({ - 'text': HTMLescape('{{ a_repo.props.name|escapejs }}'), - 'data': {'repo_id': '{{ a_repo.props.id }}', 'path': '/'} - }); -{% endfor %} -$('#choose-default-lib').on('click', function() { - var $form = $('#default-lib-form'); - $form.modal({appendTo:'#main', autoResize:true, focus:false}); - $('#simplemodal-container').css({'width':'auto', 'height':'auto'}); - FileTree.renderDirTree($('#repos-dirs').data('site_root', '{{SITE_ROOT}}'), $form, all_repos); -}); -$('#default-lib-form').on('submit', function() { - var dst_repo = $('[name="dst_repo"]', $(this)).val(); - if (!$.trim(dst_repo)) { - $('.error', $(this)).removeClass('hide'); - return false; - } -}); -{% endif %} - {% if ENABLE_ADDRESSBOOK_OPT_IN %} $("#list-in-address-book input[type='checkbox']").on('change', function() { var _this = $(this), data = {}; diff --git a/seahub/profile/templates/profile/user_profile.html b/seahub/profile/templates/profile/user_profile.html index 91ec088141..ae7e68adc9 100644 --- a/seahub/profile/templates/profile/user_profile.html +++ b/seahub/profile/templates/profile/user_profile.html @@ -11,12 +11,6 @@
      {% if d_profile %} - {% if d_profile.department %} - - {% endif %} {% if d_profile.telephone %}
    <% } else { %> - + <% } %> <% } %> <% } %> @@ -286,7 +286,7 @@ <% } %> <% if (is_staff || is_repo_owner) { %> - + <% } %> <% } %> @@ -317,11 +317,12 @@ <% } %> <% if (is_staff || is_repo_owner || is_admin) { %> - + <% } %> <% } else { %> <% if (is_staff) { %> + <% if (owner == group_id + '@seafile_group') { %> {# this repo belongs to the current group #}
    + <% } else { %> + + <% } %> <% } %> <% } %> @@ -342,7 +346,7 @@ <% } %> <% if (is_staff || is_repo_owner) { %> - + <% } %> <% } %> diff --git a/seahub/templates/sysadmin/sys_org_admin.html b/seahub/templates/sysadmin/sys_org_admin.html index e7f059cc39..df19755d01 100644 --- a/seahub/templates/sysadmin/sys_org_admin.html +++ b/seahub/templates/sysadmin/sys_org_admin.html @@ -115,9 +115,7 @@ $('#add-org-form').on('submit', function() { 'password2': pwd2 }, success: function(data) { - if (data['success']) { - location.reload(true); - } + location.reload(true); }, error: function(jqXHR, textStatus, errorThrown) { if (jqXHR.responseText) { @@ -125,9 +123,8 @@ $('#add-org-form').on('submit', function() { } else { apply_form_error(form_id, "{% trans "Failed. Please check the network." %}"); } + enable(submit_btn); } - }).complete(function() { - enable(submit_btn); }); return false; diff --git a/seahub/templates/sysadmin/sys_useradmin.html b/seahub/templates/sysadmin/sys_useradmin.html index 60be0cf814..c4b4912365 100644 --- a/seahub/templates/sysadmin/sys_useradmin.html +++ b/seahub/templates/sysadmin/sys_useradmin.html @@ -45,8 +45,6 @@

    -
    -
    {% if is_pro %} @@ -138,7 +136,6 @@ $('#add-user-form').on('submit', function() { form_id = $(this).attr('id'), email = $.trim(form.children('[name="email"]').val()), name = $.trim($('[name="name"]', form).val()), - department = $.trim($('[name="department"]', form).val()), {% if is_pro %} role = $('select[name="role"]', form).val(), {% endif %} @@ -173,7 +170,6 @@ $('#add-user-form').on('submit', function() { data: { 'email': email, 'name': name, - 'department': department, {% if is_pro %} 'role': role, {% endif %} diff --git a/seahub/templates/sysadmin/sysadmin_backbone.html b/seahub/templates/sysadmin/sysadmin_backbone.html index 69ea63e418..1912e336be 100644 --- a/seahub/templates/sysadmin/sysadmin_backbone.html +++ b/seahub/templates/sysadmin/sysadmin_backbone.html @@ -18,6 +18,7 @@ {% endcompress %} +{% if branding_css != '' %}{% endif %} {% if enable_branding_css %}{% endif %} diff --git a/seahub/templates/sysadmin/userinfo.html b/seahub/templates/sysadmin/userinfo.html index 334a985afc..786943dfb3 100644 --- a/seahub/templates/sysadmin/userinfo.html +++ b/seahub/templates/sysadmin/userinfo.html @@ -88,18 +88,6 @@ -
    {% trans "Department" %}
    -
    - - {% if d_profile and d_profile.department %} - {{ d_profile.department }} - {% else %} - -- - {% endif %} - - -
    - {% if d_profile and d_profile.telephone %}
    {% trans "Telephone" %}
    {{ d_profile.telephone }}
    @@ -572,43 +560,6 @@ $('#set-reference-id-form').on('submit', function() { return false; }); -$('#set-dept-form').on('submit', function() { - var department = $.trim($('[name="department"]', $(this)).val()); - var $department = $('#department'); - var $error = $('.error', $(this)); - var $submitBtn = $('[type="submit"]', $(this)); - disable($submitBtn); - - $.ajax({ - url: '{% url 'api-v2.1-admin-user' email %}', - type: 'PUT', - dataType: 'json', - cache: false, - beforeSend: prepareCSRFToken, - data: {'department': department}, - success: function(data) { - if (department == '') { - $department.html('--'); - } else { - $department.html(HTMLescape(data['department'])); - } - $.modal.close(); - }, - error: function(xhr, textStatus, errorThrown) { - var err_msg; - if (xhr.responseText) { - err_msg = JSON.parse(xhr.responseText).error_msg; - } else { - err_msg = "{% trans "Failed. Please check the network." %}"; - } - $error.html(err_msg).show(); - enable($submitBtn); - } - }); - - return false; -}); - $('#set-quota-form').on('submit', function() { var form = $(this), form_id = form.attr('id'), diff --git a/seahub/templates/view_file_onlyoffice.html b/seahub/templates/view_file_onlyoffice.html index 4d42e3f5ec..0aafb5875d 100644 --- a/seahub/templates/view_file_onlyoffice.html +++ b/seahub/templates/view_file_onlyoffice.html @@ -1,4 +1,4 @@ -{% load seahub_tags i18n %} +{% load seahub_tags i18n staticfiles %} @@ -15,33 +15,61 @@ html, body { padding:0; margin:0; height:100%; }
    {% get_current_language as LANGUAGE_CODE %} + + + diff --git a/seahub/templates/view_file_wopi.html b/seahub/templates/view_file_wopi.html index 0f78d9eac4..94b21a6db3 100644 --- a/seahub/templates/view_file_wopi.html +++ b/seahub/templates/view_file_wopi.html @@ -1,5 +1,5 @@ -{% load i18n %} +{% load i18n staticfiles %} {{doc_title}} @@ -38,9 +38,37 @@ + + + diff --git a/seahub/templates/view_shared_dir.html b/seahub/templates/view_shared_dir.html index 096f7256cd..1cccbe6655 100644 --- a/seahub/templates/view_shared_dir.html +++ b/seahub/templates/view_shared_dir.html @@ -183,7 +183,7 @@ var magnificOptions = { var img_link = '' + "{% trans "Open in New Tab" %}" + ''; return img_name + '
    ' + img_link; }, - tError: '{% trans 'The image could not be loaded.' %}' // Error message when image could not be loaded + tError: "{% trans "The image could not be loaded." %}" // Error message when image could not be loaded } }; diff --git a/seahub/templates/view_shared_upload_link.html b/seahub/templates/view_shared_upload_link.html index 29da179b96..6de0a51fae 100644 --- a/seahub/templates/view_shared_upload_link.html +++ b/seahub/templates/view_shared_upload_link.html @@ -215,7 +215,7 @@ form.fileupload({ file.relative_path = file_path.substring(0, file_path.lastIndexOf('/') + 1) + file.name; } - var uploaded_done_link = "{% url "upload_file_done" %}" + "?fn=" + e(file.name) + "&repo_id=" + e("{{repo.id}}"); + var uploaded_done_link = "{% url "upload_file_done" %}" + "?fn=" + e(file.name) + "&repo_id=" + e("{{repo.id}}") + "&token=" + e("{{ uploadlink.token }}"); var path = "{{path|escapejs}}"; if (file_path) { uploaded_done_link += '&p=' + e(path + file_path.substr(0, file_path.lastIndexOf('/') + 1)); diff --git a/seahub/urls.py b/seahub/urls.py index d211b1c165..c8ef046c14 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -39,7 +39,8 @@ from seahub.api2.endpoints.shared_repos import SharedRepos, SharedRepo from seahub.api2.endpoints.upload_links import UploadLinks, UploadLink, \ UploadLinkUpload from seahub.api2.endpoints.repos_batch import ReposBatchView, \ - ReposBatchCopyDirView, ReposBatchCreateDirView + ReposBatchCopyDirView, ReposBatchCreateDirView, \ + ReposBatchCopyItemView, ReposBatchMoveItemView from seahub.api2.endpoints.repos import RepoView from seahub.api2.endpoints.file import FileView from seahub.api2.endpoints.file_history import FileHistoryView @@ -56,6 +57,7 @@ from seahub.api2.endpoints.query_zip_progress import QueryZipProgressView from seahub.api2.endpoints.cancel_zip_task import CancelZipTaskView from seahub.api2.endpoints.copy_move_task import CopyMoveTaskView from seahub.api2.endpoints.query_copy_move_progress import QueryCopyMoveProgressView +from seahub.api2.endpoints.move_folder_merge import MoveFolderMergeView from seahub.api2.endpoints.invitations import InvitationsView, InvitationsBatchView from seahub.api2.endpoints.invitation import InvitationView from seahub.api2.endpoints.notifications import NotificationsView, NotificationView @@ -96,6 +98,7 @@ from seahub.api2.endpoints.admin.upload_links import AdminUploadLink, \ AdminUploadLinkUpload, AdminUploadLinkCheckPassword from seahub.api2.endpoints.admin.users_batch import AdminUsersBatch from seahub.api2.endpoints.admin.operation_logs import AdminOperationLogs +from seahub.api2.endpoints.admin.organizations import AdminOrganization from seahub.api2.endpoints.admin.org_users import AdminOrgUsers, AdminOrgUser from seahub.api2.endpoints.admin.logo import AdminLogo from seahub.api2.endpoints.admin.favicon import AdminFavicon @@ -252,6 +255,8 @@ urlpatterns = [ url(r'^api/v2.1/repos/batch/$', ReposBatchView.as_view(), name='api-v2.1-repos-batch'), url(r'^api/v2.1/repos/batch-copy-dir/$', ReposBatchCopyDirView.as_view(), name='api-v2.1-repos-batch-copy-dir'), url(r'^api/v2.1/repos/batch-create-dir/$', ReposBatchCreateDirView.as_view(), name='api-v2.1-repos-batch-create-dir'), + url(r'^api/v2.1/repos/batch-copy-item/$', ReposBatchCopyItemView.as_view(), name='api-v2.1-repos-batch-copy-item'), + url(r'^api/v2.1/repos/batch-move-item/$', ReposBatchMoveItemView.as_view(), name='api-v2.1-repos-batch-move-item'), ## user::deleted repos url(r'^api/v2.1/deleted-repos/$', DeletedRepos.as_view(), name='api2-v2.1-deleted-repos'), @@ -276,6 +281,9 @@ urlpatterns = [ url(r'^api/v2.1/cancel-zip-task/$', CancelZipTaskView.as_view(), name='api-v2.1-cancel-zip-task'), url(r'^api/v2.1/copy-move-task/$', CopyMoveTaskView.as_view(), name='api-v2.1-copy-move-task'), url(r'^api/v2.1/query-copy-move-progress/$', QueryCopyMoveProgressView.as_view(), name='api-v2.1-query-copy-move-progress'), + + url(r'^api/v2.1/move-folder-merge/$', MoveFolderMergeView.as_view(), name='api-v2.1-move-folder-merge'), + url(r'^api/v2.1/notifications/$', NotificationsView.as_view(), name='api-v2.1-notifications'), url(r'^api/v2.1/notification/$', NotificationView.as_view(), name='api-v2.1-notification'), url(r'^api/v2.1/user-enabled-modules/$', UserEnabledModulesView.as_view(), name='api-v2.1-user-enabled-module'), @@ -374,6 +382,7 @@ urlpatterns = [ url(r'^api/v2.1/admin/admin-role/$', AdminAdminRole.as_view(), name='api-v2.1-admin-admin-role'), ## admin::organizations + url(r'^api/v2.1/admin/organizations/(?P\d+)/$', AdminOrganization.as_view(), name='api-v2.1-admin-organization'), url(r'^api/v2.1/admin/organizations/(?P\d+)/users/$', AdminOrgUsers.as_view(), name='api-v2.1-admin-org-users'), url(r'^api/v2.1/admin/organizations/(?P\d+)/users/(?P[^/]+)/$', AdminOrgUser.as_view(), name='api-v2.1-admin-org-user'), @@ -580,7 +589,7 @@ if getattr(settings, 'ENABLE_ADFS_LOGIN', False): urlpatterns += [ url(r'^saml2/acs/$', assertion_consumer_service, name='saml2_acs'), url(r'^saml2/complete/$', auth_complete, name='saml2_complete'), - (r'^saml2/', include('djangosaml2.urls')), + url(r'^saml2/', include('djangosaml2.urls')), ] if getattr(settings, 'ENABLE_ONLYOFFICE', False): diff --git a/seahub/utils/file_op.py b/seahub/utils/file_op.py index f45fdb7f07..0da43fd27b 100644 --- a/seahub/utils/file_op.py +++ b/seahub/utils/file_op.py @@ -11,6 +11,8 @@ from seahub.settings import ENABLE_FOLDER_PERM # Get an instance of a logger logger = logging.getLogger(__name__) +ONLINE_OFFICE_LOCK_OWNER = 'OnlineOffice' + def check_file_lock(repo_id, file_path, username): """ Check if file is locked to current user @@ -37,3 +39,14 @@ def check_file_lock(repo_id, file_path, username): return (True, True) else: raise SearpcError('check file lock error') + +def if_locked_by_online_office(repo_id, path): + + locked_by_online_office = False + if is_pro_version(): + lock_info = seafile_api.get_lock_info(repo_id, path) + if lock_info and lock_info.user == ONLINE_OFFICE_LOCK_OWNER: + locked_by_online_office = True + + return locked_by_online_office + diff --git a/seahub/utils/repo.py b/seahub/utils/repo.py index ac1a03cb63..2981204e01 100644 --- a/seahub/utils/repo.py +++ b/seahub/utils/repo.py @@ -6,6 +6,7 @@ import seaserv from seaserv import seafile_api, ccnet_api from seahub.utils import EMPTY_SHA1, is_org_context, is_pro_version +from seahub.base.models import RepoSecretKey from seahub.settings import ENABLE_STORAGE_CLASSES, \ STORAGE_CLASS_MAPPING_POLICY, ENABLE_FOLDER_PERM @@ -39,7 +40,6 @@ def get_repo_owner(request, repo_id): return seafile_api.get_repo_owner(repo_id) def is_repo_owner(request, repo_id, username): - return username == get_repo_owner(request, repo_id) def get_repo_shared_users(repo_id, repo_owner, include_groups=True): @@ -218,5 +218,14 @@ def can_set_folder_perm_by_user(username, repo, repo_owner): return False return True +def add_encrypted_repo_secret_key_to_database(repo_id, password): + try: + if not RepoSecretKey.objects.get_secret_key(repo_id): + # get secret_key, then save it to database + secret_key = seafile_api.get_secret_key(repo_id, password) + RepoSecretKey.objects.add_secret_key(repo_id, secret_key) + except Exception as e: + logger.error(e) + # TODO from seahub.share.utils import is_repo_admin diff --git a/seahub/views/ajax.py b/seahub/views/ajax.py index 90a214a1f5..1a91a1f17b 100644 --- a/seahub/views/ajax.py +++ b/seahub/views/ajax.py @@ -46,7 +46,7 @@ from seahub.utils import check_filename_with_rename, EMPTY_SHA1, \ get_file_type_and_ext, is_pro_version from seahub.utils.star import get_dir_starred_files from seahub.utils.file_types import IMAGE, VIDEO -from seahub.utils.file_op import check_file_lock +from seahub.utils.file_op import check_file_lock, ONLINE_OFFICE_LOCK_OWNER from seahub.utils.repo import get_locked_files_by_dir, get_repo_owner from seahub.utils.error_msg import file_type_error_msg, file_size_error_msg from seahub.base.accounts import User @@ -370,10 +370,14 @@ def list_lib_dir(request, repo_id): f_['is_locked'] = True if f.is_locked else False f_['lock_owner'] = f.lock_owner f_['lock_owner_name'] = email2nickname(f.lock_owner) - if username == f.lock_owner: + + f_['locked_by_me'] = False + if f.lock_owner == username: + f_['locked_by_me'] = True + + if f.lock_owner == ONLINE_OFFICE_LOCK_OWNER and \ + repo_owner == username: f_['locked_by_me'] = True - else: - f_['locked_by_me'] = False dirent_list.append(f_) @@ -968,9 +972,17 @@ def upload_file_done(request): result['error'] = _('Wrong repo id') return HttpResponse(json.dumps(result), status=400, content_type=ct) - owner = seafile_api.get_repo_owner(repo_id) - if not owner: # this is an org repo, get org repo owner - owner = seafile_api.get_org_repo_owner(repo_id) + # get upload link share creator + token = request.GET.get('token', '') + if not token: + result['error'] = _('Argument missing') + return HttpResponse(json.dumps(result), status=400, content_type=ct) + + uls = UploadLinkShare.objects.get_valid_upload_link_by_token(token) + if uls is None: + result['error'] = _('Bad upload link token.') + return HttpResponse(json.dumps(result), status=400, content_type=ct) + creator = uls.username file_path = path.rstrip('/') + '/' + filename if seafile_api.get_file_id_by_path(repo_id, file_path) is None: @@ -981,7 +993,7 @@ def upload_file_done(request): upload_file_successful.send(sender=None, repo_id=repo_id, file_path=file_path, - owner=owner) + owner=creator) return HttpResponse(json.dumps({'success': True}), content_type=ct) diff --git a/seahub/views/file.py b/seahub/views/file.py index 7a758dbe87..cd1983cf01 100644 --- a/seahub/views/file.py +++ b/seahub/views/file.py @@ -61,9 +61,10 @@ from seahub.utils.timeutils import utc_to_local from seahub.utils.file_types import (IMAGE, PDF, SVG, DOCUMENT, SPREADSHEET, AUDIO, MARKDOWN, TEXT, VIDEO) from seahub.utils.star import is_file_starred -from seahub.utils.http import json_response, int_param, \ +from seahub.utils.http import json_response, \ BadRequestException, RequestForbbiddenException -from seahub.utils.file_op import check_file_lock +from seahub.utils.file_op import check_file_lock, \ + ONLINE_OFFICE_LOCK_OWNER, if_locked_by_online_office from seahub.views import check_folder_permission, \ get_unencry_rw_repos_by_user from seahub.utils.repo import is_repo_owner @@ -107,6 +108,7 @@ try: except ImportError: ENABLE_ONLYOFFICE = False + # Get an instance of a logger logger = logging.getLogger(__name__) @@ -415,7 +417,10 @@ def view_lib_file(request, repo_id, path): is_locked, locked_by_me = check_file_lock(repo_id, path, username) except Exception as e: logger.error(e) - is_locked, locked_by_me = False, False + is_locked = False + locked_by_me = False + + locked_by_online_office = if_locked_by_online_office(repo_id, path) if is_pro_version() and permission == 'rw': can_lock_unlock_file = True @@ -565,22 +570,39 @@ def view_lib_file(request, repo_id, path): # then check if can edit file if ENABLE_OFFICE_WEB_APP_EDIT and permission == 'rw' and \ fileext in OFFICE_WEB_APP_EDIT_FILE_EXTENSION and \ - ((not is_locked) or (is_locked and locked_by_me)): + ((not is_locked) or (is_locked and locked_by_me) or \ + (is_locked and locked_by_online_office)): action_name = 'edit' wopi_dict = get_wopi_dict(username, repo_id, path, action_name, request.LANGUAGE_CODE) - - if wopi_dict: - wopi_dict['doc_title'] = filename - send_file_access_msg(request, repo, path, 'web') - return render(request, 'view_file_wopi.html', wopi_dict) - else: + if not wopi_dict: return_dict['err'] = _(u'Error when prepare Office Online file preview page.') return render(request, 'view_file_base.html', return_dict) + if is_pro_version() and action_name == 'edit': + if not is_locked: + seafile_api.lock_file(repo_id, path, ONLINE_OFFICE_LOCK_OWNER, 0) + elif locked_by_online_office: + seafile_api.refresh_file_lock(repo_id, path) + + wopi_dict['doc_title'] = filename + wopi_dict['repo_id'] = repo_id + wopi_dict['path'] = path + send_file_access_msg(request, repo, path, 'web') + + return render(request, 'view_file_wopi.html', wopi_dict) + if ENABLE_ONLYOFFICE and fileext in ONLYOFFICE_FILE_EXTENSION: - doc_key = hashlib.md5(force_bytes(repo_id + path + file_id)).hexdigest()[:20] + + if repo.is_virtual: + origin_repo_id = repo.origin_repo_id + origin_file_path = posixpath.join(repo.origin_path, path.strip('/')) + doc_key = hashlib.md5(force_bytes(origin_repo_id + \ + origin_file_path + file_id)).hexdigest()[:20] + else: + doc_key = hashlib.md5(force_bytes(repo_id + path + file_id)).hexdigest()[:20] + if fileext in ('xls', 'xlsx', 'ods', 'fods', 'csv'): document_type = 'spreadsheet' elif fileext in ('pptx', 'ppt', 'odp', 'fodp', 'ppsx', 'pps'): @@ -603,15 +625,23 @@ def view_lib_file(request, repo_id, path): cache.set("ONLYOFFICE_%s" % doc_key, doc_info, None) + can_edit = False if permission == 'rw' and \ fileext in ONLYOFFICE_EDIT_FILE_EXTENSION and \ - ((not is_locked) or (is_locked and locked_by_me)): + ((not is_locked) or (is_locked and locked_by_me) or \ + (is_locked and locked_by_online_office)): can_edit = True - else: - can_edit = False + + if is_pro_version() and can_edit: + if not is_locked: + seafile_api.lock_file(repo_id, path, ONLINE_OFFICE_LOCK_OWNER, 0) + elif locked_by_online_office: + seafile_api.refresh_file_lock(repo_id, path) send_file_access_msg(request, repo, path, 'web') return render(request, 'view_file_onlyoffice.html', { + 'repo_id': repo_id, + 'path': path, 'ONLYOFFICE_APIJS_URL': ONLYOFFICE_APIJS_URL, 'file_type': fileext, 'doc_key': doc_key, diff --git a/seahub/views/sysadmin.py b/seahub/views/sysadmin.py index 16041e735a..65a3e791e0 100644 --- a/seahub/views/sysadmin.py +++ b/seahub/views/sysadmin.py @@ -1418,6 +1418,9 @@ def sys_org_info_user(request, org_id): org_id = int(org_id) + if not ccnet_api.get_org_by_id(org_id): + raise Http404 + org_basic_info = sys_get_org_base_info(org_id) users = org_basic_info["users"] last_logins = UserLastLogin.objects.filter(username__in=[x.email for x in users]) @@ -1447,6 +1450,10 @@ def sys_org_info_user(request, org_id): def sys_org_info_group(request, org_id): org_id = int(org_id) + + if not ccnet_api.get_org_by_id(org_id): + raise Http404 + org_basic_info = sys_get_org_base_info(org_id) return render(request, 'sysadmin/sys_org_info_group.html', @@ -1457,6 +1464,10 @@ def sys_org_info_group(request, org_id): def sys_org_info_library(request, org_id): org_id = int(org_id) + + if not ccnet_api.get_org_by_id(org_id): + raise Http404 + org_basic_info = sys_get_org_base_info(org_id) # library @@ -1477,6 +1488,10 @@ def sys_org_info_library(request, org_id): def sys_org_info_setting(request, org_id): org_id = int(org_id) + + if not ccnet_api.get_org_by_id(org_id): + raise Http404 + org_basic_info = sys_get_org_base_info(org_id) if getattr(settings, 'ORG_MEMBER_QUOTA_ENABLED', False): @@ -1885,16 +1900,14 @@ def batch_add_user_example(request): next = SITE_ROOT data_list = [] head = [_('Email'), _('Password'), _('Name')+ '(' + _('Optional') + ')', - _('Department')+ '(' + _('Optional') + ')', _('Role')+ - '(' + _('Optional') + ')', _('Space Quota') + '(MB, ' + _('Optional') + ')'] + _('Role') + '(' + _('Optional') + ')', _('Space Quota') + '(MB, ' + _('Optional') + ')'] for i in xrange(5): username = "test" + str(i) +"@example.com" password = "123456" name = "test" + str(i) - department = "department" + str(i) role = "default" quota = "1000" - data_list.append([username, password, name, department, role, quota]) + data_list.append([username, password, name, role, quota]) wb = write_xls('sample', head, data_list) if not wb: @@ -1970,21 +1983,14 @@ def batch_add_user(request): logger.error(e) try: - department = row[3].strip() - if len(department) <= 512: - DetailedProfile.objects.add_or_update(username, department, '') - except Exception as e: - logger.error(e) - - try: - role = row[4].strip() + role = row[3].strip() if is_pro_version() and role in get_available_roles(): User.objects.update_role(username, role) except Exception as e: logger.error(e) try: - space_quota_mb = int(row[5]) + space_quota_mb = int(row[4]) if space_quota_mb >= 0: space_quota = int(space_quota_mb) * get_file_size_unit('MB') seafile_api.set_user_quota(username, space_quota) diff --git a/seahub/wiki/views.py b/seahub/wiki/views.py index ba60e37302..deddfa8750 100644 --- a/seahub/wiki/views.py +++ b/seahub/wiki/views.py @@ -46,7 +46,9 @@ def slug(request, slug, page_name="home"): raise Http404 req_user = request.user.username - if req_user == wiki.username or check_folder_permission( + if not req_user: + user_can_write = False + elif req_user == wiki.username or check_folder_permission( request, wiki.repo_id, '/') == 'rw': user_can_write = True else: diff --git a/seahub/wopi/views.py b/seahub/wopi/views.py index 250e181f5b..051fd53f79 100644 --- a/seahub/wopi/views.py +++ b/seahub/wopi/views.py @@ -21,7 +21,7 @@ from seaserv import seafile_api from seahub.base.accounts import User from seahub.utils import gen_inner_file_get_url, \ gen_inner_file_upload_url, get_file_type_and_ext, is_pro_version -from seahub.utils.file_op import check_file_lock +from seahub.utils.file_op import check_file_lock, if_locked_by_online_office from seahub.base.templatetags.seahub_tags import email2nickname from seahub.settings import SITE_ROOT @@ -183,13 +183,15 @@ class WOPIFilesView(APIView): return HttpResponse(json.dumps({}), status=500, content_type=json_content_type) + locked_by_online_office = if_locked_by_online_office(repo_id, file_path) + perm = seafile_api.check_permission_by_path(repo_id, file_path, request_user) if ENABLE_OFFICE_WEB_APP_EDIT and not repo.encrypted and \ - perm == 'rw' and ((not is_locked) or (is_locked and locked_by_me)) and \ - fileext in OFFICE_WEB_APP_EDIT_FILE_EXTENSION: - + perm == 'rw' and fileext in OFFICE_WEB_APP_EDIT_FILE_EXTENSION and \ + ((not is_locked) or (is_locked and locked_by_me) or \ + (is_locked and locked_by_online_office)): result['UserCanWrite'] = True return HttpResponse(json.dumps(result), status=200, diff --git a/sql/mysql.sql b/sql/mysql.sql index 3a453f0f92..68aeea4890 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -101,7 +101,7 @@ CREATE TABLE `auth_permission` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `auth_permission` DISABLE KEYS */; -INSERT INTO `auth_permission` VALUES (1,'Can add content type',1,'add_contenttype'),(2,'Can change content type',1,'change_contenttype'),(3,'Can delete content type',1,'delete_contenttype'),(4,'Can change config',2,'change_config'),(5,'Can add session',3,'add_session'),(6,'Can change session',3,'change_session'),(7,'Can delete session',3,'delete_session'),(8,'Can add group',4,'add_group'),(9,'Can change group',4,'change_group'),(10,'Can delete group',4,'delete_group'),(11,'Can add permission',6,'add_permission'),(12,'Can change permission',6,'change_permission'),(13,'Can delete permission',6,'delete_permission'),(14,'Can add user',5,'add_user'),(15,'Can change user',5,'change_user'),(16,'Can delete user',5,'delete_user'),(17,'Can add registration profile',7,'add_registrationprofile'),(18,'Can change registration profile',7,'change_registrationprofile'),(19,'Can delete registration profile',7,'delete_registrationprofile'),(20,'Can add captcha store',8,'add_captchastore'),(21,'Can change captcha store',8,'change_captchastore'),(22,'Can delete captcha store',8,'delete_captchastore'),(23,'Can add constance',9,'add_constance'),(24,'Can change constance',9,'change_constance'),(25,'Can delete constance',9,'delete_constance'),(26,'Can add Email',12,'add_email'),(27,'Can change Email',12,'change_email'),(28,'Can delete Email',12,'delete_email'),(29,'Can add Attachment',13,'add_attachment'),(30,'Can change Attachment',13,'change_attachment'),(31,'Can delete Attachment',13,'delete_attachment'),(32,'Can add Email Template',11,'add_emailtemplate'),(33,'Can change Email Template',11,'change_emailtemplate'),(34,'Can delete Email Template',11,'delete_emailtemplate'),(35,'Can add Log',10,'add_log'),(36,'Can change Log',10,'change_log'),(37,'Can delete Log',10,'delete_log'),(38,'Can add Terms and Conditions',14,'add_termsandconditions'),(39,'Can change Terms and Conditions',14,'change_termsandconditions'),(40,'Can delete Terms and Conditions',14,'delete_termsandconditions'),(41,'Can add User Terms and Conditions',15,'add_usertermsandconditions'),(42,'Can change User Terms and Conditions',15,'change_usertermsandconditions'),(43,'Can delete User Terms and Conditions',15,'delete_usertermsandconditions'),(44,'Can add token v2',17,'add_tokenv2'),(45,'Can change token v2',17,'change_tokenv2'),(46,'Can delete token v2',17,'delete_tokenv2'),(47,'Can add token',16,'add_token'),(48,'Can change token',16,'change_token'),(49,'Can delete token',16,'delete_token'),(50,'Can add avatar',18,'add_avatar'),(51,'Can change avatar',18,'change_avatar'),(52,'Can delete avatar',18,'delete_avatar'),(53,'Can add group avatar',19,'add_groupavatar'),(54,'Can change group avatar',19,'change_groupavatar'),(55,'Can delete group avatar',19,'delete_groupavatar'),(56,'Can add user enabled module',23,'add_userenabledmodule'),(57,'Can change user enabled module',23,'change_userenabledmodule'),(58,'Can delete user enabled module',23,'delete_userenabledmodule'),(59,'Can add user starred files',25,'add_userstarredfiles'),(60,'Can change user starred files',25,'change_userstarredfiles'),(61,'Can delete user starred files',25,'delete_userstarredfiles'),(62,'Can add file discuss',26,'add_filediscuss'),(63,'Can change file discuss',26,'change_filediscuss'),(64,'Can delete file discuss',26,'delete_filediscuss'),(65,'Can add user last login',29,'add_userlastlogin'),(66,'Can change user last login',29,'change_userlastlogin'),(67,'Can delete user last login',29,'delete_userlastlogin'),(68,'Can add inner pub msg',27,'add_innerpubmsg'),(69,'Can change inner pub msg',27,'change_innerpubmsg'),(70,'Can delete inner pub msg',27,'delete_innerpubmsg'),(71,'Can add group enabled module',20,'add_groupenabledmodule'),(72,'Can change group enabled module',20,'change_groupenabledmodule'),(73,'Can delete group enabled module',20,'delete_groupenabledmodule'),(74,'Can add commands last check',22,'add_commandslastcheck'),(75,'Can change commands last check',22,'change_commandslastcheck'),(76,'Can delete commands last check',22,'delete_commandslastcheck'),(77,'Can add file comment',24,'add_filecomment'),(78,'Can change file comment',24,'change_filecomment'),(79,'Can delete file comment',24,'delete_filecomment'),(80,'Can add inner pub msg reply',28,'add_innerpubmsgreply'),(81,'Can change inner pub msg reply',28,'change_innerpubmsgreply'),(82,'Can delete inner pub msg reply',28,'delete_innerpubmsgreply'),(83,'Can add client login token',21,'add_clientlogintoken'),(84,'Can change client login token',21,'change_clientlogintoken'),(85,'Can delete client login token',21,'delete_clientlogintoken'),(86,'Can add device token',30,'add_devicetoken'),(87,'Can change device token',30,'change_devicetoken'),(88,'Can delete device token',30,'delete_devicetoken'),(89,'Can add contact',31,'add_contact'),(90,'Can change contact',31,'change_contact'),(91,'Can delete contact',31,'delete_contact'),(92,'Can add institution',33,'add_institution'),(93,'Can change institution',33,'change_institution'),(94,'Can delete institution',33,'delete_institution'),(95,'Can add institution admin',32,'add_institutionadmin'),(96,'Can change institution admin',32,'change_institutionadmin'),(97,'Can delete institution admin',32,'delete_institutionadmin'),(98,'Can add institution quota',34,'add_institutionquota'),(99,'Can change institution quota',34,'change_institutionquota'),(100,'Can delete institution quota',34,'delete_institutionquota'),(101,'Can add invitation',35,'add_invitation'),(102,'Can change invitation',35,'change_invitation'),(103,'Can delete invitation',35,'delete_invitation'),(104,'Can add personal wiki',36,'add_personalwiki'),(105,'Can change personal wiki',36,'change_personalwiki'),(106,'Can delete personal wiki',36,'delete_personalwiki'),(107,'Can add wiki',37,'add_wiki'),(108,'Can change wiki',37,'change_wiki'),(109,'Can delete wiki',37,'delete_wiki'),(110,'Can add group wiki',38,'add_groupwiki'),(111,'Can change group wiki',38,'change_groupwiki'),(112,'Can delete group wiki',38,'delete_groupwiki'),(113,'Can add message attachment',42,'add_messageattachment'),(114,'Can change message attachment',42,'change_messageattachment'),(115,'Can delete message attachment',42,'delete_messageattachment'),(116,'Can add message reply',41,'add_messagereply'),(117,'Can change message reply',41,'change_messagereply'),(118,'Can delete message reply',41,'delete_messagereply'),(119,'Can add public group',39,'add_publicgroup'),(120,'Can change public group',39,'change_publicgroup'),(121,'Can delete public group',39,'delete_publicgroup'),(122,'Can add group message',40,'add_groupmessage'),(123,'Can change group message',40,'change_groupmessage'),(124,'Can delete group message',40,'delete_groupmessage'),(125,'Can add notification',43,'add_notification'),(126,'Can change notification',43,'change_notification'),(127,'Can delete notification',43,'delete_notification'),(128,'Can add user notification',44,'add_usernotification'),(129,'Can change user notification',44,'change_usernotification'),(130,'Can delete user notification',44,'delete_usernotification'),(131,'Can add user options',45,'add_useroptions'),(132,'Can change user options',45,'change_useroptions'),(133,'Can delete user options',45,'delete_useroptions'),(134,'Can add detailed profile',46,'add_detailedprofile'),(135,'Can change detailed profile',46,'change_detailedprofile'),(136,'Can delete detailed profile',46,'delete_detailedprofile'),(137,'Can add profile',47,'add_profile'),(138,'Can change profile',47,'change_profile'),(139,'Can delete profile',47,'delete_profile'),(140,'Can add private file dir share',48,'add_privatefiledirshare'),(141,'Can change private file dir share',48,'change_privatefiledirshare'),(142,'Can delete private file dir share',48,'delete_privatefiledirshare'),(143,'Can add file share',49,'add_fileshare'),(144,'Can change file share',49,'change_fileshare'),(145,'Can delete file share',49,'delete_fileshare'),(146,'Can add extra share permission',52,'add_extrasharepermission'),(147,'Can change extra share permission',52,'change_extrasharepermission'),(148,'Can delete extra share permission',52,'delete_extrasharepermission'),(149,'Can add extra groups share permission',53,'add_extragroupssharepermission'),(150,'Can change extra groups share permission',53,'change_extragroupssharepermission'),(151,'Can delete extra groups share permission',53,'delete_extragroupssharepermission'),(152,'Can add anonymous share',54,'add_anonymousshare'),(153,'Can change anonymous share',54,'change_anonymousshare'),(154,'Can delete anonymous share',54,'delete_anonymousshare'),(155,'Can add org file share',50,'add_orgfileshare'),(156,'Can change org file share',50,'change_orgfileshare'),(157,'Can delete org file share',50,'delete_orgfileshare'),(158,'Can add upload link share',51,'add_uploadlinkshare'),(159,'Can change upload link share',51,'change_uploadlinkshare'),(160,'Can delete upload link share',51,'delete_uploadlinkshare'),(161,'Can add admin log',55,'add_adminlog'),(162,'Can change admin log',55,'change_adminlog'),(163,'Can delete admin log',55,'delete_adminlog'),(164,'Can add file tag',57,'add_filetag'),(165,'Can change file tag',57,'change_filetag'),(166,'Can delete file tag',57,'delete_filetag'),(167,'Can add tags',58,'add_tags'),(168,'Can change tags',58,'change_tags'),(169,'Can delete tags',58,'delete_tags'),(170,'Can add file uuid map',56,'add_fileuuidmap'),(171,'Can change file uuid map',56,'change_fileuuidmap'),(172,'Can delete file uuid map',56,'delete_fileuuidmap'),(173,'Can add tags',60,'add_tags'),(174,'Can change tags',60,'change_tags'),(175,'Can delete tags',60,'delete_tags'),(176,'Can add revision tags',59,'add_revisiontags'),(177,'Can change revision tags',59,'change_revisiontags'),(178,'Can delete revision tags',59,'delete_revisiontags'),(179,'Can add TOTP device',63,'add_totpdevice'),(180,'Can change TOTP device',63,'change_totpdevice'),(181,'Can delete TOTP device',63,'delete_totpdevice'),(182,'Can add static token',62,'add_statictoken'),(183,'Can change static token',62,'change_statictoken'),(184,'Can delete static token',62,'delete_statictoken'),(185,'Can add static device',64,'add_staticdevice'),(186,'Can change static device',64,'change_staticdevice'),(187,'Can delete static device',64,'delete_staticdevice'),(188,'Can add phone device',61,'add_phonedevice'),(189,'Can change phone device',61,'change_phonedevice'),(190,'Can delete phone device',61,'delete_phonedevice'),(191,'Can add admin role',65,'add_adminrole'),(192,'Can change admin role',65,'change_adminrole'),(193,'Can delete admin role',65,'delete_adminrole'),(194,'Can add trusted ip',66,'add_trustedip'),(195,'Can change trusted ip',66,'change_trustedip'),(196,'Can delete trusted ip',66,'delete_trustedip'),(197,'Can add user login log',67,'add_userloginlog'),(198,'Can change user login log',67,'change_userloginlog'),(199,'Can delete user login log',67,'delete_userloginlog'),(200,'Can add org member quota',68,'add_orgmemberquota'),(201,'Can change org member quota',68,'change_orgmemberquota'),(202,'Can delete org member quota',68,'delete_orgmemberquota'),(203,'Can add user plan',70,'add_userplan'),(204,'Can change user plan',70,'change_userplan'),(205,'Can delete user plan',70,'delete_userplan'),(206,'Can add org plan',69,'add_orgplan'),(207,'Can change org plan',69,'change_orgplan'),(208,'Can delete org plan',69,'delete_orgplan'); +INSERT INTO `auth_permission` VALUES (1,'Can add content type',1,'add_contenttype'),(2,'Can change content type',1,'change_contenttype'),(3,'Can delete content type',1,'delete_contenttype'),(4,'Can change config',2,'change_config'),(5,'Can add session',3,'add_session'),(6,'Can change session',3,'change_session'),(7,'Can delete session',3,'delete_session'),(8,'Can add user enabled module',7,'add_userenabledmodule'),(9,'Can change user enabled module',7,'change_userenabledmodule'),(10,'Can delete user enabled module',7,'delete_userenabledmodule'),(11,'Can add user starred files',9,'add_userstarredfiles'),(12,'Can change user starred files',9,'change_userstarredfiles'),(13,'Can delete user starred files',9,'delete_userstarredfiles'),(14,'Can add file discuss',10,'add_filediscuss'),(15,'Can change file discuss',10,'change_filediscuss'),(16,'Can delete file discuss',10,'delete_filediscuss'),(17,'Can add user last login',13,'add_userlastlogin'),(18,'Can change user last login',13,'change_userlastlogin'),(19,'Can delete user last login',13,'delete_userlastlogin'),(20,'Can add inner pub msg',11,'add_innerpubmsg'),(21,'Can change inner pub msg',11,'change_innerpubmsg'),(22,'Can delete inner pub msg',11,'delete_innerpubmsg'),(23,'Can add group enabled module',4,'add_groupenabledmodule'),(24,'Can change group enabled module',4,'change_groupenabledmodule'),(25,'Can delete group enabled module',4,'delete_groupenabledmodule'),(26,'Can add commands last check',6,'add_commandslastcheck'),(27,'Can change commands last check',6,'change_commandslastcheck'),(28,'Can delete commands last check',6,'delete_commandslastcheck'),(29,'Can add file comment',8,'add_filecomment'),(30,'Can change file comment',8,'change_filecomment'),(31,'Can delete file comment',8,'delete_filecomment'),(32,'Can add inner pub msg reply',12,'add_innerpubmsgreply'),(33,'Can change inner pub msg reply',12,'change_innerpubmsgreply'),(34,'Can delete inner pub msg reply',12,'delete_innerpubmsgreply'),(35,'Can add client login token',5,'add_clientlogintoken'),(36,'Can change client login token',5,'change_clientlogintoken'),(37,'Can delete client login token',5,'delete_clientlogintoken'),(38,'Can add device token',14,'add_devicetoken'),(39,'Can change device token',14,'change_devicetoken'),(40,'Can delete device token',14,'delete_devicetoken'),(41,'Can add group',15,'add_group'),(42,'Can change group',15,'change_group'),(43,'Can delete group',15,'delete_group'),(44,'Can add permission',17,'add_permission'),(45,'Can change permission',17,'change_permission'),(46,'Can delete permission',17,'delete_permission'),(47,'Can add user',16,'add_user'),(48,'Can change user',16,'change_user'),(49,'Can delete user',16,'delete_user'),(50,'Can add registration profile',18,'add_registrationprofile'),(51,'Can change registration profile',18,'change_registrationprofile'),(52,'Can delete registration profile',18,'delete_registrationprofile'),(53,'Can add captcha store',19,'add_captchastore'),(54,'Can change captcha store',19,'change_captchastore'),(55,'Can delete captcha store',19,'delete_captchastore'),(56,'Can add constance',20,'add_constance'),(57,'Can change constance',20,'change_constance'),(58,'Can delete constance',20,'delete_constance'),(59,'Can add Email',23,'add_email'),(60,'Can change Email',23,'change_email'),(61,'Can delete Email',23,'delete_email'),(62,'Can add Attachment',24,'add_attachment'),(63,'Can change Attachment',24,'change_attachment'),(64,'Can delete Attachment',24,'delete_attachment'),(65,'Can add Email Template',22,'add_emailtemplate'),(66,'Can change Email Template',22,'change_emailtemplate'),(67,'Can delete Email Template',22,'delete_emailtemplate'),(68,'Can add Log',21,'add_log'),(69,'Can change Log',21,'change_log'),(70,'Can delete Log',21,'delete_log'),(71,'Can add Terms and Conditions',25,'add_termsandconditions'),(72,'Can change Terms and Conditions',25,'change_termsandconditions'),(73,'Can delete Terms and Conditions',25,'delete_termsandconditions'),(74,'Can add User Terms and Conditions',26,'add_usertermsandconditions'),(75,'Can change User Terms and Conditions',26,'change_usertermsandconditions'),(76,'Can delete User Terms and Conditions',26,'delete_usertermsandconditions'),(77,'Can add token v2',28,'add_tokenv2'),(78,'Can change token v2',28,'change_tokenv2'),(79,'Can delete token v2',28,'delete_tokenv2'),(80,'Can add token',27,'add_token'),(81,'Can change token',27,'change_token'),(82,'Can delete token',27,'delete_token'),(83,'Can add avatar',29,'add_avatar'),(84,'Can change avatar',29,'change_avatar'),(85,'Can delete avatar',29,'delete_avatar'),(86,'Can add group avatar',30,'add_groupavatar'),(87,'Can change group avatar',30,'change_groupavatar'),(88,'Can delete group avatar',30,'delete_groupavatar'),(89,'Can add contact',31,'add_contact'),(90,'Can change contact',31,'change_contact'),(91,'Can delete contact',31,'delete_contact'),(92,'Can add institution',33,'add_institution'),(93,'Can change institution',33,'change_institution'),(94,'Can delete institution',33,'delete_institution'),(95,'Can add institution admin',32,'add_institutionadmin'),(96,'Can change institution admin',32,'change_institutionadmin'),(97,'Can delete institution admin',32,'delete_institutionadmin'),(98,'Can add institution quota',34,'add_institutionquota'),(99,'Can change institution quota',34,'change_institutionquota'),(100,'Can delete institution quota',34,'delete_institutionquota'),(101,'Can add invitation',35,'add_invitation'),(102,'Can change invitation',35,'change_invitation'),(103,'Can delete invitation',35,'delete_invitation'),(104,'Can add personal wiki',36,'add_personalwiki'),(105,'Can change personal wiki',36,'change_personalwiki'),(106,'Can delete personal wiki',36,'delete_personalwiki'),(107,'Can add wiki',37,'add_wiki'),(108,'Can change wiki',37,'change_wiki'),(109,'Can delete wiki',37,'delete_wiki'),(110,'Can add group wiki',38,'add_groupwiki'),(111,'Can change group wiki',38,'change_groupwiki'),(112,'Can delete group wiki',38,'delete_groupwiki'),(113,'Can add message attachment',42,'add_messageattachment'),(114,'Can change message attachment',42,'change_messageattachment'),(115,'Can delete message attachment',42,'delete_messageattachment'),(116,'Can add message reply',41,'add_messagereply'),(117,'Can change message reply',41,'change_messagereply'),(118,'Can delete message reply',41,'delete_messagereply'),(119,'Can add public group',39,'add_publicgroup'),(120,'Can change public group',39,'change_publicgroup'),(121,'Can delete public group',39,'delete_publicgroup'),(122,'Can add group message',40,'add_groupmessage'),(123,'Can change group message',40,'change_groupmessage'),(124,'Can delete group message',40,'delete_groupmessage'),(125,'Can add notification',43,'add_notification'),(126,'Can change notification',43,'change_notification'),(127,'Can delete notification',43,'delete_notification'),(128,'Can add user notification',44,'add_usernotification'),(129,'Can change user notification',44,'change_usernotification'),(130,'Can delete user notification',44,'delete_usernotification'),(131,'Can add user options',45,'add_useroptions'),(132,'Can change user options',45,'change_useroptions'),(133,'Can delete user options',45,'delete_useroptions'),(134,'Can add detailed profile',46,'add_detailedprofile'),(135,'Can change detailed profile',46,'change_detailedprofile'),(136,'Can delete detailed profile',46,'delete_detailedprofile'),(137,'Can add profile',47,'add_profile'),(138,'Can change profile',47,'change_profile'),(139,'Can delete profile',47,'delete_profile'),(140,'Can add private file dir share',48,'add_privatefiledirshare'),(141,'Can change private file dir share',48,'change_privatefiledirshare'),(142,'Can delete private file dir share',48,'delete_privatefiledirshare'),(143,'Can add file share',49,'add_fileshare'),(144,'Can change file share',49,'change_fileshare'),(145,'Can delete file share',49,'delete_fileshare'),(146,'Can add extra share permission',52,'add_extrasharepermission'),(147,'Can change extra share permission',52,'change_extrasharepermission'),(148,'Can delete extra share permission',52,'delete_extrasharepermission'),(149,'Can add extra groups share permission',53,'add_extragroupssharepermission'),(150,'Can change extra groups share permission',53,'change_extragroupssharepermission'),(151,'Can delete extra groups share permission',53,'delete_extragroupssharepermission'),(152,'Can add anonymous share',54,'add_anonymousshare'),(153,'Can change anonymous share',54,'change_anonymousshare'),(154,'Can delete anonymous share',54,'delete_anonymousshare'),(155,'Can add org file share',50,'add_orgfileshare'),(156,'Can change org file share',50,'change_orgfileshare'),(157,'Can delete org file share',50,'delete_orgfileshare'),(158,'Can add upload link share',51,'add_uploadlinkshare'),(159,'Can change upload link share',51,'change_uploadlinkshare'),(160,'Can delete upload link share',51,'delete_uploadlinkshare'),(161,'Can add admin log',55,'add_adminlog'),(162,'Can change admin log',55,'change_adminlog'),(163,'Can delete admin log',55,'delete_adminlog'),(164,'Can add file tag',57,'add_filetag'),(165,'Can change file tag',57,'change_filetag'),(166,'Can delete file tag',57,'delete_filetag'),(167,'Can add tags',58,'add_tags'),(168,'Can change tags',58,'change_tags'),(169,'Can delete tags',58,'delete_tags'),(170,'Can add file uuid map',56,'add_fileuuidmap'),(171,'Can change file uuid map',56,'change_fileuuidmap'),(172,'Can delete file uuid map',56,'delete_fileuuidmap'),(173,'Can add tags',60,'add_tags'),(174,'Can change tags',60,'change_tags'),(175,'Can delete tags',60,'delete_tags'),(176,'Can add revision tags',59,'add_revisiontags'),(177,'Can change revision tags',59,'change_revisiontags'),(178,'Can delete revision tags',59,'delete_revisiontags'),(179,'Can add TOTP device',63,'add_totpdevice'),(180,'Can change TOTP device',63,'change_totpdevice'),(181,'Can delete TOTP device',63,'delete_totpdevice'),(182,'Can add static token',62,'add_statictoken'),(183,'Can change static token',62,'change_statictoken'),(184,'Can delete static token',62,'delete_statictoken'),(185,'Can add phone device',61,'add_phonedevice'),(186,'Can change phone device',61,'change_phonedevice'),(187,'Can delete phone device',61,'delete_phonedevice'),(188,'Can add static device',64,'add_staticdevice'),(189,'Can change static device',64,'change_staticdevice'),(190,'Can delete static device',64,'delete_staticdevice'),(191,'Can add admin role',65,'add_adminrole'),(192,'Can change admin role',65,'change_adminrole'),(193,'Can delete admin role',65,'delete_adminrole'),(194,'Can add trusted ip',66,'add_trustedip'),(195,'Can change trusted ip',66,'change_trustedip'),(196,'Can delete trusted ip',66,'delete_trustedip'),(197,'Can add user login log',67,'add_userloginlog'),(198,'Can change user login log',67,'change_userloginlog'),(199,'Can delete user login log',67,'delete_userloginlog'),(200,'Can add org member quota',68,'add_orgmemberquota'),(201,'Can change org member quota',68,'change_orgmemberquota'),(202,'Can delete org member quota',68,'delete_orgmemberquota'),(203,'Can add session ticket',70,'add_sessionticket'),(204,'Can change session ticket',70,'change_sessionticket'),(205,'Can delete session ticket',70,'delete_sessionticket'),(206,'Can add proxy granting ticket',69,'add_proxygrantingticket'),(207,'Can change proxy granting ticket',69,'change_proxygrantingticket'),(208,'Can delete proxy granting ticket',69,'delete_proxygrantingticket'); /*!40000 ALTER TABLE `auth_permission` ENABLE KEYS */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -389,6 +389,35 @@ CREATE TABLE `contacts_contact` ( /*!40000 ALTER TABLE `contacts_contact` ENABLE KEYS */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; +CREATE TABLE `django_cas_ng_proxygrantingticket` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `session_key` varchar(255) DEFAULT NULL, + `pgtiou` varchar(255) DEFAULT NULL, + `pgt` varchar(255) DEFAULT NULL, + `date` datetime NOT NULL, + `user` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `django_cas_ng_proxygrant_session_key_user_id_4cd2ea19_uniq` (`session_key`,`user`), + KEY `django_cas_ng_proxyg_user_id_f833edd2_fk_auth_user` (`user`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +/*!40000 ALTER TABLE `django_cas_ng_proxygrantingticket` DISABLE KEYS */; +/*!40000 ALTER TABLE `django_cas_ng_proxygrantingticket` ENABLE KEYS */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `django_cas_ng_sessionticket` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `session_key` varchar(255) NOT NULL, + `ticket` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +/*!40000 ALTER TABLE `django_cas_ng_sessionticket` DISABLE KEYS */; +/*!40000 ALTER TABLE `django_cas_ng_sessionticket` ENABLE KEYS */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `django_content_type` ( `id` int(11) NOT NULL AUTO_INCREMENT, `app_label` varchar(100) NOT NULL, @@ -399,7 +428,7 @@ CREATE TABLE `django_content_type` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `django_content_type` DISABLE KEYS */; -INSERT INTO `django_content_type` VALUES (55,'admin_log','adminlog'),(16,'api2','token'),(17,'api2','tokenv2'),(4,'auth','group'),(6,'auth','permission'),(5,'auth','user'),(18,'avatar','avatar'),(19,'avatar','groupavatar'),(21,'base','clientlogintoken'),(22,'base','commandslastcheck'),(30,'base','devicetoken'),(24,'base','filecomment'),(26,'base','filediscuss'),(20,'base','groupenabledmodule'),(27,'base','innerpubmsg'),(28,'base','innerpubmsgreply'),(23,'base','userenabledmodule'),(29,'base','userlastlogin'),(25,'base','userstarredfiles'),(8,'captcha','captchastore'),(2,'constance','config'),(31,'contacts','contact'),(1,'contenttypes','contenttype'),(9,'database','constance'),(40,'group','groupmessage'),(42,'group','messageattachment'),(41,'group','messagereply'),(39,'group','publicgroup'),(33,'institutions','institution'),(32,'institutions','institutionadmin'),(34,'institutions','institutionquota'),(35,'invitations','invitation'),(43,'notifications','notification'),(44,'notifications','usernotification'),(45,'options','useroptions'),(68,'organizations','orgmemberquota'),(69,'plan','orgplan'),(70,'plan','userplan'),(13,'post_office','attachment'),(12,'post_office','email'),(11,'post_office','emailtemplate'),(10,'post_office','log'),(46,'profile','detailedprofile'),(47,'profile','profile'),(7,'registration','registrationprofile'),(59,'revision_tag','revisiontags'),(60,'revision_tag','tags'),(65,'role_permissions','adminrole'),(3,'sessions','session'),(54,'share','anonymousshare'),(53,'share','extragroupssharepermission'),(52,'share','extrasharepermission'),(49,'share','fileshare'),(50,'share','orgfileshare'),(48,'share','privatefiledirshare'),(51,'share','uploadlinkshare'),(67,'sysadmin_extra','userloginlog'),(57,'tags','filetag'),(56,'tags','fileuuidmap'),(58,'tags','tags'),(14,'termsandconditions','termsandconditions'),(15,'termsandconditions','usertermsandconditions'),(66,'trusted_ip','trustedip'),(61,'two_factor','phonedevice'),(64,'two_factor','staticdevice'),(62,'two_factor','statictoken'),(63,'two_factor','totpdevice'),(38,'wiki','groupwiki'),(36,'wiki','personalwiki'),(37,'wiki','wiki'); +INSERT INTO `django_content_type` VALUES (55,'admin_log','adminlog'),(27,'api2','token'),(28,'api2','tokenv2'),(15,'auth','group'),(17,'auth','permission'),(16,'auth','user'),(29,'avatar','avatar'),(30,'avatar','groupavatar'),(5,'base','clientlogintoken'),(6,'base','commandslastcheck'),(14,'base','devicetoken'),(8,'base','filecomment'),(10,'base','filediscuss'),(4,'base','groupenabledmodule'),(11,'base','innerpubmsg'),(12,'base','innerpubmsgreply'),(7,'base','userenabledmodule'),(13,'base','userlastlogin'),(9,'base','userstarredfiles'),(19,'captcha','captchastore'),(2,'constance','config'),(31,'contacts','contact'),(1,'contenttypes','contenttype'),(20,'database','constance'),(69,'django_cas_ng','proxygrantingticket'),(70,'django_cas_ng','sessionticket'),(40,'group','groupmessage'),(42,'group','messageattachment'),(41,'group','messagereply'),(39,'group','publicgroup'),(33,'institutions','institution'),(32,'institutions','institutionadmin'),(34,'institutions','institutionquota'),(35,'invitations','invitation'),(43,'notifications','notification'),(44,'notifications','usernotification'),(45,'options','useroptions'),(68,'organizations','orgmemberquota'),(24,'post_office','attachment'),(23,'post_office','email'),(22,'post_office','emailtemplate'),(21,'post_office','log'),(46,'profile','detailedprofile'),(47,'profile','profile'),(18,'registration','registrationprofile'),(59,'revision_tag','revisiontags'),(60,'revision_tag','tags'),(65,'role_permissions','adminrole'),(3,'sessions','session'),(54,'share','anonymousshare'),(53,'share','extragroupssharepermission'),(52,'share','extrasharepermission'),(49,'share','fileshare'),(50,'share','orgfileshare'),(48,'share','privatefiledirshare'),(51,'share','uploadlinkshare'),(67,'sysadmin_extra','userloginlog'),(57,'tags','filetag'),(56,'tags','fileuuidmap'),(58,'tags','tags'),(25,'termsandconditions','termsandconditions'),(26,'termsandconditions','usertermsandconditions'),(66,'trusted_ip','trustedip'),(61,'two_factor','phonedevice'),(64,'two_factor','staticdevice'),(62,'two_factor','statictoken'),(63,'two_factor','totpdevice'),(38,'wiki','groupwiki'),(36,'wiki','personalwiki'),(37,'wiki','wiki'); /*!40000 ALTER TABLE `django_content_type` ENABLE KEYS */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -409,11 +438,11 @@ CREATE TABLE `django_migrations` ( `name` varchar(255) NOT NULL, `applied` datetime NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `django_migrations` DISABLE KEYS */; -INSERT INTO `django_migrations` VALUES (1,'admin_log','0001_initial','2018-04-26 07:29:52.853600'),(2,'api2','0001_initial','2018-04-26 07:29:53.118754'),(3,'contenttypes','0001_initial','2018-04-26 07:29:53.182938'),(4,'contenttypes','0002_remove_content_type_name','2018-04-26 07:29:53.426044'),(5,'auth','0001_initial','2018-04-26 07:29:54.099237'),(6,'auth','0002_alter_permission_name_max_length','2018-04-26 07:29:54.147095'),(7,'auth','0003_alter_user_email_max_length','2018-04-26 07:29:54.199273'),(8,'auth','0004_alter_user_username_opts','2018-04-26 07:29:54.219055'),(9,'auth','0005_alter_user_last_login_null','2018-04-26 07:29:54.255692'),(10,'auth','0006_require_contenttypes_0002','2018-04-26 07:29:54.261340'),(11,'auth','0007_alter_validators_add_error_messages','2018-04-26 07:29:54.281880'),(12,'auth','0008_alter_user_username_max_length','2018-04-26 07:29:54.497471'),(13,'avatar','0001_initial','2018-04-26 07:29:54.572117'),(14,'tags','0001_initial','2018-04-26 07:29:54.856628'),(15,'group','0001_initial','2018-04-26 07:29:55.111989'),(16,'base','0001_initial','2018-04-26 07:29:56.398003'),(17,'captcha','0001_initial','2018-04-26 07:29:56.448209'),(18,'contacts','0001_initial','2018-04-26 07:29:56.508633'),(19,'database','0001_initial','2018-04-26 07:29:56.554294'),(20,'institutions','0001_initial','2018-04-26 07:29:56.678224'),(21,'institutions','0002_institutionquota','2018-04-26 07:29:56.772319'),(22,'institutions','0003_auto_20180426_0710','2018-04-26 07:29:56.839053'),(23,'invitations','0001_initial','2018-04-26 07:29:56.899450'),(24,'invitations','0002_invitation_invite_type','2018-04-26 07:29:56.975462'),(25,'invitations','0003_auto_20160510_1703','2018-04-26 07:29:57.037285'),(26,'invitations','0004_auto_20160629_1610','2018-04-26 07:29:57.141828'),(27,'invitations','0005_auto_20160629_1614','2018-04-26 07:29:57.324418'),(28,'notifications','0001_initial','2018-04-26 07:29:57.588317'),(29,'notifications','0002_auto_20180426_0710','2018-04-26 07:29:57.616671'),(30,'options','0001_initial','2018-04-26 07:29:57.686212'),(31,'post_office','0001_initial','2018-04-26 07:29:58.678708'),(32,'post_office','0002_add_i18n_and_backend_alias','2018-04-26 07:29:59.281260'),(33,'post_office','0003_longer_subject','2018-04-26 07:29:59.361645'),(34,'post_office','0004_auto_20160607_0901','2018-04-26 07:30:00.086345'),(35,'post_office','0005_auto_20170515_0013','2018-04-26 07:30:00.134052'),(36,'post_office','0006_attachment_mimetype','2018-04-26 07:30:00.484166'),(37,'profile','0001_initial','2018-04-26 07:30:00.700469'),(38,'revision_tag','0001_initial','2018-04-26 07:30:00.938189'),(39,'role_permissions','0001_initial','2018-04-26 07:30:00.985063'),(40,'sessions','0001_initial','2018-04-26 07:30:01.194165'),(41,'share','0001_initial','2018-04-26 07:30:02.206041'),(42,'sysadmin_extra','0001_initial','2018-04-26 07:30:02.310931'),(43,'termsandconditions','0001_initial','2018-04-26 07:30:02.646633'),(44,'trusted_ip','0001_initial','2018-04-26 07:30:02.857302'),(45,'two_factor','0001_initial','2018-04-26 07:30:03.100387'),(46,'wiki','0001_initial','2018-04-26 07:30:03.195368'),(47,'wiki','0002_auto_20180326_0548','2018-04-26 07:30:03.318736'),(48,'registration','0001_initial','2018-04-26 07:43:50.687052'); +INSERT INTO `django_migrations` VALUES (1,'admin_log','0001_initial','2018-06-27 02:50:49.548921'),(2,'api2','0001_initial','2018-06-27 02:50:49.930960'),(3,'contenttypes','0001_initial','2018-06-27 02:50:49.979518'),(4,'contenttypes','0002_remove_content_type_name','2018-06-27 02:50:50.067604'),(5,'auth','0001_initial','2018-06-27 02:50:50.970680'),(6,'auth','0002_alter_permission_name_max_length','2018-06-27 02:50:51.002810'),(7,'auth','0003_alter_user_email_max_length','2018-06-27 02:50:51.048514'),(8,'auth','0004_alter_user_username_opts','2018-06-27 02:50:51.064347'),(9,'auth','0005_alter_user_last_login_null','2018-06-27 02:50:51.097687'),(10,'auth','0006_require_contenttypes_0002','2018-06-27 02:50:51.100780'),(11,'auth','0007_alter_validators_add_error_messages','2018-06-27 02:50:51.123902'),(12,'auth','0008_alter_user_username_max_length','2018-06-27 02:50:51.162747'),(13,'avatar','0001_initial','2018-06-27 02:50:51.356427'),(14,'tags','0001_initial','2018-06-27 02:50:51.531345'),(15,'group','0001_initial','2018-06-27 02:50:52.010902'),(16,'base','0001_initial','2018-06-27 02:50:52.804154'),(17,'captcha','0001_initial','2018-06-27 02:50:52.842917'),(18,'contacts','0001_initial','2018-06-27 02:50:53.033049'),(19,'database','0001_initial','2018-06-27 02:50:53.065329'),(20,'django_cas_ng','0001_initial','2018-06-27 02:50:53.192349'),(21,'django_cas_ng','0002_auto_20180410_0948','2018-06-27 02:50:53.582217'),(22,'institutions','0001_initial','2018-06-27 02:50:53.811817'),(23,'institutions','0002_institutionquota','2018-06-27 02:50:53.862047'),(24,'institutions','0003_auto_20180426_0710','2018-06-27 02:50:53.960556'),(25,'invitations','0001_initial','2018-06-27 02:50:54.007953'),(26,'invitations','0002_invitation_invite_type','2018-06-27 02:50:54.048775'),(27,'invitations','0003_auto_20160510_1703','2018-06-27 02:50:54.252238'),(28,'invitations','0004_auto_20160629_1610','2018-06-27 02:50:54.471329'),(29,'invitations','0005_auto_20160629_1614','2018-06-27 02:50:54.493259'),(30,'notifications','0001_initial','2018-06-27 02:50:54.584081'),(31,'notifications','0002_auto_20180426_0710','2018-06-27 02:50:54.610380'),(32,'options','0001_initial','2018-06-27 02:50:54.653635'),(33,'organizations','0001_initial','2018-06-27 02:50:54.711299'),(34,'post_office','0001_initial','2018-06-27 02:50:55.643107'),(35,'post_office','0002_add_i18n_and_backend_alias','2018-06-27 02:50:56.150930'),(36,'post_office','0003_longer_subject','2018-06-27 02:50:56.364985'),(37,'post_office','0004_auto_20160607_0901','2018-06-27 02:50:57.322806'),(38,'post_office','0005_auto_20170515_0013','2018-06-27 02:50:57.365993'),(39,'post_office','0006_attachment_mimetype','2018-06-27 02:50:57.422628'),(40,'profile','0001_initial','2018-06-27 02:50:57.558227'),(41,'registration','0001_initial','2018-06-27 02:50:57.592740'),(42,'revision_tag','0001_initial','2018-06-27 02:50:57.758820'),(43,'role_permissions','0001_initial','2018-06-27 02:50:57.787048'),(44,'sessions','0001_initial','2018-06-27 02:50:57.841607'),(45,'share','0001_initial','2018-06-27 02:50:58.624777'),(46,'sysadmin_extra','0001_initial','2018-06-27 02:50:58.697467'),(47,'termsandconditions','0001_initial','2018-06-27 02:50:59.022414'),(48,'trusted_ip','0001_initial','2018-06-27 02:50:59.072886'),(49,'two_factor','0001_initial','2018-06-27 02:50:59.564555'),(50,'wiki','0001_initial','2018-06-27 02:50:59.644137'),(51,'wiki','0002_auto_20180326_0548','2018-06-27 02:50:59.738217'),(52,'wiki','0003_auto_20180428_0619','2018-06-27 02:50:59.776448'); /*!40000 ALTER TABLE `django_migrations` ENABLE KEYS */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -594,6 +623,19 @@ CREATE TABLE `options_useroptions` ( /*!40000 ALTER TABLE `options_useroptions` ENABLE KEYS */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; +CREATE TABLE `organizations_orgmemberquota` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `org_id` int(11) NOT NULL, + `quota` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `organizations_orgmemberquota_org_id_93dde51d` (`org_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +/*!40000 ALTER TABLE `organizations_orgmemberquota` DISABLE KEYS */; +/*!40000 ALTER TABLE `organizations_orgmemberquota` ENABLE KEYS */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; CREATE TABLE `post_office_attachment` ( `id` int(11) NOT NULL AUTO_INCREMENT, `file` varchar(100) NOT NULL, @@ -1128,7 +1170,8 @@ CREATE TABLE `wiki_wiki` ( PRIMARY KEY (`id`), UNIQUE KEY `slug` (`slug`), UNIQUE KEY `wiki_wiki_username_repo_id_4c8925af_uniq` (`username`,`repo_id`), - KEY `wiki_wiki_created_at_54930e39` (`created_at`) + KEY `wiki_wiki_created_at_54930e39` (`created_at`), + KEY `wiki_wiki_repo_id_2ee93c37` (`repo_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/sql/sqlite3.sql b/sql/sqlite3.sql index 52833ede86..d86a0b2b2e 100644 --- a/sql/sqlite3.sql +++ b/sql/sqlite3.sql @@ -1,54 +1,58 @@ PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; CREATE TABLE "django_migrations" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "app" varchar(255) NOT NULL, "name" varchar(255) NOT NULL, "applied" datetime NOT NULL); -INSERT INTO "django_migrations" VALUES(1,'admin_log','0001_initial','2018-04-26 07:54:03.567663'); -INSERT INTO "django_migrations" VALUES(2,'api2','0001_initial','2018-04-26 07:54:03.656897'); -INSERT INTO "django_migrations" VALUES(3,'contenttypes','0001_initial','2018-04-26 07:54:03.692763'); -INSERT INTO "django_migrations" VALUES(4,'contenttypes','0002_remove_content_type_name','2018-04-26 07:54:03.757687'); -INSERT INTO "django_migrations" VALUES(5,'auth','0001_initial','2018-04-26 07:54:03.830311'); -INSERT INTO "django_migrations" VALUES(6,'auth','0002_alter_permission_name_max_length','2018-04-26 07:54:03.873552'); -INSERT INTO "django_migrations" VALUES(7,'auth','0003_alter_user_email_max_length','2018-04-26 07:54:03.916762'); -INSERT INTO "django_migrations" VALUES(8,'auth','0004_alter_user_username_opts','2018-04-26 07:54:03.970467'); -INSERT INTO "django_migrations" VALUES(9,'auth','0005_alter_user_last_login_null','2018-04-26 07:54:04.009708'); -INSERT INTO "django_migrations" VALUES(10,'auth','0006_require_contenttypes_0002','2018-04-26 07:54:04.023718'); -INSERT INTO "django_migrations" VALUES(11,'auth','0007_alter_validators_add_error_messages','2018-04-26 07:54:04.065211'); -INSERT INTO "django_migrations" VALUES(12,'auth','0008_alter_user_username_max_length','2018-04-26 07:54:04.106460'); -INSERT INTO "django_migrations" VALUES(13,'avatar','0001_initial','2018-04-26 07:54:04.146069'); -INSERT INTO "django_migrations" VALUES(14,'tags','0001_initial','2018-04-26 07:54:04.219958'); -INSERT INTO "django_migrations" VALUES(15,'group','0001_initial','2018-04-26 07:54:04.277966'); -INSERT INTO "django_migrations" VALUES(16,'base','0001_initial','2018-04-26 07:54:04.413632'); -INSERT INTO "django_migrations" VALUES(17,'captcha','0001_initial','2018-04-26 07:54:04.441113'); -INSERT INTO "django_migrations" VALUES(18,'contacts','0001_initial','2018-04-26 07:54:04.473602'); -INSERT INTO "django_migrations" VALUES(19,'database','0001_initial','2018-04-26 07:54:04.504721'); -INSERT INTO "django_migrations" VALUES(20,'institutions','0001_initial','2018-04-26 07:54:04.553966'); -INSERT INTO "django_migrations" VALUES(21,'institutions','0002_institutionquota','2018-04-26 07:54:04.588771'); -INSERT INTO "django_migrations" VALUES(22,'institutions','0003_auto_20180426_0710','2018-04-26 07:54:04.629723'); -INSERT INTO "django_migrations" VALUES(23,'invitations','0001_initial','2018-04-26 07:54:04.660285'); -INSERT INTO "django_migrations" VALUES(24,'invitations','0002_invitation_invite_type','2018-04-26 07:54:04.703854'); -INSERT INTO "django_migrations" VALUES(25,'invitations','0003_auto_20160510_1703','2018-04-26 07:54:04.757231'); -INSERT INTO "django_migrations" VALUES(26,'invitations','0004_auto_20160629_1610','2018-04-26 07:54:04.817422'); -INSERT INTO "django_migrations" VALUES(27,'invitations','0005_auto_20160629_1614','2018-04-26 07:54:04.857951'); -INSERT INTO "django_migrations" VALUES(28,'notifications','0001_initial','2018-04-26 07:54:04.905471'); -INSERT INTO "django_migrations" VALUES(29,'notifications','0002_auto_20180426_0710','2018-04-26 07:54:04.943214'); -INSERT INTO "django_migrations" VALUES(30,'options','0001_initial','2018-04-26 07:54:04.979914'); -INSERT INTO "django_migrations" VALUES(31,'post_office','0001_initial','2018-04-26 07:54:05.082906'); -INSERT INTO "django_migrations" VALUES(32,'post_office','0002_add_i18n_and_backend_alias','2018-04-26 07:54:05.346280'); -INSERT INTO "django_migrations" VALUES(33,'post_office','0003_longer_subject','2018-04-26 07:54:05.397151'); -INSERT INTO "django_migrations" VALUES(34,'post_office','0004_auto_20160607_0901','2018-04-26 07:54:05.873262'); -INSERT INTO "django_migrations" VALUES(35,'post_office','0005_auto_20170515_0013','2018-04-26 07:54:05.903024'); -INSERT INTO "django_migrations" VALUES(36,'post_office','0006_attachment_mimetype','2018-04-26 07:54:05.939509'); -INSERT INTO "django_migrations" VALUES(37,'profile','0001_initial','2018-04-26 07:54:05.986391'); -INSERT INTO "django_migrations" VALUES(38,'registration','0001_initial','2018-04-26 07:54:06.021591'); -INSERT INTO "django_migrations" VALUES(39,'revision_tag','0001_initial','2018-04-26 07:54:06.098989'); -INSERT INTO "django_migrations" VALUES(40,'role_permissions','0001_initial','2018-04-26 07:54:06.127450'); -INSERT INTO "django_migrations" VALUES(41,'sessions','0001_initial','2018-04-26 07:54:06.163327'); -INSERT INTO "django_migrations" VALUES(42,'share','0001_initial','2018-04-26 07:54:06.281444'); -INSERT INTO "django_migrations" VALUES(43,'sysadmin_extra','0001_initial','2018-04-26 07:54:06.313919'); -INSERT INTO "django_migrations" VALUES(44,'termsandconditions','0001_initial','2018-04-26 07:54:06.397397'); -INSERT INTO "django_migrations" VALUES(45,'trusted_ip','0001_initial','2018-04-26 07:54:06.428646'); -INSERT INTO "django_migrations" VALUES(46,'two_factor','0001_initial','2018-04-26 07:54:06.509927'); -INSERT INTO "django_migrations" VALUES(47,'wiki','0001_initial','2018-04-26 07:54:06.559094'); -INSERT INTO "django_migrations" VALUES(48,'wiki','0002_auto_20180326_0548','2018-04-26 07:54:06.625018'); +INSERT INTO "django_migrations" VALUES(1,'admin_log','0001_initial','2018-06-27 02:40:26.495953'); +INSERT INTO "django_migrations" VALUES(2,'api2','0001_initial','2018-06-27 02:40:26.518230'); +INSERT INTO "django_migrations" VALUES(3,'contenttypes','0001_initial','2018-06-27 02:40:26.533803'); +INSERT INTO "django_migrations" VALUES(4,'contenttypes','0002_remove_content_type_name','2018-06-27 02:40:26.570487'); +INSERT INTO "django_migrations" VALUES(5,'auth','0001_initial','2018-06-27 02:40:26.609626'); +INSERT INTO "django_migrations" VALUES(6,'auth','0002_alter_permission_name_max_length','2018-06-27 02:40:26.630407'); +INSERT INTO "django_migrations" VALUES(7,'auth','0003_alter_user_email_max_length','2018-06-27 02:40:26.649817'); +INSERT INTO "django_migrations" VALUES(8,'auth','0004_alter_user_username_opts','2018-06-27 02:40:26.675169'); +INSERT INTO "django_migrations" VALUES(9,'auth','0005_alter_user_last_login_null','2018-06-27 02:40:26.697931'); +INSERT INTO "django_migrations" VALUES(10,'auth','0006_require_contenttypes_0002','2018-06-27 02:40:26.699813'); +INSERT INTO "django_migrations" VALUES(11,'auth','0007_alter_validators_add_error_messages','2018-06-27 02:40:26.720282'); +INSERT INTO "django_migrations" VALUES(12,'auth','0008_alter_user_username_max_length','2018-06-27 02:40:26.739091'); +INSERT INTO "django_migrations" VALUES(13,'avatar','0001_initial','2018-06-27 02:40:26.757411'); +INSERT INTO "django_migrations" VALUES(14,'tags','0001_initial','2018-06-27 02:40:26.803278'); +INSERT INTO "django_migrations" VALUES(15,'group','0001_initial','2018-06-27 02:40:26.842786'); +INSERT INTO "django_migrations" VALUES(16,'base','0001_initial','2018-06-27 02:40:26.986171'); +INSERT INTO "django_migrations" VALUES(17,'captcha','0001_initial','2018-06-27 02:40:26.997842'); +INSERT INTO "django_migrations" VALUES(18,'contacts','0001_initial','2018-06-27 02:40:27.010161'); +INSERT INTO "django_migrations" VALUES(19,'database','0001_initial','2018-06-27 02:40:27.021936'); +INSERT INTO "django_migrations" VALUES(20,'django_cas_ng','0001_initial','2018-06-27 02:40:27.083637'); +INSERT INTO "django_migrations" VALUES(21,'django_cas_ng','0002_auto_20180410_0948','2018-06-27 02:40:27.106467'); +INSERT INTO "django_migrations" VALUES(22,'institutions','0001_initial','2018-06-27 02:40:27.176150'); +INSERT INTO "django_migrations" VALUES(23,'institutions','0002_institutionquota','2018-06-27 02:40:27.192199'); +INSERT INTO "django_migrations" VALUES(24,'institutions','0003_auto_20180426_0710','2018-06-27 02:40:27.210001'); +INSERT INTO "django_migrations" VALUES(25,'invitations','0001_initial','2018-06-27 02:40:27.224310'); +INSERT INTO "django_migrations" VALUES(26,'invitations','0002_invitation_invite_type','2018-06-27 02:40:27.241029'); +INSERT INTO "django_migrations" VALUES(27,'invitations','0003_auto_20160510_1703','2018-06-27 02:40:27.271187'); +INSERT INTO "django_migrations" VALUES(28,'invitations','0004_auto_20160629_1610','2018-06-27 02:40:27.304490'); +INSERT INTO "django_migrations" VALUES(29,'invitations','0005_auto_20160629_1614','2018-06-27 02:40:27.321945'); +INSERT INTO "django_migrations" VALUES(30,'notifications','0001_initial','2018-06-27 02:40:27.346389'); +INSERT INTO "django_migrations" VALUES(31,'notifications','0002_auto_20180426_0710','2018-06-27 02:40:27.363394'); +INSERT INTO "django_migrations" VALUES(32,'options','0001_initial','2018-06-27 02:40:27.378666'); +INSERT INTO "django_migrations" VALUES(33,'post_office','0001_initial','2018-06-27 02:40:27.479093'); +INSERT INTO "django_migrations" VALUES(34,'post_office','0002_add_i18n_and_backend_alias','2018-06-27 02:40:27.763629'); +INSERT INTO "django_migrations" VALUES(35,'post_office','0003_longer_subject','2018-06-27 02:40:27.808321'); +INSERT INTO "django_migrations" VALUES(36,'post_office','0004_auto_20160607_0901','2018-06-27 02:40:28.271453'); +INSERT INTO "django_migrations" VALUES(37,'post_office','0005_auto_20170515_0013','2018-06-27 02:40:28.293987'); +INSERT INTO "django_migrations" VALUES(38,'post_office','0006_attachment_mimetype','2018-06-27 02:40:28.316823'); +INSERT INTO "django_migrations" VALUES(39,'profile','0001_initial','2018-06-27 02:40:28.349903'); +INSERT INTO "django_migrations" VALUES(40,'registration','0001_initial','2018-06-27 02:40:28.367121'); +INSERT INTO "django_migrations" VALUES(41,'revision_tag','0001_initial','2018-06-27 02:40:28.421315'); +INSERT INTO "django_migrations" VALUES(42,'role_permissions','0001_initial','2018-06-27 02:40:28.438502'); +INSERT INTO "django_migrations" VALUES(43,'sessions','0001_initial','2018-06-27 02:40:28.454444'); +INSERT INTO "django_migrations" VALUES(44,'share','0001_initial','2018-06-27 02:40:28.608266'); +INSERT INTO "django_migrations" VALUES(45,'sysadmin_extra','0001_initial','2018-06-27 02:40:28.629572'); +INSERT INTO "django_migrations" VALUES(46,'termsandconditions','0001_initial','2018-06-27 02:40:28.682367'); +INSERT INTO "django_migrations" VALUES(47,'trusted_ip','0001_initial','2018-06-27 02:40:28.699443'); +INSERT INTO "django_migrations" VALUES(48,'two_factor','0001_initial','2018-06-27 02:40:28.766687'); +INSERT INTO "django_migrations" VALUES(49,'wiki','0001_initial','2018-06-27 02:40:28.799132'); +INSERT INTO "django_migrations" VALUES(50,'wiki','0002_auto_20180326_0548','2018-06-27 02:40:28.839831'); +INSERT INTO "django_migrations" VALUES(51,'wiki','0003_auto_20180428_0619','2018-06-27 02:40:28.862964'); +INSERT INTO "django_migrations" VALUES(52,'organizations','0001_initial','2018-06-27 02:41:18.414792'); CREATE TABLE "admin_log_adminlog" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "email" varchar(254) NOT NULL, "operation" varchar(255) NOT NULL, "detail" text NOT NULL, "datetime" datetime NOT NULL); CREATE TABLE "api2_token" ("key" varchar(40) NOT NULL PRIMARY KEY, "user" varchar(255) NOT NULL UNIQUE, "created" datetime NOT NULL); CREATE TABLE "api2_tokenv2" ("key" varchar(40) NOT NULL PRIMARY KEY, "user" varchar(255) NOT NULL, "platform" varchar(32) NOT NULL, "device_id" varchar(40) NOT NULL, "device_name" varchar(40) NOT NULL, "platform_version" varchar(16) NOT NULL, "client_version" varchar(16) NOT NULL, "last_accessed" datetime NOT NULL, "last_login_ip" char(39) NULL, "created_at" datetime NOT NULL, "wiped_at" datetime NULL); @@ -56,33 +60,33 @@ CREATE TABLE "django_content_type" ("id" integer NOT NULL PRIMARY KEY AUTOINCREM INSERT INTO "django_content_type" VALUES(1,'contenttypes','contenttype'); INSERT INTO "django_content_type" VALUES(2,'constance','config'); INSERT INTO "django_content_type" VALUES(3,'sessions','session'); -INSERT INTO "django_content_type" VALUES(4,'auth','group'); -INSERT INTO "django_content_type" VALUES(5,'auth','user'); -INSERT INTO "django_content_type" VALUES(6,'auth','permission'); -INSERT INTO "django_content_type" VALUES(7,'registration','registrationprofile'); -INSERT INTO "django_content_type" VALUES(8,'captcha','captchastore'); -INSERT INTO "django_content_type" VALUES(9,'database','constance'); -INSERT INTO "django_content_type" VALUES(10,'post_office','log'); -INSERT INTO "django_content_type" VALUES(11,'post_office','emailtemplate'); -INSERT INTO "django_content_type" VALUES(12,'post_office','email'); -INSERT INTO "django_content_type" VALUES(13,'post_office','attachment'); -INSERT INTO "django_content_type" VALUES(14,'termsandconditions','termsandconditions'); -INSERT INTO "django_content_type" VALUES(15,'termsandconditions','usertermsandconditions'); -INSERT INTO "django_content_type" VALUES(16,'api2','token'); -INSERT INTO "django_content_type" VALUES(17,'api2','tokenv2'); -INSERT INTO "django_content_type" VALUES(18,'avatar','avatar'); -INSERT INTO "django_content_type" VALUES(19,'avatar','groupavatar'); -INSERT INTO "django_content_type" VALUES(20,'base','groupenabledmodule'); -INSERT INTO "django_content_type" VALUES(21,'base','clientlogintoken'); -INSERT INTO "django_content_type" VALUES(22,'base','commandslastcheck'); -INSERT INTO "django_content_type" VALUES(23,'base','userenabledmodule'); -INSERT INTO "django_content_type" VALUES(24,'base','filecomment'); -INSERT INTO "django_content_type" VALUES(25,'base','userstarredfiles'); -INSERT INTO "django_content_type" VALUES(26,'base','filediscuss'); -INSERT INTO "django_content_type" VALUES(27,'base','innerpubmsg'); -INSERT INTO "django_content_type" VALUES(28,'base','innerpubmsgreply'); -INSERT INTO "django_content_type" VALUES(29,'base','userlastlogin'); -INSERT INTO "django_content_type" VALUES(30,'base','devicetoken'); +INSERT INTO "django_content_type" VALUES(4,'base','groupenabledmodule'); +INSERT INTO "django_content_type" VALUES(5,'base','clientlogintoken'); +INSERT INTO "django_content_type" VALUES(6,'base','commandslastcheck'); +INSERT INTO "django_content_type" VALUES(7,'base','userenabledmodule'); +INSERT INTO "django_content_type" VALUES(8,'base','filecomment'); +INSERT INTO "django_content_type" VALUES(9,'base','userstarredfiles'); +INSERT INTO "django_content_type" VALUES(10,'base','filediscuss'); +INSERT INTO "django_content_type" VALUES(11,'base','innerpubmsg'); +INSERT INTO "django_content_type" VALUES(12,'base','innerpubmsgreply'); +INSERT INTO "django_content_type" VALUES(13,'base','userlastlogin'); +INSERT INTO "django_content_type" VALUES(14,'base','devicetoken'); +INSERT INTO "django_content_type" VALUES(15,'auth','group'); +INSERT INTO "django_content_type" VALUES(16,'auth','user'); +INSERT INTO "django_content_type" VALUES(17,'auth','permission'); +INSERT INTO "django_content_type" VALUES(18,'registration','registrationprofile'); +INSERT INTO "django_content_type" VALUES(19,'captcha','captchastore'); +INSERT INTO "django_content_type" VALUES(20,'database','constance'); +INSERT INTO "django_content_type" VALUES(21,'post_office','log'); +INSERT INTO "django_content_type" VALUES(22,'post_office','emailtemplate'); +INSERT INTO "django_content_type" VALUES(23,'post_office','email'); +INSERT INTO "django_content_type" VALUES(24,'post_office','attachment'); +INSERT INTO "django_content_type" VALUES(25,'termsandconditions','termsandconditions'); +INSERT INTO "django_content_type" VALUES(26,'termsandconditions','usertermsandconditions'); +INSERT INTO "django_content_type" VALUES(27,'api2','token'); +INSERT INTO "django_content_type" VALUES(28,'api2','tokenv2'); +INSERT INTO "django_content_type" VALUES(29,'avatar','avatar'); +INSERT INTO "django_content_type" VALUES(30,'avatar','groupavatar'); INSERT INTO "django_content_type" VALUES(31,'contacts','contact'); INSERT INTO "django_content_type" VALUES(32,'institutions','institutionadmin'); INSERT INTO "django_content_type" VALUES(33,'institutions','institution'); @@ -121,8 +125,8 @@ INSERT INTO "django_content_type" VALUES(65,'role_permissions','adminrole'); INSERT INTO "django_content_type" VALUES(66,'trusted_ip','trustedip'); INSERT INTO "django_content_type" VALUES(67,'sysadmin_extra','userloginlog'); INSERT INTO "django_content_type" VALUES(68,'organizations','orgmemberquota'); -INSERT INTO "django_content_type" VALUES(69,'plan','orgplan'); -INSERT INTO "django_content_type" VALUES(70,'plan','userplan'); +INSERT INTO "django_content_type" VALUES(69,'django_cas_ng','proxygrantingticket'); +INSERT INTO "django_content_type" VALUES(70,'django_cas_ng','sessionticket'); CREATE TABLE "auth_group" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(80) NOT NULL UNIQUE); CREATE TABLE "auth_group_permissions" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "group_id" integer NOT NULL REFERENCES "auth_group" ("id"), "permission_id" integer NOT NULL REFERENCES "auth_permission" ("id")); CREATE TABLE "auth_user_groups" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "user_id" integer NOT NULL REFERENCES "auth_user" ("id"), "group_id" integer NOT NULL REFERENCES "auth_group" ("id")); @@ -135,87 +139,87 @@ INSERT INTO "auth_permission" VALUES(4,2,'change_config','Can change config'); INSERT INTO "auth_permission" VALUES(5,3,'add_session','Can add session'); INSERT INTO "auth_permission" VALUES(6,3,'change_session','Can change session'); INSERT INTO "auth_permission" VALUES(7,3,'delete_session','Can delete session'); -INSERT INTO "auth_permission" VALUES(8,4,'add_group','Can add group'); -INSERT INTO "auth_permission" VALUES(9,4,'change_group','Can change group'); -INSERT INTO "auth_permission" VALUES(10,4,'delete_group','Can delete group'); -INSERT INTO "auth_permission" VALUES(11,6,'add_permission','Can add permission'); -INSERT INTO "auth_permission" VALUES(12,6,'change_permission','Can change permission'); -INSERT INTO "auth_permission" VALUES(13,6,'delete_permission','Can delete permission'); -INSERT INTO "auth_permission" VALUES(14,5,'add_user','Can add user'); -INSERT INTO "auth_permission" VALUES(15,5,'change_user','Can change user'); -INSERT INTO "auth_permission" VALUES(16,5,'delete_user','Can delete user'); -INSERT INTO "auth_permission" VALUES(17,7,'add_registrationprofile','Can add registration profile'); -INSERT INTO "auth_permission" VALUES(18,7,'change_registrationprofile','Can change registration profile'); -INSERT INTO "auth_permission" VALUES(19,7,'delete_registrationprofile','Can delete registration profile'); -INSERT INTO "auth_permission" VALUES(20,8,'add_captchastore','Can add captcha store'); -INSERT INTO "auth_permission" VALUES(21,8,'change_captchastore','Can change captcha store'); -INSERT INTO "auth_permission" VALUES(22,8,'delete_captchastore','Can delete captcha store'); -INSERT INTO "auth_permission" VALUES(23,9,'add_constance','Can add constance'); -INSERT INTO "auth_permission" VALUES(24,9,'change_constance','Can change constance'); -INSERT INTO "auth_permission" VALUES(25,9,'delete_constance','Can delete constance'); -INSERT INTO "auth_permission" VALUES(26,12,'add_email','Can add Email'); -INSERT INTO "auth_permission" VALUES(27,12,'change_email','Can change Email'); -INSERT INTO "auth_permission" VALUES(28,12,'delete_email','Can delete Email'); -INSERT INTO "auth_permission" VALUES(29,13,'add_attachment','Can add Attachment'); -INSERT INTO "auth_permission" VALUES(30,13,'change_attachment','Can change Attachment'); -INSERT INTO "auth_permission" VALUES(31,13,'delete_attachment','Can delete Attachment'); -INSERT INTO "auth_permission" VALUES(32,11,'add_emailtemplate','Can add Email Template'); -INSERT INTO "auth_permission" VALUES(33,11,'change_emailtemplate','Can change Email Template'); -INSERT INTO "auth_permission" VALUES(34,11,'delete_emailtemplate','Can delete Email Template'); -INSERT INTO "auth_permission" VALUES(35,10,'add_log','Can add Log'); -INSERT INTO "auth_permission" VALUES(36,10,'change_log','Can change Log'); -INSERT INTO "auth_permission" VALUES(37,10,'delete_log','Can delete Log'); -INSERT INTO "auth_permission" VALUES(38,14,'add_termsandconditions','Can add Terms and Conditions'); -INSERT INTO "auth_permission" VALUES(39,14,'change_termsandconditions','Can change Terms and Conditions'); -INSERT INTO "auth_permission" VALUES(40,14,'delete_termsandconditions','Can delete Terms and Conditions'); -INSERT INTO "auth_permission" VALUES(41,15,'add_usertermsandconditions','Can add User Terms and Conditions'); -INSERT INTO "auth_permission" VALUES(42,15,'change_usertermsandconditions','Can change User Terms and Conditions'); -INSERT INTO "auth_permission" VALUES(43,15,'delete_usertermsandconditions','Can delete User Terms and Conditions'); -INSERT INTO "auth_permission" VALUES(44,17,'add_tokenv2','Can add token v2'); -INSERT INTO "auth_permission" VALUES(45,17,'change_tokenv2','Can change token v2'); -INSERT INTO "auth_permission" VALUES(46,17,'delete_tokenv2','Can delete token v2'); -INSERT INTO "auth_permission" VALUES(47,16,'add_token','Can add token'); -INSERT INTO "auth_permission" VALUES(48,16,'change_token','Can change token'); -INSERT INTO "auth_permission" VALUES(49,16,'delete_token','Can delete token'); -INSERT INTO "auth_permission" VALUES(50,18,'add_avatar','Can add avatar'); -INSERT INTO "auth_permission" VALUES(51,18,'change_avatar','Can change avatar'); -INSERT INTO "auth_permission" VALUES(52,18,'delete_avatar','Can delete avatar'); -INSERT INTO "auth_permission" VALUES(53,19,'add_groupavatar','Can add group avatar'); -INSERT INTO "auth_permission" VALUES(54,19,'change_groupavatar','Can change group avatar'); -INSERT INTO "auth_permission" VALUES(55,19,'delete_groupavatar','Can delete group avatar'); -INSERT INTO "auth_permission" VALUES(56,23,'add_userenabledmodule','Can add user enabled module'); -INSERT INTO "auth_permission" VALUES(57,23,'change_userenabledmodule','Can change user enabled module'); -INSERT INTO "auth_permission" VALUES(58,23,'delete_userenabledmodule','Can delete user enabled module'); -INSERT INTO "auth_permission" VALUES(59,25,'add_userstarredfiles','Can add user starred files'); -INSERT INTO "auth_permission" VALUES(60,25,'change_userstarredfiles','Can change user starred files'); -INSERT INTO "auth_permission" VALUES(61,25,'delete_userstarredfiles','Can delete user starred files'); -INSERT INTO "auth_permission" VALUES(62,26,'add_filediscuss','Can add file discuss'); -INSERT INTO "auth_permission" VALUES(63,26,'change_filediscuss','Can change file discuss'); -INSERT INTO "auth_permission" VALUES(64,26,'delete_filediscuss','Can delete file discuss'); -INSERT INTO "auth_permission" VALUES(65,29,'add_userlastlogin','Can add user last login'); -INSERT INTO "auth_permission" VALUES(66,29,'change_userlastlogin','Can change user last login'); -INSERT INTO "auth_permission" VALUES(67,29,'delete_userlastlogin','Can delete user last login'); -INSERT INTO "auth_permission" VALUES(68,27,'add_innerpubmsg','Can add inner pub msg'); -INSERT INTO "auth_permission" VALUES(69,27,'change_innerpubmsg','Can change inner pub msg'); -INSERT INTO "auth_permission" VALUES(70,27,'delete_innerpubmsg','Can delete inner pub msg'); -INSERT INTO "auth_permission" VALUES(71,20,'add_groupenabledmodule','Can add group enabled module'); -INSERT INTO "auth_permission" VALUES(72,20,'change_groupenabledmodule','Can change group enabled module'); -INSERT INTO "auth_permission" VALUES(73,20,'delete_groupenabledmodule','Can delete group enabled module'); -INSERT INTO "auth_permission" VALUES(74,22,'add_commandslastcheck','Can add commands last check'); -INSERT INTO "auth_permission" VALUES(75,22,'change_commandslastcheck','Can change commands last check'); -INSERT INTO "auth_permission" VALUES(76,22,'delete_commandslastcheck','Can delete commands last check'); -INSERT INTO "auth_permission" VALUES(77,24,'add_filecomment','Can add file comment'); -INSERT INTO "auth_permission" VALUES(78,24,'change_filecomment','Can change file comment'); -INSERT INTO "auth_permission" VALUES(79,24,'delete_filecomment','Can delete file comment'); -INSERT INTO "auth_permission" VALUES(80,28,'add_innerpubmsgreply','Can add inner pub msg reply'); -INSERT INTO "auth_permission" VALUES(81,28,'change_innerpubmsgreply','Can change inner pub msg reply'); -INSERT INTO "auth_permission" VALUES(82,28,'delete_innerpubmsgreply','Can delete inner pub msg reply'); -INSERT INTO "auth_permission" VALUES(83,21,'add_clientlogintoken','Can add client login token'); -INSERT INTO "auth_permission" VALUES(84,21,'change_clientlogintoken','Can change client login token'); -INSERT INTO "auth_permission" VALUES(85,21,'delete_clientlogintoken','Can delete client login token'); -INSERT INTO "auth_permission" VALUES(86,30,'add_devicetoken','Can add device token'); -INSERT INTO "auth_permission" VALUES(87,30,'change_devicetoken','Can change device token'); -INSERT INTO "auth_permission" VALUES(88,30,'delete_devicetoken','Can delete device token'); +INSERT INTO "auth_permission" VALUES(8,7,'add_userenabledmodule','Can add user enabled module'); +INSERT INTO "auth_permission" VALUES(9,7,'change_userenabledmodule','Can change user enabled module'); +INSERT INTO "auth_permission" VALUES(10,7,'delete_userenabledmodule','Can delete user enabled module'); +INSERT INTO "auth_permission" VALUES(11,9,'add_userstarredfiles','Can add user starred files'); +INSERT INTO "auth_permission" VALUES(12,9,'change_userstarredfiles','Can change user starred files'); +INSERT INTO "auth_permission" VALUES(13,9,'delete_userstarredfiles','Can delete user starred files'); +INSERT INTO "auth_permission" VALUES(14,10,'add_filediscuss','Can add file discuss'); +INSERT INTO "auth_permission" VALUES(15,10,'change_filediscuss','Can change file discuss'); +INSERT INTO "auth_permission" VALUES(16,10,'delete_filediscuss','Can delete file discuss'); +INSERT INTO "auth_permission" VALUES(17,13,'add_userlastlogin','Can add user last login'); +INSERT INTO "auth_permission" VALUES(18,13,'change_userlastlogin','Can change user last login'); +INSERT INTO "auth_permission" VALUES(19,13,'delete_userlastlogin','Can delete user last login'); +INSERT INTO "auth_permission" VALUES(20,11,'add_innerpubmsg','Can add inner pub msg'); +INSERT INTO "auth_permission" VALUES(21,11,'change_innerpubmsg','Can change inner pub msg'); +INSERT INTO "auth_permission" VALUES(22,11,'delete_innerpubmsg','Can delete inner pub msg'); +INSERT INTO "auth_permission" VALUES(23,4,'add_groupenabledmodule','Can add group enabled module'); +INSERT INTO "auth_permission" VALUES(24,4,'change_groupenabledmodule','Can change group enabled module'); +INSERT INTO "auth_permission" VALUES(25,4,'delete_groupenabledmodule','Can delete group enabled module'); +INSERT INTO "auth_permission" VALUES(26,6,'add_commandslastcheck','Can add commands last check'); +INSERT INTO "auth_permission" VALUES(27,6,'change_commandslastcheck','Can change commands last check'); +INSERT INTO "auth_permission" VALUES(28,6,'delete_commandslastcheck','Can delete commands last check'); +INSERT INTO "auth_permission" VALUES(29,8,'add_filecomment','Can add file comment'); +INSERT INTO "auth_permission" VALUES(30,8,'change_filecomment','Can change file comment'); +INSERT INTO "auth_permission" VALUES(31,8,'delete_filecomment','Can delete file comment'); +INSERT INTO "auth_permission" VALUES(32,12,'add_innerpubmsgreply','Can add inner pub msg reply'); +INSERT INTO "auth_permission" VALUES(33,12,'change_innerpubmsgreply','Can change inner pub msg reply'); +INSERT INTO "auth_permission" VALUES(34,12,'delete_innerpubmsgreply','Can delete inner pub msg reply'); +INSERT INTO "auth_permission" VALUES(35,5,'add_clientlogintoken','Can add client login token'); +INSERT INTO "auth_permission" VALUES(36,5,'change_clientlogintoken','Can change client login token'); +INSERT INTO "auth_permission" VALUES(37,5,'delete_clientlogintoken','Can delete client login token'); +INSERT INTO "auth_permission" VALUES(38,14,'add_devicetoken','Can add device token'); +INSERT INTO "auth_permission" VALUES(39,14,'change_devicetoken','Can change device token'); +INSERT INTO "auth_permission" VALUES(40,14,'delete_devicetoken','Can delete device token'); +INSERT INTO "auth_permission" VALUES(41,15,'add_group','Can add group'); +INSERT INTO "auth_permission" VALUES(42,15,'change_group','Can change group'); +INSERT INTO "auth_permission" VALUES(43,15,'delete_group','Can delete group'); +INSERT INTO "auth_permission" VALUES(44,17,'add_permission','Can add permission'); +INSERT INTO "auth_permission" VALUES(45,17,'change_permission','Can change permission'); +INSERT INTO "auth_permission" VALUES(46,17,'delete_permission','Can delete permission'); +INSERT INTO "auth_permission" VALUES(47,16,'add_user','Can add user'); +INSERT INTO "auth_permission" VALUES(48,16,'change_user','Can change user'); +INSERT INTO "auth_permission" VALUES(49,16,'delete_user','Can delete user'); +INSERT INTO "auth_permission" VALUES(50,18,'add_registrationprofile','Can add registration profile'); +INSERT INTO "auth_permission" VALUES(51,18,'change_registrationprofile','Can change registration profile'); +INSERT INTO "auth_permission" VALUES(52,18,'delete_registrationprofile','Can delete registration profile'); +INSERT INTO "auth_permission" VALUES(53,19,'add_captchastore','Can add captcha store'); +INSERT INTO "auth_permission" VALUES(54,19,'change_captchastore','Can change captcha store'); +INSERT INTO "auth_permission" VALUES(55,19,'delete_captchastore','Can delete captcha store'); +INSERT INTO "auth_permission" VALUES(56,20,'add_constance','Can add constance'); +INSERT INTO "auth_permission" VALUES(57,20,'change_constance','Can change constance'); +INSERT INTO "auth_permission" VALUES(58,20,'delete_constance','Can delete constance'); +INSERT INTO "auth_permission" VALUES(59,23,'add_email','Can add Email'); +INSERT INTO "auth_permission" VALUES(60,23,'change_email','Can change Email'); +INSERT INTO "auth_permission" VALUES(61,23,'delete_email','Can delete Email'); +INSERT INTO "auth_permission" VALUES(62,24,'add_attachment','Can add Attachment'); +INSERT INTO "auth_permission" VALUES(63,24,'change_attachment','Can change Attachment'); +INSERT INTO "auth_permission" VALUES(64,24,'delete_attachment','Can delete Attachment'); +INSERT INTO "auth_permission" VALUES(65,22,'add_emailtemplate','Can add Email Template'); +INSERT INTO "auth_permission" VALUES(66,22,'change_emailtemplate','Can change Email Template'); +INSERT INTO "auth_permission" VALUES(67,22,'delete_emailtemplate','Can delete Email Template'); +INSERT INTO "auth_permission" VALUES(68,21,'add_log','Can add Log'); +INSERT INTO "auth_permission" VALUES(69,21,'change_log','Can change Log'); +INSERT INTO "auth_permission" VALUES(70,21,'delete_log','Can delete Log'); +INSERT INTO "auth_permission" VALUES(71,25,'add_termsandconditions','Can add Terms and Conditions'); +INSERT INTO "auth_permission" VALUES(72,25,'change_termsandconditions','Can change Terms and Conditions'); +INSERT INTO "auth_permission" VALUES(73,25,'delete_termsandconditions','Can delete Terms and Conditions'); +INSERT INTO "auth_permission" VALUES(74,26,'add_usertermsandconditions','Can add User Terms and Conditions'); +INSERT INTO "auth_permission" VALUES(75,26,'change_usertermsandconditions','Can change User Terms and Conditions'); +INSERT INTO "auth_permission" VALUES(76,26,'delete_usertermsandconditions','Can delete User Terms and Conditions'); +INSERT INTO "auth_permission" VALUES(77,28,'add_tokenv2','Can add token v2'); +INSERT INTO "auth_permission" VALUES(78,28,'change_tokenv2','Can change token v2'); +INSERT INTO "auth_permission" VALUES(79,28,'delete_tokenv2','Can delete token v2'); +INSERT INTO "auth_permission" VALUES(80,27,'add_token','Can add token'); +INSERT INTO "auth_permission" VALUES(81,27,'change_token','Can change token'); +INSERT INTO "auth_permission" VALUES(82,27,'delete_token','Can delete token'); +INSERT INTO "auth_permission" VALUES(83,29,'add_avatar','Can add avatar'); +INSERT INTO "auth_permission" VALUES(84,29,'change_avatar','Can change avatar'); +INSERT INTO "auth_permission" VALUES(85,29,'delete_avatar','Can delete avatar'); +INSERT INTO "auth_permission" VALUES(86,30,'add_groupavatar','Can add group avatar'); +INSERT INTO "auth_permission" VALUES(87,30,'change_groupavatar','Can change group avatar'); +INSERT INTO "auth_permission" VALUES(88,30,'delete_groupavatar','Can delete group avatar'); INSERT INTO "auth_permission" VALUES(89,31,'add_contact','Can add contact'); INSERT INTO "auth_permission" VALUES(90,31,'change_contact','Can change contact'); INSERT INTO "auth_permission" VALUES(91,31,'delete_contact','Can delete contact'); @@ -312,12 +316,12 @@ INSERT INTO "auth_permission" VALUES(181,63,'delete_totpdevice','Can delete TOTP INSERT INTO "auth_permission" VALUES(182,62,'add_statictoken','Can add static token'); INSERT INTO "auth_permission" VALUES(183,62,'change_statictoken','Can change static token'); INSERT INTO "auth_permission" VALUES(184,62,'delete_statictoken','Can delete static token'); -INSERT INTO "auth_permission" VALUES(185,64,'add_staticdevice','Can add static device'); -INSERT INTO "auth_permission" VALUES(186,64,'change_staticdevice','Can change static device'); -INSERT INTO "auth_permission" VALUES(187,64,'delete_staticdevice','Can delete static device'); -INSERT INTO "auth_permission" VALUES(188,61,'add_phonedevice','Can add phone device'); -INSERT INTO "auth_permission" VALUES(189,61,'change_phonedevice','Can change phone device'); -INSERT INTO "auth_permission" VALUES(190,61,'delete_phonedevice','Can delete phone device'); +INSERT INTO "auth_permission" VALUES(185,61,'add_phonedevice','Can add phone device'); +INSERT INTO "auth_permission" VALUES(186,61,'change_phonedevice','Can change phone device'); +INSERT INTO "auth_permission" VALUES(187,61,'delete_phonedevice','Can delete phone device'); +INSERT INTO "auth_permission" VALUES(188,64,'add_staticdevice','Can add static device'); +INSERT INTO "auth_permission" VALUES(189,64,'change_staticdevice','Can change static device'); +INSERT INTO "auth_permission" VALUES(190,64,'delete_staticdevice','Can delete static device'); INSERT INTO "auth_permission" VALUES(191,65,'add_adminrole','Can add admin role'); INSERT INTO "auth_permission" VALUES(192,65,'change_adminrole','Can change admin role'); INSERT INTO "auth_permission" VALUES(193,65,'delete_adminrole','Can delete admin role'); @@ -330,12 +334,12 @@ INSERT INTO "auth_permission" VALUES(199,67,'delete_userloginlog','Can delete us INSERT INTO "auth_permission" VALUES(200,68,'add_orgmemberquota','Can add org member quota'); INSERT INTO "auth_permission" VALUES(201,68,'change_orgmemberquota','Can change org member quota'); INSERT INTO "auth_permission" VALUES(202,68,'delete_orgmemberquota','Can delete org member quota'); -INSERT INTO "auth_permission" VALUES(203,70,'add_userplan','Can add user plan'); -INSERT INTO "auth_permission" VALUES(204,70,'change_userplan','Can change user plan'); -INSERT INTO "auth_permission" VALUES(205,70,'delete_userplan','Can delete user plan'); -INSERT INTO "auth_permission" VALUES(206,69,'add_orgplan','Can add org plan'); -INSERT INTO "auth_permission" VALUES(207,69,'change_orgplan','Can change org plan'); -INSERT INTO "auth_permission" VALUES(208,69,'delete_orgplan','Can delete org plan'); +INSERT INTO "auth_permission" VALUES(203,70,'add_sessionticket','Can add session ticket'); +INSERT INTO "auth_permission" VALUES(204,70,'change_sessionticket','Can change session ticket'); +INSERT INTO "auth_permission" VALUES(205,70,'delete_sessionticket','Can delete session ticket'); +INSERT INTO "auth_permission" VALUES(206,69,'add_proxygrantingticket','Can add proxy granting ticket'); +INSERT INTO "auth_permission" VALUES(207,69,'change_proxygrantingticket','Can change proxy granting ticket'); +INSERT INTO "auth_permission" VALUES(208,69,'delete_proxygrantingticket','Can delete proxy granting ticket'); CREATE TABLE "auth_user" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "password" varchar(128) NOT NULL, "last_login" datetime NULL, "is_superuser" bool NOT NULL, "first_name" varchar(30) NOT NULL, "last_name" varchar(30) NOT NULL, "email" varchar(254) NOT NULL, "is_staff" bool NOT NULL, "is_active" bool NOT NULL, "date_joined" datetime NOT NULL, "username" varchar(150) NOT NULL UNIQUE); CREATE TABLE "avatar_avatar" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "emailuser" varchar(255) NOT NULL, "primary" bool NOT NULL, "avatar" varchar(1024) NOT NULL, "date_uploaded" datetime NOT NULL); CREATE TABLE "avatar_groupavatar" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "group_id" varchar(255) NOT NULL, "avatar" varchar(1024) NOT NULL, "date_uploaded" datetime NOT NULL); @@ -360,6 +364,8 @@ CREATE TABLE "base_userstarredfiles" ("id" integer NOT NULL PRIMARY KEY AUTOINCR CREATE TABLE "captcha_captchastore" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "challenge" varchar(32) NOT NULL, "response" varchar(32) NOT NULL, "hashkey" varchar(40) NOT NULL UNIQUE, "expiration" datetime NOT NULL); CREATE TABLE "contacts_contact" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "user_email" varchar(255) NOT NULL, "contact_email" varchar(255) NOT NULL, "contact_name" varchar(255) NULL, "note" varchar(255) NULL); CREATE TABLE "constance_config" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "key" varchar(255) NOT NULL UNIQUE, "value" text NOT NULL); +CREATE TABLE "django_cas_ng_sessionticket" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "session_key" varchar(255) NOT NULL, "ticket" varchar(255) NOT NULL); +CREATE TABLE "django_cas_ng_proxygrantingticket" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "session_key" varchar(255) NULL, "pgtiou" varchar(255) NULL, "pgt" varchar(255) NULL, "date" datetime NOT NULL, "user" varchar(255) NOT NULL); CREATE TABLE "institutions_institution" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(200) NOT NULL, "create_time" datetime NOT NULL); CREATE TABLE "institutions_institutionquota" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "quota" bigint NOT NULL, "institution_id" integer NOT NULL REFERENCES "institutions_institution" ("id")); CREATE TABLE "institutions_institutionadmin" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "institution_id" integer NOT NULL REFERENCES "institutions_institution" ("id"), "user" varchar(255) NOT NULL); @@ -396,13 +402,15 @@ CREATE TABLE "two_factor_statictoken" ("id" integer NOT NULL PRIMARY KEY AUTOINC CREATE TABLE "two_factor_totpdevice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "user" varchar(255) NOT NULL UNIQUE, "name" varchar(64) NOT NULL, "confirmed" bool NOT NULL, "key" varchar(80) NOT NULL, "step" smallint unsigned NOT NULL, "t0" bigint NOT NULL, "digits" smallint unsigned NOT NULL, "tolerance" smallint unsigned NOT NULL, "drift" smallint NOT NULL, "last_t" bigint NOT NULL); CREATE TABLE "wiki_groupwiki" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "group_id" integer NOT NULL UNIQUE, "repo_id" varchar(36) NOT NULL); CREATE TABLE "wiki_personalwiki" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL UNIQUE, "repo_id" varchar(36) NOT NULL); -CREATE TABLE "wiki_wiki" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL, "name" varchar(255) NOT NULL, "slug" varchar(255) NOT NULL UNIQUE, "repo_id" varchar(36) NOT NULL, "permission" varchar(50) NOT NULL, "created_at" datetime NOT NULL); +CREATE TABLE "wiki_wiki" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "username" varchar(255) NOT NULL, "name" varchar(255) NOT NULL, "slug" varchar(255) NOT NULL UNIQUE, "permission" varchar(50) NOT NULL, "created_at" datetime NOT NULL, "repo_id" varchar(36) NOT NULL); +CREATE TABLE "organizations_orgmemberquota" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "org_id" integer NOT NULL, "quota" integer NOT NULL); DELETE FROM sqlite_sequence; -INSERT INTO "sqlite_sequence" VALUES('django_migrations',48); +INSERT INTO "sqlite_sequence" VALUES('django_migrations',52); INSERT INTO "sqlite_sequence" VALUES('django_content_type',70); INSERT INTO "sqlite_sequence" VALUES('auth_permission',208); INSERT INTO "sqlite_sequence" VALUES('auth_user',0); INSERT INTO "sqlite_sequence" VALUES('tags_filetag',0); +INSERT INTO "sqlite_sequence" VALUES('django_cas_ng_proxygrantingticket',0); INSERT INTO "sqlite_sequence" VALUES('institutions_institutionadmin',0); INSERT INTO "sqlite_sequence" VALUES('invitations_invitation',0); INSERT INTO "sqlite_sequence" VALUES('notifications_notification',0); @@ -412,6 +420,7 @@ INSERT INTO "sqlite_sequence" VALUES('post_office_emailtemplate',0); INSERT INTO "sqlite_sequence" VALUES('post_office_log',0); INSERT INTO "sqlite_sequence" VALUES('post_office_attachment',0); INSERT INTO "sqlite_sequence" VALUES('revision_tag_revisiontags',0); +INSERT INTO "sqlite_sequence" VALUES('wiki_wiki',0); CREATE INDEX "admin_log_adminlog_email_7213c993" ON "admin_log_adminlog" ("email"); CREATE INDEX "admin_log_adminlog_operation_4bad7bd1" ON "admin_log_adminlog" ("operation"); CREATE UNIQUE INDEX "api2_tokenv2_user_platform_device_id_37005c24_uniq" ON "api2_tokenv2" ("user", "platform", "device_id"); @@ -448,6 +457,8 @@ CREATE INDEX "base_userlastlogin_username_270de06f" ON "base_userlastlogin" ("us CREATE INDEX "base_userstarredfiles_email_29e69053" ON "base_userstarredfiles" ("email"); CREATE INDEX "base_userstarredfiles_repo_id_f5ecc00a" ON "base_userstarredfiles" ("repo_id"); CREATE INDEX "contacts_contact_user_email_149035d4" ON "contacts_contact" ("user_email"); +CREATE UNIQUE INDEX "django_cas_ng_proxygrantingticket_session_key_user_8a4ec2bc_uniq" ON "django_cas_ng_proxygrantingticket" ("session_key", "user"); +CREATE INDEX "django_cas_ng_proxygrantingticket_user_1f42619d" ON "django_cas_ng_proxygrantingticket" ("user"); CREATE INDEX "institutions_institutionquota_institution_id_d23201d9" ON "institutions_institutionquota" ("institution_id"); CREATE INDEX "institutions_institutionadmin_institution_id_1e9bb58b" ON "institutions_institutionadmin" ("institution_id"); CREATE INDEX "institutions_institutionadmin_user_c71d766d" ON "institutions_institutionadmin" ("user"); @@ -501,4 +512,6 @@ CREATE INDEX "two_factor_statictoken_token_2ade1084" ON "two_factor_statictoken" CREATE INDEX "two_factor_statictoken_device_id_93095b45" ON "two_factor_statictoken" ("device_id"); CREATE UNIQUE INDEX "wiki_wiki_username_repo_id_4c8925af_uniq" ON "wiki_wiki" ("username", "repo_id"); CREATE INDEX "wiki_wiki_created_at_54930e39" ON "wiki_wiki" ("created_at"); +CREATE INDEX "wiki_wiki_repo_id_2ee93c37" ON "wiki_wiki" ("repo_id"); +CREATE INDEX "organizations_orgmemberquota_org_id_93dde51d" ON "organizations_orgmemberquota" ("org_id"); COMMIT; diff --git a/tests/api/test_files.py b/tests/api/test_files.py index bd693476eb..0dd5672358 100644 --- a/tests/api/test_files.py +++ b/tests/api/test_files.py @@ -218,6 +218,10 @@ class FilesApiTest(ApiTestBase): self.assertIsNotNone(detail['type']) self.assertIsNotNone(detail['name']) self.assertIsNotNone(detail['size']) + self.assertIsNotNone(detail['starred']) + self.assertIsNotNone(detail['last_modifier_email']) + self.assertIsNotNone(detail['last_modifier_name']) + self.assertIsNotNone(detail['last_modifier_contact_email']) def test_get_file_history(self): with self.get_tmp_repo() as repo: