1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-01 23:38:37 +00:00

add can add public repo user role permission

This commit is contained in:
lian 2018-08-23 19:04:33 +08:00
parent f6862359e1
commit eaff121ef2
10 changed files with 116 additions and 84 deletions

View File

@ -193,13 +193,18 @@ class SharedRepo(APIView):
group_id, repo_id, '/', permission) group_id, repo_id, '/', permission)
if share_type == 'public': if share_type == 'public':
try: try:
if is_org_context(request): if is_org_context(request):
org_id = request.user.org.org_id org_id = request.user.org.org_id
seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo( seafile_api.set_org_inner_pub_repo(org_id, repo_id, permission)
org_id, repo_id, permission)
else: else:
if not request.user.permissions.can_add_public_repo():
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
seafile_api.add_inner_pub_repo(repo_id, permission) seafile_api.add_inner_pub_repo(repo_id, permission)
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
error_msg = 'Internal Server Error' error_msg = 'Internal Server Error'

View File

@ -67,8 +67,7 @@ from seahub.utils import gen_file_get_url, gen_token, gen_file_upload_url, \
gen_file_share_link, gen_dir_share_link, is_org_context, gen_shared_link, \ gen_file_share_link, gen_dir_share_link, is_org_context, gen_shared_link, \
get_org_user_events, calculate_repos_last_modify, send_perm_audit_msg, \ get_org_user_events, calculate_repos_last_modify, send_perm_audit_msg, \
gen_shared_upload_link, convert_cmmt_desc_link, is_valid_dirent_name, \ gen_shared_upload_link, convert_cmmt_desc_link, is_valid_dirent_name, \
is_org_repo_creation_allowed, normalize_file_path, \ normalize_file_path, get_no_duplicate_obj_name, normalize_dir_path
get_no_duplicate_obj_name, normalize_dir_path
from seahub.utils.file_revisions import get_file_revisions_after_renamed from seahub.utils.file_revisions import get_file_revisions_after_renamed
from seahub.utils.devices import do_unlink_device from seahub.utils.devices import do_unlink_device
@ -998,7 +997,7 @@ class PubRepos(APIView):
def post(self, request, format=None): def post(self, request, format=None):
# Create public repo # Create public repo
if not request.user.permissions.can_add_repo(): if not request.user.permissions.can_add_public_repo():
return api_error(status.HTTP_403_FORBIDDEN, return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to create library.') 'You do not have permission to create library.')
@ -1029,8 +1028,7 @@ class PubRepos(APIView):
repo_id = seafile_api.create_org_repo(repo_name, repo_desc, repo_id = seafile_api.create_org_repo(repo_name, repo_desc,
username, passwd, org_id) username, passwd, org_id)
repo = seafile_api.get_repo(repo_id) repo = seafile_api.get_repo(repo_id)
seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo( seafile_api.set_org_inner_pub_repo(org_id, repo.id, permission)
org_id, repo.id, permission)
else: else:
if is_pro_version() and ENABLE_STORAGE_CLASSES: if is_pro_version() and ENABLE_STORAGE_CLASSES:
@ -1056,6 +1054,13 @@ class PubRepos(APIView):
repo = seafile_api.get_repo(repo_id) repo = seafile_api.get_repo(repo_id)
seafile_api.add_inner_pub_repo(repo.id, permission) seafile_api.add_inner_pub_repo(repo.id, permission)
try:
send_perm_audit_msg('add-repo-perm',
username, 'all', repo_id, '/', permission)
except Exception as e:
logger.error(e)
library_template = request.data.get("library_template", '') library_template = request.data.get("library_template", '')
repo_created.send(sender=None, repo_created.send(sender=None,
org_id=org_id, org_id=org_id,
@ -3940,42 +3945,50 @@ class SharedRepo(APIView):
""" """
Share a repo to users/groups/public. Share a repo to users/groups/public.
""" """
username = request.user.username
if is_org_context(request):
repo_owner = seafile_api.get_org_repo_owner(repo_id)
else:
repo_owner = seafile_api.get_repo_owner(repo_id)
if username != repo_owner:
return api_error(status.HTTP_403_FORBIDDEN,
'You do not have permission to share library.')
# argument check
share_type = request.GET.get('share_type') share_type = request.GET.get('share_type')
user = request.GET.get('user')
users = request.GET.get('users')
group_id = request.GET.get('group_id')
permission = request.GET.get('permission') permission = request.GET.get('permission')
if permission != 'rw' and permission != "r": if permission not in ('r', 'rw'):
return api_error(status.HTTP_400_BAD_REQUEST, error_msg = 'permission invalid.'
'Permission need to be rw or r.') return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if share_type not in ('personal', 'group', 'public'):
error_msg = 'share_type invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# recourse check
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)
# permission check
username = request.user.username
repo_owner = get_repo_owner(request, repo_id)
if username != repo_owner:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if share_type == 'personal': if share_type == 'personal':
from_email = seafile_api.get_repo_owner(repo_id)
shared_users = []
invalid_users = []
notexistent_users = []
notsharable_errors = []
user = request.GET.get('user')
users = request.GET.get('users')
if not user and not users:
return api_error(status.HTTP_400_BAD_REQUEST,
'User or users (comma separated are mandatory) are not provided')
usernames = [] usernames = []
if user: if user:
usernames += user.split(",") usernames += user.split(",")
if users: if users:
usernames += users.split(",") usernames += users.split(",")
if not user and not users:
return api_error(status.HTTP_400_BAD_REQUEST, shared_users = []
'User or users (comma separated are mandatory) are not provided') invalid_users = []
notexistent_users = []
notsharable_errors = []
for u in usernames: for u in usernames:
if not u: if not u:
continue continue
@ -3989,17 +4002,23 @@ class SharedRepo(APIView):
continue continue
try: try:
seafile_api.share_repo(repo_id, from_email, u, permission) seafile_api.share_repo(repo_id, username, u, permission)
shared_users.append(u) shared_users.append(u)
except SearpcError, e: except SearpcError, e:
logger.error(e) logger.error(e)
notsharable_errors.append(e) notsharable_errors.append(e)
try:
send_perm_audit_msg('add-repo-perm',
username, u, repo_id, '/', permission)
except Exception as e:
logger.error(e)
if invalid_users or notexistent_users or notsharable_errors: if invalid_users or notexistent_users or notsharable_errors:
# removing already created share # removing already created share
for s_user in shared_users: for s_user in shared_users:
try: try:
remove_share(repo_id, from_email, s_user) remove_share(repo_id, username, s_user)
except SearpcError, e: except SearpcError, e:
# ignoring this error, go to next unsharing # ignoring this error, go to next unsharing
continue continue
@ -4015,53 +4034,56 @@ class SharedRepo(APIView):
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
'Internal error occurs, sharing rolled back') 'Internal error occurs, sharing rolled back')
elif share_type == 'group': if share_type == 'group':
group_id = request.GET.get('group_id')
if not group_id:
error_msg = 'group_id invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try: try:
group_id = int(group_id) group_id = int(group_id)
except ValueError: except ValueError:
return api_error(status.HTTP_400_BAD_REQUEST, return api_error(status.HTTP_400_BAD_REQUEST,
'Group ID must be integer.') 'Group ID must be integer.')
from_email = seafile_api.get_repo_owner(repo_id)
group = get_group(group_id) group = get_group(group_id)
if not group: if not group:
return api_error(status.HTTP_400_BAD_REQUEST, return api_error(status.HTTP_400_BAD_REQUEST,
'Group does not exist .') 'Group does not exist .')
try: try:
seafile_api.set_group_repo(repo_id, int(group_id), seafile_api.set_group_repo(repo_id,
from_email, permission) group_id, username, permission)
except SearpcError, e: except SearpcError, e:
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
"Searpc Error: " + e.msg) "Searpc Error: " + e.msg)
try:
send_perm_audit_msg('add-repo-perm',
username, group_id, repo_id, '/', permission)
except Exception as e:
logger.error(e)
elif share_type == 'public': if share_type == 'public':
if not CLOUD_MODE: try:
if not is_org_repo_creation_allowed(request):
return api_error(status.HTTP_403_FORBIDDEN,
'Failed to share library to public: permission denied.')
try:
seafile_api.add_inner_pub_repo(repo_id, permission)
except SearpcError, e:
logger.error(e)
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
'Failed to share library to public.')
else:
if is_org_context(request): if is_org_context(request):
org_id = request.user.org.org_id org_id = request.user.org.org_id
try: seafile_api.set_org_inner_pub_repo(org_id, repo_id, permission)
seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo(org_id, repo_id, permission)
send_perm_audit_msg('add-repo-perm', username, 'all', repo_id, '/', permission)
except SearpcError, e:
logger.error(e)
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
'Failed to share library to public.')
else: else:
return api_error(status.HTTP_403_FORBIDDEN, if not request.user.permissions.can_add_public_repo():
'Failed to share library to public.') error_msg = 'Permission denied.'
else: return api_error(status.HTTP_403_FORBIDDEN, error_msg)
return api_error(status.HTTP_400_BAD_REQUEST,
'Share type can only be personal or group or public.') seafile_api.add_inner_pub_repo(repo_id, permission)
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
try:
send_perm_audit_msg('add-repo-perm',
username, 'all', repo_id, '/', permission)
except Exception as e:
logger.error(e)
return Response('success', status=status.HTTP_200_OK) return Response('success', status=status.HTTP_200_OK)

View File

@ -147,6 +147,21 @@ class UserPermissions(object):
return get_enabled_role_permissions_by_role(self.user.role)['can_view_org'] return get_enabled_role_permissions_by_role(self.user.role)['can_view_org']
def can_add_public_repo(self):
""" Check if user can create public repo or share existed repo to public.
Used when MULTI_TENANCY feature is NOT enabled.
"""
if CLOUD_MODE:
return False
elif self.user.is_staff:
return True
elif get_enabled_role_permissions_by_role(self.user.role)['can_add_public_repo']:
return True
else:
return bool(config.ENABLE_USER_CREATE_ORG_REPO)
def can_drag_drop_folder_to_sync(self): def can_drag_drop_folder_to_sync(self):
return get_enabled_role_permissions_by_role(self.user.role)['can_drag_drop_folder_to_sync'] return get_enabled_role_permissions_by_role(self.user.role)['can_drag_drop_folder_to_sync']

View File

@ -13,6 +13,7 @@ DEFAULT_ENABLED_ROLE_PERMISSIONS = {
'can_add_repo': True, 'can_add_repo': True,
'can_add_group': True, 'can_add_group': True,
'can_view_org': True, 'can_view_org': True,
'can_add_public_repo': False,
'can_use_global_address_book': True, 'can_use_global_address_book': True,
'can_generate_share_link': True, 'can_generate_share_link': True,
'can_generate_upload_link': True, 'can_generate_upload_link': True,
@ -30,6 +31,7 @@ DEFAULT_ENABLED_ROLE_PERMISSIONS = {
'can_add_repo': False, 'can_add_repo': False,
'can_add_group': False, 'can_add_group': False,
'can_view_org': False, 'can_view_org': False,
'can_add_public_repo': False,
'can_use_global_address_book': False, 'can_use_global_address_book': False,
'can_generate_share_link': False, 'can_generate_share_link': False,
'can_generate_upload_link': False, 'can_generate_upload_link': False,

View File

@ -375,7 +375,7 @@
<script type="text/template" id="org-repos-toolbar-tmpl"> <script type="text/template" id="org-repos-toolbar-tmpl">
{% if can_add_pub_repo %} {% if can_add_public_repo %}
<div class="sf-dropdown js-add-pub-lib-dropdown"> <div class="sf-dropdown js-add-pub-lib-dropdown">
<button class="btn-white sf-dropdown-toggle hidden-sm-down"><span aria-hidden="true" class="icon-plus-square add vam"></span><span class="vam">{% trans "Add Library"%}</span></button> <button class="btn-white sf-dropdown-toggle hidden-sm-down"><span aria-hidden="true" class="icon-plus-square add vam"></span><span class="vam">{% trans "Add Library"%}</span></button>
<span aria-label="{% trans "Add Library" %}" class="hidden-md-up sf-dropdown-toggle sf2-icon-plus2 mobile-icon"></span> <span aria-label="{% trans "Add Library" %}" class="hidden-md-up sf-dropdown-toggle sf2-icon-plus2 mobile-icon"></span>

View File

@ -1328,14 +1328,6 @@ def within_time_range(d1, d2, maxdiff_seconds):
diff = (delta.microseconds + (delta.seconds + delta.days*24*3600) * 1e6) / 1e6 diff = (delta.microseconds + (delta.seconds + delta.days*24*3600) * 1e6) / 1e6
return diff < maxdiff_seconds return diff < maxdiff_seconds
def is_org_repo_creation_allowed(request):
"""Whether or not allow a user create organization library.
"""
if request.user.is_staff:
return True
else:
return config.ENABLE_USER_CREATE_ORG_REPO
def get_system_admins(): def get_system_admins():
db_users = seaserv.get_emailusers('DB', -1, -1) db_users = seaserv.get_emailusers('DB', -1, -1)
ldpa_imported_users = seaserv.get_emailusers('LDAPImport', -1, -1) ldpa_imported_users = seaserv.get_emailusers('LDAPImport', -1, -1)

View File

@ -43,7 +43,7 @@ from seahub.utils import render_permission_error, render_error, \
get_user_repos, EMPTY_SHA1, gen_file_get_url, \ get_user_repos, EMPTY_SHA1, gen_file_get_url, \
new_merge_with_no_conflict, get_max_upload_file_size, \ new_merge_with_no_conflict, get_max_upload_file_size, \
is_pro_version, FILE_AUDIT_ENABLED, is_valid_dirent_name, \ is_pro_version, FILE_AUDIT_ENABLED, is_valid_dirent_name, \
is_org_repo_creation_allowed, is_windows_operating_system is_windows_operating_system
from seahub.utils.star import get_dir_starred_files from seahub.utils.star import get_dir_starred_files
from seahub.utils.repo import get_library_storages from seahub.utils.repo import get_library_storages
from seahub.utils.file_op import check_file_lock from seahub.utils.file_op import check_file_lock
@ -689,7 +689,6 @@ def libraries(request):
create_default_library(request) create_default_library(request)
folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False
can_add_pub_repo = True if is_org_repo_creation_allowed(request) else False
if request.cloud_mode and request.user.org is not None: if request.cloud_mode and request.user.org is not None:
org_id = request.user.org.org_id org_id = request.user.org.org_id
@ -725,7 +724,7 @@ def libraries(request):
'folder_perm_enabled': folder_perm_enabled, 'folder_perm_enabled': folder_perm_enabled,
'is_pro': True if is_pro_version() else False, 'is_pro': True if is_pro_version() else False,
'file_audit_enabled': FILE_AUDIT_ENABLED, 'file_audit_enabled': FILE_AUDIT_ENABLED,
'can_add_pub_repo': can_add_pub_repo, 'can_add_public_repo': request.user.permissions.can_add_public_repo(),
'joined_groups': joined_groups, 'joined_groups': joined_groups,
'joined_groups_exclude_address_book': joined_groups_exclude_address_book, 'joined_groups_exclude_address_book': joined_groups_exclude_address_book,
'storages': get_library_storages(request), 'storages': get_library_storages(request),

View File

@ -1,16 +1,15 @@
import json
import pytest import pytest
pytestmark = pytest.mark.django_db pytestmark = pytest.mark.django_db
from seahub.test_utils import BaseTestCase from seahub.test_utils import BaseTestCase
from seaserv import seafile_api, ccnet_threaded_rpc from seaserv import seafile_api
class SharedRepoTest(BaseTestCase): class SharedRepoTest(BaseTestCase):
def setUp(self): def setUp(self):
from constance import config from constance import config
self.config = config self.config = config
self.repo_id = self.create_repo(name='test-admin-repo', desc='', self.repo_id = self.create_repo(name='test-admin-repo', desc='',
username=self.admin.username, username=self.admin.username,
passwd=None) passwd=None)
@ -57,8 +56,6 @@ class SharedRepoTest(BaseTestCase):
resp = self.client.put(self.shared_repo_url % self.repo.id) resp = self.client.put(self.shared_repo_url % self.repo.id)
self.assertEqual(403, resp.status_code) self.assertEqual(403, resp.status_code)
json_resp = json.loads(resp.content)
assert json_resp['error_msg'] == 'Failed to share library to public: permission denied.'
def test_admin_can_unshare_public_repo(self): def test_admin_can_unshare_public_repo(self):
seafile_api.add_inner_pub_repo(self.repo_id, "r") seafile_api.add_inner_pub_repo(self.repo_id, "r")

View File

@ -11,4 +11,4 @@ class UtilsTest(BaseTestCase):
assert DEFAULT_USER in get_available_roles() assert DEFAULT_USER in get_available_roles()
def test_get_enabled_role_permissions_by_role(self): def test_get_enabled_role_permissions_by_role(self):
assert len(get_enabled_role_permissions_by_role(DEFAULT_USER).keys()) == 15 assert len(get_enabled_role_permissions_by_role(DEFAULT_USER).keys()) == 16

View File

@ -41,14 +41,14 @@ class LibrariesTest(BaseTestCase):
resp = self.client.get(self.url) resp = self.client.get(self.url)
self.assertEqual(200, resp.status_code) self.assertEqual(200, resp.status_code)
assert resp.context['can_add_pub_repo'] is True assert resp.context['can_add_public_repo'] is True
self.config.ENABLE_USER_CREATE_ORG_REPO = 0 self.config.ENABLE_USER_CREATE_ORG_REPO = 0
assert bool(self.config.ENABLE_USER_CREATE_ORG_REPO) is False assert bool(self.config.ENABLE_USER_CREATE_ORG_REPO) is False
resp = self.client.get(self.url) resp = self.client.get(self.url)
self.assertEqual(200, resp.status_code) self.assertEqual(200, resp.status_code)
assert resp.context['can_add_pub_repo'] is False assert resp.context['can_add_public_repo'] is False
# logout # logout
self.logout() self.logout()
@ -61,14 +61,14 @@ class LibrariesTest(BaseTestCase):
resp = self.client.get(self.url) resp = self.client.get(self.url)
self.assertEqual(200, resp.status_code) self.assertEqual(200, resp.status_code)
assert resp.context['can_add_pub_repo'] is True assert resp.context['can_add_public_repo'] is True
self.config.ENABLE_USER_CREATE_ORG_REPO = 0 self.config.ENABLE_USER_CREATE_ORG_REPO = 0
assert bool(self.config.ENABLE_USER_CREATE_ORG_REPO) is False assert bool(self.config.ENABLE_USER_CREATE_ORG_REPO) is False
resp = self.client.get(self.url) resp = self.client.get(self.url)
self.assertEqual(200, resp.status_code) self.assertEqual(200, resp.status_code)
assert resp.context['can_add_pub_repo'] is True assert resp.context['can_add_public_repo'] is True
def test_get_user_joined_groups(self): def test_get_user_joined_groups(self):
self.login_as(self.user) self.login_as(self.user)