From 160e0b302783141febb048291ab3250f5b081404 Mon Sep 17 00:00:00 2001
From: zming <517046497@qq.com>
Date: Fri, 25 Aug 2017 20:15:50 +0800
Subject: [PATCH 1/2] [API] share to admin permission
---
seahub/api2/endpoints/be_shared_repo.py | 7 +-
seahub/api2/endpoints/dir_shared_items.py | 83 +++++++++++++++----
seahub/api2/views.py | 10 +++
seahub/constants.py | 5 ++
seahub/share/models.py | 78 ++++++++++++++++-
seahub/templates/js/templates.html | 36 ++++++--
static/scripts/app/models/repo.js | 3 +-
static/scripts/app/views/folder-share-item.js | 8 +-
static/scripts/app/views/share.js | 8 +-
static/scripts/app/views/shared-repo.js | 22 ++++-
.../models/test_extra_share_permission.py | 66 +++++++++++++++
11 files changed, 293 insertions(+), 33 deletions(-)
create mode 100644 tests/seahub/share/models/test_extra_share_permission.py
diff --git a/seahub/api2/endpoints/be_shared_repo.py b/seahub/api2/endpoints/be_shared_repo.py
index efeffbb1f0..0a4311f839 100644
--- a/seahub/api2/endpoints/be_shared_repo.py
+++ b/seahub/api2/endpoints/be_shared_repo.py
@@ -12,11 +12,12 @@ from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error
from seahub.utils import is_valid_username, is_org_context
+from seahub.share.models import ExtraSharePermission
json_content_type = 'application/json; charset=utf-8'
class BeSharedRepo(APIView):
- authentication_classes = (TokenAuthentication, SessionAuthentication )
+ authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
@@ -42,6 +43,10 @@ class BeSharedRepo(APIView):
else:
seaserv.remove_share(repo_id, from_email, username)
+ # Delete data of ExtraSharePermission table.
+ ExtraSharePermission.objects.delete_share_permission(repo_id,
+ username)
+
elif share_type == 'group':
from_email = request.GET.get('from', None)
diff --git a/seahub/api2/endpoints/dir_shared_items.py b/seahub/api2/endpoints/dir_shared_items.py
index 76cfaafc88..619d0b1d35 100644
--- a/seahub/api2/endpoints/dir_shared_items.py
+++ b/seahub/api2/endpoints/dir_shared_items.py
@@ -23,15 +23,19 @@ from seahub.api2.endpoints.utils import is_org_user
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.base.accounts import User
+from seahub.share.models import ExtraSharePermission
from seahub.share.signals import share_repo_to_user_successful, \
share_repo_to_group_successful
from seahub.utils import (is_org_context, is_valid_username,
send_perm_audit_msg)
+from seahub.constants import PERMISSION_READ, PERMISSION_READ_WRITE, \
+ PERMISSION_ADMIN
logger = logging.getLogger(__name__)
json_content_type = 'application/json; charset=utf-8'
+
class DirSharedItemsEndpoint(APIView):
"""Support uniform interface(list, share, unshare, modify) for sharing
library/folder to users/groups.
@@ -41,9 +45,10 @@ class DirSharedItemsEndpoint(APIView):
throttle_classes = (UserRateThrottle,)
def list_user_shared_items(self, request, repo_id, path):
- username = request.user.username
if is_org_context(request):
+ # when calling seafile API to share authority related functions, change the uesrname to repo owner.
+ username = seafile_api.get_org_repo_owner(repo_id)
org_id = request.user.org.org_id
if path == '/':
share_items = seafile_api.list_org_repo_shared_to(org_id,
@@ -52,11 +57,15 @@ class DirSharedItemsEndpoint(APIView):
share_items = seafile_api.get_org_shared_users_for_subdir(org_id,
repo_id, path, username)
else:
+ username = seafile_api.get_repo_owner(repo_id)
if path == '/':
share_items = seafile_api.list_repo_shared_to(username, repo_id)
else:
share_items = seafile_api.get_shared_users_for_subdir(repo_id,
path, username)
+
+ # change is_admin to True if user is repo admin.
+ admin_users = ExtraSharePermission.objects.get_admin_users_by_repo(repo_id)
ret = []
for item in share_items:
ret.append({
@@ -66,6 +75,7 @@ class DirSharedItemsEndpoint(APIView):
"nickname": email2nickname(item.user),
},
"permission": item.perm,
+ "is_admin": item.user in admin_users
})
return ret
@@ -179,11 +189,8 @@ class DirSharedItemsEndpoint(APIView):
if seafile_api.get_dir_id_by_path(repo.id, path) is None:
return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found.' % path)
- if username != self.get_repo_owner(request, repo_id):
- return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
-
- permission = request.data.get('permission', 'r')
- if permission not in ['r', 'rw']:
+ permission = request.data.get('permission', PERMISSION_READ)
+ if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN]:
return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.')
shared_to_user, shared_to_group = self.handle_shared_to_args(request)
@@ -192,12 +199,26 @@ class DirSharedItemsEndpoint(APIView):
if shared_to is None or not is_valid_username(shared_to):
return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % shared_to)
+ if username != self.get_repo_owner(request, repo_id) and \
+ ExtraSharePermission.objects.get_user_permission(repo_id, username) != PERMISSION_ADMIN:
+ return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
+ else:
+ if username != self.get_repo_owner(request, repo_id):
+ return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
+
+ if shared_to_user:
try:
User.objects.get(email=shared_to)
except User.DoesNotExist:
return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid user, should be registered')
+ extra_share_permission = ""
+ if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]:
+ extra_share_permission = permission
+ permission = PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else PERMISSION_READ
+
if is_org_context(request):
+ username = seafile_api.get_org_repo_owner(repo_id)
org_id = request.user.org.org_id
if path == '/':
seafile_api.org_set_share_permission(
@@ -206,6 +227,7 @@ class DirSharedItemsEndpoint(APIView):
seafile_api.org_update_share_subdir_perm_for_user(
org_id, repo_id, path, username, shared_to, permission)
else:
+ username = seafile_api.get_repo_owner(repo_id)
if path == '/':
seafile_api.set_share_permission(
repo_id, username, shared_to, permission)
@@ -213,6 +235,10 @@ class DirSharedItemsEndpoint(APIView):
seafile_api.update_share_subdir_perm_for_user(
repo_id, path, username, shared_to, permission)
+ if path == '/':
+ ExtraSharePermission.objects.update_share_permission(repo_id,
+ shared_to,
+ extra_share_permission)
send_perm_audit_msg('modify-repo-perm', username, shared_to,
repo_id, path, permission)
@@ -257,15 +283,20 @@ class DirSharedItemsEndpoint(APIView):
if seafile_api.get_dir_id_by_path(repo.id, path) is None:
return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found.' % path)
- if username != self.get_repo_owner(request, repo_id):
- return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
-
share_type = request.data.get('share_type')
if share_type != 'user' and share_type != 'group':
return api_error(status.HTTP_400_BAD_REQUEST, 'share_type invalid.')
- permission = request.data.get('permission', 'r')
- if permission not in ['r', 'rw']:
+ if share_type == 'user':
+ if username != self.get_repo_owner(request, repo_id) and \
+ ExtraSharePermission.objects.get_user_permission(repo_id, username) != PERMISSION_ADMIN:
+ return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
+ else:
+ if username != self.get_repo_owner(request, repo_id):
+ return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
+
+ permission = request.data.get('permission', PERMISSION_READ)
+ if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN]:
return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.')
result = {}
@@ -299,7 +330,13 @@ class DirSharedItemsEndpoint(APIView):
continue
try:
+ extra_share_permission = ''
+ if permission == PERMISSION_ADMIN:
+ extra_share_permission = permission
+ permission = PERMISSION_READ_WRITE
+
if is_org_context(request):
+ username = seafile_api.get_org_repo_owner(repo_id)
org_id = request.user.org.org_id
if not is_org_user(to_user, int(org_id)):
@@ -330,6 +367,7 @@ class DirSharedItemsEndpoint(APIView):
})
continue
+ username = seafile_api.get_repo_owner(repo_id)
if path == '/':
seafile_api.share_repo(
repo_id, username, to_user, permission)
@@ -337,6 +375,8 @@ class DirSharedItemsEndpoint(APIView):
sub_repo_id = seafile_api.share_subdir_to_user(
repo_id, path, username, to_user, permission)
+ if path == '/' and extra_share_permission == PERMISSION_ADMIN:
+ ExtraSharePermission.objects.create_share_permission(repo_id, to_user, extra_share_permission)
# send a signal when sharing repo successful
if path == '/':
share_repo_to_user_successful.send(sender=None,
@@ -352,7 +392,8 @@ class DirSharedItemsEndpoint(APIView):
"name": to_user,
"nickname": email2nickname(to_user),
},
- "permission": permission
+ "permission": permission,
+ "is_admin": extra_share_permission == PERMISSION_ADMIN
})
send_perm_audit_msg('add-repo-perm', username, to_user,
@@ -455,20 +496,27 @@ class DirSharedItemsEndpoint(APIView):
if seafile_api.get_dir_id_by_path(repo.id, path) is None:
return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found.' % path)
- if username != self.get_repo_owner(request, repo_id):
- return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
-
+ # check permission
shared_to_user, shared_to_group = self.handle_shared_to_args(request)
if shared_to_user:
shared_to = request.GET.get('username')
if shared_to is None or not is_valid_username(shared_to):
return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % shared_to)
+ if username != self.get_repo_owner(request, repo_id) and \
+ ExtraSharePermission.objects.get_user_permission(repo_id, username) != PERMISSION_ADMIN:
+ return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
+ else:
+ if username != self.get_repo_owner(request, repo_id):
+ return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
+
+ if shared_to_user:
# if user not found, permission will be None
permission = seafile_api.check_permission_by_path(
repo_id, '/', shared_to)
if is_org_context(request):
+ username = seafile_api.get_org_repo_owner(repo_id)
org_id = request.user.org.org_id
if path == '/':
seaserv.seafserv_threaded_rpc.org_remove_share(
@@ -478,12 +526,17 @@ class DirSharedItemsEndpoint(APIView):
org_id, repo_id, path, username, shared_to)
else:
+ username = seafile_api.get_repo_owner(repo_id)
if path == '/':
seaserv.remove_share(repo_id, username, shared_to)
else:
seafile_api.unshare_subdir_for_user(
repo_id, path, username, shared_to)
+ # Delete share permission at ExtraSharePermission table.
+ if path == '/':
+ ExtraSharePermission.objects.delete_share_permission(repo_id,
+ shared_to)
send_perm_audit_msg('delete-repo-perm', username, shared_to,
repo_id, path, permission)
diff --git a/seahub/api2/views.py b/seahub/api2/views.py
index c5705d4b7c..42773c4ef8 100644
--- a/seahub/api2/views.py
+++ b/seahub/api2/views.py
@@ -46,6 +46,7 @@ from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, \
grp_avatar
from seahub.base.accounts import User
from seahub.base.models import UserStarredFiles, DeviceToken
+from seahub.share.models import ExtraSharePermission
from seahub.base.templatetags.seahub_tags import email2nickname, \
translate_seahub_time, translate_commit_desc_escape, \
email2contact_email
@@ -485,6 +486,8 @@ class Repos(APIView):
else:
shared_repos = seafile_api.get_share_in_repo_list(
email, -1, -1)
+ repos_with_admin_share_to = ExtraSharePermission.objects.\
+ get_repos_with_admin_permission(email)
# Reduce memcache fetch ops.
owners_set = set([x.user for x in shared_repos])
@@ -518,6 +521,13 @@ class Repos(APIView):
"head_commit_id": r.head_cmmt_id,
"version": r.version,
}
+
+
+ if r.repo_id in repos_with_admin_share_to:
+ repo['is_admin'] = True
+ else:
+ repo['is_admin'] = False
+
repos_json.append(repo)
if filter_by['group']:
diff --git a/seahub/constants.py b/seahub/constants.py
index 3c76773d83..688aaebb2d 100644
--- a/seahub/constants.py
+++ b/seahub/constants.py
@@ -4,3 +4,8 @@ DEFAULT_USER = 'default'
# Guest user have limited operations, can not create group and library.
GUEST_USER = 'guest'
+
+# Permissions
+PERMISSION_READ = 'r'
+PERMISSION_READ_WRITE = 'rw'
+PERMISSION_ADMIN = 'admin'
diff --git a/seahub/share/models.py b/seahub/share/models.py
index 27e8e46a4b..546c01f4a4 100644
--- a/seahub/share/models.py
+++ b/seahub/share/models.py
@@ -1,8 +1,10 @@
# Copyright (c) 2012-2016 Seafile Ltd.
+import operator
import datetime
import logging
from django.db import models
+from django.db.models import Q
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.hashers import make_password, check_password
@@ -11,6 +13,7 @@ from constance import config
from seahub.base.fields import LowerCaseCharField
from seahub.utils import normalize_file_path, normalize_dir_path, gen_token,\
get_service_url
+from seahub.constants import PERMISSION_READ, PERMISSION_ADMIN
# Get an instance of a logger
logger = logging.getLogger(__name__)
@@ -150,6 +153,79 @@ class FileShareManager(models.Manager):
def get_valid_dir_link_by_token(self, token):
return self._get_valid_file_share_by_token(token)
+
+class ExtraSharePermissionManager(models.Manager):
+ def get_user_permission(self, repo_id, username):
+ """Get user's permission of a library.
+ return
+ e.g. 'admin'
+ """
+ record_list = super(ExtraSharePermissionManager, self).filter(
+ repo_id=repo_id, share_to=username
+ )
+ if len(record_list) > 0:
+ return record_list[0].permission
+ else:
+ return None
+
+ def get_repos_with_admin_permission(self, username):
+ """Get repo id list a user has admin permission.
+ """
+ shared_repos = super(ExtraSharePermissionManager, self).filter(
+ share_to=username, permission=PERMISSION_ADMIN
+ )
+ return [e.repo_id for e in shared_repos]
+
+ def get_admin_users_by_repo(self, repo_id):
+ """Gets the share and permissions of the record in the specified repo ID.
+ return
+ e.g. ['admin_user1', 'admin_user2']
+ """
+ shared_repos = super(ExtraSharePermissionManager, self).filter(
+ repo_id=repo_id, permission=PERMISSION_ADMIN
+ )
+
+ return [e.share_to for e in shared_repos]
+
+ def batch_is_admin(self, in_datas):
+ """return the data that input data is admin
+ e.g.
+ in_datas:
+ [(repo_id1, username1), (repo_id2, admin1)]
+ return:
+ [(repo_id2, admin1)]
+ """
+ if len(in_datas) <= 0:
+ return []
+ query = reduce(
+ operator.or_,
+ (Q(repo_id=data[0], share_to=data[1]) for data in in_datas)
+ )
+ db_data = super(ExtraSharePermissionManager, self).filter(query).filter(permission=PERMISSION_ADMIN)
+ return [(e.repo_id, e.share_to) for e in db_data]
+
+ def create_share_permission(self, repo_id, username, permission):
+ self.model(repo_id=repo_id, share_to=username,
+ permission=permission).save()
+
+ def delete_share_permission(self, repo_id, share_to):
+ super(ExtraSharePermissionManager, self).filter(repo_id=repo_id,
+ share_to=share_to).delete()
+
+ def update_share_permission(self, repo_id, share_to, permission):
+ super(ExtraSharePermissionManager, self).filter(repo_id=repo_id,
+ share_to=share_to).delete()
+ if permission in [PERMISSION_ADMIN]:
+ self.create_share_permission(repo_id, share_to, permission)
+
+
+class ExtraSharePermission(models.Model):
+ repo_id = models.CharField(max_length=36, db_index=True)
+ share_to = models.CharField(max_length=255, db_index=True)
+ permission = models.CharField(max_length=30)
+ objects = ExtraSharePermissionManager()
+
+
class FileShare(models.Model):
"""
Model used for file or dir shared link.
@@ -315,7 +391,7 @@ class PrivateFileDirShareManager(models.Manager):
"""
"""
return self.add_private_file_share(from_user, to_user, repo_id,
- path, 'r')
+ path, PERMISSION_READ)
def get_private_share_in_file(self, username, repo_id, path):
"""Get a file that private shared to ``username``.
diff --git a/seahub/templates/js/templates.html b/seahub/templates/js/templates.html
index 02b9eabd58..e3293114ed 100644
--- a/seahub/templates/js/templates.html
+++ b/seahub/templates/js/templates.html
@@ -1039,6 +1039,7 @@
|
@@ -1085,9 +1086,16 @@
<%- name %> |
+ <% if (is_admin) { %>
+
+
+
+ |
+ <% } else { %>
|
+ <% } %>
<%= size_formatted %> |
<%= mtime_relative %> |
<%- owner_nickname %> |
@@ -1289,21 +1297,33 @@
- <% if (permission == 'rw') { %>
- {% trans "Read-Write" %}
+ <% if (is_admin) { %>
+ {% trans "Admin" %}
<% } else { %>
- {% trans "Read-Only" %}
+ <% if (permission == 'rw') { %>
+ {% trans "Read-Write" %}
+ <% } else { %>
+ {% trans "Read-Only" %}
+ <% } %>
<% } %>
|
diff --git a/static/scripts/app/models/repo.js b/static/scripts/app/models/repo.js
index 3922fc6715..51e06ef446 100644
--- a/static/scripts/app/models/repo.js
+++ b/static/scripts/app/models/repo.js
@@ -16,7 +16,8 @@ define([
encrypted: false,
owner: "-",
owner_nickname: "-",
- permission: "rw"
+ permission: "rw",
+ is_admin: false
},
parse: function(response) {
diff --git a/static/scripts/app/views/folder-share-item.js b/static/scripts/app/views/folder-share-item.js
index a567022493..2851fdaaad 100644
--- a/static/scripts/app/views/folder-share-item.js
+++ b/static/scripts/app/views/folder-share-item.js
@@ -74,7 +74,13 @@ define([
'permission': perm
},
success: function () {
- item_data.permission = perm;
+ if (perm == 'admin'){
+ item_data.is_admin = true;
+ item_data.permission = 'rw';
+ } else {
+ item_data.permission = perm;
+ item_data.is_admin = false;
+ }
_this.render();
},
error: function(xhr) {
diff --git a/static/scripts/app/views/share.js b/static/scripts/app/views/share.js
index f6e41e4b42..b3a2ec9a21 100644
--- a/static/scripts/app/views/share.js
+++ b/static/scripts/app/views/share.js
@@ -576,7 +576,8 @@ define([
"user_email": item.user_info.name,
"user_name": item.user_info.nickname,
"permission": item.permission,
- 'for_user': true
+ 'for_user': true,
+ 'is_admin': item.is_admin
}
});
$add_item.after(new_item.el);
@@ -756,14 +757,15 @@ define([
"user_email": item.user_info.name,
"user_name": item.user_info.nickname,
"permission": item.permission,
- 'for_user': true
+ 'for_user': true,
+ 'is_admin': item.is_admin
}
});
$add_item.after(new_item.el);
});
emails_input.select2("val", "");
$('[value="rw"]', $perm).attr('selected', 'selected');
- $('[value="r"]', $perm).removeAttr('selected');
+ $('[value="rw"]', $perm).nextAll().removeAttr('selected');
$error.addClass('hide');
}
if (data.failed.length > 0) {
diff --git a/static/scripts/app/views/shared-repo.js b/static/scripts/app/views/shared-repo.js
index d859b7c5ef..47097b1cfc 100644
--- a/static/scripts/app/views/shared-repo.js
+++ b/static/scripts/app/views/shared-repo.js
@@ -3,8 +3,9 @@ define([
'underscore',
'backbone',
'common',
- 'app/views/widgets/hl-item-view'
-], function($, _, Backbone, Common, HLItemView) {
+ 'app/views/widgets/hl-item-view',
+ 'app/views/share',
+], function($, _, Backbone, Common, HLItemView, ShareView) {
'use strict';
var SharedRepoView = HLItemView.extend({
@@ -14,13 +15,28 @@ define([
mobileTemplate: _.template($('#shared-repo-mobile-tmpl').html()),
events: {
- 'click .unshare-btn': 'removeShare'
+ 'click .unshare-btn': 'removeShare',
+ 'click .repo-share-btn': 'share',
},
initialize: function() {
HLItemView.prototype.initialize.call(this);
},
+ share: function() {
+ var options = {
+ 'is_repo_owner': true,
+ 'user_perm': 'rw',
+ 'repo_id': this.model.get('id'),
+ 'repo_encrypted': this.model.get('encrypted'),
+ 'is_dir': true,
+ 'dirent_path': '/',
+ 'obj_name': this.model.get('name')
+ };
+ new ShareView(options);
+ return false;
+ },
+
removeShare: function(e) {
var _this = this,
success_callback = function(data) {
diff --git a/tests/seahub/share/models/test_extra_share_permission.py b/tests/seahub/share/models/test_extra_share_permission.py
new file mode 100644
index 0000000000..020e54a0be
--- /dev/null
+++ b/tests/seahub/share/models/test_extra_share_permission.py
@@ -0,0 +1,66 @@
+from seahub.share.models import ExtraSharePermission
+from seahub.test_utils import BaseTestCase
+
+from seaserv import seafile_api
+
+
+class ExtraSharePermissionTest(BaseTestCase):
+ def test_can_add(self):
+ ExtraSharePermission.objects.create_share_permission(self.repo.id,
+ self.user.username,
+ 'admin')
+ self.assertEqual(1, len(ExtraSharePermission.objects.all()))
+
+ def test_can_update(self):
+ ExtraSharePermission.objects.create_share_permission(self.repo.id,
+ self.user.username,
+ 'rw')
+ ExtraSharePermission.objects.update_share_permission(self.repo.id,
+ self.user.username,
+ 'admin')
+ self.assertEqual('admin', ExtraSharePermission.objects.all()[0].permission)
+
+ def test_can_delete(self):
+ ExtraSharePermission.objects.create_share_permission(self.repo.id,
+ self.user.username,
+ 'admin')
+ ExtraSharePermission.objects.delete_share_permission(self.repo.id,
+ self.user.username)
+ self.assertEqual(0, len(ExtraSharePermission.objects.all()))
+
+ def test_can_get_user_permission(self):
+ self.assertEqual(None, ExtraSharePermission.objects.\
+ get_user_permission(self.repo.id, self.user.username))
+ ExtraSharePermission.objects.create_share_permission(self.repo.id,
+ self.user.username,
+ 'admin')
+ self.assertEqual('admin', ExtraSharePermission.objects.\
+ get_user_permission(self.repo.id, self.user.username))
+
+ def test_can_get_shared_repos_with_admin(self):
+ self.assertEqual([], ExtraSharePermission.objects.\
+ get_repos_with_admin_permission(self.user.username))
+ ExtraSharePermission.objects.create_share_permission(self.repo.id,
+ self.user.username,
+ 'admin')
+ self.assertEqual([self.repo.id], ExtraSharePermission.objects.\
+ get_repos_with_admin_permission(self.user.username))
+
+ def test_get_permission_by_owner_shared(self):
+ self.assertEqual([], ExtraSharePermission.objects.\
+ get_admin_users_by_repo(self.repo.id))
+ ExtraSharePermission.objects.create_share_permission(self.repo.id,
+ self.user.username,
+ 'admin')
+ self.assertEqual([self.user.username], ExtraSharePermission.objects.\
+ get_admin_users_by_repo(self.repo.id))
+
+ def test_batch_is_admin(self):
+ r = seafile_api.get_repo(self.create_repo(name='repo2',
+ desc='', username=self.user.email, passwd=None))
+ data = [(self.repo.id, self.admin.email), (r.id, self.admin.email)]
+ self.assertEqual([], ExtraSharePermission.objects.batch_is_admin(data))
+ ExtraSharePermission.objects.create_share_permission(self.repo.id,
+ self.admin.username,
+ 'admin')
+ self.assertEqual([(self.repo.id, self.admin.email)], ExtraSharePermission.objects.batch_is_admin(data))
From 33266638ef661151e43fb7cc2e3098e42a6bea08 Mon Sep 17 00:00:00 2001
From: llj
Date: Wed, 30 Aug 2017 17:59:14 +0800
Subject: [PATCH 2/2] [share] share repo with 'admin' perm: modification
---
seahub/templates/js/templates.html | 58 +++++++++++--------
seahub/views/ajax.py | 6 +-
static/scripts/app/collections/dirents.js | 1 +
static/scripts/app/models/repo.js | 3 +-
static/scripts/app/views/dir.js | 3 +
static/scripts/app/views/dirent-grid.js | 4 ++
static/scripts/app/views/dirent.js | 4 ++
static/scripts/app/views/folder-share-item.js | 8 ++-
.../scripts/app/views/myhome-shared-repos.js | 2 +-
static/scripts/app/views/share.js | 18 +++---
static/scripts/app/views/shared-repo.js | 9 ++-
11 files changed, 76 insertions(+), 40 deletions(-)
diff --git a/seahub/templates/js/templates.html b/seahub/templates/js/templates.html
index e3293114ed..d278b3af3f 100644
--- a/seahub/templates/js/templates.html
+++ b/seahub/templates/js/templates.html
@@ -898,7 +898,7 @@
<% if (user_perm == 'rw' && !repo_encrypted && can_generate_upload_link) { %>
{% trans "Upload Link" %}
<% } %>
- <% if (!is_virtual && is_repo_owner) { %> {# dir private share #}
+ <% if (!is_virtual && (is_repo_owner || is_admin)) { %> {# dir private share #}
{% trans "Share to user" %}
{% trans "Share to group" %}
<% } %>
@@ -1016,7 +1016,7 @@
<% } %>
- <% if (!is_virtual && is_repo_owner) { %>
+ <% if (!is_virtual && (is_repo_owner || is_admin)) { %>
<% if (!repo_encrypted) { %>
<% } else { %>
@@ -1039,7 +1039,9 @@
|
@@ -1086,16 +1088,12 @@
<%- name %> |
- <% if (is_admin) { %>
+ <% if (app.pageOptions.is_pro && is_admin) { %>
+ <% } %>
|
- <% } else { %>
-
-
- |
- <% } %>
<%= size_formatted %> |
<%= mtime_relative %> |
<%- owner_nickname %> |
@@ -1297,32 +1295,42 @@
- <% if (is_admin) { %>
- {% trans "Admin" %}
- <% } else { %>
- <% if (permission == 'rw') { %>
- {% trans "Read-Write" %}
+ <% if (show_admin && is_admin) { %>
+ {% trans "Admin" %}
<% } else { %>
- {% trans "Read-Only" %}
+ <% if (permission == 'rw') { %>
+ {% trans "Read-Write" %}
+ <% } else { %>
+ {% trans "Read-Only" %}
+ <% } %>
<% } %>
- <% } %>
diff --git a/seahub/views/ajax.py b/seahub/views/ajax.py
index 5ca7126431..32c964a3df 100644
--- a/seahub/views/ajax.py
+++ b/seahub/views/ajax.py
@@ -30,7 +30,7 @@ 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
+from seahub.share.models import UploadLinkShare, ExtraSharePermission
from seahub.signals import upload_file_successful
from seahub.views import get_unencry_rw_repos_by_user, \
get_diff, check_folder_permission
@@ -50,6 +50,7 @@ from seahub.thumbnail.utils import get_thumbnail_src
from seahub.utils.file_types import IMAGE, VIDEO
from seahub.base.templatetags.seahub_tags import translate_seahub_time, \
email2nickname, tsstr_sec
+from seahub.constants import PERMISSION_ADMIN
# Get an instance of a logger
logger = logging.getLogger(__name__)
@@ -309,6 +310,9 @@ def list_lib_dir(request, repo_id):
except Exception as e:
logger.error(e)
+ # for shared repo
+ result["is_admin"] = ExtraSharePermission.objects.get_user_permission(repo_id, username) == PERMISSION_ADMIN
+
result["is_virtual"] = repo.is_virtual
result["repo_name"] = repo.name
result["user_perm"] = user_perm
diff --git a/static/scripts/app/collections/dirents.js b/static/scripts/app/collections/dirents.js
index 369db8b049..0b356b97b3 100644
--- a/static/scripts/app/collections/dirents.js
+++ b/static/scripts/app/collections/dirents.js
@@ -27,6 +27,7 @@ define([
this.has_been_shared_out = data.has_been_shared_out;
this.dirent_more = data.dirent_more;
this.more_start = data.more_start;
+ this.is_admin = data.is_admin;
return data.dirent_list; // return the array
},
diff --git a/static/scripts/app/models/repo.js b/static/scripts/app/models/repo.js
index 51e06ef446..3922fc6715 100644
--- a/static/scripts/app/models/repo.js
+++ b/static/scripts/app/models/repo.js
@@ -16,8 +16,7 @@ define([
encrypted: false,
owner: "-",
owner_nickname: "-",
- permission: "rw",
- is_admin: false
+ permission: "rw"
},
parse: function(response) {
diff --git a/static/scripts/app/views/dir.js b/static/scripts/app/views/dir.js
index 7425840b6e..02fe0af31c 100644
--- a/static/scripts/app/views/dir.js
+++ b/static/scripts/app/views/dir.js
@@ -824,6 +824,9 @@ define([
'dirent_path': path,
'obj_name': path == '/' ? dir.repo_name : path.substr(path.lastIndexOf('/') + 1)
};
+ if (app.pageOptions.is_pro) {
+ options.is_admin = dir.is_admin;
+ }
new ShareView(options);
},
diff --git a/static/scripts/app/views/dirent-grid.js b/static/scripts/app/views/dirent-grid.js
index 436b97960b..5e77dc069a 100644
--- a/static/scripts/app/views/dirent-grid.js
+++ b/static/scripts/app/views/dirent-grid.js
@@ -203,6 +203,10 @@ define([
'dirent_path': dirent_path,
'obj_name': obj_name
};
+ if (app.pageOptions.is_pro) {
+ options.is_admin = dir.is_admin;
+ }
+
new ShareView(options);
this.closeMenu();
return false;
diff --git a/static/scripts/app/views/dirent.js b/static/scripts/app/views/dirent.js
index 033f9dfde5..cca9eb6284 100644
--- a/static/scripts/app/views/dirent.js
+++ b/static/scripts/app/views/dirent.js
@@ -361,6 +361,10 @@ define([
'dirent_path': dirent_path,
'obj_name': obj_name
};
+ if (app.pageOptions.is_pro) {
+ options.is_admin = dir.is_admin;
+ }
+
new ShareView(options);
this._hideMenu();
diff --git a/static/scripts/app/views/folder-share-item.js b/static/scripts/app/views/folder-share-item.js
index 2851fdaaad..10ce010f85 100644
--- a/static/scripts/app/views/folder-share-item.js
+++ b/static/scripts/app/views/folder-share-item.js
@@ -20,11 +20,17 @@ define([
this.repo_id = options.repo_id;
this.path = options.path;
+ // show info about 'is_admin'
+ this.show_admin = false;
+ if (app.pageOptions.is_pro && this.path == '/' && this.item_data.for_user) {
+ this.show_admin = true;
+ }
+
this.render();
},
render: function () {
- this.$el.html(this.template(this.item_data));
+ this.$el.html(this.template($.extend({}, this.item_data, {'show_admin': this.show_admin})));
return this;
},
diff --git a/static/scripts/app/views/myhome-shared-repos.js b/static/scripts/app/views/myhome-shared-repos.js
index 45ac0551b7..00cde31e3f 100644
--- a/static/scripts/app/views/myhome-shared-repos.js
+++ b/static/scripts/app/views/myhome-shared-repos.js
@@ -4,7 +4,7 @@ define([
'backbone',
'common',
'app/collections/repos',
- 'app/views/shared-repo',
+ 'app/views/shared-repo'
], function($, _, Backbone, Common, RepoCollection, SharedRepoView) {
'use strict';
diff --git a/static/scripts/app/views/share.js b/static/scripts/app/views/share.js
index b3a2ec9a21..0b8d00cd07 100644
--- a/static/scripts/app/views/share.js
+++ b/static/scripts/app/views/share.js
@@ -14,6 +14,8 @@ define([
initialize: function(options) {
this.is_repo_owner = options.is_repo_owner;
+ // for shared repo
+ this.is_admin = options.is_admin; // true or undefined
this.is_virtual = options.is_virtual;
this.user_perm = options.user_perm;
this.repo_id = options.repo_id;
@@ -44,7 +46,7 @@ define([
if (this.user_perm == 'rw' && !this.repo_encrypted && app.pageOptions.can_generate_upload_link) {
this.uploadLinkPanelInit();
}
- if (!this.is_virtual && this.is_repo_owner) {
+ if (!this.is_virtual && (this.is_repo_owner || this.is_admin)) {
this.dirUserSharePanelInit();
this.dirGroupSharePanelInit();
@@ -66,12 +68,14 @@ define([
.replace('{placeholder}', '' + Common.HTMLescape(this.obj_name) + ''),
is_dir: this.is_dir,
is_repo_owner: this.is_repo_owner,
+ is_admin: this.is_admin,
is_virtual: this.is_virtual,
user_perm: this.user_perm,
repo_id: this.repo_id,
can_generate_share_link: app.pageOptions.can_generate_share_link,
can_generate_upload_link: app.pageOptions.can_generate_upload_link,
- repo_encrypted: this.repo_encrypted
+ repo_encrypted: this.repo_encrypted,
+ dirent_path: this.dirent_path
}));
return this;
@@ -576,8 +580,8 @@ define([
"user_email": item.user_info.name,
"user_name": item.user_info.nickname,
"permission": item.permission,
- 'for_user': true,
- 'is_admin': item.is_admin
+ 'is_admin': item.is_admin,
+ 'for_user': true
}
});
$add_item.after(new_item.el);
@@ -757,15 +761,15 @@ define([
"user_email": item.user_info.name,
"user_name": item.user_info.nickname,
"permission": item.permission,
- 'for_user': true,
- 'is_admin': item.is_admin
+ 'is_admin': item.is_admin,
+ 'for_user': true
}
});
$add_item.after(new_item.el);
});
emails_input.select2("val", "");
+ $('option', $perm).removeAttr('selected');
$('[value="rw"]', $perm).attr('selected', 'selected');
- $('[value="rw"]', $perm).nextAll().removeAttr('selected');
$error.addClass('hide');
}
if (data.failed.length > 0) {
diff --git a/static/scripts/app/views/shared-repo.js b/static/scripts/app/views/shared-repo.js
index 47097b1cfc..3eceaf0d69 100644
--- a/static/scripts/app/views/shared-repo.js
+++ b/static/scripts/app/views/shared-repo.js
@@ -4,7 +4,7 @@ define([
'backbone',
'common',
'app/views/widgets/hl-item-view',
- 'app/views/share',
+ 'app/views/share'
], function($, _, Backbone, Common, HLItemView, ShareView) {
'use strict';
@@ -16,7 +16,7 @@ define([
events: {
'click .unshare-btn': 'removeShare',
- 'click .repo-share-btn': 'share',
+ 'click .repo-share-btn': 'share'
},
initialize: function() {
@@ -25,7 +25,9 @@ define([
share: function() {
var options = {
- 'is_repo_owner': true,
+ 'is_repo_owner': false,
+ 'is_admin': true, // only for shared repo
+ 'is_virtual': false,
'user_perm': 'rw',
'repo_id': this.model.get('id'),
'repo_encrypted': this.model.get('encrypted'),
@@ -33,6 +35,7 @@ define([
'dirent_path': '/',
'obj_name': this.model.get('name')
};
+
new ShareView(options);
return false;
},
|