1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-02 07:27:04 +00:00

update create share/upload link

add SHARE_LINK_FORCE_USE_PASSWORD and SHARE_LINK_PASSWORD_STRENGTH_LEVEL
This commit is contained in:
lian
2021-08-12 15:02:03 +08:00
parent 73fd93dd07
commit 8e78d73b53
16 changed files with 180 additions and 40 deletions

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import moment from 'moment';
import copy from 'copy-to-clipboard';
import { Button, Form, FormGroup, Label, Input, InputGroup, InputGroupAddon, InputGroupText, Alert, FormText } from 'reactstrap';
import { isPro, gettext, shareLinkExpireDaysMin, shareLinkExpireDaysMax, shareLinkExpireDaysDefault, shareLinkPasswordMinLength, canSendShareLinkEmail } from '../../utils/constants';
import { isPro, gettext, shareLinkExpireDaysMin, shareLinkExpireDaysMax, shareLinkExpireDaysDefault, shareLinkForceUsePassword, shareLinkPasswordMinLength, shareLinkPasswordStrengthLevel, canSendShareLinkEmail } from '../../utils/constants';
import ShareLinkPermissionEditor from '../../components/select-editor/share-link-permission-editor';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
@@ -47,7 +47,7 @@ class GenerateShareLink extends React.Component {
this.state = {
isOpIconShown: false,
isValidate: false,
isShowPasswordInput: false,
isShowPasswordInput: shareLinkForceUsePassword ? true : false,
isPasswordVisible: false,
isExpireChecked: !this.isExpireDaysNoLimit,
setExp: 'by-days',
@@ -232,8 +232,8 @@ class GenerateShareLink extends React.Component {
seafileAPI.deleteShareLink(sharedLinkInfo.token).then(() => {
this.setState({
password: '',
passwordnew: '',
isShowPasswordInput: false,
passwdnew: '',
isShowPasswordInput: shareLinkForceUsePassword ? true : false,
expireDays: this.defaultExpireDays,
isExpireChecked: !this.isExpireDaysNoLimit,
errorInfo: '',
@@ -272,6 +272,10 @@ class GenerateShareLink extends React.Component {
this.setState({errorInfo: 'Passwords don\'t match'});
return false;
}
if (Utils.getStrengthLevel(password) < shareLinkPasswordStrengthLevel) {
this.setState({errorInfo: gettext('Password is too weak, should have at least {shareLinkPasswordStrengthLevel} of the following: num, upper letter, lower letter and other symbols'.replace('{shareLinkPasswordStrengthLevel}', shareLinkPasswordStrengthLevel))});
return false;
}
}
if (isExpireChecked) {
@@ -359,8 +363,9 @@ class GenerateShareLink extends React.Component {
return <Loading />;
}
let passwordLengthTip = gettext('(at least {passwordLength} characters)');
passwordLengthTip = passwordLengthTip.replace('{passwordLength}', shareLinkPasswordMinLength);
let passwordLengthTip = gettext('(at least {passwordLength} characters and has {shareLinkPasswordStrengthLevel} of the following: num, upper letter, lower letter and other symbols)');
passwordLengthTip = passwordLengthTip.replace('{passwordLength}', shareLinkPasswordMinLength)
.replace('{shareLinkPasswordStrengthLevel}', shareLinkPasswordStrengthLevel);
if (this.state.sharedLinkInfo) {
let sharedLinkInfo = this.state.sharedLinkInfo;
@@ -442,10 +447,17 @@ class GenerateShareLink extends React.Component {
return (
<Form className="generate-share-link">
<FormGroup check>
{shareLinkForceUsePassword ? (
<Label check>
<Input type="checkbox" checked readOnly disabled />
<span>{gettext('Add password protection')}</span>
</Label>
) : (
<Label check>
<Input type="checkbox" onChange={this.onPasswordInputChecked} />
<span>{gettext('Add password protection')}</span>
</Label>
)}
{this.state.isShowPasswordInput &&
<div className="ml-4">
<FormGroup>

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import copy from 'copy-to-clipboard';
import moment from 'moment';
import { Button, Form, FormGroup, Label, Input, InputGroup, InputGroupAddon, InputGroupText, Alert, FormText } from 'reactstrap';
import { gettext, shareLinkPasswordMinLength, canSendShareLinkEmail, uploadLinkExpireDaysMin, uploadLinkExpireDaysMax, uploadLinkExpireDaysDefault } from '../../utils/constants';
import { gettext, shareLinkForceUsePassword, shareLinkPasswordMinLength, shareLinkPasswordStrengthLevel, canSendShareLinkEmail, uploadLinkExpireDaysMin, uploadLinkExpireDaysMax, uploadLinkExpireDaysDefault } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import UploadLink from '../../models/upload-link';
@@ -42,10 +42,10 @@ class GenerateUploadLink extends React.Component {
this.expirationLimitTip = expirationLimitTip;
this.state = {
showPasswordInput: false,
showPasswordInput: shareLinkForceUsePassword ? true : false,
passwordVisible: false,
password: '',
passwdnew: '',
passwordnew: '',
sharedUploadInfo: null,
isSendLinkShown: false,
isExpireChecked: !this.isExpireDaysNoLimit,
@@ -80,7 +80,7 @@ class GenerateUploadLink extends React.Component {
this.setState({
showPasswordInput: !this.state.showPasswordInput,
password: '',
passwdnew: '',
passwordnew: '',
errorInfo: ''
});
}
@@ -155,6 +155,10 @@ class GenerateUploadLink extends React.Component {
this.setState({errorInfo: gettext('Passwords don\'t match')});
return false;
}
if (Utils.getStrengthLevel(password) < shareLinkPasswordStrengthLevel) {
this.setState({errorInfo: gettext('Password is too weak, should have at least {shareLinkPasswordStrengthLevel} of the following: num, upper letter, lower letter and other symbols'.replace('{shareLinkPasswordStrengthLevel}', shareLinkPasswordStrengthLevel))});
return false;
}
}
if (isExpireChecked) {
@@ -233,7 +237,7 @@ class GenerateUploadLink extends React.Component {
let sharedUploadInfo = this.state.sharedUploadInfo;
seafileAPI.deleteUploadLink(sharedUploadInfo.token).then(() => {
this.setState({
showPasswordInput: false,
showPasswordInput: shareLinkForceUsePassword ? true : false,
expireDays: this.defaultExpireDays,
isExpireChecked: !this.isExpireDaysNoLimit,
password: '',
@@ -256,8 +260,10 @@ class GenerateUploadLink extends React.Component {
const { isSendLinkShown } = this.state;
let passwordLengthTip = gettext('(at least {passwordLength} characters)');
passwordLengthTip = passwordLengthTip.replace('{passwordLength}', shareLinkPasswordMinLength);
let passwordLengthTip = gettext('(at least {passwordLength} characters and has {shareLinkPasswordStrengthLevel} of the following: num, upper letter, lower letter and other symbols)');
passwordLengthTip = passwordLengthTip.replace('{passwordLength}', shareLinkPasswordMinLength)
.replace('{shareLinkPasswordStrengthLevel}', shareLinkPasswordStrengthLevel);
if (this.state.sharedUploadInfo) {
let sharedUploadInfo = this.state.sharedUploadInfo;
return (
@@ -296,10 +302,19 @@ class GenerateUploadLink extends React.Component {
return (
<Form className="generate-upload-link">
<FormGroup check>
<Label check>
{shareLinkForceUsePassword ? (
<Label check>
<Input type="checkbox" checked readOnly disabled />
<span>{gettext('Add password protection')}</span>
</Label>
) : (
<Label check>
<Input type="checkbox" onChange={this.addPassword} />
<span>{gettext('Add password protection')}</span>
</Label>
)}
</Label>
{this.state.showPasswordInput &&
<div className="ml-4">
<FormGroup>

View File

@@ -299,12 +299,26 @@ class WebSettings extends Component {
value={config_dict['REPO_PASSWORD_MIN_LENGTH']}
helpTip={gettext('The least number of characters an encrypted library password should include.')}
/>
<CheckboxItem
saveSetting={this.saveSetting}
displayName={gettext('share/upload link force password')}
keyText='SHARE_LINK_FORCE_USE_PASSWORD'
value={config_dict['SHARE_LINK_FORCE_USE_PASSWORD']}
helpTip={gettext('Force user use password when generating share/upload link.')}
/>
<InputItem
saveSetting={this.saveSetting}
displayName={gettext('download/upload link password minimum length')}
displayName={gettext('share/upload link password minimum length')}
keyText='SHARE_LINK_PASSWORD_MIN_LENGTH'
value={config_dict['SHARE_LINK_PASSWORD_MIN_LENGTH']}
helpTip={gettext('The least number of characters a download/upload link password should include.')}
helpTip={gettext('The least number of characters a share/upload link password should include.')}
/>
<InputItem
saveSetting={this.saveSetting}
displayName={gettext('share/upload link password strength level')}
keyText='SHARE_LINK_PASSWORD_STRENGTH_LEVEL'
value={config_dict['SHARE_LINK_PASSWORD_STRENGTH_LEVEL']}
helpTip={gettext('The level(1-4) of a share/upload link password\'s strength. For example, \'3\' means password must have at least 3 of the following: num, upper letter, lower letter and other symbols')}
/>
<CheckboxItem
saveSetting={this.saveSetting}

View File

@@ -45,7 +45,9 @@ export const resumableUploadFileBlockSize = window.app.pageOptions.resumableUplo
export const storages = window.app.pageOptions.storages; // storage backends
export const libraryTemplates = window.app.pageOptions.libraryTemplates; // library templates
export const enableRepoSnapshotLabel = window.app.pageOptions.enableRepoSnapshotLabel;
export const shareLinkForceUsePassword = window.app.pageOptions.shareLinkForceUsePassword;
export const shareLinkPasswordMinLength = window.app.pageOptions.shareLinkPasswordMinLength;
export const shareLinkPasswordStrengthLevel = window.app.pageOptions.shareLinkPasswordStrengthLevel;
export const shareLinkExpireDaysMin = window.app.pageOptions.shareLinkExpireDaysMin;
export const shareLinkExpireDaysMax = window.app.pageOptions.shareLinkExpireDaysMax;
export const sideNavFooterCustomHtml = window.app.pageOptions.sideNavFooterCustomHtml;

View File

@@ -1,4 +1,4 @@
import { mediaUrl, gettext, serviceURL, siteRoot, isPro, enableFileComment, fileAuditEnabled, canGenerateShareLink, canGenerateUploadLink, username, folderPermEnabled } from './constants';
import { mediaUrl, gettext, serviceURL, siteRoot, isPro, enableFileComment, fileAuditEnabled, canGenerateShareLink, canGenerateUploadLink, shareLinkPasswordMinLength, username, folderPermEnabled } from './constants';
import { strChineseFirstPY } from './pinyin-by-unicode';
import TextTranslation from './text-translation';
import React from 'react';
@@ -1342,6 +1342,44 @@ export const Utils = {
hasNextPage(curPage, perPage, totalCount) {
return curPage * perPage < totalCount;
},
getStrengthLevel: function(pwd) {
const _this = this;
var num = 0;
if (pwd.length < shareLinkPasswordMinLength) {
return 0;
} else {
for (var i = 0; i < pwd.length; i++) {
// return the unicode
// bitwise OR
num |= _this.getCharMode(pwd.charCodeAt(i));
}
return _this.calculateBitwise(num);
}
},
getCharMode: function(n) {
if (n >= 48 && n <= 57) // nums
return 1;
if (n >= 65 && n <= 90) // uppers
return 2;
if (n >= 97 && n <= 122) // lowers
return 4;
else
return 8;
},
calculateBitwise: function(num) {
var level = 0;
for (var i = 0; i < 4; i++){
// bitwise AND
if (num&1) level++;
// Right logical shift
num>>>=1;
}
return level;
},
};

View File

@@ -4,7 +4,6 @@ import logging
from constance import config
from django.conf import settings as dj_settings
from django.utils.translation import ugettext as _
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAdminUser
@@ -25,6 +24,7 @@ DIGIT_WEB_SETTINGS = [
'ENABLE_REPO_HISTORY_SETTING', 'USER_STRONG_PASSWORD_REQUIRED',
'ENABLE_ENCRYPTED_LIBRARY', 'USER_PASSWORD_MIN_LENGTH',
'USER_PASSWORD_STRENGTH_LEVEL', 'SHARE_LINK_PASSWORD_MIN_LENGTH',
'SHARE_LINK_FORCE_USE_PASSWORD', 'SHARE_LINK_PASSWORD_STRENGTH_LEVEL',
'ENABLE_USER_CREATE_ORG_REPO', 'FORCE_PASSWORD_CHANGE',
'LOGIN_ATTEMPT_LIMIT', 'FREEZE_USER_ON_LOGIN_FAILED',
'ENABLE_SHARE_TO_ALL_GROUPS', 'ENABLE_TWO_FACTOR_AUTH',
@@ -87,6 +87,10 @@ class AdminWebSettings(APIView):
error_msg = 'value invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if key == 'SHARE_LINK_PASSWORD_STRENGTH_LEVEL' and value not in (1, 2, 3, 4):
error_msg = 'value invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if (key in STRING_WEB_SETTINGS and key != 'CUSTOM_CSS') and not value:
error_msg = 'value invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

View File

@@ -32,7 +32,7 @@ from seahub.constants import PERMISSION_READ_WRITE, PERMISSION_READ, \
from seahub.share.models import FileShare, UploadLinkShare, check_share_link_access
from seahub.utils import gen_shared_link, is_org_context, normalize_file_path, \
normalize_dir_path, is_pro_version, get_file_type_and_ext, \
check_filename_with_rename, gen_file_upload_url
check_filename_with_rename, gen_file_upload_url, get_password_strength_level
from seahub.utils.file_op import if_locked_by_online_office
from seahub.utils.file_types import IMAGE, VIDEO, XMIND
from seahub.utils.timeutils import datetime_to_isoformat_timestr, \
@@ -263,10 +263,21 @@ class ShareLinks(APIView):
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
password = request.data.get('password', None)
if password and len(password) < config.SHARE_LINK_PASSWORD_MIN_LENGTH:
if config.SHARE_LINK_FORCE_USE_PASSWORD and not password:
error_msg = _('Password is required.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if password:
if len(password) < config.SHARE_LINK_PASSWORD_MIN_LENGTH:
error_msg = _('Password is too short.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if get_password_strength_level(password) < config.SHARE_LINK_PASSWORD_STRENGTH_LEVEL:
error_msg = _('Password is too weak.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
expire_days = request.data.get('expire_days', '')
expiration_time = request.data.get('expiration_time', '')
if expire_days and expiration_time:

View File

@@ -26,7 +26,7 @@ from seahub.api2.permissions import CanGenerateUploadLink
from seahub.share.models import UploadLinkShare, check_share_link_common
from seahub.utils import gen_shared_upload_link, gen_file_upload_url, \
is_pro_version
is_pro_version, get_password_strength_level
from seahub.views import check_folder_permission
from seahub.utils.timeutils import datetime_to_isoformat_timestr
@@ -157,8 +157,19 @@ class UploadLinks(APIView):
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
password = request.data.get('password', None)
if password and len(password) < config.SHARE_LINK_PASSWORD_MIN_LENGTH:
error_msg = _('Password is too short')
if config.SHARE_LINK_FORCE_USE_PASSWORD and not password:
error_msg = _('Password is required.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if password:
if len(password) < config.SHARE_LINK_PASSWORD_MIN_LENGTH:
error_msg = _('Password is too short.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if get_password_strength_level(password) < config.SHARE_LINK_PASSWORD_STRENGTH_LEVEL:
error_msg = _('Password is too weak.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
expire_days = request.data.get('expire_days', '')

View File

@@ -3996,7 +3996,7 @@ class SharedFileDetailView(APIView):
password = request.GET.get('password', '')
if not password:
return api_error(status.HTTP_403_FORBIDDEN, "Password is required")
return api_error(status.HTTP_403_FORBIDDEN, _('Password is required.'))
if not check_password(password, fileshare.password):
return api_error(status.HTTP_403_FORBIDDEN, "Invalid Password")
@@ -4116,7 +4116,7 @@ class SharedDirView(APIView):
password = request.GET.get('password', '')
if not password:
return api_error(status.HTTP_403_FORBIDDEN, "Password is required")
return api_error(status.HTTP_403_FORBIDDEN, _('Password is required.'))
if not check_password(password, fileshare.password):
return api_error(status.HTTP_403_FORBIDDEN, "Invalid Password")

View File

@@ -15,7 +15,7 @@ from django.conf import settings as dj_settings
from django.utils.functional import lazy
from constance import config
from seahub.settings import SEAFILE_VERSION, SITE_TITLE, SITE_NAME, \
from seahub.settings import SEAFILE_VERSION, \
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, \
@@ -121,7 +121,9 @@ def base(request):
'max_file_name': MAX_FILE_NAME,
'has_file_search': HAS_FILE_SEARCH,
'show_repo_download_button': SHOW_REPO_DOWNLOAD_BUTTON,
'share_link_force_use_password': config.SHARE_LINK_FORCE_USE_PASSWORD,
'share_link_password_min_length': config.SHARE_LINK_PASSWORD_MIN_LENGTH,
'share_link_password_strength_level': config.SHARE_LINK_PASSWORD_STRENGTH_LEVEL,
'repo_password_min_length': config.REPO_PASSWORD_MIN_LENGTH,
'events_enabled': EVENTS_ENABLED,
'sysadmin_extra_enabled': ENABLE_SYSADMIN_EXTRA,

View File

@@ -353,8 +353,17 @@ UPLOAD_LINK_EXPIRE_DAYS_MAX = 0 # 0 means no limit
# greater than or equal to MIN and less than or equal to MAX
UPLOAD_LINK_EXPIRE_DAYS_DEFAULT = 0
# mininum length for the password of a share link
SHARE_LINK_PASSWORD_MIN_LENGTH = 8
# force use password when generate a share/upload link
SHARE_LINK_FORCE_USE_PASSWORD = False
# mininum length for the password of a share/upload link
SHARE_LINK_PASSWORD_MIN_LENGTH = 10
# LEVEL for the password of a share/upload link
# based on four types of input:
# num, upper letter, lower letter, other symbols
# '3' means password must have at least 3 types of the above.
SHARE_LINK_PASSWORD_STRENGTH_LEVEL = 1
# enable or disable share link audit
ENABLE_SHARE_LINK_AUDIT = False
@@ -901,7 +910,9 @@ CONSTANCE_CONFIG = {
'USER_PASSWORD_STRENGTH_LEVEL': (USER_PASSWORD_STRENGTH_LEVEL, ''),
'SHARE_LINK_TOKEN_LENGTH': (SHARE_LINK_TOKEN_LENGTH, ''),
'SHARE_LINK_FORCE_USE_PASSWORD': (SHARE_LINK_FORCE_USE_PASSWORD, ''),
'SHARE_LINK_PASSWORD_MIN_LENGTH': (SHARE_LINK_PASSWORD_MIN_LENGTH, ''),
'SHARE_LINK_PASSWORD_STRENGTH_LEVEL': (SHARE_LINK_PASSWORD_STRENGTH_LEVEL, ''),
'ENABLE_TWO_FACTOR_AUTH': (ENABLE_TWO_FACTOR_AUTH, ''),
'TEXT_PREVIEW_EXT': (TEXT_PREVIEW_EXT, ''),

View File

@@ -92,7 +92,9 @@
return libraryTemplates;
})(),
enableRepoSnapshotLabel: {% if enable_repo_snapshot_label %} true {% else %} false {% endif %},
shareLinkForceUsePassword: {% if share_link_force_use_password %} true {% else %} false {% endif %},
shareLinkPasswordMinLength: {{ share_link_password_min_length }},
shareLinkPasswordStrengthLevel: {{ share_link_password_strength_level }},
sideNavFooterCustomHtml: "{{ side_nav_footer_custom_html|safe|escapejs }}",
aboutDialogCustomHtml: "{{ about_dialog_custom_html|safe|escapejs }}",
maxFileName: "{{ max_file_name }}",

View File

@@ -13,7 +13,9 @@ window.app.pageOptions = {
canGenerateShareLink: {% if user.permissions.can_generate_share_link %} true {% else %} false {% endif %},
canSendShareLinkEmail: {% if user.permissions.can_send_share_link_mail %} true {% else %} false {% endif %},
shareLinkForceUsePassword: {% if share_link_force_use_password %} true {% else %} false {% endif %},
shareLinkPasswordMinLength: {{ share_link_password_min_length }},
shareLinkPasswordStrengthLevel: {{ share_link_password_strength_level }},
shareLinkExpireDaysDefault: {{ share_link_expire_days_default }},
shareLinkExpireDaysMin: {{ share_link_expire_days_min }},
shareLinkExpireDaysMax: {{ share_link_expire_days_max }},

View File

@@ -47,7 +47,9 @@
hasDraft: '{{ has_draft }}' === 'True',
draftFilePath: '{{ draft_file_path }}',
draftOriginFilePath: '{{ draft_origin_file_path }}',
shareLinkForceUsePassword: {% if share_link_force_use_password %} true {% else %} false {% endif %},
shareLinkPasswordMinLength: {{ share_link_password_min_length }},
shareLinkPasswordStrengthLevel: {{ share_link_password_strength_level }},
shareLinkExpireDaysDefault: {{ share_link_expire_days_default }},
shareLinkExpireDaysMin: {{ share_link_expire_days_min }},
shareLinkExpireDaysMax: {{ share_link_expire_days_max }},

View File

@@ -3,19 +3,18 @@
from functools import partial
import os
import re
import urllib.request, urllib.parse, urllib.error
import urllib.request, urllib.error, urllib.parse
import urllib.request
import urllib.parse
import urllib.error
import uuid
import logging
import hashlib
import tempfile
import locale
import configparser
import mimetypes
import contextlib
from datetime import datetime
from urllib.parse import urlparse, urljoin
import json
from constance import config
import seaserv
@@ -24,9 +23,9 @@ from seaserv import seafile_api
from django.urls import reverse
from django.core.mail import EmailMessage
from django.shortcuts import render
from django.template import Context, loader
from django.template import loader
from django.utils.translation import ugettext as _
from django.http import HttpResponseRedirect, HttpResponse, HttpResponseNotModified
from django.http import HttpResponseRedirect, HttpResponse
from django.utils.http import urlquote
from django.utils.html import escape
from django.utils.timezone import make_naive, is_aware
@@ -35,7 +34,7 @@ from django.views.static import serve as django_static_serve
from seahub.auth import REDIRECT_FIELD_NAME
from seahub.api2.models import Token, TokenV2
import seahub.settings
from seahub.settings import SITE_NAME, MEDIA_URL, LOGO_PATH, \
from seahub.settings import MEDIA_URL, LOGO_PATH, \
MEDIA_ROOT, CUSTOM_LOGO_PATH
try:
from seahub.settings import EVENTS_CONFIG_FILE
@@ -1254,6 +1253,16 @@ def is_user_password_strong(password):
else:
return True
def get_password_strength_level(password):
num = 0
for letter in password:
# get ascii dec
# bitwise OR
num |= get_char_mode(ord(letter))
return calculate_bitwise(num)
def get_char_mode(n):
"""Return different num according to the type of given letter:
'1': num,

View File

@@ -10,7 +10,9 @@ import json
import time
import uuid
import stat
import urllib.request, urllib.error, urllib.parse
import urllib.request
import urllib.error
import urllib.parse
import chardet
import logging
import posixpath
@@ -45,7 +47,7 @@ from seahub.onlyoffice.utils import get_onlyoffice_dict
from seahub.auth.decorators import login_required
from seahub.base.decorators import repo_passwd_set_required
from seahub.base.accounts import ANONYMOUS_EMAIL
from seahub.base.templatetags.seahub_tags import file_icon_filter, email2nickname
from seahub.base.templatetags.seahub_tags import file_icon_filter
from seahub.share.models import FileShare, check_share_link_common
from seahub.share.decorators import share_link_audit, share_link_login_required
from seahub.wiki.utils import get_wiki_dirent
@@ -87,6 +89,7 @@ import seahub.settings as settings
from seahub.settings import FILE_ENCODING_LIST, FILE_PREVIEW_MAX_SIZE, \
FILE_ENCODING_TRY_LIST, MEDIA_URL, SEAFILE_COLLAB_SERVER, ENABLE_WATERMARK, \
SHARE_LINK_EXPIRE_DAYS_MIN, SHARE_LINK_EXPIRE_DAYS_MAX, SHARE_LINK_PASSWORD_MIN_LENGTH, \
SHARE_LINK_FORCE_USE_PASSWORD, SHARE_LINK_PASSWORD_STRENGTH_LEVEL, \
SHARE_LINK_EXPIRE_DAYS_DEFAULT, ENABLE_SHARE_LINK_REPORT_ABUSE
@@ -564,7 +567,9 @@ def view_lib_file(request, repo_id, path):
'highlight_keyword': settings.HIGHLIGHT_KEYWORD,
'enable_file_comment': settings.ENABLE_FILE_COMMENT,
'enable_watermark': ENABLE_WATERMARK,
'share_link_force_use_password': SHARE_LINK_FORCE_USE_PASSWORD,
'share_link_password_min_length': SHARE_LINK_PASSWORD_MIN_LENGTH,
'share_link_password_strength_level': SHARE_LINK_PASSWORD_STRENGTH_LEVEL,
'share_link_expire_days_default': SHARE_LINK_EXPIRE_DAYS_DEFAULT,
'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,