1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-22 11:57:34 +00:00

group dtable share (#3840)

* group dtable share

* add test case
This commit is contained in:
王健辉
2019-07-13 16:05:53 +08:00
committed by Daniel Pan
parent d75f613c2d
commit c6768c725d
4 changed files with 208 additions and 47 deletions

View File

@@ -26,7 +26,6 @@ const tablePropTypes = {
onUnfreezedItem: PropTypes.func.isRequired,
onFreezedItem: PropTypes.func.isRequired,
isItemFreezed: PropTypes.bool.isRequired,
isPersonal: PropTypes.bool.isRequired,
};
class Table extends Component {
@@ -135,9 +134,7 @@ class Table extends Component {
<DropdownMenu className="drop-list" right={true}>
<DropdownItem onClick={this.onRenameTableCancel}>{gettext('Rename')}</DropdownItem>
<DropdownItem onClick={this.onDeleteTableCancel}>{gettext('Delete')}</DropdownItem>
{this.props.isPersonal &&
<DropdownItem onClick={this.onShareTableCancel}>{gettext('Share')}</DropdownItem>
}
</DropdownMenu>
</Dropdown>
}
@@ -258,7 +255,6 @@ class Workspace extends Component {
onFreezedItem={this.onFreezedItem}
onUnfreezedItem={this.onUnfreezedItem}
isItemFreezed={isItemFreezed}
isPersonal={isPersonal}
/>
);
})}

View File

@@ -112,20 +112,19 @@ class WorkspacesView(APIView):
logger.warning('Library %s not found.' % repo_id)
continue
if '@seafile_group' in owner:
group_id = int(owner.split('@')[0])
owner_name = group_id_to_name(group_id)
owner_type = "Group"
else:
owner_name = email2nickname(owner)
owner_type = "Personal"
res = workspace.to_dict()
table_list = DTables.objects.get_dtable_by_workspace(workspace)
res = workspace.to_dict()
res["owner_name"] = owner_name
res["owner_type"] = owner_type
res["table_list"] = table_list
if '@seafile_group' in owner:
group_id = owner.split('@')[0]
res["owner_name"] = group_id_to_name(group_id)
res["owner_type"] = "Group"
else:
res["owner_name"] = email2nickname(owner)
res["owner_type"] = "Personal"
workspace_list.append(res)
return Response({"workspace_list": workspace_list}, status=status.HTTP_200_OK)

View File

@@ -7,7 +7,7 @@ from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from rest_framework.response import Response
from django.utils.translation import ugettext as _
import seaserv
from seaserv import seafile_api
from seahub.base.accounts import User
@@ -22,7 +22,7 @@ from seahub.utils import normalize_file_path
from seahub.constants import PERMISSION_ADMIN, PERMISSION_PREVIEW, PERMISSION_PREVIEW_EDIT, \
PERMISSION_READ, PERMISSION_READ_WRITE
from seahub.api2.endpoints.dtable import FILE_TYPE
from seahub.group.utils import group_id_to_name
from seahub.group.utils import group_id_to_name, is_group_member
from seahub.utils.timeutils import datetime_to_isoformat_timestr
logger = logging.getLogger(__name__)
@@ -66,7 +66,12 @@ class SharedDTablesView(APIView):
dtable_info['updated_at'] = datetime_to_isoformat_timestr(dtable.updated_at)
dtable_info['permission'] = permission
dtable_info['from_user'] = from_user
dtable_info['from_user_name'] = email2nickname(from_user)
if '@seafile_group' in from_user:
group_id = from_user.split('@')[0]
dtable_info['from_user_name'] = group_id_to_name(group_id)
else:
dtable_info['from_user_name'] = email2nickname(from_user)
table_list.append(dtable_info)
@@ -108,6 +113,14 @@ class DTableShareView(APIView):
error_msg = 'Workspace %s not found.' % workspace_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
group_id = ''
if '@seafile_group' in workspace.owner:
group_id = workspace.owner.split('@')[0]
group = seaserv.get_group(group_id)
if not group:
error_msg = 'Group %s not found.' % group_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
repo_id = workspace.repo_id
repo = seafile_api.get_repo(repo_id)
if not repo:
@@ -126,13 +139,24 @@ class DTableShareView(APIView):
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# permission check
if from_user != dtable.creator:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
username = request.user.username
if group_id:
if not is_group_member(group_id, username):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if to_user == from_user:
error_msg = 'table %s can not be shared to owner.' % table_name
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if is_group_member(group_id, to_user):
error_msg = 'table %s can not be shared to group member.' % table_name
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
from_user = group_id + GROUP_DOMAIN
else:
if from_user != dtable.creator:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if from_user == to_user:
error_msg = 'table %s can not be shared to owner.' % table_name
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# org check
if is_org_context(request):
@@ -164,7 +188,7 @@ class DTableShareView(APIView):
def get(self, request, workspace_id, name):
"""list share users in dtable share
"""
from_user = request.user.username
username = request.user.username
table_name = name
table_file_name = table_name + FILE_TYPE
@@ -174,6 +198,14 @@ class DTableShareView(APIView):
error_msg = 'Workspace %s not found.' % workspace_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
group_id = ''
if '@seafile_group' in workspace.owner:
group_id = workspace.owner.split('@')[0]
group = seaserv.get_group(group_id)
if not group:
error_msg = 'Group %s not found.' % group_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
repo_id = workspace.repo_id
repo = seafile_api.get_repo(repo_id)
if not repo:
@@ -192,9 +224,14 @@ class DTableShareView(APIView):
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# permission check
if from_user != dtable.creator:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if group_id:
if not is_group_member(group_id, username):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
else:
if username != dtable.creator:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# main
try:
@@ -215,7 +252,7 @@ class DTableShareView(APIView):
def put(self, request, workspace_id, name):
"""modify dtable share permission
"""
from_user = request.user.username
username = request.user.username
table_name = name
table_file_name = table_name + FILE_TYPE
@@ -242,6 +279,14 @@ class DTableShareView(APIView):
error_msg = 'Workspace %s not found.' % workspace_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
group_id = ''
if '@seafile_group' in workspace.owner:
group_id = workspace.owner.split('@')[0]
group = seaserv.get_group(group_id)
if not group:
error_msg = 'Group %s not found.' % group_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
repo_id = workspace.repo_id
repo = seafile_api.get_repo(repo_id)
if not repo:
@@ -260,13 +305,22 @@ class DTableShareView(APIView):
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# permission check
if from_user != dtable.creator:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if group_id:
if not is_group_member(group_id, username):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if to_user == from_user:
error_msg = 'table %s can not be shared to owner.' % table_name
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if is_group_member(group_id, to_user):
error_msg = 'table %s can not be shared to group member.' % table_name
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
else:
if username != dtable.creator:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if username == to_user:
error_msg = 'table %s can not be shared to owner.' % table_name
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# main
try:
@@ -312,6 +366,14 @@ class DTableShareView(APIView):
error_msg = 'Workspace %s not found.' % workspace_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
group_id = ''
if '@seafile_group' in workspace.owner:
group_id = workspace.owner.split('@')[0]
group = seaserv.get_group(group_id)
if not group:
error_msg = 'Group %s not found.' % group_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
repo_id = workspace.repo_id
repo = seafile_api.get_repo(repo_id)
if not repo:
@@ -337,9 +399,14 @@ class DTableShareView(APIView):
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# permission check
if username not in (obj.to_user, obj.from_user):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if group_id:
if not is_group_member(group_id, username) and username != obj.to_user:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
else:
if username not in (obj.to_user, obj.from_user):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
obj.delete()
except Exception as e:

View File

@@ -1,5 +1,6 @@
import json
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from seahub.dtable.models import Workspaces, DTableShare, DTables
from seaserv import seafile_api
@@ -13,6 +14,8 @@ try:
except ImportError:
LOCAL_PRO_DEV_ENV = False
GROUP_DOMAIN = '@seafile_group'
class SharedDTablesViewTest(BaseTestCase):
def setUp(self):
@@ -80,15 +83,55 @@ class DTableShareViewTest(BaseTestCase):
self.url = reverse('api-v2.1-dtable-share', args=[self.workspace.id, self.dtable.name])
# add user to group
self.login_as(self.user)
self.group_id = self.group.id
self.endpoint = reverse('api-v2.1-group-members', args=[self.group_id])
self.client.post(self.endpoint, {
'email': self.user.email
})
self.logout()
# create group workspace
group_repo_id = seafile_api.create_repo(
_("My Workspace"),
_("My Workspace"),
"dtable@seafile"
)
self.group_workspace = Workspaces.objects.create_workspace(
str(self.group_id) + GROUP_DOMAIN, group_repo_id
)
assert len(Workspaces.objects.all()) == 2
# create group dtable
seafile_api.post_empty_file(
group_repo_id, '/', 'group.dtable', self.user.username
)
self.group_dtable = DTables.objects.create_dtable(
self.user.username, self.group_workspace, 'group'
)
assert len(DTables.objects.all()) == 2
# share group dtable to admin
DTableShare.objects.add(
self.group_dtable, str(self.group_id) + GROUP_DOMAIN, self.admin.username, 'rw'
)
assert len(DTableShare.objects.all()) == 2
self.url2 = reverse(
'api-v2.1-dtable-share', args=[self.group_workspace.id, self.group_dtable.name]
)
def tearDown(self):
workspace = Workspaces.objects.get_workspace_by_owner(self.user.username)
workspace_id = workspace.id
Workspaces.objects.delete_workspace(workspace_id)
self.remove_repo()
self.remove_group()
def test_can_post(self):
assert len(DTableShare.objects.all()) == 1
assert len(DTableShare.objects.all()) == 2
DTableShare.objects.all().delete()
assert len(DTableShare.objects.all()) == 0
@@ -102,9 +145,25 @@ class DTableShareViewTest(BaseTestCase):
self.assertEqual(201, resp.status_code)
assert len(DTableShare.objects.all()) == 1
def test_can_not_post_with_already_share(self):
def test_can_post_group_share(self):
assert len(DTableShare.objects.all()) == 2
DTableShare.objects.all().delete()
assert len(DTableShare.objects.all()) == 0
self.login_as(self.user)
data = {
'email': self.admin.username,
'permission': 'rw',
}
resp = self.client.post(self.url2, data)
self.assertEqual(201, resp.status_code)
assert len(DTableShare.objects.all()) == 1
def test_can_not_post_with_already_share(self):
assert len(DTableShare.objects.all()) == 2
self.login_as(self.user)
data = {
@@ -115,7 +174,7 @@ class DTableShareViewTest(BaseTestCase):
self.assertEqual(409, resp.status_code)
def test_can_not_post_with_not_owner(self):
assert len(DTableShare.objects.all()) == 1
assert len(DTableShare.objects.all()) == 2
DTableShare.objects.all().delete()
assert len(DTableShare.objects.all()) == 0
@@ -129,7 +188,7 @@ class DTableShareViewTest(BaseTestCase):
self.assertEqual(403, resp.status_code)
def test_can_not_post_with_share_to_owner(self):
assert len(DTableShare.objects.all()) == 1
assert len(DTableShare.objects.all()) == 2
DTableShare.objects.all().delete()
assert len(DTableShare.objects.all()) == 0
@@ -142,11 +201,25 @@ class DTableShareViewTest(BaseTestCase):
resp = self.client.post(self.url, data)
self.assertEqual(400, resp.status_code)
def test_can_not_post_to_group_member(self):
assert len(DTableShare.objects.all()) == 2
DTableShare.objects.all().delete()
assert len(DTableShare.objects.all()) == 0
self.login_as(self.user)
data = {
'email': self.user.username,
'permission': 'rw',
}
resp = self.client.post(self.url2, data)
self.assertEqual(400, resp.status_code)
def test_can_not_post_with_share_to_org_user(self):
if not LOCAL_PRO_DEV_ENV:
return
assert len(DTableShare.objects.all()) == 1
assert len(DTableShare.objects.all()) == 2
DTableShare.objects.all().delete()
assert len(DTableShare.objects.all()) == 0
@@ -193,8 +266,22 @@ class DTableShareViewTest(BaseTestCase):
assert DTableShare.objects.get_by_dtable_and_to_user(
self.dtable, self.admin.username).permission == 'r'
def test_can_put_group_share(self):
self.login_as(self.user)
data = {
'email': self.admin.username,
'permission': 'r',
}
resp = self.client.put(self.url2, json.dumps(data), 'application/json')
self.assertEqual(200, resp.status_code)
assert DTableShare.objects.get_by_dtable_and_to_user(
self.group_dtable, self.admin.username
).permission == 'r'
def test_can_not_put_with_not_shared(self):
assert len(DTableShare.objects.all()) == 1
assert len(DTableShare.objects.all()) == 2
DTableShare.objects.all().delete()
assert len(DTableShare.objects.all()) == 0
@@ -228,6 +315,7 @@ class DTableShareViewTest(BaseTestCase):
self.assertEqual(400, resp.status_code)
def test_can_delete(self):
assert len(DTableShare.objects.all()) == 2
self.login_as(self.user)
data = {
@@ -235,7 +323,18 @@ class DTableShareViewTest(BaseTestCase):
}
resp = self.client.delete(self.url, json.dumps(data), 'application/json')
self.assertEqual(200, resp.status_code)
assert len(DTableShare.objects.all()) == 0
assert len(DTableShare.objects.all()) == 1
def test_can_delete_group_share(self):
assert len(DTableShare.objects.all()) == 2
self.login_as(self.user)
data = {
'email': self.admin.username,
}
resp = self.client.delete(self.url2, json.dumps(data), 'application/json')
self.assertEqual(200, resp.status_code)
assert len(DTableShare.objects.all()) == 1
def test_can_delete_with_share_user(self):
self.login_as(self.admin)
@@ -245,10 +344,10 @@ class DTableShareViewTest(BaseTestCase):
}
resp = self.client.delete(self.url, json.dumps(data), 'application/json')
self.assertEqual(200, resp.status_code)
assert len(DTableShare.objects.all()) == 0
assert len(DTableShare.objects.all()) == 1
def test_can_not_delete_with_not_shared(self):
assert len(DTableShare.objects.all()) == 1
assert len(DTableShare.objects.all()) == 2
DTableShare.objects.all().delete()
assert len(DTableShare.objects.all()) == 0