From 93dee8ed6a4094816ad34c54c2720f49636f0a50 Mon Sep 17 00:00:00 2001 From: zhengxie Date: Fri, 20 Mar 2015 13:48:40 +0800 Subject: [PATCH] Fix group repo related apis, and add a few unittests --- media/scripts/app/collections/repos.js | 10 +++- media/scripts/app/models/repo.js | 5 +- seahub/api2/urls.py | 2 +- seahub/api2/views.py | 71 ++++++++++++++++---------- tests/api/test_group_repos.py | 46 +++++++++++++++++ 5 files changed, 102 insertions(+), 32 deletions(-) create mode 100644 tests/api/test_group_repos.py diff --git a/media/scripts/app/collections/repos.js b/media/scripts/app/collections/repos.js index eb76241bf9..273beee877 100644 --- a/media/scripts/app/collections/repos.js +++ b/media/scripts/app/collections/repos.js @@ -24,8 +24,16 @@ define([ //call Backbone's fetch return Backbone.Collection.prototype.fetch.call(this, options); - } + }, + create: function(model, options) { + // override default create url + options = options ? _.clone(options) : {}; + options.url = this.url + '?from=web'; + + //call Backbone's create + return Backbone.Collection.prototype.create.call(this, model, options); + } }); return RepoCollection; diff --git a/media/scripts/app/models/repo.js b/media/scripts/app/models/repo.js index e8e3bdeb0a..9fff178d76 100644 --- a/media/scripts/app/models/repo.js +++ b/media/scripts/app/models/repo.js @@ -30,11 +30,10 @@ define([ if (!attrs.desc) return gettext("Description is required"); if (attrs.encrypted) { - if (!attrs.passwd1) return gettext("Please enter password"); - if (!attrs.passwd2) return gettext("Please enter the password again"); + if (!attrs.passwd1) return gettext("Please enter password"); + if (!attrs.passwd2) return gettext("Please enter the password again"); if (attrs.passwd1.length < app.pageOptions.repo_password_min_length) { return gettext("Password is too short"); - } if (attrs.passwd1 != attrs.passwd2) return gettext("Passwords don't match"); } diff --git a/seahub/api2/urls.py b/seahub/api2/urls.py index da7b8f7eeb..0642ef19bf 100644 --- a/seahub/api2/urls.py +++ b/seahub/api2/urls.py @@ -72,7 +72,7 @@ urlpatterns = patterns('', url(r'^groups/(?P\d+)/members/$', GroupMembers.as_view()), url(r'^groups/(?P\d+)/changes/$', GroupChanges.as_view(), name="api2-group-changes"), url(r'^groups/(?P\d+)/repos/$', GroupRepos.as_view(), name="api2-grouprepos"), - url(r'^groups/(?P\d+)/repos/(?P[-0-9a-f]{36})/$', GroupRepo.as_view()), + url(r'^groups/(?P\d+)/repos/(?P[-0-9a-f]{36})/$', GroupRepo.as_view(), name="api2-grouprepo"), url(r'^html/events/$', EventsHtml.as_view()), url(r'^html/more_events/$', AjaxEvents.as_view(), name="more_events"), diff --git a/seahub/api2/views.py b/seahub/api2/views.py index a43f9cd1a2..7a7c237d40 100644 --- a/seahub/api2/views.py +++ b/seahub/api2/views.py @@ -456,16 +456,19 @@ class Search(APIView): return Response(res) ########## Repo related -def repo_download_info(request, repo_id): +def repo_download_info(request, repo_id, gen_sync_token=True): repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') # generate download url for client relay_id = get_session_info().id - addr, port = get_ccnet_server_addr_port () + addr, port = get_ccnet_server_addr_port() email = request.user.username - token = seafile_api.generate_repo_token(repo_id, request.user.username) + if gen_sync_token: + token = seafile_api.generate_repo_token(repo_id, email) + else: + token = '' repo_name = repo.name repo_desc = repo.desc enc = 1 if repo.encrypted else '' @@ -643,12 +646,17 @@ class Repos(APIView): return api_error(status.HTTP_403_FORBIDDEN, 'You do not have permission to create library.') + req_from = request.GET.get('from', "") + if req_from == 'web': + gen_sync_token = False # Do not generate repo sync token + else: + gen_sync_token = True + username = request.user.username repo_name = request.DATA.get("name", None) if not repo_name: return api_error(status.HTTP_400_BAD_REQUEST, 'Library name is required.') - repo_desc = request.DATA.get("desc", 'new repo') passwd = request.DATA.get("passwd", None) if not passwd: @@ -677,7 +685,8 @@ class Repos(APIView): creator=username, repo_id=repo_id, repo_name=repo_name) - resp = repo_download_info(request, repo_id) + resp = repo_download_info(request, repo_id, + gen_sync_token=gen_sync_token) # FIXME: according to the HTTP spec, need to return 201 code and # with a corresponding location header @@ -2899,12 +2908,9 @@ class GroupChanges(APIView): permission_classes = (IsAuthenticated,) throttle_classes = (UserRateThrottle, ) - def get(self, request, group_id, format=None): - # TODO: group check - - # TODO: perm check - - group_id = int(group_id) + @api_group_check + def get(self, request, group, format=None): + group_id = int(group.id) username = request.user.username if is_org_context(request): org_id = request.user.org.org_id @@ -2964,11 +2970,9 @@ class GroupRepos(APIView): permission_classes = (IsAuthenticated,) throttle_classes = (UserRateThrottle, ) - def post(self, request, group_id, format=None): + @api_group_check + def post(self, request, group, format=None): # add group repo - - # TODO: perm check - username = request.user.username repo_name = request.DATA.get("name", None) repo_desc = request.DATA.get("desc", 'new repo') @@ -2976,14 +2980,23 @@ class GroupRepos(APIView): if not passwd: passwd = None permission = request.DATA.get("permission", 'r') + if permission != 'r' and permission != 'rw': + return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid permission') + + if is_org_context(request): + org_id = request.user.org.org_id + repo_id = seafile_api.create_org_repo(repo_name, repo_desc, + username, passwd, org_id) + repo = seafile_api.get_repo(repo_id) + seafile_api.add_org_group_repo(repo_id, org_id, group.id, + username, permission) + else: + repo_id = seafile_api.create_repo(repo_name, repo_desc, + username, passwd) + repo = seafile_api.get_repo(repo_id) + seafile_api.set_group_repo(repo.id, group.id, username, permission) - repo_id = seafile_api.create_repo(repo_name, repo_desc, - username, passwd) - repo = seafile_api.get_repo(repo_id) calculate_repos_last_modify([repo]) - - seafile_api.set_group_repo(repo.id, int(group_id), username, permission) - group_repo = { "id": repo.id, "name": repo.name, @@ -2998,13 +3011,14 @@ class GroupRepos(APIView): return Response(group_repo, status=200) - def get(self, request, group_id, format=None): + @api_group_check + def get(self, request, group, format=None): username = request.user.username if is_org_context(request): org_id = request.user.org.org_id - repos = get_org_group_repos(org_id, group_id, username) + repos = seaserv.get_org_group_repos(org_id, group.id, username) else: - repos = seaserv.get_group_repos(int(group_id), username) + repos = seaserv.get_group_repos(group.id, username) repos_json = [] for r in repos: @@ -3028,11 +3042,14 @@ class GroupRepo(APIView): permission_classes = (IsAuthenticated,) throttle_classes = (UserRateThrottle, ) - def delete(self, request, group_id, repo_id, format=None): + @api_group_check + def delete(self, request, group, repo_id, format=None): username = request.user.username - group_id = int(group_id) + group_id = group.id - # TODO: perm check + if not group.is_staff and not seafile_api.is_repo_owner(username, repo_id): + return api_error(status.HTTP_403_FORBIDDEN, + 'You do not have permission to delete repo.') if seaserv.is_org_group(group_id): org_id = seaserv.get_org_id_by_group(group_id) diff --git a/tests/api/test_group_repos.py b/tests/api/test_group_repos.py new file mode 100644 index 0000000000..6735beef0b --- /dev/null +++ b/tests/api/test_group_repos.py @@ -0,0 +1,46 @@ +from django.core.urlresolvers import reverse + +from tests.api.apitestbase import ApiTestBase +from tests.common.utils import apiurl + + +class GroupRepoTest(ApiTestBase): + def create_group_repo(self, group_id, *args, **kwargs): + path = apiurl(reverse("api2-grouprepos", args=[group_id])) + data = {"name": 'grepo-test'} + data.update(kwargs) + resp = self.post(path, data=data) + + return resp + + def test_can_add(self): + with self.get_tmp_group() as group: + resp = self.create_group_repo(group.group_id) + + assert resp.status_code == 200 + assert len(resp.json()) == 9 + + def test_add_with_wrong_perm(self): + with self.get_tmp_group() as group: + resp = self.create_group_repo(group.group_id, permission='rr') + + assert resp.status_code == 400 + + def test_can_list(self): + with self.get_tmp_group() as group: + self.create_group_repo(group.group_id) + + path = apiurl(reverse("api2-grouprepos", args=[group.group_id])) + resp = self.get(path) + + assert resp.status_code == 200 + assert len(resp.json()) == 1 + + def test_can_delete(self): + with self.get_tmp_group() as group: + resp = self.create_group_repo(group.group_id) + + repo_id = resp.json()['id'] + path = apiurl(reverse("api2-grouprepo", args=[group.group_id, repo_id])) + resp = self.delete(path) + assert resp.status_code == 200