);
diff --git a/frontend/src/view-file-video.js b/frontend/src/view-file-video.js
index ff760fdb1c..a873fbc2cc 100644
--- a/frontend/src/view-file-video.js
+++ b/frontend/src/view-file-video.js
@@ -34,7 +34,7 @@ class FileContent extends React.Component {
}]
};
return (
-
+
);
diff --git a/media/css/seafile-ui.css b/media/css/seafile-ui.css
index 3c32f16fb3..54361604c2 100644
--- a/media/css/seafile-ui.css
+++ b/media/css/seafile-ui.css
@@ -1277,7 +1277,7 @@ pre {
background-color: #fff;
border-color: #1991eb;
outline: 0;
- box-shadow: 0 0 0 2px rgba(241, 150, 69, 0.25); }
+ box-shadow: 0 0 0 2px rgba(70, 127, 207, 0.25); }
.form-control::placeholder {
color: #adb5bd;
opacity: 1; }
diff --git a/media/css/seahub_react.css b/media/css/seahub_react.css
index c4bbddcca7..dcb0710c7d 100644
--- a/media/css/seahub_react.css
+++ b/media/css/seahub_react.css
@@ -335,13 +335,14 @@ ul,ol,li {
}
.op-icon {
- color: #f89a68;
+ color: #f19645;
}
.op-icon:focus,
.op-icon:hover {
padding-bottom: 0.125rem;
- border-bottom: 0.125rem solid #f89a68;
+ border-bottom: 0.125rem solid #e0873b;
+ color: #e0873b;
}
.action-icon,
diff --git a/seahub/api2/endpoints/repo_trash.py b/seahub/api2/endpoints/repo_trash.py
index 007b908311..b52d587acb 100644
--- a/seahub/api2/endpoints/repo_trash.py
+++ b/seahub/api2/endpoints/repo_trash.py
@@ -16,6 +16,8 @@ from seahub.signals import clean_up_repo_trash
from seahub.utils.timeutils import timestamp_to_isoformat_timestr
from seahub.utils.repo import get_repo_owner
from seahub.views import check_folder_permission
+from seahub.group.utils import is_group_admin
+from seahub.api2.endpoints.group_owned_libraries import get_group_id_by_repo_owner
from seaserv import seafile_api
from pysearpc import SearpcError
@@ -129,7 +131,8 @@ class RepoTrash(APIView):
""" Clean library's trash.
Permission checking:
- 1. only repo owner can perform this action.
+ 1. repo owner can perform this action.
+ 2. is group admin.
"""
# argument check
@@ -148,10 +151,20 @@ class RepoTrash(APIView):
# permission check
username = request.user.username
repo_owner = get_repo_owner(request, repo_id)
- if username != repo_owner or not config.ENABLE_USER_CLEAN_TRASH:
+ if not config.ENABLE_USER_CLEAN_TRASH:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
+ if '@seafile_group' in repo_owner:
+ group_id = get_group_id_by_repo_owner(repo_owner)
+ if not is_group_admin(group_id, username):
+ error_msg = 'Permission denied.'
+ return api_error(status.HTTP_403_FORBIDDEN, error_msg)
+ else:
+ if username != repo_owner:
+ error_msg = 'Permission denied.'
+ return api_error(status.HTTP_403_FORBIDDEN, error_msg)
+
try:
seafile_api.clean_up_repo_history(repo_id, keep_days)
org_id = None if not request.user.org else request.user.org.org_id
diff --git a/seahub/api2/views.py b/seahub/api2/views.py
index 9c5ea0a18c..d3318cdfb2 100644
--- a/seahub/api2/views.py
+++ b/seahub/api2/views.py
@@ -89,7 +89,7 @@ from seahub.utils.timeutils import utc_to_local, \
timestamp_to_isoformat_timestr
from seahub.views import is_registered_user, check_folder_permission, \
create_default_library, list_inner_pub_repos
-from seahub.views.file import get_file_view_path_and_perm, send_file_access_msg
+from seahub.views.file import get_file_view_path_and_perm, send_file_access_msg, can_edit_file
if HAS_FILE_SEARCH:
from seahub_extra.search.utils import search_files, get_search_repos_map, SEARCH_FILEEXT
from seahub.utils import HAS_OFFICE_CONVERTER
@@ -3156,10 +3156,11 @@ class FileDetailView(APIView):
entry["last_modifier_contact_email"] = email2contact_email(latest_contributor)
try:
- entry["size"] = get_file_size(real_repo_id, repo.version, obj_id)
+ file_size = get_file_size(real_repo_id, repo.version, obj_id)
except Exception as e:
logger.error(e)
- entry["size"] = 0
+ file_size = 0
+ entry["size"] = file_size
starred_files = UserStarredFiles.objects.filter(repo_id=repo_id,
path=path)
@@ -3168,6 +3169,8 @@ class FileDetailView(APIView):
comment_total = file_comments.count()
entry["comment_total"] = comment_total
+ entry["can_edit"], _ = can_edit_file(file_name, file_size, repo)
+
return Response(entry)
diff --git a/seahub/templates/history_file_view_react.html b/seahub/templates/history_file_view_react.html
new file mode 100644
index 0000000000..5652c4c98c
--- /dev/null
+++ b/seahub/templates/history_file_view_react.html
@@ -0,0 +1,47 @@
+{% extends "base_for_react.html" %}
+{% load seahub_tags i18n %}
+{% load render_bundle from webpack_loader %}
+
+{% block sub_title %}{{file_name}} - {% endblock %}
+
+{% block extra_style %}
+{% if filetype == 'PDF' %}
+
+{% endif %}
+{% render_bundle 'historyTrashFileView' 'css' %}
+{% endblock %}
+
+{% block extra_script %}
+
+{% render_bundle 'historyTrashFileView' 'js' %}
+{% if filetype == 'PDF' %}
+
+
+
+{% endif %}
+{% endblock %}
diff --git a/seahub/views/file.py b/seahub/views/file.py
index e4434a51b6..c98ac00b60 100644
--- a/seahub/views/file.py
+++ b/seahub/views/file.py
@@ -1005,7 +1005,8 @@ def view_history_file(request, repo_id):
repo = ret_dict['repo']
ret_dict['zipped'] = gen_path_link(path, repo.name)
- return render(request, 'view_history_file.html', ret_dict)
+ #return render(request, 'view_history_file.html', ret_dict)
+ return render(request, 'history_file_view_react.html', ret_dict)
@repo_passwd_set_required
def view_trash_file(request, repo_id):
@@ -1030,7 +1031,9 @@ def view_trash_file(request, repo_id):
tmp_path = posixpath.join(basedir.rstrip('/'), ret_dict['path'].lstrip('/'))
ret_dict['path'] = tmp_path
- return render(request, 'view_trash_file.html', ret_dict)
+ #return render(request, 'view_trash_file.html', ret_dict)
+ ret_dict['from_trash'] = True
+ return render(request, 'history_file_view_react.html', ret_dict)
@repo_passwd_set_required
def view_snapshot_file(request, repo_id):
@@ -1052,7 +1055,8 @@ def view_snapshot_file(request, repo_id):
repo = ret_dict['repo']
ret_dict['zipped'] = gen_path_link(path, repo.name)
- return render(request, 'view_snapshot_file.html', ret_dict)
+ #return render(request, 'view_snapshot_file.html', ret_dict)
+ return render(request, 'history_file_view_react.html', ret_dict)
def _download_file_from_share_link(request, fileshare):
"""Download shared file.
diff --git a/tests/api/endpoints/test_repo_trash.py b/tests/api/endpoints/test_repo_trash.py
index ec2a324506..b172a5a070 100644
--- a/tests/api/endpoints/test_repo_trash.py
+++ b/tests/api/endpoints/test_repo_trash.py
@@ -3,9 +3,10 @@ import json
from django.core.urlresolvers import reverse
-from seaserv import seafile_api
+from seaserv import seafile_api, ccnet_api
from seahub.test_utils import BaseTestCase
+from seahub.group.utils import is_group_admin
from tests.common.utils import randstring
class RepoTrashTest(BaseTestCase):
@@ -26,9 +27,13 @@ class RepoTrashTest(BaseTestCase):
self.url = reverse('api-v2.1-repo-trash', args=[self.repo_id])
+ self.tmp_user = self.create_user(
+ 'user_%s@test.com' % randstring(4), is_staff=False)
+
def tearDown(self):
self.remove_repo()
self.remove_group()
+ self.remove_user(self.tmp_user.username)
def test_can_get(self):
@@ -83,6 +88,56 @@ class RepoTrashTest(BaseTestCase):
json_resp = json.loads(resp.content)
assert len(json_resp['data']) == 0
+ def test_can_clean_department_repo_trash(self):
+ # create a department
+ group_id = ccnet_api.create_group('department_test', 'system admin', parent_group_id=-1)
+ seafile_api.set_group_quota(group_id, -2)
+ repo_id = seafile_api.add_group_owned_repo(group_id, 'dep_test', 'rw')
+ repo_owner = seafile_api.get_repo_owner(repo_id)
+ assert '@seafile_group' in repo_owner
+ group_repos = seafile_api.get_repos_by_group(group_id)
+ assert len(group_repos) == 1
+ group = ccnet_api.get_group(group_id)
+
+ # department add user
+ ccnet_api.group_add_member(group_id, group.creator_name, self.user_name)
+ ccnet_api.group_add_member(group_id, group.creator_name, self.tmp_user.username)
+ ccnet_api.group_set_admin(group_id, self.user_name)
+ ccnet_api.group_unset_admin(group_id, self.tmp_user.username)
+ assert is_group_admin(group_id, self.user_name)
+ assert not is_group_admin(group_id, self.tmp_user.username)
+
+ file_name = 'dep_test.txt'
+ self.create_file(
+ repo_id=repo_id, parent_dir='/', filename=file_name, username=self.user_name)
+
+ # delete a file first
+ seafile_api.del_file(repo_id, '/', file_name, self.user_name)
+
+ # get trash item count
+ self.login_as(self.user)
+ resp = self.client.get(reverse('api-v2.1-repo-trash', args=[repo_id]))
+ json_resp = json.loads(resp.content)
+ assert len(json_resp['data']) > 0
+
+ # department member can not clean trash
+ self.logout()
+ self.login_as(self.tmp_user)
+ resp = self.client.delete(self.url)
+ self.assertEqual(403, resp.status_code)
+
+ # department admin can clean library trash
+ self.logout()
+ self.login_as(self.user)
+ ccnet_api.group_set_admin(group_id, self.user_name)
+ resp = self.client.delete(self.url)
+ self.assertEqual(200, resp.status_code)
+
+ # get trash item count again
+ resp = self.client.get(self.url)
+ json_resp = json.loads(resp.content)
+ assert len(json_resp['data']) == 0
+
def test_can_not_clean_with_invalid_user_permission(self):
self.login_as(self.admin)