mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-03 07:55:36 +00:00
Add setting to enable/disable organization repo creation
This commit is contained in:
@@ -71,7 +71,7 @@ from seahub.utils import gen_file_get_url, gen_token, gen_file_upload_url, \
|
||||
gen_block_get_url, get_file_type_and_ext, HAS_FILE_SEARCH, \
|
||||
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, \
|
||||
gen_shared_upload_link, convert_cmmt_desc_link
|
||||
gen_shared_upload_link, convert_cmmt_desc_link, enable_org_repo_creation
|
||||
from seahub.utils.repo import get_sub_repo_abbrev_origin_path
|
||||
from seahub.utils.star import star_file, unstar_file
|
||||
from seahub.utils.file_types import IMAGE, DOCUMENT
|
||||
@@ -1067,15 +1067,21 @@ class DownloadRepo(APIView):
|
||||
return repo_download_info(request, repo_id)
|
||||
|
||||
class RepoPublic(APIView):
|
||||
authentication_classes = (TokenAuthentication, )
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsAuthenticated, )
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
def post(self, request, repo_id, format=None):
|
||||
"""Set organization library.
|
||||
"""
|
||||
repo = get_repo(repo_id)
|
||||
if not repo:
|
||||
return api_error(status.HTTP_404_NOT_FOUND, 'Library not found.')
|
||||
|
||||
if not enable_org_repo_creation(request):
|
||||
return api_error(status.HTTP_403_FORBIDDEN,
|
||||
'Failed to share library to public: permission denied.')
|
||||
|
||||
if check_permission(repo_id, request.user.username) != 'rw':
|
||||
return api_error(status.HTTP_403_FORBIDDEN,
|
||||
'You do not have permission to access this library.')
|
||||
@@ -1090,13 +1096,18 @@ class RepoPublic(APIView):
|
||||
content_type=json_content_type)
|
||||
|
||||
def delete(self, request, repo_id, format=None):
|
||||
"""Unset organization library.
|
||||
"""
|
||||
username = request.user.username
|
||||
|
||||
repo = get_repo(repo_id)
|
||||
if not repo:
|
||||
return api_error(status.HTTP_404_NOT_FOUND, 'Library not found.')
|
||||
|
||||
if check_permission(repo_id, request.user.username) != 'rw':
|
||||
if not request.user.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 access this library.')
|
||||
'You do not have permission to unshare library.')
|
||||
|
||||
try:
|
||||
seafile_api.remove_inner_pub_repo(repo_id)
|
||||
@@ -3057,10 +3068,12 @@ class SharedRepo(APIView):
|
||||
|
||||
def delete(self, request, repo_id, format=None):
|
||||
"""
|
||||
Unshare a library. Only repo owner can perform this operation.
|
||||
Unshare a library.
|
||||
Repo owner and system admin can perform this operation.
|
||||
"""
|
||||
username = request.user.username
|
||||
if not seafile_api.is_repo_owner(username, repo_id):
|
||||
if not request.user.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 unshare library.')
|
||||
|
||||
@@ -3201,6 +3214,10 @@ class SharedRepo(APIView):
|
||||
|
||||
elif share_type == 'public':
|
||||
if not CLOUD_MODE:
|
||||
if not enable_org_repo_creation(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:
|
||||
|
@@ -623,6 +623,7 @@ CONSTANCE_CONFIG = {
|
||||
'ACTIVATE_AFTER_REGISTRATION': (ACTIVATE_AFTER_REGISTRATION,''),
|
||||
'REGISTRATION_SEND_MAIL': (REGISTRATION_SEND_MAIL ,''),
|
||||
'LOGIN_REMEMBER_DAYS': (LOGIN_REMEMBER_DAYS,''),
|
||||
'ENABLE_ORGANIZATION_LIBRARY': (True, ''),
|
||||
|
||||
'ENABLE_ENCRYPTED_LIBRARY': (ENABLE_ENCRYPTED_LIBRARY,''),
|
||||
'REPO_PASSWORD_MIN_LENGTH': (REPO_PASSWORD_MIN_LENGTH,''),
|
||||
|
@@ -185,7 +185,7 @@
|
||||
<div id="organization-repos" class="tab-tabs hide">
|
||||
<div class="hd">
|
||||
<h3 class="fleft">{% trans "Libraries" %}</h3>
|
||||
<button id="add-pub-lib" class="fright"><span class="icon-plus-square add vam"></span><span class="vam">{% trans "Add Library"%}</span></button>
|
||||
<button id="add-pub-lib" class="fright {% if not can_add_pub_repo %}hide{% endif %}"><span class="icon-plus-square add vam"></span><span class="vam">{% trans "Add Library"%}</span></button>
|
||||
<ul id="add-pub-lib-menu" class="hide">
|
||||
<li class="item share-existing">{% trans "Share existing libraries" %}</li>
|
||||
<li class="item create-new">{% trans "Create a new library" %}</li>
|
||||
|
@@ -69,6 +69,10 @@
|
||||
{% include "snippets/web_settings_form.html" %}
|
||||
{% endwith %}
|
||||
|
||||
{% with type="checkbox" setting_display_name="organization library" help_tip="Allow user to add organization library. If unchecked, only system admin can add library." setting_name="ENABLE_ORGANIZATION_LIBRARY" setting_val=config_dict.ENABLE_ORGANIZATION_LIBRARY %}
|
||||
{% include "snippets/web_settings_form.html" %}
|
||||
{% endwith %}
|
||||
|
||||
{% with type="input" setting_display_name="library password minimum length" help_tip="The least number of characters an encrypted library password should include." setting_name="REPO_PASSWORD_MIN_LENGTH" setting_val=config_dict.REPO_PASSWORD_MIN_LENGTH %}
|
||||
{% include "snippets/web_settings_form.html" %}
|
||||
{% endwith %}
|
||||
|
@@ -1311,3 +1311,11 @@ def within_time_range(d1, d2, maxdiff_seconds):
|
||||
# delta.total_seconds() is only available in python 2.7+
|
||||
diff = (delta.microseconds + (delta.seconds + delta.days*24*3600) * 1e6) / 1e6
|
||||
return diff < maxdiff_seconds
|
||||
|
||||
def enable_org_repo_creation(request):
|
||||
"""Whether or not enable organization library.
|
||||
"""
|
||||
if request.user.is_staff:
|
||||
return True
|
||||
else:
|
||||
return config.ENABLE_ORGANIZATION_LIBRARY
|
||||
|
@@ -53,7 +53,8 @@ from seahub.utils import render_permission_error, render_error, list_to_string,
|
||||
EVENTS_ENABLED, get_user_events, get_org_user_events, show_delete_days, \
|
||||
TRAFFIC_STATS_ENABLED, get_user_traffic_stat, new_merge_with_no_conflict, \
|
||||
user_traffic_over_limit, send_perm_audit_msg, get_origin_repo_info, \
|
||||
get_max_upload_file_size, is_pro_version, FILE_AUDIT_ENABLED
|
||||
get_max_upload_file_size, is_pro_version, FILE_AUDIT_ENABLED, \
|
||||
enable_org_repo_creation
|
||||
from seahub.utils.paginator import get_page_range
|
||||
from seahub.utils.star import get_dir_starred_files
|
||||
from seahub.utils.timeutils import utc_to_local
|
||||
@@ -1267,6 +1268,8 @@ def libraries(request):
|
||||
UserOptions.objects.disable_user_guide(username)
|
||||
|
||||
folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False
|
||||
can_add_pub_repo = True if enable_org_repo_creation(request) else False
|
||||
|
||||
return render_to_response('libraries.html', {
|
||||
"allow_public_share": allow_public_share,
|
||||
"guide_enabled": guide_enabled,
|
||||
@@ -1279,6 +1282,7 @@ def libraries(request):
|
||||
'folder_perm_enabled': folder_perm_enabled,
|
||||
'is_pro': True if is_pro_version() else False,
|
||||
'file_audit_enabled': FILE_AUDIT_ENABLED,
|
||||
'can_add_pub_repo': can_add_pub_repo,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
|
@@ -2142,12 +2142,15 @@ def sys_settings(request):
|
||||
"""List and change seahub settings in admin panel.
|
||||
"""
|
||||
|
||||
DIGIT_WEB_SETTINGS = ('DISABLE_SYNC_WITH_ANY_FOLDER', 'ENABLE_SIGNUP',
|
||||
DIGIT_WEB_SETTINGS = (
|
||||
'DISABLE_SYNC_WITH_ANY_FOLDER', 'ENABLE_SIGNUP',
|
||||
'ACTIVATE_AFTER_REGISTRATION', 'REGISTRATION_SEND_MAIL',
|
||||
'LOGIN_REMEMBER_DAYS', 'REPO_PASSWORD_MIN_LENGTH',
|
||||
'ENABLE_REPO_HISTORY_SETTING', 'USER_STRONG_PASSWORD_REQUIRED',
|
||||
'ENABLE_ENCRYPTED_LIBRARY', 'USER_PASSWORD_MIN_LENGTH',
|
||||
'USER_PASSWORD_STRENGTH_LEVEL', 'SHARE_LINK_PASSWORD_MIN_LENGTH')
|
||||
'USER_PASSWORD_STRENGTH_LEVEL', 'SHARE_LINK_PASSWORD_MIN_LENGTH',
|
||||
'ENABLE_ORGANIZATION_LIBRARY'
|
||||
)
|
||||
|
||||
STRING_WEB_SETTINGS = ('SERVICE_URL', 'FILE_SERVER_ROOT',)
|
||||
|
||||
|
70
tests/api/test_public_repo.py
Normal file
70
tests/api/test_public_repo.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import json
|
||||
|
||||
from constance import config
|
||||
from seaserv import seafile_api, ccnet_threaded_rpc
|
||||
|
||||
from seahub.test_utils import BaseTestCase
|
||||
|
||||
|
||||
class RepoPublicTest(BaseTestCase):
|
||||
def setUp(self):
|
||||
self.repo_id = self.create_repo(name='test-admin-repo', desc='',
|
||||
username=self.admin.username,
|
||||
passwd=None)
|
||||
self.url = '/api2/repos/%s/public/' % self.repo_id
|
||||
self.user_repo_url = '/api2/repos/%s/public/' % self.repo.id
|
||||
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = 1
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo(self.repo_id)
|
||||
|
||||
def test_admin_can_set_pub_repo(self):
|
||||
self.login_as(self.admin)
|
||||
|
||||
resp = self.client.post(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['success'] is True
|
||||
|
||||
def test_admin_can_unset_pub_repo(self):
|
||||
seafile_api.add_inner_pub_repo(self.repo_id, "r")
|
||||
|
||||
self.login_as(self.admin)
|
||||
|
||||
resp = self.client.delete(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['success'] is True
|
||||
|
||||
def test_user_can_set_pub_repo(self):
|
||||
self.login_as(self.user)
|
||||
|
||||
resp = self.client.post(self.user_repo_url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['success'] is True
|
||||
|
||||
def test_admin_can_set_pub_repo_when_setting_disalbed(self):
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is True
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = False
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is False
|
||||
|
||||
self.login_as(self.admin)
|
||||
|
||||
resp = self.client.post(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['success'] is True
|
||||
|
||||
def test_user_can_not_set_pub_repo_when_setting_disalbed(self):
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is True
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = False
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is False
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
resp = self.client.post(self.user_repo_url)
|
||||
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.'
|
77
tests/api/test_shared_repo.py
Normal file
77
tests/api/test_shared_repo.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import json
|
||||
from seahub.test_utils import BaseTestCase
|
||||
|
||||
from constance import config
|
||||
|
||||
from seaserv import seafile_api, ccnet_threaded_rpc
|
||||
|
||||
|
||||
class SharedRepoTest(BaseTestCase):
|
||||
def setUp(self):
|
||||
self.repo_id = self.create_repo(name='test-admin-repo', desc='',
|
||||
username=self.admin.username,
|
||||
passwd=None)
|
||||
self.shared_repo_url = '/api2/shared-repos/%s/?share_type=public&permission=rw'
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = 1
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo(self.repo_id)
|
||||
|
||||
def test_admin_can_share_repo_to_public(self):
|
||||
self.login_as(self.admin)
|
||||
|
||||
url = self.shared_repo_url % self.repo_id
|
||||
resp = self.client.put(url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert "success" in resp.content
|
||||
|
||||
def test_user_can_share_repo_to_public(self):
|
||||
self.login_as(self.user)
|
||||
|
||||
url = self.shared_repo_url % self.repo.id
|
||||
resp = self.client.put(url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert "success" in resp.content
|
||||
|
||||
def test_admin_can_set_pub_repo_when_setting_disalbed(self):
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is True
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = False
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is False
|
||||
|
||||
self.login_as(self.admin)
|
||||
|
||||
resp = self.client.put(self.shared_repo_url % self.repo_id)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert "success" in resp.content
|
||||
|
||||
def test_user_can_not_set_pub_repo_when_setting_disalbed(self):
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is True
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = False
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is False
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
resp = self.client.put(self.shared_repo_url % self.repo.id)
|
||||
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):
|
||||
seafile_api.add_inner_pub_repo(self.repo_id, "r")
|
||||
|
||||
self.login_as(self.admin)
|
||||
|
||||
url = self.shared_repo_url % self.repo_id
|
||||
resp = self.client.delete(url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert "success" in resp.content
|
||||
|
||||
def test_user_can_unshare_public_repo(self):
|
||||
seafile_api.add_inner_pub_repo(self.repo_id, "r")
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
url = self.shared_repo_url % self.repo_id
|
||||
resp = self.client.delete(url)
|
||||
self.assertEqual(403, resp.status_code)
|
||||
assert 'You do not have permission to unshare library.' in resp.content
|
46
tests/seahub/views/test_libraries.py
Normal file
46
tests/seahub/views/test_libraries.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from seahub.test_utils import BaseTestCase
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from constance import config
|
||||
|
||||
class LibrariesTests(BaseTestCase):
|
||||
def setUp(self):
|
||||
self.url = reverse('libraries')
|
||||
|
||||
def test_pub_repo_creation_config(self):
|
||||
# user
|
||||
self.login_as(self.user)
|
||||
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = 1
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is True
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert resp.context['can_add_pub_repo'] is True
|
||||
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = 0
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is False
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert resp.context['can_add_pub_repo'] is False
|
||||
|
||||
# logout
|
||||
self.client.logout()
|
||||
|
||||
# admin
|
||||
self.login_as(self.admin)
|
||||
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = 1
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is True
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert resp.context['can_add_pub_repo'] is True
|
||||
|
||||
config.ENABLE_ORGANIZATION_LIBRARY = 0
|
||||
assert bool(config.ENABLE_ORGANIZATION_LIBRARY) is False
|
||||
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
assert resp.context['can_add_pub_repo'] is True
|
Reference in New Issue
Block a user