mirror of
https://github.com/haiwen/seahub.git
synced 2025-05-10 08:55:02 +00:00
Merge branch '6.3' into master
This commit is contained in:
commit
dac30d24c5
locale
ar/LC_MESSAGES
bg/LC_MESSAGES
ca/LC_MESSAGES
cs/LC_MESSAGES
de/LC_MESSAGES
el/LC_MESSAGES
en/LC_MESSAGES
es/LC_MESSAGES
es_AR/LC_MESSAGES
es_MX/LC_MESSAGES
fi/LC_MESSAGES
fr/LC_MESSAGES
he/LC_MESSAGES
hu/LC_MESSAGES
is/LC_MESSAGES
it/LC_MESSAGES
ja/LC_MESSAGES
ko/LC_MESSAGES
lt/LC_MESSAGES
lv/LC_MESSAGES
mk/LC_MESSAGES
nl/LC_MESSAGES
pl/LC_MESSAGES
pt_BR/LC_MESSAGES
ru/LC_MESSAGES
sv/LC_MESSAGES
tr/LC_MESSAGES
uk/LC_MESSAGES
vi/LC_MESSAGES
zh_CN/LC_MESSAGES
zh_TW/LC_MESSAGES
media/css
seahub
static/scripts
tests
api/endpoints/admin
seahub
thirdpart/shibboleth
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: seahub\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-09-07 10:41+0800\n"
|
||||
"POT-Creation-Date: 2018-09-17 12:01+0800\n"
|
||||
"PO-Revision-Date: 2018-09-07 02:46+0000\n"
|
||||
"Last-Translator: C_Q <helloworld.c@outlook.com>\n"
|
||||
"Language-Team: Chinese (China) (http://www.transifex.com/haiwen/seahub/language/zh_CN/)\n"
|
||||
@ -75,14 +75,14 @@ msgstr "提交"
|
||||
|
||||
#: frontend/src/components/menu-component/menu-dialog/create-fileforder-dialog.js:91
|
||||
#: frontend/src/components/menu-component/menu-dialog/rename-dialog.js:71
|
||||
#: static/scripts/app/views/fileupload.js:21
|
||||
#: static/scripts/app/views/fileupload.js:22
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#: frontend/src/components/menu-component/menu-dialog/delete-dialog.js:16
|
||||
#: frontend/src/components/menu-component/node-menu.js:39
|
||||
#: frontend/src/components/menu-component/node-menu.js:47
|
||||
#: static/scripts/app/views/fileupload.js:22
|
||||
#: static/scripts/app/views/fileupload.js:23
|
||||
#: static/scripts/sysadmin-app/views/device-trusted-ipaddress.js:27
|
||||
msgid "Delete"
|
||||
msgstr "删除"
|
||||
@ -203,23 +203,23 @@ msgid "View-on-Cloud"
|
||||
msgstr "仅云端只读"
|
||||
|
||||
#: static/scripts/app/models/deleted-repo.js:19
|
||||
#: static/scripts/app/models/repo.js:59 static/scripts/common.js:343
|
||||
#: static/scripts/app/models/repo.js:59 static/scripts/common.js:344
|
||||
msgid "Encrypted library"
|
||||
msgstr "加密资料库"
|
||||
|
||||
#: static/scripts/app/models/deleted-repo.js:21
|
||||
#: static/scripts/app/models/repo.js:61 static/scripts/common.js:347
|
||||
#: static/scripts/app/models/repo.js:61 static/scripts/common.js:348
|
||||
#: static/scripts/sysadmin-app/models/trash-repo.js:14
|
||||
msgid "Read-Write library"
|
||||
msgstr "可读写资料库"
|
||||
|
||||
#: static/scripts/app/models/dirent.js:113 static/scripts/app/views/dir.js:682
|
||||
#: static/scripts/app/views/dir.js:752
|
||||
#: static/scripts/app/views/fileupload.js:392
|
||||
#: static/scripts/app/views/fileupload.js:406
|
||||
#: static/scripts/app/views/fileupload.js:418
|
||||
#: static/scripts/app/views/fileupload.js:430
|
||||
#: static/scripts/app/views/group.js:65 static/scripts/common.js:643
|
||||
#: static/scripts/app/views/fileupload.js:394
|
||||
#: static/scripts/app/views/fileupload.js:408
|
||||
#: static/scripts/app/views/fileupload.js:420
|
||||
#: static/scripts/app/views/fileupload.js:432
|
||||
#: static/scripts/app/views/group.js:65 static/scripts/common.js:644
|
||||
msgid "Just now"
|
||||
msgstr "刚才"
|
||||
|
||||
@ -230,29 +230,29 @@ msgstr "名称为必填项"
|
||||
#: static/scripts/app/models/repo.js:37
|
||||
#: static/scripts/app/views/dialogs/dirent-rename.js:65
|
||||
#: static/scripts/app/views/dir.js:667 static/scripts/app/views/dir.js:727
|
||||
#: static/scripts/app/views/dirent.js:515
|
||||
#: static/scripts/app/views/dirent.js:513
|
||||
#: static/scripts/app/views/group-repo.js:131
|
||||
#: static/scripts/app/views/repo.js:187
|
||||
msgid "Name should not include '/'."
|
||||
msgstr "名字不能包含 ‘/’。"
|
||||
|
||||
#: static/scripts/app/models/repo.js:41 static/scripts/app/views/share.js:334
|
||||
#: static/scripts/app/models/repo.js:41 static/scripts/app/views/share.js:338
|
||||
msgid "Please enter password"
|
||||
msgstr "请输入密码"
|
||||
|
||||
#: static/scripts/app/models/repo.js:42 static/scripts/app/views/share.js:342
|
||||
#: static/scripts/app/models/repo.js:42 static/scripts/app/views/share.js:346
|
||||
msgid "Please enter the password again"
|
||||
msgstr "请再次输入密码"
|
||||
|
||||
#: static/scripts/app/models/repo.js:44 static/scripts/app/views/share.js:338
|
||||
#: static/scripts/app/models/repo.js:44 static/scripts/app/views/share.js:342
|
||||
msgid "Password is too short"
|
||||
msgstr "密码太短"
|
||||
|
||||
#: static/scripts/app/models/repo.js:46 static/scripts/app/views/share.js:346
|
||||
#: static/scripts/app/models/repo.js:46 static/scripts/app/views/share.js:350
|
||||
msgid "Passwords don't match"
|
||||
msgstr "两次输入的密码不一致"
|
||||
|
||||
#: static/scripts/app/models/repo.js:63 static/scripts/common.js:345
|
||||
#: static/scripts/app/models/repo.js:63 static/scripts/common.js:346
|
||||
msgid "Read-Only library"
|
||||
msgstr "只读资料库"
|
||||
|
||||
@ -369,7 +369,7 @@ msgstr "成功拷贝 %(name)s"
|
||||
|
||||
#: static/scripts/app/views/dialogs/dirent-rename.js:59
|
||||
#: static/scripts/app/views/dir.js:662 static/scripts/app/views/dir.js:722
|
||||
#: static/scripts/app/views/dirent.js:509
|
||||
#: static/scripts/app/views/dirent.js:507
|
||||
#: static/scripts/app/views/group-repo.js:125
|
||||
#: static/scripts/app/views/groups.js:118
|
||||
#: static/scripts/app/views/invitations.js:65
|
||||
@ -493,7 +493,7 @@ msgid "Password is required."
|
||||
msgstr "密码为必填项。"
|
||||
|
||||
#: static/scripts/app/views/dir.js:479
|
||||
#: static/scripts/app/views/notifications.js:63 static/scripts/common.js:467
|
||||
#: static/scripts/app/views/notifications.js:63 static/scripts/common.js:468
|
||||
msgid "Please check the network."
|
||||
msgstr "请检查网络是否已连接。"
|
||||
|
||||
@ -617,8 +617,8 @@ msgstr "移动 %(name)s 失败"
|
||||
msgid "Failed to copy %(name)s"
|
||||
msgstr "复制 %(name)s 失败"
|
||||
|
||||
#: static/scripts/app/views/dirent-details.js:95 static/scripts/common.js:694
|
||||
#: static/scripts/common.js:765
|
||||
#: static/scripts/app/views/dirent-details.js:95 static/scripts/common.js:695
|
||||
#: static/scripts/common.js:766
|
||||
msgid "No matches"
|
||||
msgstr "没有匹配项"
|
||||
|
||||
@ -632,37 +632,37 @@ msgid "locked by {placeholder}"
|
||||
msgstr "被 {placeholder} 锁定"
|
||||
|
||||
#: static/scripts/app/views/dirent-grid.js:187
|
||||
#: static/scripts/app/views/dirent.js:416
|
||||
#: static/scripts/app/views/dirent.js:414
|
||||
msgid "Successfully deleted %(name)s"
|
||||
msgstr "删除 %(name)s 成功"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:10
|
||||
#: static/scripts/app/views/fileupload.js:11
|
||||
msgid "File is too big"
|
||||
msgstr "文件太大"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:11
|
||||
#: static/scripts/app/views/fileupload.js:12
|
||||
msgid "File is too small"
|
||||
msgstr "文件太小"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:12
|
||||
#: static/scripts/app/views/fileupload.js:13
|
||||
msgid "Filetype not allowed"
|
||||
msgstr "不支持的文件类型"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:13
|
||||
#: static/scripts/app/views/fileupload.js:14
|
||||
msgid "Maximum number of files exceeded"
|
||||
msgstr "文件太多"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:14
|
||||
#: static/scripts/app/views/fileupload.js:15
|
||||
msgid "Uploaded bytes exceed file size"
|
||||
msgstr "上传大小超过了文件大小"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:15
|
||||
#: static/scripts/app/views/fileupload.js:16
|
||||
msgid "Empty file upload result"
|
||||
msgstr "空文件"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:17
|
||||
#: static/scripts/app/views/fileupload.js:225
|
||||
#: static/scripts/app/views/fileupload.js:265
|
||||
#: static/scripts/app/views/fileupload.js:18
|
||||
#: static/scripts/app/views/fileupload.js:226
|
||||
#: static/scripts/app/views/fileupload.js:266
|
||||
#: static/scripts/app/views/repo-details.js:37
|
||||
#: static/scripts/sysadmin-app/views/address-book-group-item.js:145
|
||||
#: static/scripts/sysadmin-app/views/address-book-group-item.js:152
|
||||
@ -670,43 +670,43 @@ msgstr "空文件"
|
||||
msgid "Error"
|
||||
msgstr "错误"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:18
|
||||
#: static/scripts/app/views/fileupload.js:19
|
||||
msgid "uploaded"
|
||||
msgstr "已上传"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:19
|
||||
#: static/scripts/app/views/fileupload.js:20
|
||||
msgid "canceled"
|
||||
msgstr "已取消"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:20
|
||||
#: static/scripts/app/views/fileupload.js:21
|
||||
msgid "Start"
|
||||
msgstr "上传"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:46
|
||||
#: static/scripts/app/views/fileupload.js:47
|
||||
msgid "File Uploading..."
|
||||
msgstr "文件上传中..."
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:47
|
||||
#: static/scripts/app/views/fileupload.js:48
|
||||
msgid "File Upload complete"
|
||||
msgstr "文件上传已完成"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:48
|
||||
#: static/scripts/app/views/fileupload.js:49
|
||||
msgid "File Upload canceled"
|
||||
msgstr "文件上传已取消"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:49
|
||||
#: static/scripts/app/views/fileupload.js:50
|
||||
msgid "File Upload failed"
|
||||
msgstr "文件上传失败"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:279
|
||||
#: static/scripts/app/views/fileupload.js:280
|
||||
msgid "Replace file {filename}?"
|
||||
msgstr "覆盖文件 {filename} ?"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:305
|
||||
#: static/scripts/app/views/fileupload.js:306
|
||||
msgid "File is locked"
|
||||
msgstr "文件已锁定"
|
||||
|
||||
#: static/scripts/app/views/fileupload.js:440
|
||||
#: static/scripts/app/views/fileupload.js:442
|
||||
msgid "Network error"
|
||||
msgstr "网络错误"
|
||||
|
||||
@ -715,7 +715,7 @@ msgid "Set {placeholder}'s permission"
|
||||
msgstr "设置 {placeholder} 权限"
|
||||
|
||||
#: static/scripts/app/views/folder-perm.js:126
|
||||
#: static/scripts/app/views/share.js:842
|
||||
#: static/scripts/app/views/share.js:846
|
||||
msgid "Select groups"
|
||||
msgstr "选择群组"
|
||||
|
||||
@ -725,7 +725,7 @@ msgstr "编辑失败"
|
||||
|
||||
#: static/scripts/app/views/folder-share-item.js:127
|
||||
#: static/scripts/app/views/folder-share-item.js:188
|
||||
#: static/scripts/common.js:444
|
||||
#: static/scripts/common.js:445
|
||||
#: static/scripts/sysadmin-app/views/dashboard.js:84
|
||||
msgid "Failed. Please check the network."
|
||||
msgstr "操作失败。请检查网络是否已连接。"
|
||||
@ -864,45 +864,45 @@ msgstr "成功更改权限"
|
||||
msgid "Successfully deleted 1 item"
|
||||
msgstr "成功删除 1 个条目"
|
||||
|
||||
#: static/scripts/app/views/share.js:109
|
||||
#: static/scripts/app/views/share.js:90
|
||||
#: static/scripts/sysadmin-app/views/share.js:42
|
||||
msgid "Share {placeholder}"
|
||||
msgstr "共享 {placeholder}"
|
||||
|
||||
#: static/scripts/app/views/share.js:209
|
||||
#: static/scripts/app/views/share.js:186
|
||||
msgid "Expired"
|
||||
msgstr "已过期"
|
||||
|
||||
#: static/scripts/app/views/share.js:287 static/scripts/app/views/share.js:288
|
||||
#: static/scripts/app/views/share.js:309 static/scripts/app/views/share.js:310
|
||||
#: static/scripts/app/views/share.js:291 static/scripts/app/views/share.js:292
|
||||
#: static/scripts/app/views/share.js:313 static/scripts/app/views/share.js:314
|
||||
msgid "Hide"
|
||||
msgstr "隐藏"
|
||||
|
||||
#: static/scripts/app/views/share.js:305 static/scripts/app/views/share.js:306
|
||||
#: static/scripts/app/views/share.js:309 static/scripts/app/views/share.js:310
|
||||
msgid "Show"
|
||||
msgstr "显示"
|
||||
|
||||
#: static/scripts/app/views/share.js:361
|
||||
#: static/scripts/app/views/share.js:365
|
||||
msgid "Please enter days."
|
||||
msgstr "请输入天数。"
|
||||
|
||||
#: static/scripts/app/views/share.js:365
|
||||
#: static/scripts/app/views/share.js:369
|
||||
msgid "Please enter valid days"
|
||||
msgstr "请输入有效的天数"
|
||||
|
||||
#: static/scripts/app/views/share.js:468
|
||||
#: static/scripts/app/views/share.js:472
|
||||
msgid "Share link is copied to the clipboard."
|
||||
msgstr "共享链接已复制到剪贴板。"
|
||||
|
||||
#: static/scripts/app/views/share.js:485
|
||||
#: static/scripts/app/views/share.js:489
|
||||
msgid "Please input at least an email."
|
||||
msgstr "请输入至少一个邮箱。"
|
||||
|
||||
#: static/scripts/app/views/share.js:502
|
||||
#: static/scripts/app/views/share.js:506
|
||||
msgid "Successfully sent to {placeholder}"
|
||||
msgstr "成功发送给 {placeholder}"
|
||||
|
||||
#: static/scripts/app/views/share.js:506
|
||||
#: static/scripts/app/views/share.js:510
|
||||
msgid "Failed to send to {placeholder}"
|
||||
msgstr "发送给 {placeholder} 失败"
|
||||
|
||||
@ -919,34 +919,34 @@ msgstr "成功"
|
||||
msgid "Successfully unstared {placeholder}"
|
||||
msgstr "成功取消星标 {placeholder}"
|
||||
|
||||
#: static/scripts/common.js:458 static/scripts/common.js:460
|
||||
#: static/scripts/common.js:459 static/scripts/common.js:461
|
||||
#: static/scripts/sysadmin-app/views/dashboard.js:79
|
||||
msgid "Permission error"
|
||||
msgstr "权限错误"
|
||||
|
||||
#: static/scripts/common.js:685
|
||||
#: static/scripts/common.js:686
|
||||
#: static/scripts/sysadmin-app/views/address-book-group.js:172
|
||||
#: static/scripts/sysadmin-app/views/group-members.js:41
|
||||
msgid "Search users or enter emails and press Enter"
|
||||
msgstr "搜索用户或输入电子邮件,然后按Enter"
|
||||
|
||||
#: static/scripts/common.js:693 static/scripts/common.js:764
|
||||
#: static/scripts/common.js:694 static/scripts/common.js:765
|
||||
msgid "Please enter 1 or more character"
|
||||
msgstr "请输入 1 个或更多字符"
|
||||
|
||||
#: static/scripts/common.js:695 static/scripts/common.js:766
|
||||
#: static/scripts/common.js:696 static/scripts/common.js:767
|
||||
msgid "Searching..."
|
||||
msgstr "搜索中..."
|
||||
|
||||
#: static/scripts/common.js:696 static/scripts/common.js:767
|
||||
#: static/scripts/common.js:697 static/scripts/common.js:768
|
||||
msgid "Loading failed"
|
||||
msgstr "加载失败"
|
||||
|
||||
#: static/scripts/common.js:756
|
||||
#: static/scripts/common.js:757
|
||||
msgid "Search groups"
|
||||
msgstr "查找群组"
|
||||
|
||||
#: static/scripts/common.js:1091
|
||||
#: static/scripts/common.js:1092
|
||||
msgid "Packaging..."
|
||||
msgstr "正在打包"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2674,18 +2674,6 @@ button.sf-dropdown-toggle:focus {
|
||||
display:inline;
|
||||
margin-right:5px;
|
||||
}
|
||||
.audit-item .audit-select-hidden {
|
||||
position:absolute;
|
||||
background:#fff;
|
||||
padding:6px 1px;
|
||||
border:1px solid #eee;
|
||||
border-radius:5px;
|
||||
z-index:10;
|
||||
}
|
||||
.audit-select-hidden li a {
|
||||
display:block;
|
||||
padding:0 12px;
|
||||
}
|
||||
.file-choose-form {
|
||||
width:500px;
|
||||
padding:10px 20px;
|
||||
@ -3086,12 +3074,23 @@ button.sf-dropdown-toggle:focus {
|
||||
padding:0;
|
||||
}
|
||||
#file-view-tip {
|
||||
height:130px;
|
||||
min-height:130px;
|
||||
padding:30px 10px 10px;
|
||||
width:950px;
|
||||
background:#fff;
|
||||
text-align:center;
|
||||
}
|
||||
#file-view-tip .open-via-client { /* for the text link */
|
||||
display:block;
|
||||
margin-top:25px;
|
||||
color:#333;
|
||||
font-weight:normal;
|
||||
text-decoration:underline;
|
||||
}
|
||||
#file-view-op .open-via-client { /* for the button */
|
||||
padding-top:6px;
|
||||
padding-bottom:4px;
|
||||
}
|
||||
@media (max-width:991.98px) {
|
||||
#file-view-tip {
|
||||
width: 80%;
|
||||
@ -3789,25 +3788,21 @@ button.sf-dropdown-toggle:focus {
|
||||
}
|
||||
|
||||
/* file audit*/
|
||||
.audit-show-select {
|
||||
font-weight: normal;
|
||||
font-size: 13px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
#audit-unselect-op div {
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
border: 1px solid #ccc;
|
||||
.audit-unselect-item {
|
||||
display:inline-block;
|
||||
border:1px solid #ccc;
|
||||
border-radius:2px;
|
||||
padding:1px 8px;
|
||||
background: #f2f2f2;
|
||||
cursor: pointer;
|
||||
font-size:14px;
|
||||
}
|
||||
#audit-unselect-op span {
|
||||
margin-right: 5px;
|
||||
.audit-unselect-item:hover {
|
||||
border-color:#a9a9a9;
|
||||
}
|
||||
#audit-unselect-op a {
|
||||
margin: 0 8px;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
.audit-select-user,
|
||||
.audit-select-repo {
|
||||
font-size:13px;
|
||||
}
|
||||
/* multi repo operation */
|
||||
.repo-op .op-link {
|
||||
|
@ -279,7 +279,7 @@ class AdminLibrary(APIView):
|
||||
return Response({'success': True})
|
||||
|
||||
def put(self, request, repo_id, format=None):
|
||||
""" transfer a library
|
||||
""" transfer a library, rename a library
|
||||
|
||||
Permission checking:
|
||||
1. only admin can perform this action.
|
||||
@ -289,100 +289,113 @@ class AdminLibrary(APIView):
|
||||
error_msg = 'Library %s not found.' % repo_id
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
new_owner = request.data.get('owner', None)
|
||||
if not new_owner:
|
||||
error_msg = 'owner invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
try:
|
||||
new_owner_obj = User.objects.get(email=new_owner)
|
||||
except User.DoesNotExist:
|
||||
error_msg = 'User %s not found.' % new_owner
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
if not new_owner_obj.permissions.can_add_repo():
|
||||
error_msg = 'Transfer failed: role of %s is %s, can not add library.' % \
|
||||
(new_owner, new_owner_obj.role)
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
if MULTI_TENANCY:
|
||||
new_repo_name = request.data.get('name', None)
|
||||
if new_repo_name:
|
||||
try:
|
||||
if seafile_api.get_org_id_by_repo_id(repo_id) > 0:
|
||||
error_msg = 'Can not transfer organization library.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
if ccnet_api.get_orgs_by_user(new_owner):
|
||||
error_msg = 'Can not transfer library to organization user %s' % new_owner
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
res = seafile_api.edit_repo(repo_id, new_repo_name, '', None)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
repo_owner = seafile_api.get_repo_owner(repo_id)
|
||||
if res == -1:
|
||||
e = 'Admin rename failed: ID of library is %s, edit_repo api called failed.' % \
|
||||
repo_id
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
# get repo shared to user/group list
|
||||
shared_users = seafile_api.list_repo_shared_to(
|
||||
repo_owner, repo_id)
|
||||
shared_groups = seafile_api.list_repo_shared_group_by_user(
|
||||
repo_owner, repo_id)
|
||||
new_owner = request.data.get('owner', None)
|
||||
if new_owner:
|
||||
try:
|
||||
new_owner_obj = User.objects.get(email=new_owner)
|
||||
except User.DoesNotExist:
|
||||
error_msg = 'User %s not found.' % new_owner
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# get all pub repos
|
||||
pub_repos = []
|
||||
if not request.cloud_mode:
|
||||
pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner)
|
||||
if not new_owner_obj.permissions.can_add_repo():
|
||||
error_msg = 'Transfer failed: role of %s is %s, can not add library.' % \
|
||||
(new_owner, new_owner_obj.role)
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
# transfer repo
|
||||
seafile_api.set_repo_owner(repo_id, new_owner)
|
||||
if MULTI_TENANCY:
|
||||
try:
|
||||
if seafile_api.get_org_id_by_repo_id(repo_id) > 0:
|
||||
error_msg = 'Can not transfer organization library.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
# reshare repo to user
|
||||
for shared_user in shared_users:
|
||||
shared_username = shared_user.user
|
||||
if ccnet_api.get_orgs_by_user(new_owner):
|
||||
error_msg = 'Can not transfer library to organization user %s' % new_owner
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
if new_owner == shared_username:
|
||||
continue
|
||||
repo_owner = seafile_api.get_repo_owner(repo_id)
|
||||
|
||||
seafile_api.share_repo(repo_id, new_owner,
|
||||
shared_username, shared_user.perm)
|
||||
# get repo shared to user/group list
|
||||
shared_users = seafile_api.list_repo_shared_to(
|
||||
repo_owner, repo_id)
|
||||
shared_groups = seafile_api.list_repo_shared_group_by_user(
|
||||
repo_owner, repo_id)
|
||||
|
||||
# reshare repo to group
|
||||
for shared_group in shared_groups:
|
||||
shared_group_id = shared_group.group_id
|
||||
# get all pub repos
|
||||
pub_repos = []
|
||||
if not request.cloud_mode:
|
||||
pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner)
|
||||
|
||||
if not is_group_member(shared_group_id, new_owner):
|
||||
continue
|
||||
# transfer repo
|
||||
seafile_api.set_repo_owner(repo_id, new_owner)
|
||||
|
||||
seafile_api.set_group_repo(repo_id, shared_group_id,
|
||||
new_owner, shared_group.perm)
|
||||
# reshare repo to user
|
||||
for shared_user in shared_users:
|
||||
shared_username = shared_user.user
|
||||
|
||||
# reshare repo to links
|
||||
try:
|
||||
UploadLinkShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner)
|
||||
FileShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
if new_owner == shared_username:
|
||||
continue
|
||||
|
||||
# check if current repo is pub-repo
|
||||
# if YES, reshare current repo to public
|
||||
for pub_repo in pub_repos:
|
||||
if repo_id != pub_repo.id:
|
||||
continue
|
||||
seafile_api.share_repo(repo_id, new_owner,
|
||||
shared_username, shared_user.perm)
|
||||
|
||||
seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission)
|
||||
# reshare repo to group
|
||||
for shared_group in shared_groups:
|
||||
shared_group_id = shared_group.group_id
|
||||
|
||||
break
|
||||
if not is_group_member(shared_group_id, new_owner):
|
||||
continue
|
||||
|
||||
# send admin operation log signal
|
||||
admin_op_detail = {
|
||||
"id": repo_id,
|
||||
"name": repo.name,
|
||||
"from": repo_owner,
|
||||
"to": new_owner,
|
||||
}
|
||||
admin_operation.send(sender=None, admin_name=request.user.username,
|
||||
operation=REPO_TRANSFER, detail=admin_op_detail)
|
||||
seafile_api.set_group_repo(repo_id, shared_group_id,
|
||||
new_owner, shared_group.perm)
|
||||
|
||||
# reshare repo to links
|
||||
try:
|
||||
UploadLinkShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner)
|
||||
FileShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
# check if current repo is pub-repo
|
||||
# if YES, reshare current repo to public
|
||||
for pub_repo in pub_repos:
|
||||
if repo_id != pub_repo.id:
|
||||
continue
|
||||
|
||||
seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission)
|
||||
|
||||
break
|
||||
|
||||
# send admin operation log signal
|
||||
admin_op_detail = {
|
||||
"id": repo_id,
|
||||
"name": repo.name,
|
||||
"from": repo_owner,
|
||||
"to": new_owner,
|
||||
}
|
||||
admin_operation.send(sender=None, admin_name=request.user.username,
|
||||
operation=REPO_TRANSFER, detail=admin_op_detail)
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
repo_info = get_repo_info(repo)
|
||||
|
@ -22,6 +22,8 @@ from seahub.utils import check_filename_with_rename, is_pro_version, \
|
||||
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, if_locked_by_online_office
|
||||
from seahub.views.file import can_preview_file, can_edit_file
|
||||
from seahub.constants import PERMISSION_READ_WRITE
|
||||
|
||||
from seahub.settings import MAX_UPLOAD_FILE_NAME_LEN, \
|
||||
FILE_LOCK_EXPIRATION_DAYS, OFFICE_TEMPLATE_ROOT
|
||||
@ -44,7 +46,13 @@ class FileView(APIView):
|
||||
|
||||
def get_file_info(self, username, repo_id, file_path):
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
file_obj = seafile_api.get_dirent_by_path(repo_id, file_path)
|
||||
file_name = file_obj.obj_name
|
||||
file_size = file_obj.size
|
||||
|
||||
can_preview, error_msg = can_preview_file(file_name, file_size, repo)
|
||||
can_edit, error_msg = can_edit_file(file_name, file_size, repo)
|
||||
|
||||
try:
|
||||
is_locked, locked_by_me = check_file_lock(repo_id, file_path, username)
|
||||
@ -56,11 +64,13 @@ class FileView(APIView):
|
||||
'type': 'file',
|
||||
'repo_id': repo_id,
|
||||
'parent_dir': os.path.dirname(file_path),
|
||||
'obj_name': file_obj.obj_name,
|
||||
'obj_name': file_name,
|
||||
'obj_id': file_obj.obj_id,
|
||||
'size': file_obj.size,
|
||||
'size': file_size,
|
||||
'mtime': timestamp_to_isoformat_timestr(file_obj.mtime),
|
||||
'is_locked': is_locked,
|
||||
'can_preview': can_preview,
|
||||
'can_edit': can_edit,
|
||||
}
|
||||
|
||||
return file_info
|
||||
@ -156,7 +166,7 @@ class FileView(APIView):
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# permission check
|
||||
if check_folder_permission(request, repo_id, parent_dir) != 'rw':
|
||||
if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@ -244,7 +254,7 @@ class FileView(APIView):
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# permission check
|
||||
if check_folder_permission(request, repo_id, parent_dir) != 'rw':
|
||||
if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@ -315,12 +325,12 @@ class FileView(APIView):
|
||||
# permission check for source file
|
||||
src_repo_id = repo_id
|
||||
src_dir = os.path.dirname(path)
|
||||
if check_folder_permission(request, src_repo_id, src_dir) != 'rw':
|
||||
if check_folder_permission(request, src_repo_id, src_dir) != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
# permission check for dst dir
|
||||
if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw':
|
||||
if check_folder_permission(request, dst_repo_id, dst_dir) != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@ -401,7 +411,7 @@ class FileView(APIView):
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
# permission check for dst dir
|
||||
if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw':
|
||||
if check_folder_permission(request, dst_repo_id, dst_dir) != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@ -427,7 +437,7 @@ class FileView(APIView):
|
||||
|
||||
if seafile_api.get_file_id_by_path(repo_id, path):
|
||||
# file exists in repo
|
||||
if check_folder_permission(request, repo_id, parent_dir) != 'rw':
|
||||
if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@ -445,7 +455,7 @@ class FileView(APIView):
|
||||
|
||||
else:
|
||||
# file NOT exists in repo
|
||||
if check_folder_permission(request, repo_id, '/') != 'rw':
|
||||
if check_folder_permission(request, repo_id, '/') != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@ -499,7 +509,7 @@ class FileView(APIView):
|
||||
|
||||
# permission check
|
||||
parent_dir = os.path.dirname(path)
|
||||
if check_folder_permission(request, repo_id, parent_dir) != 'rw':
|
||||
if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@ -535,10 +545,7 @@ class FileView(APIView):
|
||||
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):
|
||||
if locked_by_me or locked_by_online_office:
|
||||
# unlock file
|
||||
try:
|
||||
seafile_api.unlock_file(repo_id, path)
|
||||
@ -600,7 +607,7 @@ class FileView(APIView):
|
||||
parent_dir = os.path.dirname(path)
|
||||
|
||||
username = request.user.username
|
||||
if check_folder_permission(request, repo_id, parent_dir) != 'rw':
|
||||
if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
|
@ -35,8 +35,9 @@ from seahub.utils.rpc import SeafileAPI
|
||||
from seahub.share.signals import share_repo_to_user_successful, share_repo_to_group_successful
|
||||
from seahub.share.utils import share_dir_to_user, share_dir_to_group, update_user_dir_permission, \
|
||||
check_user_share_out_permission, update_group_dir_permission, \
|
||||
check_group_share_out_permission
|
||||
check_group_share_out_permission, check_user_share_in_permission
|
||||
from seahub.constants import PERMISSION_READ, PERMISSION_READ_WRITE
|
||||
from seahub.views import check_folder_permission
|
||||
|
||||
from seahub.settings import ENABLE_STORAGE_CLASSES, STORAGE_CLASS_MAPPING_POLICY
|
||||
|
||||
@ -1313,3 +1314,43 @@ class GroupOwnedLibraryGroupShare(APIView):
|
||||
repo_id, path, permission)
|
||||
|
||||
return Response({'success': True})
|
||||
|
||||
|
||||
class GroupOwnedLibraryUserShareInLibrary(APIView):
|
||||
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsAuthenticated, IsProVersion)
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
|
||||
@add_org_context
|
||||
def delete(self, request, repo_id, org_id, format=None):
|
||||
""" User delete a repo shared to him/her.
|
||||
"""
|
||||
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 check_folder_permission(request, repo_id, '/'):
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
username = request.user.username
|
||||
repo_owner = get_repo_owner(request, repo_id)
|
||||
try:
|
||||
if org_id:
|
||||
is_org = True
|
||||
seafile_api.org_remove_share(org_id, repo_id, repo_owner, username)
|
||||
else:
|
||||
is_org = False
|
||||
seafile_api.remove_share(repo_id, repo_owner, username)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
permission = check_user_share_in_permission(repo_id, username, is_org)
|
||||
send_perm_audit_msg('delete-repo-perm', repo_owner, username,
|
||||
repo_id, '/', permission)
|
||||
|
||||
return Response({'success': True})
|
||||
|
@ -704,6 +704,11 @@ class Repos(APIView):
|
||||
if q and q.lower() not in r.name.lower():
|
||||
continue
|
||||
|
||||
library_group_name = ''
|
||||
if '@seafile_group' in r.user:
|
||||
library_group_id = get_group_id_by_repo_owner(r.user)
|
||||
library_group_name= group_id_to_name(library_group_id)
|
||||
|
||||
r.password_need = is_passwd_set(r.repo_id, email)
|
||||
repo = {
|
||||
"type": "srepo",
|
||||
@ -726,6 +731,7 @@ class Repos(APIView):
|
||||
"root": '',
|
||||
"head_commit_id": r.head_cmmt_id,
|
||||
"version": r.version,
|
||||
"group_name": library_group_name,
|
||||
}
|
||||
|
||||
if r.repo_id in repos_with_admin_share_to:
|
||||
|
@ -9,15 +9,6 @@ class BaseConfig(AppConfig):
|
||||
def ready(self):
|
||||
super(BaseConfig, self).ready()
|
||||
|
||||
# check memcache is available
|
||||
cache.set('test_cache', 'worked')
|
||||
if cache.get('test_cache') != 'worked':
|
||||
print '''
|
||||
Warning: Cache is not working, please check memcached is running if you are using
|
||||
memcached backend, otherwise, please check permission of cache directory on your
|
||||
file system.
|
||||
'''
|
||||
|
||||
# check table `base_filecomment` is ok
|
||||
from seahub.base.models import FileComment
|
||||
try:
|
||||
|
@ -47,22 +47,30 @@ DEFAULT_ENABLED_ROLE_PERMISSIONS = {
|
||||
},
|
||||
}
|
||||
|
||||
_default_role_perms = DEFAULT_ENABLED_ROLE_PERMISSIONS.copy()
|
||||
role_permissions = DEFAULT_ENABLED_ROLE_PERMISSIONS.copy()
|
||||
|
||||
try:
|
||||
_default_role_perms.update(settings.ENABLED_ROLE_PERMISSIONS) # merge outter dict
|
||||
role_permissions.update(settings.ENABLED_ROLE_PERMISSIONS) # merge outter dict
|
||||
except AttributeError:
|
||||
pass # ignore error if ENABLED_ROLE_PERMISSONS is not set in settings.py
|
||||
|
||||
def get_enabled_role_permissions():
|
||||
for role, perms in _default_role_perms.iteritems():
|
||||
permissions = {}
|
||||
for role, perms in role_permissions.iteritems():
|
||||
default_permissions = DEFAULT_ENABLED_ROLE_PERMISSIONS[DEFAULT_USER]
|
||||
# check role permission syntax
|
||||
for k in perms.keys():
|
||||
if k not in DEFAULT_ENABLED_ROLE_PERMISSIONS[DEFAULT_USER].keys():
|
||||
if k not in default_permissions.keys():
|
||||
logger.warn('"%s" is not valid permission, please review the ENABLED_ROLE_PERMISSIONS setting.' % k)
|
||||
assert False, '"%s" is not valid permission, please review the ENABLED_ROLE_PERMISSIONS setting.' % k
|
||||
|
||||
return _default_role_perms
|
||||
all_false_permission = {}
|
||||
for permission in default_permissions.keys():
|
||||
all_false_permission[permission] = False
|
||||
|
||||
all_false_permission.update(perms)
|
||||
permissions[role] = all_false_permission
|
||||
|
||||
return permissions
|
||||
|
||||
ENABLED_ROLE_PERMISSIONS = get_enabled_role_permissions()
|
||||
|
||||
@ -107,16 +115,16 @@ DEFAULT_ENABLED_ADMIN_ROLE_PERMISSIONS = {
|
||||
},
|
||||
}
|
||||
|
||||
_default_admin_role_permissions = DEFAULT_ENABLED_ADMIN_ROLE_PERMISSIONS.copy()
|
||||
admin_role_permissions = DEFAULT_ENABLED_ADMIN_ROLE_PERMISSIONS.copy()
|
||||
|
||||
try:
|
||||
_default_admin_role_permissions.update(settings.ENABLED_ADMIN_ROLE_PERMISSIONS) # merge outter dict
|
||||
admin_role_permissions.update(settings.ENABLED_ADMIN_ROLE_PERMISSIONS) # merge outter dict
|
||||
except AttributeError:
|
||||
pass # ignore error if ENABLED_ADMIN_ROLE_PERMISSIONS is not set in settings.py
|
||||
|
||||
def get_enabled_admin_role_permissions():
|
||||
permissions = {}
|
||||
for role, perms in _default_admin_role_permissions.iteritems():
|
||||
for role, perms in admin_role_permissions.iteritems():
|
||||
# check admin role permission syntax
|
||||
default_admin_permissions = DEFAULT_ENABLED_ADMIN_ROLE_PERMISSIONS[DEFAULT_ADMIN]
|
||||
for k in perms.keys():
|
||||
|
@ -313,6 +313,9 @@ REPO_PASSWORD_MIN_LENGTH = 8
|
||||
# token length for the share link
|
||||
SHARE_LINK_TOKEN_LENGTH = 20
|
||||
|
||||
# if limit only authenticated user can view preview share link
|
||||
SHARE_LINK_LOGIN_REQUIRED = False
|
||||
|
||||
# min/max expire days for a share link
|
||||
SHARE_LINK_EXPIRE_DAYS_MIN = 0 # 0 means no limit
|
||||
SHARE_LINK_EXPIRE_DAYS_MAX = 0 # 0 means no limit
|
||||
@ -378,7 +381,6 @@ ENABLE_FILE_COMMENT = True
|
||||
|
||||
# File preview
|
||||
FILE_PREVIEW_MAX_SIZE = 30 * 1024 * 1024
|
||||
OFFICE_PREVIEW_MAX_SIZE = 2 * 1024 * 1024
|
||||
FILE_ENCODING_LIST = ['auto', 'utf-8', 'gbk', 'ISO-8859-1', 'ISO-8859-5']
|
||||
FILE_ENCODING_TRY_LIST = ['utf-8', 'gbk']
|
||||
HIGHLIGHT_KEYWORD = False # If True, highlight the keywords in the file when the visit is via clicking a link in 'search result' page.
|
||||
|
@ -5,7 +5,7 @@ from django.http import Http404
|
||||
from django.shortcuts import render
|
||||
|
||||
from seahub.share.models import FileShare, UploadLinkShare
|
||||
from seahub.utils import normalize_cache_key, is_pro_version
|
||||
from seahub.utils import normalize_cache_key, is_pro_version, redirect_to_login
|
||||
|
||||
def share_link_audit(func):
|
||||
def _decorated(request, token, *args, **kwargs):
|
||||
@ -56,3 +56,14 @@ def share_link_audit(func):
|
||||
assert False, 'TODO'
|
||||
|
||||
return _decorated
|
||||
|
||||
def share_link_login_required(func):
|
||||
|
||||
def _decorated(request, *args, **kwargs):
|
||||
if not request.user.is_authenticated() \
|
||||
and settings.SHARE_LINK_LOGIN_REQUIRED:
|
||||
return redirect_to_login(request)
|
||||
else:
|
||||
return func(request, *args, **kwargs)
|
||||
|
||||
return _decorated
|
||||
|
@ -1246,18 +1246,14 @@
|
||||
<input type="radio" name="permission" value="preview_download" checked="checked" class="vam" />
|
||||
<span class="vam">{% trans "Preview and download" %}</span>
|
||||
</label><br />
|
||||
<% if (show_link_preview_only_perm_option) { %>
|
||||
<label class="radio-item">
|
||||
<label id="share-link-preview-only-radio" class="radio-item">
|
||||
<input type="radio" name="permission" value="preview_only" class="vam" />
|
||||
<span class="vam">{% trans "Preview only" %}</span>
|
||||
</label><br />
|
||||
<% } %>
|
||||
<% if (show_link_edit_perm_option) { %>
|
||||
<label class="radio-item">
|
||||
<label id="share-link-edit-download-radio" class="radio-item hide">
|
||||
<input type="radio" name="permission" value="edit_download" class="vam" />
|
||||
<span class="vam">{% trans "Edit on cloud and download" %}</span>
|
||||
</label>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
@ -1439,7 +1435,7 @@
|
||||
</td>
|
||||
<td><%= size_formatted %></td>
|
||||
<td><%= mtime_relative %></td>
|
||||
<td><span title="<%- owner_nickname %>"><%- owner_nickname %></span></td>
|
||||
<td><span title="<%- owner_name_shown %>"><%- owner_name_shown %></span></td>
|
||||
</script>
|
||||
<script type="text/template" id="shared-repo-mobile-tmpl">
|
||||
<td>
|
||||
@ -1447,7 +1443,7 @@
|
||||
</td>
|
||||
<td>
|
||||
<a href="#shared-libs/lib/<%= id %>" class="normal"><%- name %></a><br />
|
||||
<span class="repo-meta-info" title="<%- owner %>"><%- owner_nickname %></span>
|
||||
<span class="repo-meta-info" title="<%- owner_name_shown %>"><%- owner_name_shown %></span>
|
||||
<span class="repo-meta-info"><%= size_formatted %></span>
|
||||
<span class="repo-meta-info"><%= mtime_relative %></span>
|
||||
</td>
|
||||
|
@ -41,7 +41,7 @@ html,body {
|
||||
<span>{% trans "Deleted Libraries" %}</span>
|
||||
</div>
|
||||
<div class="cur-view-main-con">
|
||||
<p class="tip">{% trans "Tip: libraries deleted 30 days ago will be cleaned automatically."%}</p>
|
||||
<p class="tip">{% blocktrans %}Tip: libraries deleted {{ trash_repos_expire_days }} days ago will be cleaned automatically.{% endblocktrans %}</p>
|
||||
<table class="my-deleted-repos-table hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
|
@ -40,14 +40,16 @@ For details please refer to 'snippets/file_content_js.html'.
|
||||
<img src="{{raw_path}}" alt="{{ file_name }}" id="svg-view" class="hide" />
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if filetype == 'SpreadSheet' %}
|
||||
{% include 'snippets/spreadsheet_convert_html.html' %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div id="file-view-tip">
|
||||
{% if err != 'invalid extension' %}
|
||||
<p class="error">{{ err }}</p>
|
||||
{% if err != 'File preview unsupported' %}
|
||||
<p class="error">{{ err }}</p>
|
||||
{% else %}
|
||||
<p>{% trans "Online view is not applicable to this file format" %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -67,11 +67,18 @@
|
||||
<div id="file-view" class="flex-1 ov-auto {% block file_view_extra_class %}{% endblock %}">
|
||||
{% if err %}
|
||||
<div id="file-view-tip">
|
||||
{% if err != 'invalid extension' %}
|
||||
{% if err != 'File preview unsupported' %}
|
||||
<p class="error">{{ err }}</p>
|
||||
{% else %}
|
||||
{% else %}
|
||||
<p>{% trans "Online view is not applicable to this file format" %}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<a href="?dl=1" class="sf-btn-link big-btn-link">{% trans "Download" %}</a>
|
||||
{% if file_perm == 'rw' %}
|
||||
{% if filetype == 'Document' or filetype == 'SpreadSheet' %}
|
||||
<a class="open-via-client" href="seafile://openfile?repo_id={{repo.id}}&path={{path|urlencode}}">{% trans "Open via Client" %}</a>
|
||||
<p class="tip">{% trans "Please install the desktop client to open file via client." %}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{% block file_view %}{% endblock %}
|
||||
@ -132,6 +139,12 @@
|
||||
<script type="text/template" id="editor-tools-tmpl">
|
||||
<a class="sf-btn-group-btn sf-btn-group-btn-first sf-btn-link op-icon sf2-icon-folder" href="{{ SITE_ROOT }}#common/lib/{{ repo.id }}/{{ parent_dir|strip_slash }}" title="{% trans "Open parent folder" %}"></a>
|
||||
|
||||
{% if not err and file_perm == 'rw' %}
|
||||
{% if filetype == 'Document' or filetype == 'SpreadSheet' %}
|
||||
<a class="sf-btn-group-btn sf-btn-link op-icon sf2-icon-monitor open-via-client" href="seafile://openfile?repo_id={{repo.id}}&path={{path|urlencode}}" title="{% trans "Open via Client" %}"></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if can_lock_unlock_file %}
|
||||
{% if not file_locked %}
|
||||
<button id="lock-file" class="sf-btn-group-btn op-icon sf2-icon-lock" title="{% trans "Lock" %}"></button>
|
||||
@ -225,12 +238,6 @@
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/findAndReplaceDOMText.js"></script>
|
||||
{% endif %}
|
||||
<script type="text/javascript">
|
||||
// download
|
||||
$(function() {
|
||||
var dld_url = $('#download').attr('href');
|
||||
$('#file-view-tip').append('<a href="' + dld_url + '" class="sf-btn-link big-btn-link">' + "{% trans "Download" %}" + '</a>');
|
||||
});
|
||||
|
||||
// share link
|
||||
{% include "snippets/shared_link_js.html" %}
|
||||
|
||||
|
@ -11,8 +11,8 @@ from seahub.views.sso import *
|
||||
|
||||
from seahub.views.file import view_history_file, view_trash_file,\
|
||||
view_snapshot_file, file_edit, view_shared_file, view_file_via_shared_dir,\
|
||||
text_diff, view_raw_file, view_raw_shared_file, \
|
||||
download_file, view_lib_file, file_access, view_lib_file_via_smart_link
|
||||
text_diff, view_raw_file, download_file, view_lib_file, \
|
||||
file_access, view_lib_file_via_smart_link
|
||||
from seahub.views.repo import repo_history_view, view_shared_dir, \
|
||||
view_shared_upload_link, view_lib_as_wiki
|
||||
from notifications.views import notification_list
|
||||
@ -28,7 +28,7 @@ from seahub.api2.endpoints.group_libraries import GroupLibraries, GroupLibrary
|
||||
from seahub.api2.endpoints.group_owned_libraries import GroupOwnedLibraries, \
|
||||
GroupOwnedLibrary, GroupOwnedLibraryUserFolderPermission, \
|
||||
GroupOwnedLibraryGroupFolderPermission, GroupOwnedLibraryUserShare, \
|
||||
GroupOwnedLibraryGroupShare
|
||||
GroupOwnedLibraryGroupShare, GroupOwnedLibraryUserShareInLibrary
|
||||
from seahub.api2.endpoints.address_book.groups import AddressBookGroupsSubGroups
|
||||
from seahub.api2.endpoints.address_book.members import AddressBookGroupsSearchMember
|
||||
|
||||
@ -170,7 +170,6 @@ urlpatterns = [
|
||||
|
||||
### share/upload link ###
|
||||
url(r'^f/(?P<token>[a-f0-9]+)/$', view_shared_file, name='view_shared_file'),
|
||||
url(r'^f/(?P<token>[a-f0-9]+)/raw/(?P<obj_id>[0-9a-f]{40})/(?P<file_name>.*)', view_raw_shared_file, name='view_raw_shared_file'),
|
||||
url(r'^d/(?P<token>[a-f0-9]+)/$', view_shared_dir, name='view_shared_dir'),
|
||||
url(r'^d/(?P<token>[a-f0-9]+)/files/$', view_file_via_shared_dir, name='view_file_via_shared_dir'),
|
||||
url(r'^u/d/(?P<token>[a-f0-9]+)/$', view_shared_upload_link, name='view_shared_upload_link'),
|
||||
@ -244,6 +243,7 @@ urlpatterns = [
|
||||
url(r'^api/v2.1/group-owned-libraries/(?P<repo_id>[-0-9a-f]{36})/group-folder-permission/$', GroupOwnedLibraryGroupFolderPermission.as_view(), name='api-v2.1-group-owned-library-group-folder-permission'),
|
||||
url(r'^api/v2.1/group-owned-libraries/(?P<repo_id>[-0-9a-f]{36})/user-share/$', GroupOwnedLibraryUserShare.as_view(), name='api-v2.1-group-owned-library-user-share'),
|
||||
url(r'^api/v2.1/group-owned-libraries/(?P<repo_id>[-0-9a-f]{36})/group-share/$', GroupOwnedLibraryGroupShare.as_view(), name='api-v2.1-group-owned-library-group-share'),
|
||||
url(r'^api/v2.1/group-owned-libraries/user-share-in-libraries/(?P<repo_id>[-0-9-a-f]{36})/$', GroupOwnedLibraryUserShareInLibrary.as_view(), name='api-v2.1-group-owned-library-user-share-in-library'),
|
||||
|
||||
## user::shared-folders
|
||||
url(r'^api/v2.1/shared-folders/$', SharedFolders.as_view(), name='api-v2.1-shared-folders'),
|
||||
|
@ -31,6 +31,7 @@ from django.utils.http import urlquote
|
||||
from django.utils.html import escape
|
||||
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, \
|
||||
@ -954,7 +955,7 @@ def redirect_to_login(request):
|
||||
from django.conf import settings
|
||||
login_url = settings.LOGIN_URL
|
||||
path = urlquote(request.get_full_path())
|
||||
tup = login_url, redirect_field_name, path
|
||||
tup = login_url, REDIRECT_FIELD_NAME, path
|
||||
return HttpResponseRedirect('%s?%s=%s' % tup)
|
||||
|
||||
def mkstemp():
|
||||
@ -1052,6 +1053,7 @@ if EVENTS_CONFIG_FILE:
|
||||
|
||||
HAS_OFFICE_CONVERTER = check_office_converter_enabled()
|
||||
|
||||
OFFICE_PREVIEW_MAX_SIZE = 2 * 1024 * 1024
|
||||
if HAS_OFFICE_CONVERTER:
|
||||
|
||||
OFFICE_HTML_DIR = get_office_converter_html_dir()
|
||||
|
@ -710,6 +710,12 @@ def libraries(request):
|
||||
joined_groups_exclude_address_book = [item for item in joined_groups if
|
||||
item.parent_group_id == 0]
|
||||
|
||||
try:
|
||||
expire_days = seafile_api.get_server_config_int('library_trash', 'expire_days')
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
expire_days = -1
|
||||
|
||||
return render(request, 'libraries.html', {
|
||||
"allow_public_share": allow_public_share,
|
||||
"guide_enabled": guide_enabled,
|
||||
@ -742,6 +748,7 @@ def libraries(request):
|
||||
'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
|
||||
'enable_office_web_app': ENABLE_OFFICE_WEB_APP,
|
||||
'enable_onlyoffice': ENABLE_ONLYOFFICE,
|
||||
'trash_repos_expire_days': expire_days if expire_days > 0 else 30,
|
||||
})
|
||||
|
||||
@login_required
|
||||
|
@ -12,7 +12,6 @@ import StringIO
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.template.loader import render_to_string
|
||||
from django.shortcuts import render
|
||||
from django.utils.http import urlquote
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import ugettext as _
|
||||
@ -21,7 +20,7 @@ from django.template.defaultfilters import filesizeformat
|
||||
|
||||
import seaserv
|
||||
from seaserv import seafile_api, is_passwd_set, ccnet_api, \
|
||||
seafserv_threaded_rpc, ccnet_threaded_rpc
|
||||
seafserv_threaded_rpc
|
||||
from pysearpc import SearpcError
|
||||
|
||||
from seahub.auth.decorators import login_required_ajax
|
||||
@ -30,11 +29,10 @@ from seahub.forms import RepoRenameDirentForm
|
||||
from seahub.options.models import UserOptions, CryptoOptionNotSetError
|
||||
from seahub.notifications.models import UserNotification
|
||||
from seahub.notifications.views import add_notice_from_info
|
||||
from seahub.share.models import UploadLinkShare, ExtraSharePermission, ExtraGroupsSharePermission
|
||||
from seahub.share.models import UploadLinkShare
|
||||
from seahub.signals import upload_file_successful
|
||||
from seahub.views import get_unencry_rw_repos_by_user, \
|
||||
get_diff, check_folder_permission
|
||||
from seahub.views.file import can_preview_file
|
||||
from seahub.group.utils import is_group_member, is_group_admin_or_owner, \
|
||||
get_group_member_info
|
||||
import seahub.settings as settings
|
||||
@ -43,8 +41,7 @@ from seahub.settings import ENABLE_THUMBNAIL, THUMBNAIL_ROOT, \
|
||||
from seahub.utils import check_filename_with_rename, EMPTY_SHA1, \
|
||||
gen_block_get_url, TRAFFIC_STATS_ENABLED, get_user_traffic_stat,\
|
||||
new_merge_with_no_conflict, get_commit_before_new_merge, \
|
||||
get_repo_last_modify, gen_file_upload_url, is_org_context, \
|
||||
get_file_type_and_ext, is_pro_version, normalize_dir_path, \
|
||||
gen_file_upload_url, is_org_context, is_pro_version, normalize_dir_path, \
|
||||
FILEEXT_TYPE_MAP
|
||||
from seahub.utils.star import get_dir_starred_files
|
||||
from seahub.utils.file_types import IMAGE, VIDEO
|
||||
@ -56,7 +53,7 @@ from seahub.thumbnail.utils import get_thumbnail_src
|
||||
from seahub.share.utils import is_repo_admin
|
||||
from seahub.base.templatetags.seahub_tags import translate_seahub_time, \
|
||||
email2nickname, tsstr_sec
|
||||
from seahub.constants import PERMISSION_ADMIN
|
||||
from seahub.constants import PERMISSION_READ_WRITE
|
||||
from seahub.constants import HASH_URLS
|
||||
|
||||
# Get an instance of a logger
|
||||
@ -322,9 +319,6 @@ def list_lib_dir(request, repo_id):
|
||||
if fpath in starred_files:
|
||||
dirent.starred = True
|
||||
|
||||
can_preview, err_msg = can_preview_file(dirent.obj_name, file_size, repo)
|
||||
dirent.can_preview = can_preview
|
||||
|
||||
file_list.append(dirent)
|
||||
|
||||
if is_org_context(request):
|
||||
@ -394,7 +388,6 @@ def list_lib_dir(request, repo_id):
|
||||
f_['file_size'] = filesizeformat(f.file_size)
|
||||
f_['obj_id'] = f.obj_id
|
||||
f_['perm'] = f.permission # perm for file in current dir
|
||||
f_['can_preview'] = f.can_preview # if user can preview current file
|
||||
|
||||
if not repo.encrypted and ENABLE_THUMBNAIL:
|
||||
# used for providing a way to determine
|
||||
@ -430,7 +423,7 @@ def list_lib_dir(request, repo_id):
|
||||
f_['locked_by_me'] = True
|
||||
|
||||
if f.lock_owner == ONLINE_OFFICE_LOCK_OWNER and \
|
||||
repo_owner == username:
|
||||
user_perm == PERMISSION_READ_WRITE:
|
||||
f_['locked_by_me'] = True
|
||||
|
||||
dirent_list.append(f_)
|
||||
@ -854,8 +847,10 @@ def cp_dirents(request, src_repo_id, src_path, dst_repo_id, dst_path, obj_file_n
|
||||
result['error'] = error_msg
|
||||
return HttpResponse(json.dumps(result), status=403, content_type=content_type)
|
||||
|
||||
dst_path = normalize_dir_path(dst_path)
|
||||
for obj_name in obj_dir_names:
|
||||
src_dir = posixpath.join(src_path, obj_name)
|
||||
src_dir = normalize_dir_path(src_dir)
|
||||
if dst_path.startswith(src_dir):
|
||||
error_msg = _(u'Can not copy directory %(src)s to its subdirectory %(des)s') \
|
||||
% {'src': escape(src_dir), 'des': escape(dst_path)}
|
||||
@ -1196,9 +1191,8 @@ def get_file_upload_url_ul(request, token):
|
||||
return HttpResponse(json.dumps({"error": _("Permission denied")}),
|
||||
status=403, content_type=content_type)
|
||||
|
||||
username = request.user.username or request.session.get('anonymous_email') or ''
|
||||
|
||||
args = [repo_id, json.dumps({'anonymous_user': username}), 'upload-link', '']
|
||||
dir_id = seafile_api.get_dir_id_by_path(uls.repo_id, uls.path)
|
||||
args = [repo_id, dir_id, 'upload-link', shared_by]
|
||||
kwargs = {
|
||||
'use_onetime': False,
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ from seaserv import get_repo, send_message, get_commits, \
|
||||
seafserv_threaded_rpc
|
||||
from pysearpc import SearpcError
|
||||
|
||||
from seahub.auth import REDIRECT_FIELD_NAME
|
||||
from seahub.tags.models import FileUUIDMap
|
||||
from seahub.wopi.utils import get_wopi_dict
|
||||
from seahub.onlyoffice.utils import get_onlyoffice_dict
|
||||
@ -45,7 +44,7 @@ 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.share.models import FileShare, check_share_link_common
|
||||
from seahub.share.decorators import share_link_audit
|
||||
from seahub.share.decorators import share_link_audit, share_link_login_required
|
||||
from seahub.wiki.utils import get_wiki_dirent
|
||||
from seahub.wiki.models import WikiDoesNotExist, WikiPageMissing
|
||||
from seahub.utils import render_error, is_org_context, \
|
||||
@ -54,8 +53,8 @@ from seahub.utils import render_error, is_org_context, \
|
||||
mkstemp, EMPTY_SHA1, HtmlDiff, gen_inner_file_get_url, \
|
||||
user_traffic_over_limit, get_file_audit_events_by_path, \
|
||||
generate_file_audit_event_type, FILE_AUDIT_ENABLED, \
|
||||
get_conf_text_ext, HAS_OFFICE_CONVERTER, FILEEXT_TYPE_MAP, \
|
||||
normalize_file_path, get_service_url
|
||||
get_conf_text_ext, HAS_OFFICE_CONVERTER, PREVIEW_FILEEXT, \
|
||||
normalize_file_path, get_service_url, OFFICE_PREVIEW_MAX_SIZE
|
||||
|
||||
from seahub.utils.ip import get_remote_ip
|
||||
from seahub.utils.timeutils import utc_to_local
|
||||
@ -76,7 +75,7 @@ from seahub.constants import HASH_URLS
|
||||
if HAS_OFFICE_CONVERTER:
|
||||
from seahub.utils import (
|
||||
query_office_convert_status, add_office_convert_task,
|
||||
prepare_converted_html, OFFICE_PREVIEW_MAX_SIZE, get_office_converted_page
|
||||
prepare_converted_html, get_office_converted_page
|
||||
)
|
||||
|
||||
import seahub.settings as settings
|
||||
@ -105,11 +104,18 @@ except ImportError:
|
||||
|
||||
try:
|
||||
from seahub.settings import ENABLE_ONLYOFFICE
|
||||
from seahub.onlyoffice.settings import ONLYOFFICE_FILE_EXTENSION, \
|
||||
ONLYOFFICE_EDIT_FILE_EXTENSION
|
||||
except ImportError:
|
||||
ENABLE_ONLYOFFICE = False
|
||||
|
||||
try:
|
||||
from seahub.onlyoffice.settings import ONLYOFFICE_FILE_EXTENSION
|
||||
except ImportError:
|
||||
ONLYOFFICE_FILE_EXTENSION = ()
|
||||
|
||||
try:
|
||||
from seahub.onlyoffice.settings import ONLYOFFICE_EDIT_FILE_EXTENSION
|
||||
except ImportError:
|
||||
ONLYOFFICE_EDIT_FILE_EXTENSION = ()
|
||||
|
||||
# Get an instance of a logger
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -301,56 +307,82 @@ def convert_md_link(file_content, repo_id, username):
|
||||
|
||||
return re.sub(r'\[\[(.+?)\]\]|(`.+?`)', repl, file_content)
|
||||
|
||||
def file_size_exceeds_preview_limit(file_size, file_type):
|
||||
"""Check whether file size exceeds the preview limit base on different
|
||||
type of file.
|
||||
def can_preview_file(file_name, file_size, repo):
|
||||
"""Check whether Seafile supports view file.
|
||||
Returns (True, None) if Yes, otherwise (False, error_msg).
|
||||
"""
|
||||
if file_type in (DOCUMENT, ) and HAS_OFFICE_CONVERTER:
|
||||
if file_size > OFFICE_PREVIEW_MAX_SIZE:
|
||||
err = _(u'File size surpasses %s, can not be opened online.') % \
|
||||
filesizeformat(OFFICE_PREVIEW_MAX_SIZE)
|
||||
return True, err
|
||||
else:
|
||||
return False, ''
|
||||
elif file_type in (VIDEO, AUDIO):
|
||||
return False, ''
|
||||
else:
|
||||
if file_size > FILE_PREVIEW_MAX_SIZE:
|
||||
err = _(u'File size surpasses %s, can not be opened online.') % \
|
||||
filesizeformat(FILE_PREVIEW_MAX_SIZE)
|
||||
return True, err
|
||||
else:
|
||||
return False, ''
|
||||
|
||||
def can_preview_file(file_name, file_size, repo=None):
|
||||
"""Check whether a file can be viewed online.
|
||||
Returns (True, None) if file can be viewed online, otherwise
|
||||
(False, erro_msg).
|
||||
filetype, fileext = get_file_type_and_ext(file_name)
|
||||
|
||||
# Seafile defines 9 kinds of filetype:
|
||||
# TEXT, MARKDOWN, IMAGE, DOCUMENT, SPREADSHEET, VIDEO, AUDIO, PDF, SVG
|
||||
if filetype in (TEXT, MARKDOWN, IMAGE) or fileext in get_conf_text_ext():
|
||||
if file_size > FILE_PREVIEW_MAX_SIZE:
|
||||
error_msg = _(u'File size surpasses %s, can not be opened online.') % \
|
||||
filesizeformat(FILE_PREVIEW_MAX_SIZE)
|
||||
return False, error_msg
|
||||
|
||||
elif filetype in (DOCUMENT, SPREADSHEET):
|
||||
|
||||
if repo.encrypted:
|
||||
error_msg = _(u'The library is encrypted, can not open file online.')
|
||||
return False, error_msg
|
||||
|
||||
if not HAS_OFFICE_CONVERTER and \
|
||||
not ENABLE_OFFICE_WEB_APP and \
|
||||
not ENABLE_ONLYOFFICE:
|
||||
error_msg = "File preview unsupported"
|
||||
return False, error_msg
|
||||
|
||||
# priority of view office file is:
|
||||
# OOS > OnlyOffice > Seafile integrated
|
||||
if ENABLE_OFFICE_WEB_APP:
|
||||
if fileext not in OFFICE_WEB_APP_FILE_EXTENSION:
|
||||
error_msg = "File preview unsupported"
|
||||
return False, error_msg
|
||||
|
||||
elif ENABLE_ONLYOFFICE:
|
||||
if fileext not in ONLYOFFICE_FILE_EXTENSION:
|
||||
error_msg = "File preview unsupported"
|
||||
return False, error_msg
|
||||
|
||||
else:
|
||||
# HAS_OFFICE_CONVERTER
|
||||
if file_size > OFFICE_PREVIEW_MAX_SIZE:
|
||||
error_msg = _(u'File size surpasses %s, can not be opened online.') % \
|
||||
filesizeformat(OFFICE_PREVIEW_MAX_SIZE)
|
||||
return False, error_msg
|
||||
else:
|
||||
# NOT depends on Seafile settings
|
||||
if filetype not in PREVIEW_FILEEXT.keys():
|
||||
error_msg = "File preview unsupported"
|
||||
return False, error_msg
|
||||
|
||||
return True, ''
|
||||
|
||||
def can_edit_file(file_name, file_size, repo):
|
||||
"""Check whether Seafile supports edit file.
|
||||
Returns (True, None) if Yes, otherwise (False, error_msg).
|
||||
"""
|
||||
|
||||
can_preview, err_msg = can_preview_file(file_name, file_size, repo)
|
||||
if not can_preview:
|
||||
return False, err_msg
|
||||
|
||||
file_type, file_ext = get_file_type_and_ext(file_name)
|
||||
|
||||
if file_type in (TEXT, MARKDOWN) or file_ext in get_conf_text_ext():
|
||||
return True, ''
|
||||
|
||||
if ENABLE_OFFICE_WEB_APP and file_ext in OFFICE_WEB_APP_FILE_EXTENSION:
|
||||
return (True, None)
|
||||
if file_type in (DOCUMENT, SPREADSHEET):
|
||||
if ENABLE_OFFICE_WEB_APP_EDIT and \
|
||||
file_ext in OFFICE_WEB_APP_EDIT_FILE_EXTENSION:
|
||||
return True, ''
|
||||
|
||||
if ENABLE_ONLYOFFICE and file_ext in ONLYOFFICE_FILE_EXTENSION:
|
||||
return (True, None)
|
||||
if ENABLE_ONLYOFFICE and file_ext in ONLYOFFICE_EDIT_FILE_EXTENSION:
|
||||
return True, ''
|
||||
|
||||
if repo and repo.encrypted and (file_type in (DOCUMENT, SPREADSHEET)):
|
||||
return (False, _(u'The library is encrypted, can not open file online.'))
|
||||
|
||||
if file_ext in FILEEXT_TYPE_MAP or file_ext in get_conf_text_ext(): # check file extension
|
||||
exceeds_limit, err_msg = file_size_exceeds_preview_limit(file_size,
|
||||
file_type)
|
||||
if exceeds_limit:
|
||||
return (False, err_msg)
|
||||
else:
|
||||
return (True, None)
|
||||
else:
|
||||
# TODO: may need a better way instead of return string, and compare
|
||||
# that string in templates
|
||||
return (False, "invalid extension")
|
||||
return False, 'File edit unsupported'
|
||||
|
||||
def send_file_access_msg_when_preview(request, repo, path, access_from):
|
||||
""" send file access msg when user preview file from web
|
||||
@ -696,7 +728,7 @@ def view_lib_file(request, repo_id, path):
|
||||
return_dict['err'] = _(u'Error when prepare OnlyOffice file preview page.')
|
||||
|
||||
if not HAS_OFFICE_CONVERTER:
|
||||
return_dict['err'] = "invalid extension"
|
||||
return_dict['err'] = "File preview unsupported"
|
||||
return render(request, 'view_file_base.html', return_dict)
|
||||
|
||||
if file_size > OFFICE_PREVIEW_MAX_SIZE:
|
||||
@ -713,7 +745,7 @@ def view_lib_file(request, repo_id, path):
|
||||
# render file preview page
|
||||
return render(request, template, return_dict)
|
||||
else:
|
||||
return_dict['err'] = "invalid extension"
|
||||
return_dict['err'] = "File preview unsupported"
|
||||
return render(request, 'view_file_base.html', return_dict)
|
||||
|
||||
def view_history_file_common(request, repo_id, ret_dict):
|
||||
@ -884,7 +916,6 @@ def _download_file_from_share_link(request, fileshare):
|
||||
next = request.META.get('HTTP_REFERER', settings.SITE_ROOT)
|
||||
|
||||
username = request.user.username
|
||||
shared_by = fileshare.username
|
||||
repo = get_repo(fileshare.repo_id)
|
||||
if not repo:
|
||||
raise Http404
|
||||
@ -914,7 +945,7 @@ def _download_file_from_share_link(request, fileshare):
|
||||
send_file_access_msg(request, repo, real_path, 'share-link')
|
||||
|
||||
dl_token = seafile_api.get_fileserver_access_token(repo.id,
|
||||
obj_id, 'download-link', username, use_onetime=False)
|
||||
obj_id, 'download-link', fileshare.username, use_onetime=False)
|
||||
|
||||
if not dl_token:
|
||||
messages.error(request, _(u'Unable to download file.'))
|
||||
@ -922,12 +953,14 @@ def _download_file_from_share_link(request, fileshare):
|
||||
return HttpResponseRedirect(gen_file_get_url(dl_token, filename))
|
||||
|
||||
@share_link_audit
|
||||
@share_link_login_required
|
||||
def view_shared_file(request, fileshare):
|
||||
"""
|
||||
View file via shared link.
|
||||
Download share file if `dl` in request param.
|
||||
View raw share file if `raw` in request param.
|
||||
"""
|
||||
|
||||
token = fileshare.token
|
||||
|
||||
# check if share link is encrypted
|
||||
@ -952,16 +985,6 @@ def view_shared_file(request, fileshare):
|
||||
if not seafile_api.check_permission_by_path(repo_id, '/', shared_by):
|
||||
return render_error(request, _(u'Permission denied'))
|
||||
|
||||
# get share link permission
|
||||
can_download = fileshare.get_permissions()['can_download']
|
||||
can_edit = fileshare.get_permissions()['can_edit']
|
||||
|
||||
if can_edit and not request.user.is_authenticated():
|
||||
login_url = settings.LOGIN_URL
|
||||
path = urlquote(request.get_full_path())
|
||||
tup = login_url, REDIRECT_FIELD_NAME, path
|
||||
return HttpResponseRedirect('%s?%s=%s' % tup)
|
||||
|
||||
# Increase file shared link view_cnt, this operation should be atomic
|
||||
fileshare.view_cnt = F('view_cnt') + 1
|
||||
fileshare.save()
|
||||
@ -970,6 +993,10 @@ def view_shared_file(request, fileshare):
|
||||
file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)
|
||||
send_file_access_msg(request, repo, path, 'share-link')
|
||||
|
||||
# get share link permission
|
||||
can_download = fileshare.get_permissions()['can_download']
|
||||
can_edit = fileshare.get_permissions()['can_edit']
|
||||
|
||||
# download shared file
|
||||
if request.GET.get('dl', '') == '1':
|
||||
if can_download is False:
|
||||
@ -1082,68 +1109,10 @@ def view_shared_file(request, fileshare):
|
||||
'enable_watermark': ENABLE_WATERMARK,
|
||||
})
|
||||
|
||||
def view_raw_shared_file(request, token, obj_id, file_name):
|
||||
"""Returns raw content of a shared file.
|
||||
|
||||
Arguments:
|
||||
- `request`:
|
||||
- `token`:
|
||||
- `obj_id`:
|
||||
- `file_name`:
|
||||
"""
|
||||
fileshare = FileShare.objects.get_valid_file_link_by_token(token)
|
||||
if fileshare is None:
|
||||
raise Http404
|
||||
|
||||
password_check_passed, err_msg = check_share_link_common(request, fileshare)
|
||||
if not password_check_passed:
|
||||
d = {'token': token, 'err_msg': err_msg}
|
||||
if fileshare.is_file_share_link():
|
||||
d['view_name'] = 'view_shared_file'
|
||||
else:
|
||||
d['view_name'] = 'view_shared_dir'
|
||||
|
||||
return render(request, 'share_access_validation.html', d)
|
||||
|
||||
repo_id = fileshare.repo_id
|
||||
repo = get_repo(repo_id)
|
||||
if not repo:
|
||||
raise Http404
|
||||
|
||||
# Normalize file path based on file or dir share link
|
||||
req_path = request.GET.get('p', '').rstrip('/')
|
||||
if req_path:
|
||||
file_path = posixpath.join(fileshare.path, req_path.lstrip('/'))
|
||||
else:
|
||||
if fileshare.is_file_share_link():
|
||||
file_path = fileshare.path.rstrip('/')
|
||||
else:
|
||||
file_path = fileshare.path.rstrip('/') + '/' + file_name
|
||||
|
||||
real_obj_id = seafile_api.get_file_id_by_path(repo_id, file_path)
|
||||
if not real_obj_id:
|
||||
raise Http404
|
||||
|
||||
if real_obj_id != obj_id: # perm check
|
||||
raise Http404
|
||||
|
||||
if not seafile_api.check_permission_by_path(repo_id, '/',
|
||||
fileshare.username):
|
||||
return render_error(request, _(u'Permission denied'))
|
||||
|
||||
filename = os.path.basename(file_path)
|
||||
username = request.user.username
|
||||
token = seafile_api.get_fileserver_access_token(repo_id,
|
||||
real_obj_id, 'view', username, use_onetime=False)
|
||||
|
||||
if not token:
|
||||
raise Http404
|
||||
|
||||
outer_url = gen_file_get_url(token, filename)
|
||||
return HttpResponseRedirect(outer_url)
|
||||
|
||||
@share_link_audit
|
||||
@share_link_login_required
|
||||
def view_file_via_shared_dir(request, fileshare):
|
||||
|
||||
token = fileshare.token
|
||||
|
||||
# argument check
|
||||
|
@ -4,7 +4,6 @@ import os
|
||||
import posixpath
|
||||
import logging
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db.models import F
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
@ -16,7 +15,7 @@ from seaserv import seafile_api
|
||||
|
||||
from seahub.auth.decorators import login_required
|
||||
from seahub.options.models import UserOptions, CryptoOptionNotSetError
|
||||
from seahub.share.decorators import share_link_audit
|
||||
from seahub.share.decorators import share_link_audit, share_link_login_required
|
||||
from seahub.share.models import FileShare, UploadLinkShare, \
|
||||
check_share_link_common
|
||||
from seahub.views import gen_path_link, get_repo_dirents, \
|
||||
@ -179,7 +178,9 @@ def view_lib_as_wiki(request, repo_id, path):
|
||||
|
||||
########## shared dir/uploadlink
|
||||
@share_link_audit
|
||||
@share_link_login_required
|
||||
def view_shared_dir(request, fileshare):
|
||||
|
||||
token = fileshare.token
|
||||
|
||||
password_check_passed, err_msg = check_share_link_common(request, fileshare)
|
||||
|
@ -201,12 +201,10 @@ define([
|
||||
|
||||
share: function() {
|
||||
var dir = this.dir,
|
||||
can_preview = this.model.get('can_preview'),
|
||||
obj_name = this.model.get('obj_name'),
|
||||
dirent_path = this.model.getPath();
|
||||
|
||||
var options = {
|
||||
'can_preview': can_preview,
|
||||
'is_repo_owner': dir.is_repo_owner,
|
||||
'is_virtual': dir.is_virtual,
|
||||
'user_perm': this.model.get('perm'),
|
||||
|
@ -373,11 +373,9 @@ define([
|
||||
this.hideMobileMenu();
|
||||
var dir = this.dir,
|
||||
obj_name = this.model.get('obj_name'),
|
||||
can_preview = this.model.get('can_preview'),
|
||||
dirent_path = Common.pathJoin([dir.path, obj_name]);
|
||||
|
||||
var options = {
|
||||
'can_preview': can_preview,
|
||||
'is_repo_owner': dir.is_repo_owner,
|
||||
'is_virtual': dir.is_virtual,
|
||||
'user_perm': this.model.get('perm'),
|
||||
|
@ -21,9 +21,12 @@ define([
|
||||
'click .rm-invitation': 'removeInvitation'
|
||||
},
|
||||
|
||||
removeInvitation: function() {
|
||||
removeInvitation: function(e) {
|
||||
var _this = this;
|
||||
|
||||
var $el = $(e.currentTarget);
|
||||
$el.hide(); // hide the icon to avoid being clicked repeatedly
|
||||
|
||||
$.ajax({
|
||||
url: Common.getUrl({
|
||||
'name': 'invitation',
|
||||
@ -37,6 +40,7 @@ define([
|
||||
Common.feedback(gettext("Successfully deleted 1 item."), 'success');
|
||||
},
|
||||
error: function(xhr) {
|
||||
$el.show();
|
||||
Common.ajaxErrorHandler(xhr);
|
||||
}
|
||||
});
|
||||
|
@ -30,7 +30,6 @@ define([
|
||||
this.dirent_path = options.dirent_path;
|
||||
this.obj_name = options.obj_name;
|
||||
this.is_dir = options.is_dir;
|
||||
this.can_preview = options.can_preview;
|
||||
|
||||
// share to user/group
|
||||
var enable_dir_private_share = false;
|
||||
@ -87,24 +86,6 @@ define([
|
||||
show_admin_perm_option = true;
|
||||
}
|
||||
|
||||
// show 'can edit' perm option for download link or not
|
||||
var show_link_edit_perm_option = false;
|
||||
var show_link_preview_only_perm_option = true;
|
||||
var file_ext = '';
|
||||
if (!this.is_dir && this.obj_name.lastIndexOf('.') != -1) {
|
||||
file_ext = this.obj_name.substr(this.obj_name.lastIndexOf('.') + 1)
|
||||
.toLowerCase();
|
||||
}
|
||||
if (this.user_perm == 'rw' && !this.is_dir &&
|
||||
(app.pageOptions.enable_office_web_app ||
|
||||
app.pageOptions.enable_onlyoffice) &&
|
||||
(file_ext == 'docx' || file_ext == 'xlsx' || file_ext == 'pptx')) {
|
||||
show_link_edit_perm_option = true;
|
||||
}
|
||||
if (!this.is_dir && !this.can_preview) {
|
||||
show_link_preview_only_perm_option = false;
|
||||
}
|
||||
|
||||
this.$el.html(this.template({
|
||||
title: gettext("Share {placeholder}")
|
||||
.replace('{placeholder}', '<span class="op-target ellipsis ellipsis-op-target" title="' + Common.HTMLescape(this.obj_name) + '">' + Common.HTMLescape(this.obj_name) + '</span>'),
|
||||
@ -113,10 +94,6 @@ define([
|
||||
|
||||
enable_dir_private_share: this.enable_dir_private_share,
|
||||
show_admin_perm_option: show_admin_perm_option,
|
||||
|
||||
show_link_edit_perm_option: show_link_edit_perm_option,
|
||||
show_link_preview_only_perm_option: show_link_preview_only_perm_option,
|
||||
|
||||
user_perm: this.user_perm,
|
||||
repo_id: this.repo_id,
|
||||
repo_encrypted: this.repo_encrypted,
|
||||
@ -269,6 +246,33 @@ define([
|
||||
$loadingTip.hide();
|
||||
}
|
||||
});
|
||||
|
||||
if (!this.is_dir) {
|
||||
// check if can preview/edit file
|
||||
$.ajax({
|
||||
url: Common.getUrl({name: 'get_file_info', repo_id: this.repo_id}),
|
||||
data: {
|
||||
'p': this.dirent_path
|
||||
},
|
||||
cache: false,
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
// show 'can preview/edit' perm option for download link or not
|
||||
if (!data.can_preview) {
|
||||
_this.$('#share-link-preview-only-radio').addClass('hide');
|
||||
}
|
||||
|
||||
var file_ext = '';
|
||||
if (_this.obj_name.lastIndexOf('.') != -1) {
|
||||
file_ext = _this.obj_name.substr(_this.obj_name.lastIndexOf('.') + 1)
|
||||
.toLowerCase();
|
||||
}
|
||||
if ((file_ext == 'docx' || file_ext == 'xlsx' || file_ext == 'pptx') && data.can_edit) {
|
||||
_this.$('#share-link-edit-download-radio').removeClass('hide');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
generateRandomPassword: function(e, form) {
|
||||
|
@ -52,9 +52,21 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
var url,
|
||||
repo_id = this.model.get('id'),
|
||||
owner = this.model.get('owner');
|
||||
if (owner.indexOf('@seafile_group') == -1) {
|
||||
url = Common.getUrl({name: 'beshared_repo', repo_id: repo_id})
|
||||
+ "?share_type=personal&from=" + encodeURIComponent(owner);
|
||||
} else {
|
||||
url = Common.getUrl({
|
||||
name: 'group-owned-library-user-share-in-library',
|
||||
repo_id: repo_id
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: Common.getUrl({name: 'beshared_repo', repo_id: this.model.get('id')})
|
||||
+ "?share_type=personal&from=" + encodeURIComponent(this.model.get('owner')),
|
||||
url: url,
|
||||
type: 'DELETE',
|
||||
beforeSend: Common.prepareCSRFToken,
|
||||
dataType: 'json',
|
||||
@ -69,9 +81,15 @@ define([
|
||||
var icon_size = Common.isHiDPI() ? 48 : 24;
|
||||
var icon_url = this.model.getIconUrl(icon_size);
|
||||
var tmpl = $(window).width() >= 768 ? this.template : this.mobileTemplate;
|
||||
|
||||
var owner_name_shown = obj.owner_name;
|
||||
if (obj.owner.indexOf('@seafile_group') != -1) {
|
||||
owner_name_shown = obj.group_name;
|
||||
}
|
||||
_.extend(obj, {
|
||||
'icon_url': icon_url,
|
||||
'icon_title': this.model.getIconTitle()
|
||||
'icon_title': this.model.getIconTitle(),
|
||||
'owner_name_shown': owner_name_shown
|
||||
});
|
||||
this.$el.html(tmpl(obj));
|
||||
return this;
|
||||
|
@ -77,6 +77,7 @@ define([
|
||||
case 'list_lib_dir': return siteRoot + 'ajax/lib/' + options.repo_id + '/dir/';
|
||||
case 'del_dir': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/dir/';
|
||||
case 'del_file': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/file/';
|
||||
case 'get_file_info': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/file/';
|
||||
case 'download_dir_zip_url': return fileServerRoot + 'zip/' + options.zip_token;
|
||||
case 'zip_task': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/zip-task/';
|
||||
case 'query_zip_progress': return siteRoot + 'api/v2.1/query-zip-progress/';
|
||||
@ -127,6 +128,7 @@ define([
|
||||
|
||||
case 'group-owned-library-user-folder-permission': return siteRoot + 'api/v2.1/group-owned-libraries/' + options.repo_id + '/user-folder-permission/';
|
||||
case 'group-owned-library-group-folder-permission': return siteRoot + 'api/v2.1/group-owned-libraries/' + options.repo_id + '/group-folder-permission/';
|
||||
case 'group-owned-library-user-share-in-library': return siteRoot + 'api/v2.1/group-owned-libraries/user-share-in-libraries/' + options.repo_id + '/';
|
||||
|
||||
// Share admin
|
||||
case 'share_admin_repos': return siteRoot + 'api/v2.1/shared-repos/';
|
||||
|
@ -171,11 +171,6 @@ class AdminLibraryTest(BaseTestCase):
|
||||
|
||||
self.login_as(self.admin)
|
||||
|
||||
# invalid new owner
|
||||
data = 'invalid_new_owner=%s' % self.admin_name
|
||||
resp = self.client.put(self.library_url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(400, resp.status_code)
|
||||
|
||||
# new owner not exist
|
||||
data = 'owner=invalid@email.com'
|
||||
resp = self.client.put(self.library_url, data, 'application/x-www-form-urlencoded')
|
||||
|
@ -10,6 +10,9 @@ except ImportError:
|
||||
|
||||
class AdminOrgStatsTrafficTest(BaseTestCase):
|
||||
def test_get(self):
|
||||
if not LOCAL_PRO_DEV_ENV:
|
||||
return
|
||||
|
||||
self.login_as(self.admin)
|
||||
|
||||
url = reverse('api-v2.1-admin-org-stats-traffic', args=[1])
|
||||
|
@ -29,7 +29,7 @@ class ShibbolethRemoteUserMiddlewareTest(BaseTestCase):
|
||||
self.middleware = ShibbolethRemoteUserMiddleware()
|
||||
self.factory = RequestFactory()
|
||||
# Create an instance of a GET request.
|
||||
self.request = self.factory.get('/foo/')
|
||||
self.request = self.factory.get('/sso/')
|
||||
|
||||
self.request.user = self.user
|
||||
self.request.user.is_authenticated = lambda: False
|
||||
|
@ -4,6 +4,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.test import override_settings
|
||||
|
||||
from seahub.share.models import UploadLinkShare
|
||||
from seahub.utils import EMPTY_SHA1
|
||||
from seahub.test_utils import BaseTestCase
|
||||
|
||||
|
||||
@ -27,8 +28,8 @@ class GetFileUploadUrlULTest(BaseTestCase):
|
||||
self.login_as(self.user)
|
||||
resp = self.client.get(self.url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
mock_get_fileserver_access_token.assert_called_with(
|
||||
self.repo.id, '{"anonymous_user": "%s"}' % self.user.username,
|
||||
'upload', '', use_onetime=False)
|
||||
self.repo.id, EMPTY_SHA1,
|
||||
'upload-link', self.user.username, use_onetime=False)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert 'test_token' in json_resp['url']
|
||||
|
||||
@ -39,8 +40,8 @@ class GetFileUploadUrlULTest(BaseTestCase):
|
||||
|
||||
resp = self.client.get(self.url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
mock_get_fileserver_access_token.assert_called_with(
|
||||
self.repo.id, '{"anonymous_user": ""}',
|
||||
'upload', '', use_onetime=False)
|
||||
self.repo.id, EMPTY_SHA1,
|
||||
'upload-link', self.user.username, use_onetime=False)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert 'test_token' in json_resp['url']
|
||||
|
||||
@ -54,8 +55,8 @@ class GetFileUploadUrlULTest(BaseTestCase):
|
||||
session.save()
|
||||
resp = self.client.get(self.url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
mock_get_fileserver_access_token.assert_called_with(
|
||||
self.repo.id, '{"anonymous_user": "anonymous@email.com"}',
|
||||
'upload', '', use_onetime=False)
|
||||
self.repo.id, EMPTY_SHA1,
|
||||
'upload-link', self.user.username, use_onetime=False)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert 'test_token' in json_resp['url']
|
||||
|
||||
@ -69,7 +70,7 @@ class GetFileUploadUrlULTest(BaseTestCase):
|
||||
|
||||
resp = self.client.get(self.url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
mock_get_fileserver_access_token.assert_called_with(
|
||||
self.repo.id, '{"anonymous_user": ""}',
|
||||
'upload', '', use_onetime=False, check_virus=True)
|
||||
self.repo.id, EMPTY_SHA1,
|
||||
'upload-link', self.user.username, use_onetime=False, check_virus=True)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert 'test_token' in json_resp['url']
|
||||
|
216
tests/seahub/views/file/test_can_edit_file.py
Normal file
216
tests/seahub/views/file/test_can_edit_file.py
Normal file
@ -0,0 +1,216 @@
|
||||
from mock import patch
|
||||
from seaserv import seafile_api
|
||||
from seahub.views.file import can_edit_file
|
||||
from seahub.test_utils import BaseTestCase
|
||||
|
||||
from seahub.settings import FILE_PREVIEW_MAX_SIZE
|
||||
from seahub.utils import OFFICE_PREVIEW_MAX_SIZE
|
||||
|
||||
OFFICE_WEB_APP_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx')
|
||||
OFFICE_WEB_APP_EDIT_FILE_EXTENSION = ('docx', 'pptx', 'xlsx')
|
||||
|
||||
ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx')
|
||||
ONLYOFFICE_EDIT_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx')
|
||||
|
||||
class CanEditFileTest(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.file_size = 1
|
||||
self.exceeded_file_size = FILE_PREVIEW_MAX_SIZE + 1
|
||||
|
||||
self.office_file_size = 1
|
||||
self.exceeded_office_file_size = OFFICE_PREVIEW_MAX_SIZE + 1
|
||||
|
||||
self.encrypted_repo_id = seafile_api.create_repo('encrypted-repo',
|
||||
'', self.user.username, 'password')
|
||||
self.encrypted_repo = seafile_api.get_repo(self.encrypted_repo_id)
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo(self.repo.id)
|
||||
self.remove_repo(self.encrypted_repo.id)
|
||||
|
||||
def can_edit_in_normal_repo_normal_size(self, file_name):
|
||||
|
||||
if file_name.endswith('.doc') or file_name.endswith('.docx'):
|
||||
file_size = self.office_file_size
|
||||
else:
|
||||
file_size = self.file_size
|
||||
|
||||
can_edit, error_msg = can_edit_file(file_name, file_size,
|
||||
self.repo)
|
||||
return can_edit
|
||||
|
||||
def can_edit_in_encrypted_repo_normal_size(self, file_name):
|
||||
|
||||
if file_name.endswith('.doc') or file_name.endswith('.docx'):
|
||||
file_size = self.office_file_size
|
||||
else:
|
||||
file_size = self.file_size
|
||||
|
||||
can_edit, error_msg = can_edit_file(file_name, file_size,
|
||||
self.encrypted_repo)
|
||||
return can_edit
|
||||
|
||||
def can_edit_in_normal_repo_exceeded_size(self, file_name):
|
||||
|
||||
if file_name.endswith('.doc') or file_name.endswith('.docx'):
|
||||
file_size = self.exceeded_office_file_size
|
||||
else:
|
||||
file_size = self.exceeded_file_size
|
||||
|
||||
can_edit, error_msg = can_edit_file(file_name, file_size,
|
||||
self.repo)
|
||||
return can_edit
|
||||
|
||||
def can_edit_in_encrypted_repo_exceeded_size(self, file_name):
|
||||
|
||||
if file_name.endswith('.doc') or file_name.endswith('.docx'):
|
||||
file_size = self.exceeded_office_file_size
|
||||
else:
|
||||
file_size = self.exceeded_file_size
|
||||
|
||||
can_edit, error_msg = can_edit_file(file_name, file_size,
|
||||
self.encrypted_repo)
|
||||
return can_edit
|
||||
|
||||
def test_iso(self):
|
||||
|
||||
file_name = '123.iso'
|
||||
|
||||
assert not self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_pdf(self):
|
||||
|
||||
file_name = '123.pdf'
|
||||
|
||||
assert not self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_jpg(self):
|
||||
|
||||
file_name = '123.jpg'
|
||||
|
||||
assert not self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_txt(self):
|
||||
|
||||
file_name = '123.txt'
|
||||
|
||||
assert self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_md(self):
|
||||
|
||||
file_name = '123.md'
|
||||
|
||||
assert self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_doc(self):
|
||||
|
||||
file_name = '123.doc'
|
||||
|
||||
assert not self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.HAS_OFFICE_CONVERTER', True)
|
||||
def test_doc_has_office_converter(self):
|
||||
|
||||
file_name = '123.doc'
|
||||
|
||||
assert not self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.ENABLE_ONLYOFFICE', True)
|
||||
@patch('seahub.views.file.ONLYOFFICE_FILE_EXTENSION',
|
||||
ONLYOFFICE_FILE_EXTENSION)
|
||||
@patch('seahub.views.file.ONLYOFFICE_EDIT_FILE_EXTENSION',
|
||||
ONLYOFFICE_EDIT_FILE_EXTENSION)
|
||||
def test_doc_enable_onlyoffice(self):
|
||||
|
||||
file_name = '123.doc'
|
||||
|
||||
assert self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.ENABLE_OFFICE_WEB_APP', True)
|
||||
@patch('seahub.views.file.OFFICE_WEB_APP_FILE_EXTENSION',
|
||||
OFFICE_WEB_APP_FILE_EXTENSION)
|
||||
@patch('seahub.views.file.ENABLE_OFFICE_WEB_APP_EDIT', True)
|
||||
@patch('seahub.views.file.OFFICE_WEB_APP_EDIT_FILE_EXTENSION',
|
||||
OFFICE_WEB_APP_EDIT_FILE_EXTENSION)
|
||||
def test_doc_enable_office_web_app(self):
|
||||
|
||||
file_name = '123.doc'
|
||||
|
||||
assert not self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_docx(self):
|
||||
|
||||
file_name = '123.docx'
|
||||
|
||||
assert not self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.HAS_OFFICE_CONVERTER', True)
|
||||
def test_docx_has_office_converter(self):
|
||||
|
||||
file_name = '123.docx'
|
||||
|
||||
assert not self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.ENABLE_ONLYOFFICE', True)
|
||||
@patch('seahub.views.file.ONLYOFFICE_FILE_EXTENSION',
|
||||
ONLYOFFICE_FILE_EXTENSION)
|
||||
@patch('seahub.views.file.ONLYOFFICE_EDIT_FILE_EXTENSION',
|
||||
ONLYOFFICE_EDIT_FILE_EXTENSION)
|
||||
def test_docx_enable_onlyoffice(self):
|
||||
|
||||
file_name = '123.docx'
|
||||
|
||||
assert self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.ENABLE_OFFICE_WEB_APP', True)
|
||||
@patch('seahub.views.file.OFFICE_WEB_APP_FILE_EXTENSION',
|
||||
OFFICE_WEB_APP_FILE_EXTENSION)
|
||||
@patch('seahub.views.file.ENABLE_OFFICE_WEB_APP_EDIT', True)
|
||||
@patch('seahub.views.file.OFFICE_WEB_APP_EDIT_FILE_EXTENSION',
|
||||
OFFICE_WEB_APP_EDIT_FILE_EXTENSION)
|
||||
def test_docx_enable_office_web_app(self):
|
||||
|
||||
file_name = '123.docx'
|
||||
|
||||
assert self.can_edit_in_normal_repo_normal_size(file_name)
|
||||
assert self.can_edit_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_edit_in_encrypted_repo_exceeded_size(file_name)
|
203
tests/seahub/views/file/test_can_preview_file.py
Normal file
203
tests/seahub/views/file/test_can_preview_file.py
Normal file
@ -0,0 +1,203 @@
|
||||
from mock import patch
|
||||
from seaserv import seafile_api
|
||||
from seahub.views.file import can_preview_file
|
||||
from seahub.test_utils import BaseTestCase
|
||||
|
||||
from seahub.settings import FILE_PREVIEW_MAX_SIZE
|
||||
from seahub.utils import OFFICE_PREVIEW_MAX_SIZE
|
||||
|
||||
OFFICE_WEB_APP_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx')
|
||||
ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx')
|
||||
|
||||
class CanPreviewFileTest(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.file_size = 1
|
||||
self.exceeded_file_size = FILE_PREVIEW_MAX_SIZE + 1
|
||||
|
||||
self.office_file_size = 1
|
||||
self.exceeded_office_file_size = OFFICE_PREVIEW_MAX_SIZE + 1
|
||||
|
||||
self.encrypted_repo_id = seafile_api.create_repo('encrypted-repo',
|
||||
'', self.user.username, 'password')
|
||||
self.encrypted_repo = seafile_api.get_repo(self.encrypted_repo_id)
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo(self.repo.id)
|
||||
self.remove_repo(self.encrypted_repo.id)
|
||||
|
||||
def can_preview_in_normal_repo_normal_size(self, file_name):
|
||||
|
||||
if file_name.endswith('.doc') or file_name.endswith('.docx'):
|
||||
file_size = self.office_file_size
|
||||
else:
|
||||
file_size = self.file_size
|
||||
|
||||
can_preview, error_msg = can_preview_file(file_name, file_size,
|
||||
self.repo)
|
||||
return can_preview
|
||||
|
||||
def can_preview_in_encrypted_repo_normal_size(self, file_name):
|
||||
|
||||
if file_name.endswith('.doc') or file_name.endswith('.docx'):
|
||||
file_size = self.office_file_size
|
||||
else:
|
||||
file_size = self.file_size
|
||||
|
||||
can_preview, error_msg = can_preview_file(file_name, file_size,
|
||||
self.encrypted_repo)
|
||||
return can_preview
|
||||
|
||||
def can_preview_in_normal_repo_exceeded_size(self, file_name):
|
||||
|
||||
if file_name.endswith('.doc') or file_name.endswith('.docx'):
|
||||
file_size = self.exceeded_office_file_size
|
||||
else:
|
||||
file_size = self.exceeded_file_size
|
||||
|
||||
can_preview, error_msg = can_preview_file(file_name, file_size,
|
||||
self.repo)
|
||||
return can_preview
|
||||
|
||||
def can_preview_in_encrypted_repo_exceeded_size(self, file_name):
|
||||
|
||||
if file_name.endswith('.doc') or file_name.endswith('.docx'):
|
||||
file_size = self.exceeded_office_file_size
|
||||
else:
|
||||
file_size = self.exceeded_file_size
|
||||
|
||||
can_preview, error_msg = can_preview_file(file_name, file_size,
|
||||
self.encrypted_repo)
|
||||
return can_preview
|
||||
|
||||
def test_iso(self):
|
||||
|
||||
file_name = '123.iso'
|
||||
|
||||
assert not self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_pdf(self):
|
||||
|
||||
file_name = '123.pdf'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_jpg(self):
|
||||
|
||||
file_name = '123.jpg'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_txt(self):
|
||||
|
||||
file_name = '123.txt'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_md(self):
|
||||
|
||||
file_name = '123.md'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_doc(self):
|
||||
|
||||
file_name = '123.doc'
|
||||
|
||||
assert not self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.HAS_OFFICE_CONVERTER', True)
|
||||
def test_doc_has_office_converter(self):
|
||||
|
||||
file_name = '123.doc'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.ENABLE_ONLYOFFICE', True)
|
||||
@patch('seahub.views.file.ONLYOFFICE_FILE_EXTENSION',
|
||||
ONLYOFFICE_FILE_EXTENSION)
|
||||
def test_doc_enable_onlyoffice(self):
|
||||
|
||||
file_name = '123.doc'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.ENABLE_OFFICE_WEB_APP', True)
|
||||
@patch('seahub.views.file.OFFICE_WEB_APP_FILE_EXTENSION',
|
||||
OFFICE_WEB_APP_FILE_EXTENSION)
|
||||
def test_doc_enable_office_web_app(self):
|
||||
|
||||
file_name = '123.doc'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
def test_docx(self):
|
||||
|
||||
file_name = '123.docx'
|
||||
|
||||
assert not self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.HAS_OFFICE_CONVERTER', True)
|
||||
def test_docx_has_office_converter(self):
|
||||
|
||||
file_name = '123.docx'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.ENABLE_ONLYOFFICE', True)
|
||||
@patch('seahub.views.file.ONLYOFFICE_FILE_EXTENSION',
|
||||
ONLYOFFICE_FILE_EXTENSION)
|
||||
def test_docx_enable_onlyoffice(self):
|
||||
|
||||
file_name = '123.docx'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
||||
|
||||
@patch('seahub.views.file.ENABLE_OFFICE_WEB_APP', True)
|
||||
@patch('seahub.views.file.OFFICE_WEB_APP_FILE_EXTENSION',
|
||||
OFFICE_WEB_APP_FILE_EXTENSION)
|
||||
def test_docx_enable_office_web_app(self):
|
||||
|
||||
file_name = '123.docx'
|
||||
|
||||
assert self.can_preview_in_normal_repo_normal_size(file_name)
|
||||
assert self.can_preview_in_normal_repo_exceeded_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_normal_size(file_name)
|
||||
assert not self.can_preview_in_encrypted_repo_exceeded_size(file_name)
|
@ -56,7 +56,7 @@ class ViewLibFileTest(BaseTestCase):
|
||||
resp = self.client.get(url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'view_file_base.html')
|
||||
assert resp.context['err'] == 'invalid extension'
|
||||
assert resp.context['err'] == 'File preview unsupported'
|
||||
|
||||
@patch('seahub.views.file.FILE_PREVIEW_MAX_SIZE', -1)
|
||||
def test_file_size_exceeds_limit(self):
|
||||
|
@ -1,88 +0,0 @@
|
||||
import os
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test import TestCase
|
||||
|
||||
from seaserv import seafile_api
|
||||
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.test_utils import Fixtures
|
||||
|
||||
class RawSharedFileTest(TestCase, Fixtures):
|
||||
def setUp(self):
|
||||
share_file_info = {
|
||||
'username': 'test@test.com',
|
||||
'repo_id': self.repo.id,
|
||||
'path': '/',
|
||||
'password': None,
|
||||
'expire_date': None,
|
||||
}
|
||||
|
||||
self.fs = FileShare.objects.create_dir_link(**share_file_info)
|
||||
self.file_id = seafile_api.get_file_id_by_path(self.repo.id, self.file)
|
||||
self.filename= os.path.basename(self.file)
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo()
|
||||
|
||||
def test_can_get_fileserver_url(self):
|
||||
resp = self.client.get(
|
||||
reverse('view_raw_shared_file', args=[self.fs.token,
|
||||
self.file_id, self.filename])
|
||||
)
|
||||
|
||||
self.assertEqual(302, resp.status_code)
|
||||
self.assertRegexpMatches(resp['Location'],
|
||||
r'http(.*)/files/[-0-9a-f]{36}/%s' % self.filename)
|
||||
|
||||
class EncryptRawSharedFileTest(TestCase, Fixtures):
|
||||
def setUp(self):
|
||||
share_file_info = {
|
||||
'username': 'test@test.com',
|
||||
'repo_id': self.repo.id,
|
||||
'path': '/',
|
||||
'password': '12345678',
|
||||
'expire_date': None,
|
||||
}
|
||||
|
||||
self.fs = FileShare.objects.create_dir_link(**share_file_info)
|
||||
self.file_id = seafile_api.get_file_id_by_path(self.repo.id, self.file)
|
||||
self.filename= os.path.basename(self.file)
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo()
|
||||
|
||||
def test_can_decrypt(self):
|
||||
resp = self.client.post(
|
||||
reverse('view_raw_shared_file', args=[self.fs.token,
|
||||
self.file_id, self.filename]), {'password': '12345678'}
|
||||
)
|
||||
self.assertEqual(302, resp.status_code)
|
||||
self.assertRegexpMatches(resp['Location'],
|
||||
r'http(.*)/files/[-0-9a-f]{36}/%s' % self.filename)
|
||||
|
||||
def test_wrong_password(self):
|
||||
resp = self.client.post(
|
||||
reverse('view_raw_shared_file', args=[self.fs.token,
|
||||
self.file_id, self.filename]), {'password': '1234567'}
|
||||
)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'share_access_validation.html')
|
||||
self.assertContains(resp, 'Please enter a correct password')
|
||||
|
||||
def test_no_password(self):
|
||||
resp = self.client.get(
|
||||
reverse('view_raw_shared_file', args=[self.fs.token,
|
||||
self.file_id, self.filename])
|
||||
)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'share_access_validation.html')
|
||||
|
||||
resp = self.client.post(
|
||||
reverse('view_raw_shared_file', args=[self.fs.token,
|
||||
self.file_id, self.filename])
|
||||
)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertTemplateUsed(resp, 'share_access_validation.html')
|
@ -51,6 +51,9 @@ class ShibbolethRemoteUserBackend(RemoteUserBackend):
|
||||
email=username, is_active=self.activate_after_creation)
|
||||
if user and self.activate_after_creation is False:
|
||||
notify_admins_on_activate_request(user.email)
|
||||
# Do not send follwing registration finished email (if any)
|
||||
# which will cause confusion.
|
||||
return user
|
||||
if user and settings.NOTIFY_ADMIN_AFTER_REGISTRATION is True:
|
||||
notify_admins_on_register_complete(user.email)
|
||||
else:
|
||||
|
@ -31,6 +31,9 @@ class ShibbolethRemoteUserMiddleware(RemoteUserMiddleware):
|
||||
super(ShibbolethRemoteUserMiddleware, self).__init__(*a, **kw)
|
||||
|
||||
def process_request(self, request):
|
||||
if request.path.rstrip('/') != settings.SITE_ROOT + 'sso':
|
||||
return
|
||||
|
||||
# AuthenticationMiddleware is required so that request.user exists.
|
||||
if not hasattr(request, 'user'):
|
||||
raise ImproperlyConfigured(
|
||||
|
Loading…
Reference in New Issue
Block a user