diff --git a/frontend/src/pages/org-admin/web-settings/web-settings.js b/frontend/src/pages/org-admin/web-settings/web-settings.js index 195bc49a61..721b59d027 100644 --- a/frontend/src/pages/org-admin/web-settings/web-settings.js +++ b/frontend/src/pages/org-admin/web-settings/web-settings.js @@ -12,6 +12,9 @@ import FileItem from './file-item'; import '../../../css/system-admin-web-settings.css'; import CheckboxItem from '../../sys-admin/web-settings/checkbox-item'; +const { sysEnableUserCleanTrash, sysEnableEncryptedLibrary } = window.org.pageOptions; + + class OrgWebSettings extends Component { constructor(props) { @@ -23,6 +26,8 @@ class OrgWebSettings extends Component { logoPath: logoPath, file_ext_white_list: '', force_adfs_login: false, + disable_org_encrypted_library: false, + disable_org_user_clean_trash: false }; } @@ -32,7 +37,9 @@ class OrgWebSettings extends Component { loading: false, config_dict: res.data, file_ext_white_list: res.data.file_ext_white_list, - force_adfs_login: res.data.force_adfs_login + force_adfs_login: res.data.force_adfs_login, + disable_org_encrypted_library: res.data.disable_org_encrypted_library, + disable_org_user_clean_trash: res.data.disable_org_user_clean_trash }); }).catch((error) => { this.setState({ @@ -66,23 +73,8 @@ class OrgWebSettings extends Component { }); }; - updateSSOLgoin = (key, value) => { + orgSaveSetting = (key, value) => { seafileAPI.orgAdminSetSysSettingInfo(orgID, key, value).then((res) => { - this.setState({ - force_adfs_login: res.data.force_adfs_login - }); - toaster.success(gettext('Success')); - }).catch((error) => { - let errMessage = Utils.getErrorMsg(error); - toaster.danger(errMessage); - }); - }; - - updateFileExtWhiteList = (key, value) => { - seafileAPI.orgAdminSetSysSettingInfo(orgID, key, value).then((res) => { - this.setState({ - file_ext_white_list: res.data.file_ext_white_list - }); toaster.success(gettext('Success')); }).catch((error) => { let errMessage = Utils.getErrorMsg(error); @@ -91,7 +83,7 @@ class OrgWebSettings extends Component { }; render() { - const { loading, errorMsg, config_dict, file_ext_white_list, force_adfs_login } = this.state; + const { loading, errorMsg, config_dict, file_ext_white_list, force_adfs_login, disable_org_encrypted_library, disable_org_user_clean_trash } = this.state; let logoPath = this.state.logoPath; logoPath = logoPath.indexOf('image-view') != -1 ? logoPath : mediaUrl + logoPath; return ( @@ -134,7 +126,7 @@ class OrgWebSettings extends Component {
} + {(sysEnableUserCleanTrash || sysEnableEncryptedLibrary) && +
+ + {sysEnableEncryptedLibrary && + + } + {sysEnableUserCleanTrash && + + } + +
+ } } diff --git a/frontend/src/repo-folder-trash.js b/frontend/src/repo-folder-trash.js index 20f738e095..f412a4f198 100644 --- a/frontend/src/repo-folder-trash.js +++ b/frontend/src/repo-folder-trash.js @@ -204,7 +204,7 @@ class RepoFolderTrash extends React.Component {

{gettext('Current path: ')}{showFolder ? this.renderFolderPath() : {repoFolderName}}

- {(path == '/' && enableUserCleanTrash && !showFolder && isRepoAdmin) && + {(path === '/' && enableUserCleanTrash && !showFolder && isRepoAdmin) && }
diff --git a/seahub/api2/endpoints/group_libraries.py b/seahub/api2/endpoints/group_libraries.py index 40a8254d03..244ae3a99e 100644 --- a/seahub/api2/endpoints/group_libraries.py +++ b/seahub/api2/endpoints/group_libraries.py @@ -17,6 +17,7 @@ from seahub.api2.throttling import UserRateThrottle from seahub.api2.authentication import TokenAuthentication from seahub.api2.endpoints.utils import api_check_group from seahub.api2.endpoints.group_owned_libraries import get_group_id_by_repo_owner +from seahub.organizations.models import OrgAdminSettings, DISABLE_ORG_ENCRYPTED_LIBRARY from seahub.signals import repo_created from seahub.group.utils import is_group_member, is_group_admin, \ @@ -189,7 +190,7 @@ class GroupLibraries(APIView): if password and not config.ENABLE_ENCRYPTED_LIBRARY: error_msg = 'NOT allow to create encrypted library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) - + permission = request.data.get('permission', PERMISSION_READ) if permission not in get_available_repo_perms(): error_msg = 'permission invalid.' @@ -213,6 +214,12 @@ class GroupLibraries(APIView): if is_org_context(request): is_org = True org_id = request.user.org.org_id + disable_encrypted_library = OrgAdminSettings.objects.filter(org_id=org_id, + key=DISABLE_ORG_ENCRYPTED_LIBRARY).first() + if (disable_encrypted_library is not None) and int(disable_encrypted_library.value): + return None, api_error(status.HTTP_403_FORBIDDEN, + 'NOT allow to create encrypted library.') + repo_id = seafile_api.create_org_repo(repo_name, '', username, org_id, password, enc_version=settings.ENCRYPTED_LIBRARY_VERSION, pwd_hash_algo=settings.ENCRYPTED_LIBRARY_PWD_HASH_ALGO, diff --git a/seahub/api2/endpoints/group_owned_libraries.py b/seahub/api2/endpoints/group_owned_libraries.py index 67f0a83fdd..460327947a 100644 --- a/seahub/api2/endpoints/group_owned_libraries.py +++ b/seahub/api2/endpoints/group_owned_libraries.py @@ -24,6 +24,7 @@ from seahub.api2.endpoints.utils import ( from seahub.base.templatetags.seahub_tags import email2nickname, \ email2contact_email from seahub.base.accounts import User +from seahub.organizations.models import OrgAdminSettings, DISABLE_ORG_ENCRYPTED_LIBRARY from seahub.signals import repo_created from seahub.group.utils import is_group_admin from seahub.utils import is_valid_dirent_name, is_org_context, \ @@ -103,6 +104,12 @@ class GroupOwnedLibraries(APIView): error_msg = 'NOT allow to create encrypted library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) + if org_id and org_id > 0: + disable_encrypted_library = OrgAdminSettings.objects.filter(org_id=org_id, key=DISABLE_ORG_ENCRYPTED_LIBRARY).first() + if (disable_encrypted_library is not None) and int(disable_encrypted_library.value): + return None, api_error(status.HTTP_403_FORBIDDEN, + 'NOT allow to create encrypted library.') + permission = request.data.get('permission', PERMISSION_READ_WRITE) if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]: error_msg = 'permission invalid.' diff --git a/seahub/api2/endpoints/repo_trash.py b/seahub/api2/endpoints/repo_trash.py index a21f93dc53..4389359f5e 100644 --- a/seahub/api2/endpoints/repo_trash.py +++ b/seahub/api2/endpoints/repo_trash.py @@ -15,12 +15,13 @@ from seahub.api2.authentication import TokenAuthentication from seahub.api2.utils import api_error from seahub.signals import clean_up_repo_trash -from seahub.utils import get_trash_records +from seahub.utils import get_trash_records, is_org_context from seahub.utils.timeutils import timestamp_to_isoformat_timestr from seahub.utils.repo import get_repo_owner, is_repo_admin from seahub.views import check_folder_permission from seahub.group.utils import is_group_admin from seahub.api2.endpoints.group_owned_libraries import get_group_id_by_repo_owner +from seahub.organizations.models import OrgAdminSettings, DISABLE_ORG_USER_CLEAN_TRASH from seaserv import seafile_api from pysearpc import SearpcError @@ -236,6 +237,13 @@ class RepoTrash(APIView): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) + if is_org_context(request): + org_id = request.user.org.org_id + if org_id and org_id > 0: + disable_clean_trash = OrgAdminSettings.objects.filter(org_id=org_id, key=DISABLE_ORG_USER_CLEAN_TRASH).first() + if (disable_clean_trash is not None) and int(disable_clean_trash.value): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.clean_up_repo_history(repo_id, keep_days) org_id = None if not request.user.org else request.user.org.org_id diff --git a/seahub/api2/views.py b/seahub/api2/views.py index 006341819e..5fbb9405fd 100644 --- a/seahub/api2/views.py +++ b/seahub/api2/views.py @@ -111,6 +111,7 @@ from seahub.settings import THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, \ ENABLE_RESET_ENCRYPTED_REPO_PASSWORD, SHARE_LINK_EXPIRE_DAYS_MAX, \ SHARE_LINK_EXPIRE_DAYS_MIN, SHARE_LINK_EXPIRE_DAYS_DEFAULT from seahub.subscription.utils import subscription_check +from seahub.organizations.models import OrgAdminSettings, DISABLE_ORG_ENCRYPTED_LIBRARY try: from seahub.settings import CLOUD_MODE @@ -1135,6 +1136,10 @@ class Repos(APIView): 'NOT allow to create encrypted library.') if org_id and org_id > 0: + disable_encrypted_library = OrgAdminSettings.objects.filter(org_id=org_id, key=DISABLE_ORG_ENCRYPTED_LIBRARY).first() + if (disable_encrypted_library is not None) and int(disable_encrypted_library.value): + return None, api_error(status.HTTP_403_FORBIDDEN, + 'NOT allow to create encrypted library.') repo_id = seafile_api.create_org_repo(repo_name, repo_desc, username, org_id, passwd, enc_version=settings.ENCRYPTED_LIBRARY_VERSION, @@ -1180,6 +1185,11 @@ class Repos(APIView): def _create_enc_repo(self, request, repo_id, repo_name, repo_desc, username, org_id): if not config.ENABLE_ENCRYPTED_LIBRARY: return None, api_error(status.HTTP_403_FORBIDDEN, 'NOT allow to create encrypted library.') + if org_id and org_id > 0: + disable_encrypted_library = OrgAdminSettings.objects.filter(org_id=org_id, key=DISABLE_ORG_ENCRYPTED_LIBRARY).first() + if (disable_encrypted_library is not None) and int(disable_encrypted_library.value): + return None, api_error(status.HTTP_403_FORBIDDEN, + 'NOT allow to create encrypted library.') if not _REPO_ID_PATTERN.match(repo_id): return None, api_error(status.HTTP_400_BAD_REQUEST, 'Repo id must be a valid uuid') @@ -1316,6 +1326,11 @@ class PubRepos(APIView): org_id = -1 if is_org_context(request): org_id = request.user.org.org_id + disable_encrypted_library = OrgAdminSettings.objects.filter(org_id=org_id, + key=DISABLE_ORG_ENCRYPTED_LIBRARY).first() + if (disable_encrypted_library is not None) and int(disable_encrypted_library.value): + return None, api_error(status.HTTP_403_FORBIDDEN, + 'NOT allow to create encrypted library.') repo_id = seafile_api.create_org_repo(repo_name, repo_desc, username, org_id, passwd, enc_version=settings.ENCRYPTED_LIBRARY_VERSION, diff --git a/seahub/organizations/api/admin/info.py b/seahub/organizations/api/admin/info.py index 71f70cd5e3..53a9a91c9f 100644 --- a/seahub/organizations/api/admin/info.py +++ b/seahub/organizations/api/admin/info.py @@ -16,7 +16,7 @@ from seahub.api2.permissions import IsProVersion from seahub.api2.throttling import UserRateThrottle from seahub.api2.authentication import TokenAuthentication -from seahub.organizations.models import OrgMemberQuota, FORCE_ADFS_LOGIN +from seahub.organizations.models import OrgMemberQuota, FORCE_ADFS_LOGIN, DISABLE_ORG_ENCRYPTED_LIBRARY, DISABLE_ORG_USER_CLEAN_TRASH from seahub.utils.file_size import get_file_size_unit from seahub.organizations.settings import ORG_MEMBER_QUOTA_ENABLED, \ ORG_ENABLE_ADMIN_CUSTOM_NAME @@ -70,13 +70,20 @@ def get_org_info(request, org_id): active_members = len([m for m in org_members if m.is_active]) file_ext_white_list = seafile_api.org_get_file_ext_white_list(org_id) - info = {} - if getattr(settings, 'ENABLE_MULTI_ADFS', False): - org_settings = OrgAdminSettings.objects.filter(org_id=org_id, key=FORCE_ADFS_LOGIN).first() - if org_settings: - info[FORCE_ADFS_LOGIN] = int(org_settings.value) - else: - info[FORCE_ADFS_LOGIN] = False + info = { + DISABLE_ORG_ENCRYPTED_LIBRARY: False, + DISABLE_ORG_USER_CLEAN_TRASH: False, + FORCE_ADFS_LOGIN: False + } + org_settings = OrgAdminSettings.objects.filter(org_id=org_id) + setting_items = {item.key: item.value for item in org_settings} + for key, value in info.items(): + if key in setting_items: + info[key] = int(setting_items[key]) + + if settings.ENABLE_MULTI_ADFS is False: + info[FORCE_ADFS_LOGIN] = False + info['storage_quota'] = storage_quota info['storage_usage'] = storage_usage info['user_default_quota'] = user_default_quota diff --git a/seahub/organizations/api/admin/trash_libraries.py b/seahub/organizations/api/admin/trash_libraries.py index 54445af0cc..59065cd86b 100644 --- a/seahub/organizations/api/admin/trash_libraries.py +++ b/seahub/organizations/api/admin/trash_libraries.py @@ -8,6 +8,7 @@ from rest_framework import status from seaserv import seafile_api, ccnet_api from pysearpc import SearpcError +from seahub.organizations.models import OrgAdminSettings, DISABLE_ORG_USER_CLEAN_TRASH from seahub.utils import is_valid_username from seahub.utils.db_api import SeafileDB from seahub.utils.timeutils import timestamp_to_isoformat_timestr @@ -20,6 +21,7 @@ from seahub.group.utils import group_id_to_name from seahub.api2.endpoints.group_owned_libraries import get_group_id_by_repo_owner from seahub.organizations.views import org_user_exists +from constance import config logger = logging.getLogger(__name__) @@ -98,6 +100,17 @@ class OrgAdminTrashLibraries(APIView): """ org_id = int(org_id) + if not config.ENABLE_USER_CLEAN_TRASH: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + + if org_id and org_id > 0: + disable_clean_trash = OrgAdminSettings.objects.filter(org_id=org_id, key=DISABLE_ORG_USER_CLEAN_TRASH).first() + if (disable_clean_trash is not None) and int(disable_clean_trash.value): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + try: db_api = SeafileDB() diff --git a/seahub/organizations/api/admin/web_settings.py b/seahub/organizations/api/admin/web_settings.py index 4b6693a88a..931e0c21f8 100644 --- a/seahub/organizations/api/admin/web_settings.py +++ b/seahub/organizations/api/admin/web_settings.py @@ -13,10 +13,13 @@ from seahub.api2.permissions import IsProVersion, IsOrgAdminUser from seahub.api2.authentication import TokenAuthentication from seahub.api2.throttling import UserRateThrottle from seahub.api2.utils import api_error -from seahub.organizations.models import OrgAdminSettings, FORCE_ADFS_LOGIN +from seahub.organizations.models import OrgAdminSettings, FORCE_ADFS_LOGIN, DISABLE_ORG_USER_CLEAN_TRASH, DISABLE_ORG_ENCRYPTED_LIBRARY logger = logging.getLogger(__name__) +ORG_ADMIN_SETTING_KEYS = [ + FORCE_ADFS_LOGIN, DISABLE_ORG_USER_CLEAN_TRASH, DISABLE_ORG_ENCRYPTED_LIBRARY +] class OrgAdminWebSettings(APIView): authentication_classes = (TokenAuthentication, SessionAuthentication) @@ -58,14 +61,15 @@ class OrgAdminWebSettings(APIView): else: seafile_api.org_del_file_ext_white_list(org_id) config_dict['file_ext_white_list'] = '' - - if key == FORCE_ADFS_LOGIN: + + if key in ORG_ADMIN_SETTING_KEYS: try: - OrgAdminSettings.objects.update_or_create(org_id=org_id, key=FORCE_ADFS_LOGIN, + OrgAdminSettings.objects.update_or_create(org_id=org_id, key=key, defaults={'value': value}) - config_dict[FORCE_ADFS_LOGIN] = value + config_dict[key] = value except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + return Response(config_dict) diff --git a/seahub/organizations/models.py b/seahub/organizations/models.py index c06f2a37fc..4d2556a506 100644 --- a/seahub/organizations/models.py +++ b/seahub/organizations/models.py @@ -15,6 +15,8 @@ logger = logging.getLogger(__name__) FORCE_ADFS_LOGIN = 'force_adfs_login' +DISABLE_ORG_USER_CLEAN_TRASH = 'disable_org_user_clean_trash' +DISABLE_ORG_ENCRYPTED_LIBRARY = 'disable_org_encrypted_library' class OrgMemberQuotaManager(models.Manager): def get_quota(self, org_id): diff --git a/seahub/organizations/templates/organizations/org_admin_react.html b/seahub/organizations/templates/organizations/org_admin_react.html index 03117e518a..c8d52e85b3 100644 --- a/seahub/organizations/templates/organizations/org_admin_react.html +++ b/seahub/organizations/templates/organizations/org_admin_react.html @@ -20,6 +20,8 @@ enableMultiADFS: '{{ enable_multi_adfs }}', isOrgContext: true, enableSubscription: {% if enable_subscription %} true {% else %} false {% endif %}, + sysEnableUserCleanTrash: {% if sys_enable_user_clean_trash %} true {% else %} false {% endif %}, + sysEnableEncryptedLibrary: {% if sys_enable_encrypted_library %} true {% else %} false {% endif %} } } diff --git a/seahub/organizations/views.py b/seahub/organizations/views.py index 035060907c..35a2e5ece6 100644 --- a/seahub/organizations/views.py +++ b/seahub/organizations/views.py @@ -4,6 +4,8 @@ import logging import json from urllib.parse import urlparse +from constance import config + from django.conf import settings from django.contrib import messages @@ -265,6 +267,8 @@ def react_fake_view(request, **kwargs): 'invitation_link': invitation_link, 'enable_multi_adfs': ENABLE_MULTI_ADFS, 'enable_subscription': subscription_check(), + 'sys_enable_user_clean_trash': config.ENABLE_USER_CLEAN_TRASH, + 'sys_enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY }) @login_required diff --git a/seahub/views/__init__.py b/seahub/views/__init__.py index 2e525fe531..e4e5f4ca72 100644 --- a/seahub/views/__init__.py +++ b/seahub/views/__init__.py @@ -68,6 +68,8 @@ from seahub.group.settings import GROUP_IMPORT_MEMBERS_EXTRA_MSG from seahub.weixin.settings import ENABLE_WEIXIN from seahub.onlyoffice.settings import ONLYOFFICE_DESKTOP_EDITOR_HTTP_USER_AGENT +from seahub.organizations.models import OrgAdminSettings, DISABLE_ORG_USER_CLEAN_TRASH, DISABLE_ORG_ENCRYPTED_LIBRARY + LIBRARY_TEMPLATES = getattr(settings, 'LIBRARY_TEMPLATES', {}) CUSTOM_NAV_ITEMS = getattr(settings, 'CUSTOM_NAV_ITEMS', '') @@ -307,6 +309,13 @@ def repo_folder_trash(request, repo_id): raise Http404 repo_admin = is_repo_admin(username, repo_id) + org_setting = None + if is_org_context(request): + org_id = request.user.org.org_id + org_setting = OrgAdminSettings.objects.filter(org_id=org_id, key=DISABLE_ORG_USER_CLEAN_TRASH).first() + enable_clean_trash = config.ENABLE_USER_CLEAN_TRASH + if enable_clean_trash: + enable_clean_trash = int(not org_setting.value) if org_setting else True if path == '/': name = repo.name @@ -317,7 +326,7 @@ def repo_folder_trash(request, repo_id): 'repo': repo, 'repo_folder_name': name, 'path': path, - 'enable_user_clean_trash': config.ENABLE_USER_CLEAN_TRASH, + 'enable_user_clean_trash': enable_clean_trash, 'is_repo_admin': repo_admin }) @@ -1080,6 +1089,25 @@ def react_fake_view(request, **kwargs): logger.error(e) max_upload_file_size = -1 + org_setting = { + DISABLE_ORG_ENCRYPTED_LIBRARY: False, + DISABLE_ORG_USER_CLEAN_TRASH: False + } + if is_org_context(request): + org_id = request.user.org.org_id + if org_id and org_id > 0: + org_configs = OrgAdminSettings.objects.filter(org_id=org_id) + org_configs = {item.key: item.value for item in org_configs} + for key, value in org_setting.items(): + if key in org_configs: + org_setting[key] = int(org_configs[key]) + + enable_encryped_lib, enable_clean_trash = config.ENABLE_ENCRYPTED_LIBRARY, config.ENABLE_USER_CLEAN_TRASH + if enable_encryped_lib: + enable_encryped_lib = int(not org_setting[DISABLE_ORG_ENCRYPTED_LIBRARY]) + if enable_clean_trash: + enable_clean_trash = int(not org_setting[DISABLE_ORG_USER_CLEAN_TRASH]) + return render(request, "react_app.html", { "guide_enabled": guide_enabled, 'trash_repos_expire_days': expire_days if expire_days > 0 else 30, @@ -1096,9 +1124,9 @@ def react_fake_view(request, **kwargs): 'upload_link_expire_days_default': UPLOAD_LINK_EXPIRE_DAYS_DEFAULT, 'upload_link_expire_days_min': UPLOAD_LINK_EXPIRE_DAYS_MIN, 'upload_link_expire_days_max': UPLOAD_LINK_EXPIRE_DAYS_MAX, - 'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY, + 'enable_encrypted_library': enable_encryped_lib, 'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING, - 'enable_user_clean_trash': config.ENABLE_USER_CLEAN_TRASH, + 'enable_user_clean_trash': enable_clean_trash, 'enable_reset_encrypted_repo_password': ENABLE_RESET_ENCRYPTED_REPO_PASSWORD, 'is_email_configured': IS_EMAIL_CONFIGURED, 'can_add_public_repo': request.user.permissions.can_add_public_repo(),